Message Boards Message Boards

What's the difference between plotting and solving?

GROUPS:

Hello community,

this is something that's been bugging me for a long time, I simply don't get it: Why can Mathematica plot some functions without any problem, but not numerically solve an equation containing this function? I mean, I can see that Mathematica obviously calculated the values for plotting. Now why can't NSolve just use these values, compare them to the value I want to solve for (e.g., 0) and then tell me for which x the function f(x) is closest to 0? I had to build my own functions doing exactly that, and that's cumbersome and very prone to errors since I'm not a programmer.

Any insight provided to me about this issue is appreciated!

POSTED BY: Sebastian Neumann
Answer
18 days ago

Sebastian,

Nsolve always works for me. Please give an example of code that has an issue so we can see how you are using it.

Regards

POSTED BY: Neil Singer
Answer
18 days ago

As already noted, it is difficult to respond to a question like this in absence of code for an example. Taking a guess I would surmise that no restriction was given to NSolve for where the solutions(s) might be located (Reals, an interval of the form a<=x<=b, etc.) and if the unrestricted solution set is perhaps infinite it cannot give a result.

POSTED BY: Daniel Lichtblau
Answer
18 days ago

Another reason is that they use different algorithms and sometimes domains (Complexes, Reals).

For a Plot-like solver for the real roots of a smooth function over an interval, consider this:

{x -> #} & /@ Reap[
   NDSolve[{y'[x] == f, y[a] == (f /. x -> a), 
     WhenEvent[f == 0, Sow[x, "root"]]}, {}, {x, a, b}],
   "root"
   ][[2, 1]]

WhenEvent uses FindRoot under the hood. Of course it might well miss double roots, just like Plot, that NSolve might actually catch.

Example:

NSolve[Re@PolyLog[2, x] - Sin[x] + x/10 == 0 && 1 < x < 100, x]
(*
NSolve::nsmet: This system cannot be solved with the methods available to NSolve.

NSolve[x/10 + Re[PolyLog[2, x]] - Sin[x] == 0 && 1 < x < 100, x]
*)

ClearAll[nsolve];  (* general solver based on the above idea *)
nsolve[eq_, {x_, a_, b_}] := Module[{y},
  With[{f = eq /. Equal -> Subtract},
   {x -> #} & /@ Reap[
      NDSolve[{y'[x] == f, y[a] == (f /. x -> a), 
        WhenEvent[f == 0, Sow[x, "root"]]}, {}, {x, a, b}],
      "root"
      ][[2, 1]]
   ]];

roots = nsolve[Re@PolyLog[2, x] - Sin[x] + x/10 == 0, {x, 1, 100}]
(*
{{x -> 19.7212}, {x -> 21.2187}, {x -> 25.7155}, {x -> 27.743}, {x -> 
   31.8867}, {x -> 34.0993}, {x -> 38.1639}, {x -> 40.3583}, {x -> 
   44.523}, {x -> 46.5435}, {x -> 50.9595}, {x -> 52.6584}, {x -> 
   57.4995}, {x -> 58.675}}
*)

Plot[Re@PolyLog[2, x] - Sin[x] + x/10, {x, 1, 100}, 
 Mesh -> {x /. roots}, MeshStyle -> Red]

enter image description here

POSTED BY: Michael Rogers
Answer
17 days ago

Ted Ersek's package RootSearch fills in quite nicely for the missing built-in functionality.

POSTED BY: Gianluca Gorni
Answer
17 days ago

Yes, I have never understood why Ted's RootSearch code has not been made part of regular Mathematica! In my experience it works very well, finding multiple roots - crossings and zeros, and even though it's specialized to searching along a line this is one of the most common applications and IS missing functionality. Also, I don't understand why FindRoot, when given a domain doesn't stay within the domain.

POSTED BY: David J M Park Jr
Answer
16 days ago

In this Stackexchange answer, Adam Strzebonski showed a way to get complex roots from System`TRootsDump`GuessRoots[f, {a, b}, False], where f is a pure function. For real roots one can use System`TRootsDump`GuessRealRoots[f, {a, b}]. These use ContourPlot and Plot respectively to approximate the roots. The results can be polished with FindRoot.

It's not clear to me how they plug into the high-level solvers.

POSTED BY: Updating Name
Answer
14 days ago

Group Abstract Group Abstract