3

NSolve is unpredictably unreliable. I change a parameter that has no effect on the solution and get one of four outcomes: 1) both correct answers, 2) one correct answer, 3) it just returns the command back, or 4) it hangs for a long time.

Do[
  Print[r, " ",
    NSolve[
      {n1 == E^(r (1 - n1 - 0.6 n2)) n1, n2 == E^(r (1 - 1.2 (0.6 n1 + n2))) n2}
    , {n1, n2}]
  ]
, {r, 1.0, 2.0, 0.1}]

gives

1. {{n1->1.,n2->0.},{n1->0.78125,n2->0.364583}}
1.1 NSolve[{n1==E^(1.1 (1-n1-0.6 n2)) n1,n2==E^(1.1 (1-1.2 (0.6 n1+n2))) n2},{n1,n2}]
1.2 {{n1->0.78125,n2->0.364583}}
1.3 {{n1->0.78125,n2->0.364583}}
1.4 {{n1->0.78125,n2->0.364583}}
1.5 {{n1->1.,n2->0.},{n1->0.78125,n2->0.364583}}
1.6 {{n1->0.78125,n2->0.364583}}
1.7 {{n1->0.78125,n2->0.364583}}
1.8 {{n1->0.78125,n2->0.364583}}
1.9 NSolve[{n1==E^(1.9 (1-n1-0.6 n2)) n1,n2==E^(1.9 (1-1.2 (0.6 n1+n2))) n2},{n1,n2}]

and hangs on r=2.0 when I run it on Mathematica 10.4.1 on MacOS 10.11.6. I tried all of the NSolve Methods from this answer but they make no difference.

Bug? Possible workaround (not for this particular problem, but this phenomenon in general)?

Chris K
  • 20,207
  • 3
  • 39
  • 74
  • 2
    I wouldn't really rely on it for solving transcendental equations. – J. M.'s missing motivation Aug 02 '16 at 20:47
  • 1
    Do you want real or complex solutions? – Michael E2 Aug 02 '16 at 21:07
  • 1
    It's usually wise to eliminate extraneous variables and simplify equations anyway. Removing them solves the entire loop in a fraction of a second. – Feyre Aug 02 '16 at 21:07
  • 1
    there are actually four solutions. Interesting it never finds the trivial {0,0}. If you specify Reals it finds all four in some cases but still hangs on others. – george2079 Aug 02 '16 at 21:48
  • Yes, there should be four real solutions. Solving this particular problem isn't the real issue, it's that I have a function that calls NSolve on unknown arguments that might fail. Anyhow, I'll think about changing that function to not rely so heavily on NSolve. – Chris K Aug 02 '16 at 22:43

1 Answers1

4

Rationalize the equations and use rational values of r (i.e., use exact numbers) and restrict the domain to nonnegative Reals. Although this is quite slow, it works.

$Version

(*  "10.4.1 for Mac OS X x86 (64-bit) (April 11, 2016)"  *)

eqns = {
   n1 == E^(r (1 - n1 - 3/5 n2)) n1,
   n2 == E^(r (1 - 6/5 (3/5 n1 + n2))) n2,
   n1 >= 0, n2 >= 0};

Do[Print[r // N, " ",
  soln = NSolve[eqns, {n1, n2}, Reals],
  " ", And @@ (And @@ eqns /. soln)],
 {r, 1, 2, 1/10}]

(*  1. {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True

1.1 {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True

1.2 {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True

1.3 {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True

1.4 {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True

1.5 {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True

1.6 {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True

1.7 {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True

1.8 {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True

1.9 {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True

2. {{n1->0,n2->0},{n1->0,n2->0.833333},{n1->0.78125,n2->0.364583},{n1->1.,n2->0}} True  *)
Bob Hanlon
  • 157,611
  • 7
  • 77
  • 198
  • Thanks! In my quick testing, it's the Reals not the rational numbers that prevents the wrong and non-answers, which is for the better, because I can't insist on rational numbers in actual cases. Still, some r values take 2 minutes while others take 0.1 seconds. – Chris K Aug 03 '16 at 14:31
  • 2
    @ChrisK - you don't have to insist on rational numbers since you can Rationalize any equations: eqns // Rationalize[#, 0] &. NSolve will do this sometimes; but when it does, it throws a waning: "NSolve::ratnz: NSolve was unable to solve the system with inexact coefficients. The answer was obtained by solving a corresponding exact system and numericizing the result." – Bob Hanlon Aug 03 '16 at 14:48