Roots of a function
- To: mathgroup at smc.vnet.net
- Subject: [mg29404] Roots of a function
- From: Ranko Bojanic <bojanic at math.ohio-state.edu>
- Date: Sat, 16 Jun 2001 22:43:52 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
Maarten van der Burgt wrote today:
> What is the easiest solution to finding the 13 (real) roots of
> 0.05 x +Cos[x] == 0.
> I can be easily seen that there are 13 roots by plotting:
> Plot[{0.05 x,-Cos[x]},{x,-30,30}]
> but this is not sufficient for finding accurate numerical values.
> FindRoot only gives one value and it is hard to predict which root it will find
> with a specified start value:
> In[83]:= FindRoot[0.05 x +Cos[x] == 0,{x,0}]
> Out[83]= {x -> -4.96317}
> There are three roots closer to 0 then x == -4.96317
> An NSolve only works for polynomials.
> Is there no simple way to find all roots of such an equation, eventually within
> a specified range.
> thanks for your help
> Maarten van der Burgt
> Leuven
Newton's method does not work here well with the initial value 0 because the
derivative of
f[x] = 0.05 +Cos[x]
is small at 0. The best procedure in cases like
this is to find a list of intervals which contain a zero and then use the
function FindRoot[f[x]==0,{x, {x1,x2}}]. The function
zIntList[f_, a_, b_, h_] :=
Select[Partition[Range[a,b,h],2,1],f[First[#]]*f[Last[#]]<0&]
produces the list of 13 intervals:
int = zIntList[f, -20, 20, 0.1]
{{-19.2,-19.1},{-18.5,-18.4},{-13.5,-13.4},{-11.7,-11.6},{-7.5,-7.4},
{-5.,-4.9},{-1.5,-1.4},{1.6,1.7},{4.4,4.5},{8.2,8.3},{10.4,10.5},
{14.9,15.},{16.3,16.4}}
and
Map[ FindRoot[f[x] == 0,{x,#}]& , int]
gives the list of zeros:
{{x -> -19.1433},{x -> -18.4538},{x -> -13.4028},{x -> -11.6152},
{x -> -7.47114},{x -> -4.96317},{x -> -1.49593},{x -> 1.65357},
{x -> 4.48616},{x -> 8.28087},{x -> 10.446},{x -> 14.984},
{x ->16.324}}
Ranko
bojanic at math.ohio-state.edu
PS. In a Mathematica based Numerical Analysis course I asked students
to find the fastest function that would produce intervals containing zeros
of a given function. My solution, given above, was somewhere in the middle.
The fastest function, found by a student (Yu Zhang) looks like this:
zIntList[f_, a_, b_, h_]:=
Module[{aLst, bLst, cLst, dLst},
aLst = Range[(b-a)/h]*h+a;
bLst=f[aLst];
cLst=Sign[Take[bLst, Length[bLst]-1]*Take[bLst,1-Length[bLst]]];
dLst=Flatten[Position[cLst,-1]];
Return[Transpose[{aLst[[dLst]], aLst[[dLst]]+h}]]];