# Matlab code for solving nonlinear equations

6 views (last 30 days)
Asma on 24 Sep 2022
Commented: John D'Errico on 24 Sep 2022
How can I solve three nonlinear equations to get the closest real solutions and not complex numbers.
Walter Roberson on 24 Sep 2022
Taking the cosine of 55 radians is... unusual. Perhaps you want the cosine of 55 degrees instead?

John D'Errico on 24 Sep 2022
Edited: John D'Errico on 24 Sep 2022
Actiiually, this is almost trivial. Seriously. It is. All of the trig terms are just known constants. And everything else is in terms of sqrt(n), sqrt(d), and sqrt(p). Right? And sqrt(21.8*d) is just sqrt(21.8)*sqrt(d). So we can extract each of those constants out of the sqrt.
I'll assume you really wanted to assume degrees there, as cos(55.7) is silly in terms of radians. Every time in the history of mankind, when a nivice writes something like cos(55.7), they REALLY mean for that to be in DEGREES. But in MATLAB, cos and sin are functions of numbers in RADIANS. So you need to use cosd, not cos.
syms d n p real
f1 = (1+cosd(55.7))*72.8-2*(sqrt(21.8*d)+sqrt(25.5*p)+sqrt(25.5*n))
f1 =
f2 = (1+cosd(76.6))*58-2*(sqrt(39*d)+sqrt(39.6*p)+sqrt(2.28*n))
f2 =
f3 = (1+cosd(43.1))*50.8-2*(sqrt(50.8*d))
f3 =
You want only the real solutions. So we know that n,d, and p must always be positive values. A question is, when you write sqrt(n), for example, do you allow either branch of the sqrt? Thus do you actually mean +/- sqrt(n)? Or are you taking only the positive branch in each case? Be CLEAR when you write a question, else you will get a random answer as we try to guess what is your true question.
For example, I see the third equation contains ONLY d. That means there would be two solutions, IF you allowed the negative as well as the positive branch. Anyway, solve should be able to give you the value of d.
dsol = solve(f3,d)
dsol =
vpa(dsol)
ans =
38.016961093707107403435038236245
Given that, we can substitute back into the other equations, to get
f1 = subs(f1,d,dsol)
f1 =
f2 = subs(f2,d,dsol)
f2 =
Can we solve them?
solve(f1,f2,'returnconditions',true)
ans = struct with fields:
n: [0×1 sym] p: [0×1 sym] parameters: [1×0 sym] conditions: [0×1 sym]
So solve finds no solutions. If a real solution existed, it would have had no problems with these equations. And that suggests that again, you may be needing to allow either branch of the sqrt. But your question was to find the closest real solution to the problem as posed. (Sorry, but too often, people pose problems, not really understanding what they have written, or asked for.)
Anyway, I'll use a simple substitution here, by elminating the sqrts. We will recover them later. Thus...
syms P N real
F1 = simplify(subs(f1,[n,p],[N^2,P^2]))
F1 =
F2 = simplify(subs(f2,[n,p],[N^2,P^2]))
F2 =
That gives us two LINEAR equations in the absolute values of N and P.
NPsol = solve(F1,F2,[N,P],'returnconditions', true)
NPsol = struct with fields:
N: [0×1 sym] P: [0×1 sym] parameters: [1×0 sym] conditions: [0×1 sym]
So if N and P are forced to be real numbers, there are no solutions to those equations. If we allowed any solutions, positive or negative, we would find at least one of those numbers will be negative, and since they are absolute values, that won't work.
Let me first get rid of the absolute values.
syms NN PP
F1hat = subs(F1,[abs(N),abs(P)],[NN,PP])
F1hat =
F2hat = subs(F2,[abs(N),abs(P)],[NN,PP])
F2hat =
[A,b] = equationsToMatrix([F1hat==0,F2hat==0],[NN,PP])
A =
b =
Does a solution exist for that problem?
vpa(A\b)
ans =
And therein lies your problem. For a solution to exist, we must have sqrt(P) be a negative number. (Again, that negative branch of the sqrt rears its ugly head again.) The closest real solution therefore has P=0, and therefore p=0. Or we could just use lsqnonneg now.
NP = lsqnonneg(double(A),double(b))
NP = 2×1
4.9609 0
So the solution to your problem (as posed) reduces to
npq = [NP.^2;double(dsol)]
npq = 3×1
24.6108 0 38.0170
But still, I have some fears that your problem will change. Perhaps you really do intend for those constants inside the cosine calls to be in radians, not degrees as I assumed. Or perhaps you are willing to allow either branch of the sqrt in those equations.
John D'Errico on 24 Sep 2022
Then I gave you the solution.

Sam Chak on 24 Sep 2022
Since you generally asked for any three nonlinear equations, I guess you just need to constrain the solver/algorithm to take only the integer values.
Otherwise, you can try this as shown in the example:
intcon = 1;
rng default % For reproducibility
fun = @(x) (x - 3.25).^2;
A = [];
b = [];
Aeq = [];
beq = [];
lb = [];
ub = [];
nonlcon = [];
x = ga(fun, 1, A, b, Aeq, beq, lb, ub, nonlcon, intcon)
Optimization terminated: average change in the penalty fitness value less than options.FunctionTolerance and constraint violation is less than options.ConstraintTolerance.
x = 3
Asma on 24 Sep 2022
I actually meant real numbers not integer numbers

Walter Roberson on 24 Sep 2022
In the general case that could be difficult and time consuming. For example the nonlinear system might be describing Elliptic Curve Cryptography.
Nonlinear systems often have multiple local minima, sometimes a large or infinite number of them. Finding the nearest integer solution could require finding all of those minima and testing all combinations of round() +/- 1 and picking out the one with the lowest residue.
Now, there are certainly some nonlinear systems that are less work than that, but finding the combination that is certain to be the closest integer solution is generally a hard problem.