Message Boards Message Boards

0
|
7231 Views
|
8 Replies
|
3 Total Likes
View groups...
Share
Share this post:

FindRoot troubles

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:
POSTED BY: Michael Paterson
8 Replies
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 BY: Frank Kampas
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 BY: Udo Krause
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 BY: Frank Kampas
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 BY: Frank Kampas
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.
POSTED BY: Michael Paterson
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 BY: Michael Paterson
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 BY: Michael Paterson
x_?NumberQ and x_?NumericQ seem to deal with my actual problems nicely. Thank you guys for helping me with this.
POSTED BY: Michael Paterson
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract