Re: FindRoot problem

*To*: mathgroup at smc.vnet.net*Subject*: [mg4856] Re: FindRoot problem*From*: Robert Knapp <rknapp>*Date*: Thu, 26 Sep 1996 22:42:16 -0400*Organization*: Wolfram Research*Sender*: owner-wri-mathgroup at wolfram.com

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] ====