Root Finding

The Solutions of Nonlinear Equations f x = 0 : Root Finding
In introductory calculus we typically do problems involving the finding of extrema for
functions. This requires finding the solution of
g ′ x = 0.
If the function g is properly chosen, this can be done but, even for a lot of polynomials (let
alone the transendentals) it may not be possible to get an analytic solution - e.g. for what value
of x is x 5 − x 3 = 15 ? sin x − x = 0?, Or are there any such value?
There are many situations that arise for which we need to know at what point(s) a function
becomes equal to 0. We will take a look at the basic methods for finding such points. We will
see that each method will have its pros and cons which will suggest that we need to use some
combinations of the methods for general use.
Definition 2.3 (Root of an equation, Zero of a function). Assume that f x is a continuous
function. Any number r for which f r = 0 is called a root of the equation
f x = 0. Also we say r is a zero of the function f x.
For the simple polynomial cases
ax + b = 0
ax 2 + bx + c = 0
ax 3 + bx 2 + cx + d = 0
we can solve analytically. In other cases we may be able to find a method of factoring but, in
general, for problems that involve higher degree polynomials and transcendental functions we
have to use numerical methods.
Graphically we see that a root occurs when the graph of f x touches or crosses the x-axis.
6
4.0
4
3.5
2
-1.0
-0.5
0
0.0
-2
x0
0.5
1.0
1.5
2.0
3.0
2.5
2.5
3.0
2.0
-4
1.5
-6
1.0
-8
0.5
-10
-1.0
(A) y = x − 1 3 − 2
-0.5
x0
0.0
0.0
0.5
1.0
1.5
2.0
2.5
3.0
(B) y = x − 1 2
How do we identify such points numerically?
For case (A) we can use the simple and reliable method i.e. bisection or binary search. This is a
bracketing method.
Roots 1
The first challenge in this method is determining an interval in which the root lies. While this is
easy if we can plot the function, it may not be so easy to do numerically (it would require a
search technique).
The process is that of finding points a and b such that f a and f b have opposite signs. This is
usually done by testing
f a f b < 0.
A couple of difficulties that can arise in this when we have a root finding routine inside a larger
program-
4.0
1.0
3.5
0.8
0.6
3.0
0.4
2.5
a
0.2
b
2.0
0.0
0.90
-0.2
1.5
-1.0
1.0
-0.4
0.5
-0.6
0.0
-0.5
0.0
-0.5
0.5
1.0
1.5
2.0
2.5
0.95
1.00
1.05
1.10
-0.8
3.0
-1.0
i) The graph dips below the axis only briefly
x − 1 2 − 0.05
ii) There are several roots close together
- a slight change in a or b could lead to different roots
1000x − 0.9999x − 1.0x − 1.0001
We will assume that f is a continuous function on a, b and f af b < 0. If this is not the case
it is possible to have a sign change without the function crossing the axis.
A theorem that we need frequently is the Intermediate Value Theorem.
Theorem Assume that f ∈ Ca, b (continuous) and L is any number between f a and f b.
Then there exists a number c, with c ∈ a, b, such that f c = L.
For finding roots, we are interested in whether there is a zero in an interval. By the above, if the
f a and f b have opposite signs there is a c such that f c = 0 in a, b (there may be several).
Bisection as the name suggests operates by cutting the current interval in half
p 1 = a + b/2 or
p 1 = a + b − a/2
While it might be possible that p 1 will be such that f p 1  = 0, in general
f p 1  > 0
or
f p 1  < 0
Roots 2
p1
a
b
a
p1
b
f p 1  < 0
f p 1  > 0
Take as our new interval p 1, b and drop a
Take as our new interval a, p 1  and drop b
In either case we repeat the process and the interval (and hence the ‘error’) is cut in half each
time.
We repeat this as often as we need to.
After n times the width of the current interval is
1 b − a
2n
(assuming that we did not hit f p = 0 in the process) and we know that the root must be in the
current interval (IVT).
The Matlab code for all the algorithms in the text are available at
http://math.fullerton.edu/mathews/n2003/MatlabUsingProg.html
In order to illustrate the behaviour of root finding routines, the following functions are defined.
function y = bigroot(x)
y = (x - 1000000.1)^3;
endfunction
function y = smallroot(x)
y = (x - 0.000000000000001)^3;
endfunction
function y = root2(x)
y = x^2 - 2;
endfunction
function y = xex(x)
y = x*exp(x)-5;
endfunction
The following is the code for the bisection algorithm, converted to Scilab with changes made to
allow for display of intermediate results - including an additional argument to allow for
different outout formats..
Roots 3
function [c, err, yc, k] = bisect(f, a, b, delta, form)
//Input - f is the function input as a string ’f’
//
- a and b are the left and right endpoints
//
- delta is the tolerance
//Output - c is the zero
//
- yc= f(c)
//
- err is the error estimate for c
// NUMERICAL METHODS: Matlab Programs
// (c) 2004 by John H. Mathews and Kurtis D. Fink
// Complementary Software to accompany the textbook:
// NUMERICAL METHODS: Using Matlab, Fourth Edition
// ISBN: 0-13-065248-2
// Prentice-Hall Pub. Inc.
// One Lake Street
// Upper Saddle River, NJ 07458
ya = evstr(f+”(a)”);
// Note the change
yb = evstr(f+”(b)”);
//does not exit in Scilab if ya*yb > 0,break,end
if ya*yb > 0, error(’Not bracketed’), end
max1 = 1 + round((log(b - a) - log(delta))/log(2));
// 1 line added
printf(’
a
c
b
for k = 1:max1
c = (a + b)/2;
yc = evstr(f + ”(c)”);
// 1 line added
printf(form, a, c, b, b - a, yc)
if yc == 0
a = c;
b = c;
elseif yb*yc > 0
b = c;
yb = yc;
else
a = c;
ya = yc;
end
if b - a < delta, break,end
end
c = (a + b)/2;
err = abs(b - a);
yc = evstr(f + ”(c)”);
endfunction
b - a
f(c)\n’)
One thing to watch for in using this algorithm - if fafb > 0 it fails.
A problem can arise if this occurs in a large piece of software. How would the system react to
the error message?
A couple of possibilities would be
1. If the function fails, rather than return an error message it could return a NULL which
could be tested for;
2. A very useful technique to use when there is a possibility of failure (for example
trying to read a non-existant file or dividing by zero.
Roots 4
-->try
-->
100/0
-->catch
-->
disp(”Division by zero”)
Division by zero
-->try
-->[c err yc k] = bisect(’bigroot’, 1, 2, 0.0005, ’%15.6f %15.6f %f %f %14.5g\n’);
-->
disp(”Worked”)
-->catch
-->
disp(”Root not bracketed”)
Root not bracketed
–>end
–>try
–>
[c err yc k] = bisect(’bigroot’, 1000000, 1000001, 0.0005,
’%15.6f %15.6f %f %f %14.5g\n’);
a
c
b
b - a
f(c)
1000000.000000 1000000.500000 1000001.000000 1.000000
0.064
1000000.000000 1000000.250000 1000000.500000 0.500000
0.003375
1000000.000000 1000000.125000 1000000.250000 0.250000
1.5625e-005
1000000.000000 1000000.062500 1000000.125000 0.125000
-5.2734e-005
1000000.062500 1000000.093750 1000000.125000 0.062500
-2.4414e-007
1000000.093750 1000000.109375 1000000.125000 0.031250
8.2397e-007
1000000.093750 1000000.101563 1000000.109375 0.015625
3.8147e-009
1000000.093750 1000000.097656 1000000.101563 0.007813
-1.2875e-008
1000000.097656 1000000.099609 1000000.101563 0.003906
-5.9605e-011
1000000.099609 1000000.100586 1000000.101563 0.001953
2.0117e-010
1000000.099609 1000000.100098 1000000.100586 0.000977
9.3132e-013
–>
disp(”Worked”)
Worked
–>catch
–>
disp(”Root not bracketed”)
–>end
–>err
err =
0.0004883
Here we are seeking a root with an error of 0.0005. Do we mean to 4 decimal places?
Because the intervals have been properly chosen, we will drop the try/catch for the rest of
these examples.
-->[c err yc k] = bisect(’bigroot’, 1000000, 1000001, %eps,
’%15.6f %15.6f %f %f %14.5g\n’);
a
c
b
b - a
f(c)
1000000.000000 1000000.500000 1000001.000000 1.000000
0.064
1000000.000000 1000000.250000 1000000.500000 0.500000
0.003375
1000000.000000 1000000.125000 1000000.250000 0.250000
1.5625e-005
1000000.000000 1000000.062500 1000000.125000 0.125000
-5.2734e-005
1000000.062500 1000000.093750 1000000.125000 0.062500
-2.4414e-007
1000000.093750 1000000.109375 1000000.125000 0.031250
8.2397e-007
1000000.093750 1000000.101563 1000000.109375 0.015625
3.8147e-009
1000000.093750 1000000.097656 1000000.101563 0.007813
-1.2875e-008
1000000.097656 1000000.099609 1000000.101563 0.003906
-5.9605e-011
1000000.099609 1000000.100586 1000000.101563 0.001953
2.0117e-010
1000000.099609 1000000.100098 1000000.100586 0.000977
9.3132e-013
1000000.099609 1000000.099854 1000000.100098 0.000488
-3.1432e-012
1000000.099854 1000000.099976 1000000.100098 0.000244
-1.4552e-014
1000000.099976 1000000.100037 1000000.100098 0.000122
4.9113e-014
1000000.099976 1000000.100006 1000000.100037 0.000061
2.2738e-016
1000000.099976 1000000.099991 1000000.100006 0.000031
-7.6738e-016
1000000.099991 1000000.099998 1000000.100006 0.000015
-3.5526e-018
Roots 5
1000000.099998
1000000.099998
1000000.099998
1000000.099999
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
–>err
err =
0.
1000000.100002
1000000.100000
1000000.099999
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100006
1000000.100002
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
1000000.100000
0.000008
0.000004
0.000002
0.000001
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
1.1991e-017
5.5521e-020
-1.8733e-019
-8.6673e-022
2.9288e-021
1.3592e-023
-4.5651e-023
-2.0929e-025
7.2028e-025
3.4663e-027
-1.0822e-026
-4.2598e-029
1.9722e-028
1.5777e-030
-1.5777e-030
0
Here we are seeking a solution with an error of 2.220D-16. If this means to 15 decimal places,
then we should see if it achieves that accuracy.
One way is to see what happens if we try for less accuracy
-->[c err yc k] = bisect(’bigroot’, 1000000, 1000001, 5*10^(-11),
’%15.6f %15.6f %f %14.5g %14.5g\n’);
a
c
b
b - a
f(c)
1000000.000000 1000000.500000 1000001.000000
1
0.064
1000000.000000 1000000.250000 1000000.500000
0.5
0.003375
1000000.000000 1000000.125000 1000000.250000
0.25
1.5625e-005
1000000.000000 1000000.062500 1000000.125000
0.125
-5.2734e-005
1000000.062500 1000000.093750 1000000.125000
0.0625
-2.4414e-007
1000000.093750 1000000.109375 1000000.125000
0.03125
8.2397e-007
1000000.093750 1000000.101563 1000000.109375
0.015625
3.8147e-009
1000000.093750 1000000.097656 1000000.101563
0.0078125
-1.2875e-008
1000000.097656 1000000.099609 1000000.101563
0.0039063
-5.9605e-011
1000000.099609 1000000.100586 1000000.101563
0.0019531
2.0117e-010
1000000.099609 1000000.100098 1000000.100586
0.00097656
9.3132e-013
1000000.099609 1000000.099854 1000000.100098
0.00048828
-3.1432e-012
1000000.099854 1000000.099976 1000000.100098
0.00024414
-1.4552e-014
1000000.099976 1000000.100037 1000000.100098
0.00012207
4.9113e-014
1000000.099976 1000000.100006 1000000.100037
6.1035e-005
2.2738e-016
1000000.099976 1000000.099991 1000000.100006
3.0518e-005
-7.6738e-016
1000000.099991 1000000.099998 1000000.100006
1.5259e-005
-3.5526e-018
1000000.099998 1000000.100002 1000000.100006
7.6294e-006
1.1991e-017
1000000.099998 1000000.100000 1000000.100002
3.8147e-006
5.5521e-020
1000000.099998 1000000.099999 1000000.100000
1.9073e-006
-1.8733e-019
1000000.099999 1000000.100000 1000000.100000
9.5367e-007
-8.6673e-022
1000000.100000 1000000.100000 1000000.100000
4.7684e-007
2.9288e-021
1000000.100000 1000000.100000 1000000.100000
2.3842e-007
1.3592e-023
1000000.100000 1000000.100000 1000000.100000
1.1921e-007
-4.5651e-023
1000000.100000 1000000.100000 1000000.100000
5.9605e-008
-2.0929e-025
1000000.100000 1000000.100000 1000000.100000
2.9802e-008
7.2028e-025
1000000.100000 1000000.100000 1000000.100000
1.4901e-008
3.4663e-027
1000000.100000 1000000.100000 1000000.100000
7.4506e-009
-1.0822e-026
1000000.100000 1000000.100000 1000000.100000
3.7253e-009
-4.2598e-029
1000000.100000 1000000.100000 1000000.100000
1.8626e-009
1.9722e-028
1000000.100000 1000000.100000 1000000.100000
9.3132e-010
1.5777e-030
1000000.100000 1000000.100000 1000000.100000
4.6566e-010
-1.5777e-030
1000000.100000 1000000.100000 1000000.100000
2.3283e-010
0
–>err
err =
0.
We get the same result with a request for less accuracy. This means that we cannot get 15
decimal place accuracy. This is reasonable in view of the fact that there are 7 digits before the
Roots 6
decimal place. If we want 15 decimal place accuracy we need to use a different value for
delta. This suggests that we need to use different values for different ranges.
-->[c err yc k] = bisect(’smallroot’, 0, 1, 0.0005,
’%15.6f %15.6f %14.6f %f %14.5g\n’);
a
c
b
b - a
f(c)
0.000000
0.500000
1.000000 1.000000
0.125
0.000000
0.250000
0.500000 0.500000
0.015625
0.000000
0.125000
0.250000 0.250000
0.0019531
0.000000
0.062500
0.125000 0.125000
0.00024414
0.000000
0.031250
0.062500 0.062500
3.0518e-005
0.000000
0.015625
0.031250 0.031250
3.8147e-006
0.000000
0.007813
0.015625 0.015625
4.7684e-007
0.000000
0.003906
0.007813 0.007813
5.9605e-008
0.000000
0.001953
0.003906 0.003906
7.4506e-009
0.000000
0.000977
0.001953 0.001953
9.3132e-010
0.000000
0.000488
0.000977 0.000977
1.1642e-010
–>err
err =
0.0004883
For the smallroot example, the root is at x = 10 −15 . Notice that, using a delta value of 0.0005,
gives us a root at 0.000488. i.e. we do not have any valid digits.
-->[c err yc k] = bisect(’smallroot’, 0, 1, %eps,
’%15.6g %15.6g %14.6g %13.6g %12.5g\n’)
a
c
b
b - a
f(c)
0
0.5
1
1
0.125
0
0.25
0.5
0.5
0.015625
0
0.125
0.25
0.25
0.0019531
0
0.0625
0.125
0.125
0.00024414
0
0.03125
0.0625
0.0625 3.0518e-005
0
0.015625
0.03125
0.03125 3.8147e-006
0
0.0078125
0.015625
0.015625 4.7684e-007
0
0.00390625
0.0078125
0.0078125 5.9605e-008
0
0.00195313
0.00390625
0.00390625 7.4506e-009
0
0.000976563
0.00195313
0.00195313 9.3132e-010
0
0.000488281
0.000976563
0.000976563 1.1642e-010
0
0.000244141
0.000488281
0.000488281 1.4552e-011
0
0.00012207
0.000244141
0.000244141
1.819e-012
0
6.10352e-005
0.00012207
0.00012207 2.2737e-013
0
3.05176e-005
6.10352e-005 6.10352e-005 2.8422e-014
0
1.52588e-005
3.05176e-005 3.05176e-005 3.5527e-015
0
7.62939e-006
1.52588e-005 1.52588e-005 4.4409e-016
0
3.8147e-006
7.62939e-006 7.62939e-006 5.5511e-017
0
1.90735e-006
3.8147e-006
3.8147e-006 6.9389e-018
0
9.53674e-007
1.90735e-006 1.90735e-006 8.6736e-019
0
4.76837e-007
9.53674e-007 9.53674e-007 1.0842e-019
0
2.38419e-007
4.76837e-007 4.76837e-007 1.3553e-020
0
1.19209e-007
2.38419e-007 2.38419e-007 1.6941e-021
0
5.96046e-008
1.19209e-007 1.19209e-007 2.1176e-022
0
2.98023e-008
5.96046e-008 5.96046e-008
2.647e-023
0
1.49012e-008
2.98023e-008 2.98023e-008 3.3087e-024
0
7.45058e-009
1.49012e-008 1.49012e-008 4.1359e-025
0
3.72529e-009
7.45058e-009 7.45058e-009 5.1699e-026
0
1.86265e-009
3.72529e-009 3.72529e-009 6.4623e-027
0
9.31323e-010
1.86265e-009 1.86265e-009 8.0779e-028
0
4.65661e-010
9.31323e-010 9.31323e-010 1.0097e-028
0
2.32831e-010
4.65661e-010 4.65661e-010 1.2622e-029
0
1.16415e-010
2.32831e-010 2.32831e-010 1.5777e-030
0
5.82077e-011
1.16415e-010 1.16415e-010 1.9721e-031
0
2.91038e-011
5.82077e-011 5.82077e-011 2.4649e-032
0
1.45519e-011
2.91038e-011 2.91038e-011 3.0809e-033
0
7.27596e-012
1.45519e-011 1.45519e-011 3.8503e-034
0
3.63798e-012
7.27596e-012 7.27596e-012 4.8109e-035
Roots 7
0
0
0
0
0
0
0
0
0
0
0
0
8.88178e-016
8.88178e-016
8.88178e-016
–>err
err =
1.110D-16
1.81899e-012
9.09495e-013
4.54747e-013
2.27374e-013
1.13687e-013
5.68434e-014
2.84217e-014
1.42109e-014
7.10543e-015
3.55271e-015
1.77636e-015
8.88178e-016
1.33227e-015
1.11022e-015
9.99201e-016
3.63798e-012
1.81899e-012
9.09495e-013
4.54747e-013
2.27374e-013
1.13687e-013
5.68434e-014
2.84217e-014
1.42109e-014
7.10543e-015
3.55271e-015
1.77636e-015
1.77636e-015
1.33227e-015
1.11022e-015
3.63798e-012 6.0086e-036
1.81899e-012 7.4984e-037
9.09495e-013 9.3421e-038
4.54747e-013 1.1601e-038
2.27374e-013 1.4309e-039
1.13687e-013 1.7415e-040
5.68434e-014
2.062e-041
2.84217e-014 2.3056e-042
1.42109e-014 2.2759e-043
7.10543e-015 1.6634e-044
3.55271e-015 4.6793e-046
1.77636e-015 -1.3982e-048
8.88178e-016 3.6683e-047
4.44089e-016 1.3391e-048
2.22045e-016 -5.1061e-055
Here the root is at 9.99201e-016. We have one valid digit.
It is obvious that the stopping condition in this algorithm is inappropriate.
Rather than look at the the stopping condition for bisection alone, we will look at the concept in
general.
Here is the relevant part of the text:
This is necessary but not sufficient.
Roots 8
Notice that he does not use a function that has a very shallow slope. That possibility makes this
criterion problematic.
What would “sufficiently close” mean?
Recall that the definition of “M significant digits” is a relative error measurment.
Roots 9
Roots 10
|p n − p n−1 |
rather
|p n | + |p n−1 |/2
are very close together.
There is not much to be gained by using the midpoint of the interval
|p n − p n−1 |
when p n and p n−1
|p n |
Lets look at how various texts deal with this (X means they use the condition).
|p n − p n−1 |
< T3
|fp n  | < T 1 |p n − p n−1 | < T 2
|p n |
than an end point
Atkinson
1985
X
Buchanan/Turner 1992
Burden/Faires
1997
Cheney/Kincaid
1980
Fausett
1999
Gerald/Wheatley
1999
Lins/Wang
2003
Mathews/Fink
2004
X
Schilling/Harris
2000
X
X
For Bisection
others-no algorithm
X
b − a
k > log 2
T2
X
others-no algorithm
X
b − a
k > log 2
T2
X
others-no algorithm
X
It is typical of root finding algorithms in Numerical Analysis textbooks to use the absolute error
as a stopping criterion. It is also typical that the examples that are used are those with roots near
1 where absolute and relative error are the effectively the same.
Note that if we assume that the absolute error condition is to be used, then after k steps the
interval would be
1 b − a < T 2
so
2k
b − a
2k >
T2
b − a
k > log 2
T2
The following is from a very well known text “Numerical Analysis” by Burden and Faires (I
used it from 1980 to the late 90s)
Roots 11
As can be seen. Burden/Faires lists the 3 possible stopping criteria (strangely, while they state
that the relative error is best, they never use it).
Because I wondered why they recommended the relative error but used the absolute error, I sent
an email to them. Professor Burden’s response gives their rational “We have chosen to use |p_(i+1) - p_i| < tol as a stopping criterion in the textbook for the
following reasons:
1. If the actual solution is near zero, estimates for the relative error are more difficult for
the student to program;
2. Because of the assumed continuity of the function f, if the sequence {p_i} converges it
will converge to a zero of f. Further, if the sequence {p_i} converges then the
differences |p_(i+1) - p_i| will converge to zero.
3. We have chosen to use |p_(i+1) - p_i| to estimate actual error which can be justified by
actual error bound theorems in Chapter 2.It is certainly true that one could make a case
for estimating relative error and using that as a stopping criterion. In the textbook our
main concern has always been to teach the student about the methods and the
mathematics behind the methods. Most students would use professional software after
graduation and seldom have a need to write their own programs.
I hope I have given you adequate answers to your questions. Thank you for using our
textbook in the past.”
Roots 12
Professor Burden has a Java applet for computing the bisection so I used it and sent him the
following f = (x - 10^(-30))^93
a = -1
b = 1
tol = 0.000000001
N = 100
I
A
B
p
F(p)
===============================================================
1
-1.000000000
1.000000000
0.000000000
2
-1.000000000
0.000000000
-0.500000000
3
-0.500000000
0.000000000
-0.250000000
4
-0.250000000
0.000000000
-0.125000000
5
-0.125000000
0.000000000
-0.062500000
6
-0.062500000
0.000000000
-0.031250000
7
-0.031250000
0.000000000
-0.015625000
8
-0.015625000
0.000000000
-0.007812500
9
-0.015625000
-0.007812500
-0.011718750
10
-0.015625000
-0.011718750
-0.013671875
11
-0.015625000
-0.013671875
-0.014648438
12
-0.015625000
-0.014648438
-0.015136719
13
-0.015625000
-0.015136719
-0.015380859
14
-0.015625000
-0.015380859
-0.015502930
15
-0.015625000
-0.015502930
-0.015563965
16
-0.015625000
-0.015563965
-0.015594482
17
-0.015625000
-0.015594482
-0.015609741
18
-0.015625000
-0.015609741
-0.015617371
19
-0.015625000
-0.015617371
-0.015621185
20
-0.015625000
-0.015621185
-0.015623093
21
-0.015625000
-0.015623093
-0.015624046
22
-0.015625000
-0.015624046
-0.015624523
23
-0.015625000
-0.015624523
-0.015624762
24
-0.015625000
-0.015624762
-0.015624881
25
-0.015625000
-0.015624881
-0.015624940
26
-0.015625000
-0.015624940
-0.015624970
27
-0.015625000
-0.015624970
-0.015624985
28
-0.015625000
-0.015624985
-0.015624993
29
-0.015625000
-0.015624993
-0.015624996
30
-0.015625000
-0.015624996
-0.015624998
31
-0.015625000
-0.015624998
-0.015624999
No of Iterations 31
Approximation solution -0.015624999
Tolerance 1.0E-9
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
-0.000000000
Here the root is claimed to be -0.015624999 when it is in fact 1.0E-30 (stopped on small
Summary:
1. |p N − p N−1 | < TOL - absolute error. This operates by stopping when the value of the
digits after the decimal is smaller than TOL. We have just seen this in use and
observed that, if we just want a certain number of digits of accuracy, for large roots
this may do too much work, and for small roots it does too little (i.e. may give NO
digits of accuracy). This means that we need different ways of treating TOL in
different regions.
2. |f p N | < TOL. It might seem that when you are searching for a zero that requiring the
value of the function to be small would produce the desired result. It turns out that this
is not sufficient. Consider the case in which the function has a very small slope.
As we can see, |f |could be within  of the axis and p still be far from the root.
p N − p N−1
3.
< TOL - relative error. This is the way that we can treat TOL differently
pN
Roots 13
in different regions. If we rewrite this as |p N − p N−1 | ≤ TOL × |p N |, the effective value
of TOL changes with the position of the root. Another reason for rewriting this is to
avoid division by 0 if p N = 0. Note that by the use of ≤ we cover the case in which
p N − p N−1 = 0 and p N = p N−1 = 0.
The only reasonable stopping criterion is the relative error.
The bisection method generates a sequence of p i that approximates p such that
|p i − p| ≤ b −n a n ≥ 1.
2
We say that this sequence converges to zero with rate of convergence O 1n .
2
Bisection: Advantage - always converges once a, b is found.
Disadvantage - Slow, may be hard to find a, b.
As a simple (but useful) example we will find 2 .
-->[c err yc k] = bisect(’root2’, 0, 2, 0.0000005,
’%13.6f %14.6f %14.6f %11.6f %13.5f\n’);
a
c
b
b - a
f(c)
0.000000
1.000000
2.000000
2.000000
-1.00000
1.000000
1.500000
2.000000
1.000000
0.25000
1.000000
1.250000
1.500000
0.500000
-0.43750
1.250000
1.375000
1.500000
0.250000
-0.10938
1.375000
1.437500
1.500000
0.125000
0.06641
1.375000
1.406250
1.437500
0.062500
-0.02246
1.406250
1.421875
1.437500
0.031250
0.02173
1.406250
1.414063
1.421875
0.015625
-0.00043
1.414063
1.417969
1.421875
0.007813
0.01064
1.414063
1.416016
1.417969
0.003906
0.00510
1.414063
1.415039
1.416016
0.001953
0.00234
1.414063
1.414551
1.415039
0.000977
0.00095
1.414063
1.414307
1.414551
0.000488
0.00026
1.414063
1.414185
1.414307
0.000244
-0.00008
1.414185
1.414246
1.414307
0.000122
0.00009
1.414185
1.414215
1.414246
0.000061
0.00000
1.414185
1.414200
1.414215
0.000031
-0.00004
1.414200
1.414207
1.414215
0.000015
-0.00002
1.414207
1.414211
1.414215
0.000008
-0.00001
1.414211
1.414213
1.414215
0.000004
-0.00000
1.414213
1.414214
1.414215
0.000002
0.00000
1.414213
1.414214
1.414214
0.000001
0.00000
–>c
c =
1.4142134
Roots 14
Supppose that we want to find the extrema of
y = xe x − e x − 5x.
25
20
15
10
5
-1
0
1
x
2
3
-5
The derivative is y′ = xe x − 5 and, from the graph, it appears that the minimum occurs between
0 and 2 (we could be more precise). We can check this by noting that 0e 0 − 5 = −5, while
2e 2 − 5 = 9.778 so we can use a = 0, b = 2 as starting brackets.
-->[c err yc k] = bisect(’xex’, 0, 2, .0005, ’%13.6f %14.6f %14.6f %11.6f %13.5f\n’)
a
c
b
b - a
f(c)
0.000000
1.000000
2.000000
2.000000
-2.28172
1.000000
1.500000
2.000000
1.000000
1.72253
1.000000
1.250000
1.500000
0.500000
-0.63707
1.250000
1.375000
1.500000
0.250000
0.43823
1.250000
1.312500
1.375000
0.125000
-0.12347
1.312500
1.343750
1.375000
0.062500
0.15112
1.312500
1.328125
1.343750
0.031250
0.01229
1.312500
1.320313
1.328125
0.015625
-0.05597
1.320313
1.324219
1.328125
0.007813
-0.02193
1.324219
1.326172
1.328125
0.003906
-0.00485
1.326172
1.327148
1.328125
0.001953
0.00372
1.326172
1.326660
1.327148
0.000977
-0.00057
–>c
c =
1.3269043
This looks like a reasonable position for the minimum.
-->err
err =
0.0004883
–>yc
yc =
0.0015753
–>k
k =
12.
Suppose that we wish to find the point(s) at which the curves
y = x3
y = 10 − 4x 2
intersect.
Roots 15
10
5
-3
-2
x
-1
1
2
0
-5
-10
-15
-20
-25
x3
-->[c err yc k] = bisect(’x3p4xm10’, 0, 2, 0.0000005,
’%13.9f %14.9f %14.9f
a
c
b
b - a
0.000000000
1.000000000
2.000000000
2.000000000
1.000000000
1.500000000
2.000000000
1.000000000
1.000000000
1.250000000
1.500000000
0.500000000
1.250000000
1.375000000
1.500000000
0.250000000
1.250000000
1.312500000
1.375000000
0.125000000
1.312500000
1.343750000
1.375000000
0.062500000
1.343750000
1.359375000
1.375000000
0.031250000
1.359375000
1.367187500
1.375000000
0.015625000
1.359375000
1.363281250
1.367187500
0.007812500
1.363281250
1.365234375
1.367187500
0.003906250
1.363281250
1.364257813
1.365234375
0.001953125
1.364257813
1.364746094
1.365234375
0.000976563
1.364746094
1.364990234
1.365234375
0.000488281
1.364990234
1.365112305
1.365234375
0.000244141
1.365112305
1.365173340
1.365234375
0.000122070
1.365173340
1.365203857
1.365234375
0.000061035
1.365203857
1.365219116
1.365234375
0.000030518
1.365219116
1.365226746
1.365234375
0.000015259
1.365226746
1.365230560
1.365234375
0.000007629
1.365226746
1.365228653
1.365230560
0.000003815
1.365228653
1.365229607
1.365230560
0.000001907
1.365229607
1.365230083
1.365230560
0.000000954
%14.9f %13.5f\n’);
f(c)
-5.00000
2.37500
-1.79688
0.16211
-0.84839
-0.35098
-0.09641
0.03236
-0.03215
0.00007
-0.01605
-0.00799
-0.00396
-0.00194
-0.00094
-0.00043
-0.00018
-0.00005
0.00001
-0.00002
-0.00001
0.00000
Note that, because the root is near 1, it does not matter that we have used the absolute error.
Roots 16