Computational Lab in Physics: Finding roots of nonlinear functions. Steven Kornreich www.beachlook.com Picture above shows the function exp(x)*log(x)-cos(x) in the interval x=0-4. The function crosses the ordinate axis at some value, called the root. We can find roots of nonlinear equations numerically when an analytic solution is not possible. Finding roots of “simple” polynomials Quadratic equation ax2+bx+c=0 x=(-b±(b2-4ac))/2a Cubic equation x3+ax2+bx+c=0 Scipione del Ferro p a x u 3u 3 a2 p b 3 2a 3 9ab q c 27 2 3 q q p u3 2 4 27 Niccolo Fontana Tartaglia 2 Many nonlinear functions cannot be given in closed form: Need numerical approach. Bisection Method Simplest and most robust. How does it work: We want to find the roots of f(x), i.e. f(x)=0. Start with an interval [a,b] such that f(x) changes sign in the interval. f(x) is continuous in [a,b] f(a)f(b)<0 There must be at least one real root on the interval [a,b]. 3 Example: f(x)=ln(x)-cos(5x) Interval: Function at the boundaries: a=0.2 b=2 f(a)=-2.149 f(b)=1.53 Therefore: f(a)f(b)<0 At least one root. From graph, we see there are actually 3 roots. Bisection will find one of the roots. Multiple bisections will find the rest. 4 Bisection procedure Divide the interval [a,b] into two equal intervals. (Hence the name) Middle point x1=(a+b)/2. Three possibilities 0, root in [a, x1 ] f (a) f ( x1 ) 0, root in [ x1 , b] 0, root is x 1 If x1 is not the root, we have a new interval. Bisect new interval and test. 5 Example Procedure: f(x)=ln(x)-cos(5x) Interval [0.2,2] 1st Iteration: [ ] 2nd Iteration f(a)=-2.149, f(b)=1.53 x1=(a+b)/2=1.1, f(x1)=-0.61 New interval [1.1,2] x2=1.55, f(x2) = 0.33 New interval [1.1,1.55] 3rd Iteration x3= 1.325, f(x3) = -0.66 New Interval [1.325,1.55] 6 Continue iterating… When do you stop? Convergence criteria: Want f(xi)=0 for the true root. Usually set |f(xi)|<d for a small number. Smaller d, closer to the true root. Small d might require more iterations. Interval size: alternately, can use |xi-xi-1|<d. For our example d=10-2, needs 9 iterations: d=10-3, needs 12 iterations: xr=1.49, f(xr)=6.9 x 10-3. xr=1.489, f(xr)=-1.2 x 10-5. d=10-5, needs 18 iterations: xr=1.48892, f(xr)=6.9 x 10-6. 7 Bisection Method in ROOT while (fabs(func->Eval(x_root))>delta) { ++iteration; TF1* func = new TF1("func","log(x)cos(5*x)",0,3); func->SetNpx(1000); TCanvas* funcCnv = new TCanvas("funcCnv","Function",500,500); func->Draw(); TLine* xaxis = new TLine(0,0,3,0); xaxis->Draw(); double lowLim=0.2; double uppLim=2; double x_root = uppLim; size_t iteration = 0; double delta = 1e-5; // // Here is the calculation using the bisection method x_root=(lowLim+uppLim)/2.0; cout << "x_" <<iteration <<" = " << x_root; cout << ", f(x)= " << func->Eval(x_root) << endl; if (func->Eval(x_root)==0.0) break; if (func->Eval(lowLim)*func->Eval(x_root)<0) { uppLim=x_root; } else { lowLim=x_root; } } TMarker* rootMarker = new TMarker(x_root,func->Eval(x_root),20); rootMarker->SetMarkerColor(4); rootMarker->SetMarkerSize(1.5); rootMarker->Draw("same"); 8 Newton’s Method Use a Taylor expansion of the function: f '( x0 ) 2 f ''( x0 ) 3 f '''( x0 ) f ( x) f ( x0 ) ( x x0 ) ( x x0 ) ( x x0 ) 1 2! 3! Keep only first two terms f ( x) f ( x0 ) ( x x0 ) f '( x0 ) Linear approximation, the root of this approximation is then x1 = x0 - f (x0 ) / f '(x0 ) If x1 is not a root, repeat the procedure around x1. For many classes of function, speeds up the method. Note: It also has weaknesses: Very slow convergence if f’(x)~0 near the root. Local minima cause wild jumps from one point to the next. 9 Example: f(x)=ln(x)-cos(5x) For precision 10-5. x_1 = 2, f(x)= 1.53221871 x_2 = 2.690155793, f(x)= 0.3558518309 x_3 = 2.606217121, f(x)= 0.06395045778 x_4 = 2.581850754, f(x)= 0.006717235596 x_5 = 2.578603106, f(x)= 0.0001236111542 10 Combination of Newton+Bisection Newton Method drawbacks: When close to root: If x1 is far, f’(x1) could have opposite sign than near f’(x_root): numerical derivative error ~ root value. Subsequent iterations diverge! Solution: combine Newton+Bisection Select interval [a,b] containing root. If x2 in [a,b] for Newton method, ok. Otherwise use bisection to determine x2. 11 Assignments Chapter 7, Section 7.5 1. and 2. Bisection Method in ROOT Write a program for the bisection method in ROOT. Use the function: f(x)=exp(x)ln(x)-cos(x)=0 Find a root between x=[0,4], precision 10-8. Plot the function and put a blue, square marker at location of root. use TF1’s for the function, use TMarker’s for the marker. 3. and 4. Write a program for Newton’s method in ROOT. Compare the effectiveness of the bisection method and Newton’s method for 3 x - 2x - 2 = 0 This has a single root in [-4,2] Plot the function, and put a red circle at location of root. To compare effectiveness, have your program print out each iteration. Show how many iterations are needed to reach a precision of 10-8. 12