| Introduction | Exercise 1 |
| A Sample Problem | Exercise 2 |
| The Bisection Idea | Exercise 3 |
| Programming Bisection | Exercise 4 |
| Variable Function Names | Exercise 5 |
| Exercise 6 |
The root finding problem is the task of finding one or more
values for a variable
so that an equation
This lab will take two sessions. If you print this lab, you may find the pdf version more appropriate.
Suppose we want to know if there is a solution to:
Since we can't solve this equation exactly, it's worth knowing
whether there is anything we can say about it. In fact, if
there is a solution
to the equation, we can probably
find a computer representable number x which approximately
satisfies the equation (has low residual error) and which is close to
(has a low approximation error). The exercise below uses
a plot to illustrate the existance of a solution.
Note: Matlab has the capability of plotting some
functions by name. We won't be using this capability in this
course because it is too specialized. Instead, we will construct
plots the way you probably learned when you first learned about
plotting: by constructing a list of
-values (abscissæ) and
corresponding
-values (ordinates) and then plotting the points
with lines connecting them.
plot(xplot,y1plot)then hold on, plot the second, and hold off. You saw this done before in Lab 2.
print -djpeg exer1.jpgor use the ``File'' menu, ``export'' and choose JPEG image.
function y = cosmx ( x ) % y = cosmx(x) computes the difference y=cos(x)-x % your name and the date y = ???(This is very simple-the object of this exercise is to get going.) Include a copy of this file with your summary.
plot(??? hold on plot(??? hold offas above to plot cosmx and the horizontal axis on the interval
Hint: The horizontal axis is the line
. To plot
this as a function, you need a vector
-values between
and
and a vector of
-values all of which are
zero (use the Matlab function zeros).
The idea of the bisection method is very simple. We assume that we
are given two values
and
(
), and that the function
is positive at one of these values (say at
) and
negative at the other. (When this occurs, we say that
is
a ``change-of-sign interval'' for the function.)
Assuming
is continuous, we know that there must be at least
one root in the interval.
Intuitively speaking, if you divide a change-of-sign interval in half, one or the other half must end up being a change-of-sign interval, and it is only half as big. Keep dividing in half until the change-of-sign interval is so small that any point in it is within the specified tolerance.
More precisely, consider the point
.
If
we are done. (This is pretty unlikely).
Otherwise, depending on the sign of
, we know that the
root lies in
or
. In any case, our
change-of-sign interval is now half as large as before. Repeat this
process with the new change of sign interval until the interval is
sufficiently small and declare victory.
We are guaranteed to converge. We can even compute the
maximum number of steps this will take, because if the original
change-of-sign interval has length
then after one bisection the
current change-of-sign interval is of length
, etc.
We know in advance how well
we will approximate the root
. These are very powerful
facts, which make bisection a robust algorithm--that is, it
is very hard to defeat it.
Before we look at a sample bisection program, let's discuss some things. If you haven't done much programming before, this is a good time to try to understand the logic behind how we choose variables to set up, what names to give them, and how to control the logic.
First of all, we should write the bisection algorithm as a Matlab function. There are two reasons for writing it as a function instead of a script m-file (without the function header) or by typing everything at the command line. The first reason is a practical one: we will be executing the algorithm several times, with differing end points, and functions allow us to use temporary variables without worrying about whether or not they have already been used before. The second reason is pedantic: you should learn how to do this now because it is an important tool in your toolbox.
Atkinson describes the bisection algorithm (Section 2.1) in the following manner. (The variable names have changed slightly.)
Algorithm Bisect(
,
,
,root,
)
The language of this description is based on a computer language called Algol that is now mainly used in papers in order to specify algorithms. One objective of this lab is to show how to rewrite it in the Matlab language. As a starting point, let's fix cosmx as the function and leave it out of the calling sequence. Let's also fix epsilon=1.0e-6. Note also that, in Matlab, returned values are separated from arguments, so the variable root, which I will call approxRoot to make a point, is written on the left of an equal sign. The first few lines of the file bisect_cosmx.m should be:
function approxRoot = bisect_cosmx( xa, xb) % approxRoot = bisect( xa, xb) uses bisection to find a % root of cosmx between a and b to tolerance 0.000001 % xa=left end point of interval % xb=right end point of interval % cosmx(xa) and cosmx(xb) should be of opposite signs
Now think about the iteration. Atkinson's algorithm employs the
return to Step 1 device to indicate uncounted repetition
of Steps 1-4. Matlab provides a more elegant construct for uncounted
repetition: the while loop. In Atkinson's Step 2, the
algorithm is terminated. Matlab while loops usually terminate at
their end, so we continue iterating for as long as
is larger
than epsilon, rather than stopping when
is smaller. This
reversal of the test is sometimes confusing, but it is how it is
done.
Here is a Matlab function that carries out the bisection algorithm
for our cosmx function. The endpoints of the initial interval
are variables that you specify when you invoke the function. The
Matlab variables xa, xb and xc represent the
mathematical quantities
,
and
.
function approxRoot = bisect_cosmx( xa, xb)
% approxRoot = bisect_cosmx( xa, xb) uses bisection to find a
% root of cosmx between xa and xb to tolerance 0.000001
% xa=left end point of interval
% xb=right end point of interval
% cosmx(xa) and cosmx(xb) should be of opposite signs
% your name and the date
EPSILON = 1.0e-6;
fa = cosmx(xa);
fb = cosmx(xb);
approxRoot = (xb+xa)/2;
itCount = 0;
while ( abs ( xb - xa ) > EPSILON )
itCount = itCount + 1;
xc = ( xa + xb ) / 2;
approxRoot = xc;
fc = cosmx(xc);
% The following statement prints the progress of the algorithm
disp(strcat('xa=',num2str(xa),', fa=',num2str(fa),', xc=',num2str(xc),...
', fc=',num2str(fc),', xb=',num2str(xb),', fb=',num2str(fb)))
if ( fc == 0 )
break;
elseif ( sign(fb) * sign(fc) <= 0 )
xa = xc; fa = fc;
else
xb = xc;
fb = fc;
end
end
disp(strcat('bisect_cosmx took itcount=',num2str(itCount),' steps.'))
Note: I have violated my own rule twice about having functions print things. The first disp statement merely prints progress of the function and can be discarded once you are confident it is correct. The print of the ``number of steps'' at the end is different, and really should be returned along with the approximate root. Matlab has the capability of returning more than one quantity, but we will not use that capability until later in this course.
approxRoot = (xb+xa)/2; preceeding the while statement?
x = bisect_cosmx ( 0, 3 )Is the value x close to a root of the equation cos(x)=x?
Now we have written an m-file called bisect_cosmx.m that can find roots of the function cosmx on any interval, but we really want to use it on an arbitrary function. To do this, we could create an m-file for the other function, but we would have to call it cosmx.m, because that is what the bisect_cosmx function expects. Suppose that we have three files, called f1.m through f3.m, each of which evaluates a function that we want to use bisection on. We could rename f1.m to cosmx.m, and change its name inside the file as well, and repeat this for the other files. But who wants to do that?
It is more convenient to introduce a dummy variable for the function name, just as we used the dummy variables a and b for numerical values. In Matlab, function names are passed as quoted strings and their use is only a little more difficult than for numbers.
Warning: If you forget the quotes around the function name, you will get strange errors.
Note: Matlab also uses the @ character
to denote ``function handles'' that are used in much the same way
as quoted strings for function names. Release 14 and newer versions
of Matlab also use the @ character to define ``anonymous''
functions, and it can be used instead of the feval function
below. Since Release 13 is installed on the computers in GSCC, and
since the syntax below remains valid in newer versions, we will
continue using feval.
function approxRoot = bisect ( f, xa, xb )
fa = cosmx(xa);must be rewritten as:
fa = feval ( f, xa );Make this change for fa, and a similar change for fb and fc.
x = bisect ( 'cosmx', 0, 3 )Execute this command and make sure that you get the same result as before. (This is called ``regression testing.'')
Warning: If you forget the quotes around cosmx and use the command
x = bisect ( cosmx, 0, 3 ) % error!you will get the following mysterious error message:
>> bisect(cosmx,0,3) ??? Input argument 'x' is undefined. Error in ==> cosmx.m On line 2 ==> y=cos(x)-x;
Name Formula Interval approxRoot No. Steps f1 x^2-9 [0,5] _________ _________ f2 x^6-x-1 [1,2] _________ _________ f3 2*x-exp(-x) [-10,100] _________ _________
Back to MATH2070 page.