0
|
6990 Views
|
8 Replies
|
3 Total Likes
View groups...
Share
GROUPS:

# FindRoot troubles

Posted 11 years ago
 I use Mathematica 9 and am having trouble understanding 1-dimensional FindRoot, which ought to be using Brent's interval method. Problems arise when my real functions have involved Undefined as an auxiliary.For example,step[x_] := If[x < 1, -1, 1] + x/7;stepa[x_] := If[NumberQ[If[x < 1, 0, Undefined]], -1, 1] + x/7;stepb[x_] := If[NumberQ[If[x > 1, 0, Undefined]], 1, -1] + x/7;all define the same real function and give the same Plots, but{FindRoot[step, {x, 0, 2}], FindRoot[stepa, {x, 0, 2}], FindRoot[stepb, {x, 0, 2}]}yields 3 different answers, the last two not being in the initial interval [0,2]:{{x -> 1.}, {x -> -7.}, {x -> 7.}}Can anyone help? Howand why does Mathematica use the innards of the function definitions? Attachments:
8 Replies
Sort By:
Posted 11 years ago
 Udo, Thanks for ?NumericQ magic. I'll try to understand what it's doing; I haven't used that before.Frank, A good tip to use EvaluationMonitor. Thanks.I'd like to understand why FindRoot doesn't seem to do "what it says on the tin", i.e., do a proper Brent method for an interval. Maybe you have given me the tools to do it.
Posted 11 years ago
 x_?NumberQ and x_?NumericQ seem to deal with my actual problems nicely. Thank you guys for helping me with this.
Posted 11 years ago
 You could use EvaluationMonitor to see where FindRoot is going for hte different cases.  In[10]:= step[x_] := If[x < 1, -1, 1] + x/7;    In[11]:= FindRoot[step[x], {x, 0, 2}, EvaluationMonitor :> Print[x]]    During evaluation of In[11]:= 0.    During evaluation of In[11]:= 2.    During evaluation of In[11]:= 0.875  During evaluation of In[11]:= 1.4375  During evaluation of In[11]:= 1.11159  During evaluation of In[11]:= 0.976787  During evaluation of In[11]:= 1.04419  During evaluation of In[11]:= 1.00565  During evaluation of In[11]:= 0.989177  During evaluation of In[11]:= 0.997412  During evaluation of In[11]:= 1.00153  During evaluation of In[11]:= 0.999176  During evaluation of In[11]:= 1.00035  During evaluation of In[11]:= 0.99968  During evaluation of In[11]:= 1.00002  During evaluation of In[11]:= 0.999824  During evaluation of In[11]:= 0.999921  During evaluation of In[11]:= 0.999969  During evaluation of In[11]:= 0.999993  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 0.999998  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 0.999999  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.  During evaluation of In[11]:= 1.During evaluation of In[11]:= 1.During evaluation of In[11]:= 1.During evaluation of In[11]:= 1.During evaluation of In[11]:= 1.During evaluation of In[11]:= 1.During evaluation of In[11]:= 1.During evaluation of In[11]:= 1.During evaluation of In[11]:= FindRoot::brmp: The root has been bracketed as closely as possible with machine precision but the function value exceeds the absolute tolerance 1.0536712127723497*^-8. >>Out[11]= {x -> 1.}
Posted 11 years ago
 this works In[87]:= Clear[step, stepa, stepb]  step[x_] := If[x < 1, -1, 1] + x/7; stepa[x_?NumericQ] :=   If[NumberQ[If[x < 1, 0, Undefined]], -1, 1] + x/7; stepb[x_?NumericQ] :=   If[NumberQ[If[x > 1, 0, Undefined]], 1, -1] + x/7;  In[78]:= FindRoot[step[x], {x, 0, 2}] During evaluation of In[78]:= FindRoot::brmp: The root has been bracketed as closely as possible with machine precision but the function value exceeds the absolute tolerance 1.0536712127723497*^-8. >> Out[78]= {x -> 1.}In[93]:= FindRoot[stepa[x], {x, 0, 2}]During evaluation of In[93]:= FindRoot::brmp: The root has been bracketed as closely as possible with machine precision but the function value exceeds the absolute tolerance 1.0536712127723497*^-8. >>Out[93]= {x -> 1.}In[94]:= FindRoot[stepb[x], {x, 0, 2}]During evaluation of In[94]:= FindRoot::brmp: The root has been bracketed as closely as possible with machine precision but the function value exceeds the absolute tolerance 1.0536712127723497*^-8. >>Out[94]= {x -> 1.}
Posted 11 years ago
 Michael,Yes, an interval of starting methods should force Brent's method.  For further exploration, you might want to try defining your function as f[x_?NumberQ], rather than putting NumberQ inside the function.
Posted 11 years ago
 Frank,The functions I am really using don't have NumberQ explicitly. I was just trying to produce the simplest functions to illustrate the problem. All these functions evaluate to reals without apparent problems and plot nicely. What I can't understand is why Mathematica, which is supposed to be using Brent's method, uses anything other than function evaluations and produces an answer outside the initial interval. Maybe we need a Mathematica insider to explain??
Posted 11 years ago
 Mathematica uses the innards of function definitions to decide which method to use, whether or not to do symbolic or numerical differentiation, etc.  In the section "Some Notes on Internal Implementation" the description of FindRoot gives 3 methods, damped Newton's method, secant method and Brent's method.
Posted 11 years ago
 Frank,Thanks for your quick response. As I understood things, Mathematica should be using Brent's method because I gave FindRoot an interval of starting values. It ought to be pretty infallible if the values at the ends of the interval have opposite signs and it certainly should produce a result in the interval. What goes wrong here?Is it possible that under some conditions Mathematica might not use Brent's method even when two starting values are given? I found the same problem even when I specified: Method->"Brent". Can you point me to documentation on this? What I found under "Some Notes on Internal Implementation" didn't suggest such a possibility.