# Solving 5 nonlinear equations, is there a suitable way?

I'm trying to solve a set of 5 nonlinear equations using NSolve:

exp1 := y*E^(x - z) == 18 a*x + b*y
exp2 := E^(x - z) == 8 a*y + b (x + z)
exp3 := -y*E^(x - z) == 72 a*z + b*y
exp4 := 9 x^2 + 4 y^2 + 36 z^2 == 36
exp5 := x*y + y*z == 1
NSolve[{exp1, exp2, exp3, exp4, exp5}, {x, y, z, a, b}, Reals]


But after 30 minutes running it gives me nothing and I stopped running it because I've thought that I did something wrong or used a non-suitable method. So my question is: Why Mathematica cannot solve this problem in the way that I've asked for?

AbsoluteTiming[
xyz = Reduce[{exp1, exp2, exp3, exp4, exp5, Element[{x, y, z}, Reals]}, {x, y, z}, {a, b}];
ans = NSolve[{exp1, exp2, exp3, xyz}, {x, y, z, a, b}] // Quiet;
]
ans
{exp1, exp2, exp3, exp4, exp5} /. ans


Output

{0.466927, Null}
{{x -> 0.222444, y -> -2.15701, z -> -0.686049, a -> -0.200401, b -> 2.10858},
{x -> 0.155142, y -> 0.904622, z -> 0.950293, a -> -0.0124473, b -> 0.489938},
{x -> -1.95192, y -> -0.545867, z -> 0.119973, a -> 0.00314125, b -> -0.0762384},
{x -> 1.13873, y -> 1.76806, z -> -0.573138, a -> 0.317141, b -> 1.86267}}

{{True, True, True, True, True}, {True, True, True, True, True},
{True, True, True, True, True}, {True, True, True, True, True}}

• Thank you so much for your answer, it solved my problem. But what I have not understood is why does we need to split the variablems in two parts ({x, y, z}, {a, b}) when you used Reduce? I know that this is essential for the program quickness, but I don't know what is it mean Nov 9, 2019 at 22:27
• @fercc My pleasure. See reference.wolfram.com/language/tutorial/…. It also applies to Reduce. Nov 10, 2019 at 2:15

Introduce a sixth variable for the exponential term

    eq6 = E^(x - z) == exz
{eq1, eq2, eq3, eq4, eq5} ={exp1, exp2, exp3, exp4, exp5} /. E^(x - z) -> exz


And tell NSolve all variables are Reals

    (nsol = NSolve[And @@ {eq1, eq2, eq3, eq4, eq5, eq6} &&
Element[{x, y, z, a, b, exz}, Reals], {x, y, z, a, b, exz}]) // Timing

{0.641, {{x -> -1.95192, y -> -0.545867, z -> 0.119973,
a -> 0.00314125, b -> -0.0762384, exz -> 0.125947},
{x -> 0.155142,y -> 0.904622, z -> 0.950293, a -> -0.0124473, b -> 0.489938,
exz -> 0.451513},
{x -> 0.222444, y -> -2.15701, z -> -0.686049, a -> -0.200401, b -> 2.10858,
exz -> 2.48058},
{x -> 1.13873, y -> 1.76806, z -> -0.573138, a -> 0.317141, b -> 1.86267,
exz -> 5.5393}}}

{eq1, eq2, eq3, eq4, eq5, eq6} /. nsol

{{True, True, True, True, True, True}, {True, True, True, True, True, True},
{True, True, True, True, True, True}, {True, True, True, True, True, True}}


Even Solve is very fast.

    (sol = Solve[And @@ {eq1, eq2, eq3, eq4, eq5, eq6} &&
Element[{x, y, z, a, b, exz}, Reals], {x, y, z, a, b, exz}]); // Timing

{0.797, Null}


Try

exp1 = y*E^(x - z) == 18 a*x + b*y;
exp2 = 18 a*x + b*y == y*(8 a*y + b (x + z));
exp3 = 0 ==  18 a*x + 72 a*z +2 b*y;
exp4 = 9 x^2 + 4 y^2 + 36 z^2 == 36;
exp5 = x*y + y*z == 1;
Reduce[{exp1, exp2, exp3, exp4, exp5}, {x, y, z, a, b}]


which adds some of your equations to others to eliminate some of the exponentials AND it removes the Reals argument which I have seen greatly slows things down at times.

Perhaps you can extract the Real solutions once you see the results.

Check all this very carefully to make certain it is still correct.

• There is an improvement: exp1 = 0 == y*(8 a y + b (x + z)) + 72 az + by; can be taken instead of your exp1. Then we deal with a system of polynomial equations. Nov 9, 2019 at 7:57