Arturas Acus wrote:
>
> Dear All,
>
> I came to the conclusion that FindRoot sometimes behaves a bit
> strange. Say I want to calculate:
> x=x/.First[FindRoot[(x-Pi),{x,-4,4},AccuracyGoal->20, WorkingPrecision->30,
> Compiled->False,MaxIterations->Infinity]
>
> The result of this is MachineNumber!!! It seems, problem is related
> with evaluation of Pi. And hint N[Pi,30] do not help!!
>
> Then I tried:
>
> x=x/.First[FindRoot[x-Rationalize[N[Pi,30],0],{x,{-4,4}},
> Compiled->False,AccuracyGoal->20,MaxIterations->Infinity,
> WorkingPrecision->30]]
>
> 3.141592653589793238462643383279
>
> Now it works correct. Does anybody had similar problem?
> I tried two methods: secant and brent's. Both gives the same
> results. Can anybody explain this behaviour? This is important for my
> job.
> Sincerely
> Arturas Acus
>
This is an unusual case, but can be easily explained.
When you specify WorkingPrecision->30, this is the maximum precision
that FindRoot will use, and also the precision to which the given
equations are numericized to initially. However, because of the
superlinear convergence of the methods used in FindRoot, typically, the
iterations start with machine numbers, and the precision is increased as
the root is approached.
This can save a substatial amount of time, particularly for very high
accuracy goals.
So why has this stopped in machine numbers? Well, since the function is
linear, FindRoot finds the root on the first step. But for the first
step, it has used machine numbers. The stopping criterion is that the
Accuracy of the objective function be 20 or greater. With the value
In[2]:=
root = First[FindRoot[(x-Pi),{x,-4,4},AccuracyGoal->30,
WorkingPrecision->30,
Compiled->False,MaxIterations->1000]]
Out[2]=
x -> 3.14159
we substitute into the numericized function,
In[3]:=
x - N[Pi,30] /. root
Out[3]=
0.
This is a machine zero. Its Accuracy is
In[4]:=
Accuracy[%]
Out[4]=
308
So FindRoot has worked as advertised.
At zero there is a singularity in the precision model used by
Mathematica. The accuracy of a machine 0 is tied to the size of the
minimum (normalized) machine number, which on my machine is
In[5]:=
$MinMachineNumber
Out[5]=
-308
1.11254 10
I have explained why FindRoot has done what it did, but haven't yet
helped much in getting you what you want--a bignum approximation to Pi
found through FindRoot. There are a few ways to do this.
If your function was even a little bit nonlinear, this would be very
unlikely to happen. For linear functions, a command which should get
faster results, to the precision you desire would be NSolve:
In[7]:=
NSolve[x-Pi == 0,x,30]
Out[7]=
{{x -> 3.14159265358979323846264338328}}
give the answer with 30 digits of precision.
On the other hand, if you need to use FindRoot because your function may
or may not be linear and you don't want to test, there is also a good
option. You can prevent FindRoot from using machine numbers or lower
precision numbers by setting the variable $MinPrecision.
In[8]:=
$MinPrecision = 30
Out[8]=
30
In[9]:=
bigroot = First[FindRoot[(x-Pi),{x,-4,4},AccuracyGoal->30,
WorkingPrecision->30,
Compiled->False,MaxIterations->1000]]
Out[9]=
x -> 3.14159265358979323846264338328
Don't forget to reset $MinPrecision to it default value (0) after doing
this, or you will slow down Mathematica substatially.
Rob Knapp
Wolfram Research
==== [MESSAGE SEPARATOR] ====