# What's the difference between plotting and solving?

Posted 4 years ago
4056 Views
|
6 Replies
|
5 Total Likes
|
 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! Answer
6 Replies
Sort By:
Posted 4 years 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 Answer
Posted 4 years 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. Answer
Posted 4 years 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]  Answer
Posted 4 years ago
 Ted Ersek's package RootSearch fills in quite nicely for the missing built-in functionality. Answer
Posted 4 years 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. Answer
Posted 4 years ago
 In this Stackexchange answer, Adam Strzebonski showed a way to get complex roots from SystemTRootsDumpGuessRoots[f, {a, b}, False], where f is a pure function. For real roots one can use SystemTRootsDumpGuessRealRoots[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. Answer