4
$\begingroup$

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?

$\endgroup$
0

3 Answers 3

6
$\begingroup$
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}}

$\endgroup$
2
  • $\begingroup$ 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 $\endgroup$
    – fercc
    Nov 9, 2019 at 22:27
  • $\begingroup$ @fercc My pleasure. See reference.wolfram.com/language/tutorial/…. It also applies to Reduce. $\endgroup$
    – chyanog
    Nov 10, 2019 at 2:15
3
$\begingroup$

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}
$\endgroup$
2
$\begingroup$

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.

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$
    – user64494
    Nov 9, 2019 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.