Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
1397 views
%auto sage.plot.graphics.Graphics.SHOW_OPTIONS['figsize']=4

Newton's Method

Newton's Method is a tool that uses calculus to estimate the roots (zeros or x-intercepts) of a function.

In a previous lab, we considered the find_root and solve commands in Sage, which can be used to find roots. The purpose of this lab is to give us some idea of the math behind these commands. There is no practical reason to use Newton's Method (unless you really need to find a root without a computer/calculator). However, it is instructive to see how calculus (which is not directly related to roots) can be used to estimate roots.

Newton's basic idea is that a differentiable function is "close" to its tangent lines (at least near the point of tangency). So if we know the root of a tangent line (easy algebra), we suppose that the root of the function is somewhere close.

Example 1

Estimate the roots of f(x)=x2+2x1f(x)=x^2+2x-1. [Of course, we can find the roots of a quadratic function with the Quadratic Formula, but it's just an example.] Let's look at a graph:

f(x)=x^2+2*x-1 plot(f,xmin=-5,xmax=5)

From this graph, it appears that there is a root near x=12x=\frac{1}{2}.

Let's find the tangent line at this point. Remember, an equation for the tangent line at x=ax=a is y=f(a)+f(a)(xa)y=f(a)+f'(a)(x-a).

f(x)=x^2+2*x-1 df(x)=derivative(f,x) #find the derivative TL(x)=f(1/2)+df(1/2)*(x-1/2) #find the tangent line print 'The tangent line is y =',TL(x) plot(f,xmin=0,xmax=1)+plot(TL,xmin=0,xmax=1,color='red')+point((1/2,f(1/2)),color='black',size=25)
The tangent line is y = 3*x - 5/4

Notice that the tangent line and the graph of ff are close together near x=12x=\frac{1}{2}, and we can see that the root of the tangent line is close to the root of ff.

Sage gives the equation of the tangent line as y=3x54y=3x-\frac{5}{4}. To find the root of this line, just plug in 0 for yy and solve for xx:

0=3x540=3x-\frac{5}{4}

54=3x\frac{5}{4}=3x

543=x\frac{\frac{5}{4}}{3}=x

x=5120.41666x=\frac{5}{12}\approx 0.41666

Let's zoom in on the graph and plot this root.

f(x)=x^2+2*x-1 df(x)=derivative(f,x) TL(x)=f(1/2)+df(1/2)*(x-1/2) plot(f,xmin=0.4,xmax=.5)+plot(TL,xmin=0.4,xmax=.5,color='red')+point((5/12,0),size=25,color='black')+point((1/2,f(1/2)),color='black',size=25)

On this window, we can see that the root of ff is not exactly 512\frac{5}{12}, but this is a good approximation.

If we want a better approximation, we can repeat the process, starting with a point of tangency that's closer to the root. Remember we started this example using x=12x=\frac{1}{2} as our point of tangency. This time, we'll use x=512x=\frac{5}{12}, the approximation we got last time. We can see from the graph that this is closer to the root of ff than 12\frac{1}{2}, so the tangent line we get from x=512x=\frac{5}{12} should be even closer to the actual root of ff.

So let's find a new tangent line:

f(x)=x^2+2*x-1 df(x)=derivative(f,x) TL(x)=f(5/12)+df(5/12)*(x-5/12) print 'The tangent line is y =',TL(x) plot(f,xmin=.41,xmax=.42)+plot(TL,xmin=.41,xmax=.42,color='red',linestyle='--')+point((5/12,f(5/12)),size=25,color='black')
The tangent line is y = 17/6*x - 169/144

We can see that the tangent line and ff are very close together on this window, so the root of the tangent line is very close to the root of ff.

Let's find the root of the tangent line:

0=176x1691440=\frac{17}{6}x-\frac{169}{144}

169144=176x\frac{169}{144}=\frac{17}{6}x

169144176=x\frac{\frac{169}{144}}{\frac{17}{6}}=x

x=1694080.414216x=\frac{169}{408}\approx0.414216

Just for comparison, let's find the exact root of ff.

f(x)=x^2+2*x-1 solve(f(x)==0,x)
[x == -sqrt(2) - 1, x == sqrt(2) - 1]

There are two solutions, x=21x=-\sqrt{2}-1 and x=21x=\sqrt{2}-1. We have been trying to estimate the postive root, which is x=210.414214x=\sqrt{2}-1\approx0.414214.

This is very close to our estimate, which is off by only 169408(21)0.0000021239\frac{169}{408}-(\sqrt{2}-1)\approx0.0000021239 (about 0.0005%0.0005\% error).

If we wanted to improve our estimate even more, then we could repeat the process again, using x=169408x=\frac{169}{408} as our new point of tangency.

I hope you see from this short example that this process involves repetition of the same steps over and over with different numbers. It lends itself very easily to be made into an algorithm that can be automated.

Let's develop the algorithm.

Generalizing Newton's Method

First, notice that we had to start the process with a point of tangency (we used 12\frac{1}{2} in our example above). The closer this point is to the actual root, the better. In fact, if our point of tangency is chosen poorly, Newton's Method might never get close to the actual root, or it might take more repetitions than we want to use.

Also notice that Newton's Method only estimates one root at a time. If we had chosen a different point of tangency, we may have ended up at the other root of ff (in our example, ff has two roots).

We'll use a graph to get a ballpark estimate of the root. We'll use this initial guess as our first point of tangency. We'll call this initial guess x0x_0.

So here's the setup: We have a function ff with at least one root, and we have a ballpark guess that this root is close to x0x_0.

Now we find the tangent line to ff when x=x0x=x_0:

TL(x)=f(x0)+f(x0)(xx0)TL(x)=f(x_0)+f'(x_0)(x-x_0)

Then we find the root of the tangent line by setting it equal to 0 and solving for xx:

0=f(x0)+f(x0)(xx0)0=f(x_0)+f'(x_0)(x-x_0)

First, distribute:

0=f(x0)+f(x0)xf(x0)x00=f(x_0)+f'(x_0)*x-f'(x_0)*x_0

Then gather like terms:

f(x0)x0f(x0)=f(x0)xf'(x_0)*x_0-f(x_0)=f'(x_0)*x

Now divide both sides by f(x0)f'(x_0):

f(x0)x0f(x0)f(x0)=x\frac{f'(x_0)*x_0-f(x_0)}{f'(x_0)}=x

And simplify:

x0f(x0)f(x0)=xx_0-\frac{f(x_0)}{f'(x_0)}=x

This is the root of the tangent line, so this becomes our new estimate for the root of ff. Let's call it x1x_1. Thus,

x1=x0f(x0)f(x0)x_1=x_0-\frac{f(x_0)}{f'(x_0)}

To improve our approximation, use x=x1x=x_1 as our new point of tangency and repeat the process. The algebra is exactly the same. Simply replace all the x0x_0 in the above equations with x1x_1.

What we get is a new approximation, x2x_2, given by

x2=x1f(x1)f(x1)x_2=x_1-\frac{f(x_1)}{f'(x_1)}

In general, if we have repeated this process nn times to get an estimate xnx_n, then repeating the process again will give a new estimate, xn+1x_{n+1} given by:

xn+1=xnf(xn)f(xn)x_{n+1}=x_n-\frac{f(x_n)}{f'(x_n)}

Example 2

Now we're ready to lay out an algorithm for Newton's Method.

As I go through the steps, I'll use the example of f(x)=x3+2x1f(x)=x^3+2x-1.

Step 1 Define the function

f(x)=x^3+2*x-1

Step 2 Choose an initial value by graphing the function

plot(f,xmin=-5,xmax=5)

From this graph, we can see that ff has one (real) root, somewhere in the neighborhood of x=1x=1.

We'll use this as our initial guess. I'm going to abandon subscripts to make it easier to do this in Sage. Instead, I'll call our estimate "rr," and we'll replace rr with better approximations as we go:

r=1 #initial guess

Step 3 Define the number of repetitions

Now we have to decide how many times we want to repeat the process. I'll call this number "nn."

n=5 #number of repetitions

Step 4 Define the derivative

df(x)=derivative(f,x) #find the derivative

Step 5 Iterate Newton's Method

for i in range(n): r=r-f(r)/df(r) N(r)
0.600000000000000 0.464935064935065 0.453467173827973 0.453397654028907 0.453397651516404

Our estimates get better as we go down the list, so our best estimate for the root of ff is x0.453397651516404x\approx0.453397651516404.

Let's have Sage compute the root and compare:

solve(f(x)==0,x)
[x == -1/2*(1/18*sqrt(59)*sqrt(3) + 1/2)^(1/3)*(I*sqrt(3) + 1) - 1/3*(I*sqrt(3) - 1)/(1/18*sqrt(59)*sqrt(3) + 1/2)^(1/3), x == -1/2*(1/18*sqrt(59)*sqrt(3) + 1/2)^(1/3)*(-I*sqrt(3) + 1) - 1/3*(-I*sqrt(3) - 1)/(1/18*sqrt(59)*sqrt(3) + 1/2)^(1/3), x == (1/18*sqrt(59)*sqrt(3) + 1/2)^(1/3) - 2/3/(1/18*sqrt(59)*sqrt(3) + 1/2)^(1/3)]

The only real solution is (118593+12)1/323(118593+12)1/30.453397651516404\left(\frac{1}{18}\sqrt{59}\sqrt{3} + \frac{1}{2}\right)^{1/3} - \frac{\frac{2}{3}}{\left(\frac{1}{18}\sqrt{59}\sqrt{3} + \frac{1}{2}\right)^{1/3}}\approx0.453397651516404

To 15 decimal places, our estimate matches the actual root exactly - and that's after only 5 repetitions.

Note 1 It is possible to use Newton's Method to find complex roots as well (just start with a complex guess), but we will not do this in this class.

Note 2 As mentioned above, Newton's Method does not always work. An obvious example is when our initial guess is a local minimum or maximum. Then we get a horizontal tangent line, which has no roots.

In fact, if you choose an initial guess that is close to a local minimum or maximum, then the root of the tangent line may be very far from the root of ff (although the algorithm may eventually get back to the right place).

Example 3

Here's an example of a poor choice of initial guess. I have chosen an initial guess of x=0.1x=0.1 which is close to the minimum at x=0x=0. Although the root of the function is 21.41\sqrt{2}\approx1.41, the root of the tangent line is 10.0510.05.

f(x)=x^2-2 df(x)=derivative(f,x) TL(x)=f(.1)+df(.1)*(x-.1) plot(f,xmin=-5,xmax=10)+plot(TL,xmin=-5,xmax=10,color='red',ymax=20)

In this case, Newton's Method will eventually get back to the root, but it requires a few more repetitions.

f(x)=x^2-2 df(x)=derivative(f,x) r=.1 n=10 for i in range(n): r=r-f(r)/df(r) N(r)
10.0500000000000 5.12450248756219 2.75739213841957 1.74135758044959 1.44494338195892 1.41454033012869 1.41421360011580 1.41421356237310 1.41421356237310 1.41421356237309
N(sqrt(2)) #This is the exact answer for comparison.
1.41421356237310

Example 4

Here's another poor choice of initial guess. Consider the function f(x)=ln(3x)f(x)=\ln(3x). I'm going to choose an initial guess of x=1x=1.

Below is a graph of ff with the tangent line at x=1x=1.

Notice that the root of the tangent line is a negative number, which is not in the domain of ff. That means we can't find a new tangent line using that root for the point of tangency.

f(x)=ln(3*x) df(x)=derivative(f,x) TL(x)=f(1)+df(1)*(x-1) plot(f,xmin=0,xmax=3)+plot(TL,xmin=-1,xmax=3,color='red')

If we try Newton's Method, we end up with complex numbers!

f(x)=ln(3*x) df(x)=derivative(f,x) r=1 n=5 for i in range(n): r=r-f(r)/df(r) N(r)
-0.0986122886681098 -0.218716840163818 + 0.309799641633410*I 0.486573380029165 + 0.747851351286348*I 0.750863295538137 - 0.472094422407519*I 0.281017333228160 + 0.411360592167485*I

Newton's Method in One Cell

You can copy and paste the input below to implement Newton's Method.

Change the function ff, then hit run.

If no root is visible, adjust the plot window and run until you find a root.

Once you see a root, choose an initial guess in the ballpark of the root, change the number rr, and hit run.

Example 5

Find the roots of f(x)=x22f(x)=x^2-2.

f(x)=x^2-2 #change this (original function) plot(f,xmin=-10,xmax=10) #change the -10 and 10, if necessary r=1 #change this based on the graph (initial guess) n=10 #number of iterations df(x)=derivative(f,x) #only change the rest if you change the function's name print '' for i in range(n): r=r-f(r)/df(r) N(r)
1.50000000000000 1.41666666666667 1.41421568627451 1.41421356237469 1.41421356237310 1.41421356237310 1.41421356237310 1.41421356237310 1.41421356237310 1.41421356237310

We found a root near 1.41421.4142.

Notice how the answers stabilize after a few repetitions. This suggests we have the right answer.

For this example, the graph shows two roots. We have found the positive root; to find the negative root, change the initial guess and run it again.

r=-1 #changed to -1 n=10 for i in range(n): r=r-f(r)/df(r) N(r)
-1.50000000000000 -1.41666666666667 -1.41421568627451 -1.41421356237469 -1.41421356237310 -1.41421356237310 -1.41421356237310 -1.41421356237310 -1.41421356237310 -1.41421356237310

Now we have found the second root, around 1.4142-1.4142.

Using Newton's Method to find a point of intersection

If you have two functions, f1f_1 and f2f_2, and you want to know where they cross, then define a new function f=f1f2f=f_1-f_2 and find the roots of ff. This gives you the x-coordinate of a point of intersection. Plug this into either f1f_1 or f2f_2 to get the corresponding y-coordinate.

Example 6

Find the point of intersection of f1(x)=2sin(x)3f_1(x)=\sqrt[3]{2\sin(x)} and f2(x)=e2xf_2(x)=e^{-2x}.

f1(x)=(2*sin(x))^(1/3) f2(x)=e^(-2*x) f(x)=f1(x)-f2(x) #find the root of f1-f2 plot(f,xmin=0,xmax=1) #I have adjusted the window r=.2 #Based on the graph, the root is close to 0.2 n=5 #I'll use only 5 repetitions (Sage is a little slow with these functions, since it keeps exact values until the end). df(x)=derivative(f,x) print '' for i in range(n): r=r-f(r)/df(r) N(r)
0.174564614046446 0.175422261883443 0.175423347113948 0.175423347115679 0.175423347115679

Let's check using find_root:

find_root(f,0,.2)
0.17542334711567936

Our estimate looks good. This is the x-coordinate of the point of intersection.

To find the y-coordinate, plug this into f1f_1 or f2f_2. I'll plug it into both as a check (I'd better get the same answer).

f1(x)=(2*sin(x))^(1/3) f2(x)=e^(-2*x) N(f1(0.175423347115679)) #Note that N converts to a decimal f2(0.175423347115679)
0.704091686899284 0.704091686899285

So our point of intersection is approximately (0.175423347115679,0.704091686899284)(0.175423347115679,0.704091686899284).

Here's a graph:

f1(x)=(2*sin(x))^(1/3) f2(x)=e^(-2*x) plot(f1,xmin=0,xmax=1)+plot(f2,xmin=0,xmax=1,color='red')+point((0.175423347115679,0.704091686899284),size=25,color='black')

Newton's Method Assignment

Question 1

Estimate the roots of the function ff using the algorithm developed in class:

  • Graph the function.

  • Use the graph to choose a guess close to one root.

  • Use your guess to perform Newton's Method (use 5 iterations).

  • Repeat the process for any additional roots.

Part a

f(x)=x33x2+2x1f(x)=x^3-3x^2+2x-1

f(x)=x^3-3*x^2+2*x-1 plot(f,xmin=-10,xmax=10) r=1 n=10 df(x)=derivative(f,x) print '' for i in range(n): r=r-f(r)/df(r) N(r)
0.000000000000000 0.500000000000000 -2.00000000000000 -1.03846153846154 -0.390282147216736 0.0883881022820729 0.654971503251831 -0.427750704027271 0.0575820874905167 0.595050642800620

Part b

f(x)=3ln(x)xf(x)=3\ln(x)-x

f(x)=3*ln(x)-x plot(f,xmin=-10,xmax=10) r=1 n=10 df(x)=derivative(f,x) print '' for i in range(n): r=r-f(r)/df(r) N(r)
verbose 0 (2717: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 100 points. verbose 0 (2717: plot.py, generate_plot_points) Last error message: 'can't convert complex to float'
1.50000000000000 1.78360467567551 1.85354064971539 1.85717450334217 1.85718386014596 1.85718386020783 1.85718386020783 1.85718386020784 1.85718386020783 1.85718386020783

Question 2

Find the points of intersection of two functions f1f_1 and f2f_2:

  • Define a new function f(x)=f1(x)f2(x)f(x)=f_1(x)-f_2(x).

  • Follow the steps above to find the roots of ff. These are the x-coordinates of the points of intersection.

  • Find the y-coordinates of the points of intersection by plugging the roots into both f1f_1 and f2f_2 (you should get the same answer).

Practice your LaTeX\LaTeX: display nicely the points of intersection (ordered pairs).

Part a

f1(x)=exf_1(x)=e^x, f2(x)=2xf_2(x)=2-x [Hint: there is one answer.]

f(x)=(e^x)-(2-x) f(x)=(e^x)-(2-x) plot(f,xmin=-10,xmax=10) r=1 n=10 df(x)=derivative(f,x) print '' for i in range(n): r=r-f(r)/df(r) N(r)
0.537882842739990 0.445616748526545 0.442856724645110 0.442854401004033 0.442854401002389 0.442854401002389 0.442854401002389 0.442854401002388 0.442854401002388 0.442854401002388
f(x)=(e^x)-(2-x) f1(x)=(e^x) f2(x)=(2-x) f(x)=f1(x)-f2(x) plot(f,xmin=0,xmax=1) r=.2 n=5 df(x)=derivative(f,x) print '' for i in range(n): r=r-f(r)/df(r) N(r)
0.460464807525062 0.442948918401642 0.442854403722393 0.442854401002389 0.442854401002388
︠8612c512-a4cd-4e12-985d-543ec3599537i︠ %md #### Part b $f_1(x)=\ln(x)$, $f_2(x)=x^2-10$ [Hint: there are two answers, and one is *really* close to 0.]

Part b

f1(x)=ln(x)f_1(x)=\ln(x), f2(x)=x210f_2(x)=x^2-10 [Hint: there are two answers, and one is really close to 0.]

f(x)=(ln(x))-(x^2-10) f(x)=(ln(x))-(x^2-10) plot(f,xmin=-10,xmax=10) r=1 n=10 df(x)=derivative(f,x) print '' for i in range(n): r=r-f(r)/df(r) N(r)
verbose 0 (2717: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 100 points. verbose 0 (2717: plot.py, generate_plot_points) Last error message: 'can't convert complex to float'
10.0000000000000 5.59309472829116 3.81600111684884 3.37873051960070 3.34803793738373 3.34788419566937 3.34788419180966 3.34788419180966 3.34788419180966 3.34788419180966
f(x)=(ln(x))-(x^2-10) f1(x)=(ln(x)) f2(x)=(x^2-10) f(x)=f1(x)-f2(x) plot(f,xmin=0,xmax=1) r=.2 n=5 df(x)=derivative(f,x) print '' for i in range(n): r=r-f(r)/df(r) N(r)
-1.61533958425346 -4.62888689660294 - 1.20293132987998*I -3.37186037099793 + 0.00446537276904424*I -3.34726943869851 - 0.487248447539933*I -3.23414042847855 + 0.472435506798018*I