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}]]];