Re: Using FindRoot on an equation involving Log terms

*To*: mathgroup at smc.vnet.net*Subject*: [mg115739] Re: Using FindRoot on an equation involving Log terms*From*: Bill Rowe <readnews at sbcglobal.net>*Date*: Wed, 19 Jan 2011 05:30:05 -0500 (EST)

On 1/18/11 at 5:51 AM, adeyoung at andrew.cmu.edu (Andrew DeYoung) wrote: >I am trying to find the root of a certain expression in Mathematica >version 7: >expr = 110.52499999999998 + (300. - 135.52499999999998/(1 - x)) (1 - >x) - 300. x - 135.52499999999998 Log[1 - x] + 135.52499999999998 >Log[x] >It appears to plot fine, for example using Plot[expr, {x, 0, >1}]. The plot shows that there should be a root at about >x=0.85. However, when I try to find this root, using for >example the >following: >FindRoot[expr, {x, 0.5}] >I get an error message: <snip> >FindRoot[expr, {x, 0.7}] >do I get the seemingly "correct" root: {x -> 0.849823}. > >Can you help me see why the FindRoot is getting stuck at {x -> >0.344678} when I use starting values far away from 0.7 or 0.8? With only one starting point, FindRoot uses Newton's method to find the root. Newton's method simply is not guaranteed to converge for arbitrary starting points. If you use the EvaluationMonitor as follows: In[23]:= {res, {evx}} = Reap[FindRoot[expr == 0, {x, .5}, EvaluationMonitor :> Sow[x]]]; evx[[;; 5]] Out[24]= {0.5,0.0682211,0.456822,0.0377306,0.414913} you can see with 0.5 as a starting point, the algorithm is not converging as you want. Contrast that with starting at 0.7 In[25]:= {res, {evx}} = Reap[FindRoot[expr == 0, {x, .7}, EvaluationMonitor :> Sow[x]]]; evx[[;; 5]] Out[26]= {0.7,1.36516,0.766516,0.917897,0.793223} With Newton's method success won't occur if the starting point is to far away from the root. There are a couple of ways around this difficulty. First you can bound the root and do: In[27]:= FindRoot[expr == 0, {x, .5, .9}] Out[27]= {x->0.849823} With two initial points which bound the root, FindRoot uses the secant method which will always converge on the desired root when there is only one root in the interval. Another approach would be to use NMimimze as follows: In[28]:= NMinimize[{Abs[expr], -1 < x < 1}, x] Out[28]= {5.86936*10^-7,{x->0.849823}} NMinimize uses different algorithms than FindRoot which are often more robust for finding a root in this manner. However, this will not always be the case without some tweaking of the settings used by NMimimize.