You are on page 1of 5

MATLAB Mini-Project 4

Solving Nonlinear Equations


When the astronomer Johannes Kepler was attempting to determine the orbits of planets, he had
measured quantities he called M and ALPHA, and he needed to solve the following equation to
determine the quantity X:

M = X - ALPHA * sin X

At that time, there was no way known to solve this equation exactly; nor did anyone know a way
to systematically determine a good approximation. That left a long and painful trial and error
process.

In this project, we'll learn a little MATLAB, and also look at one way to determine an
approximate answer to Kepler's problem, or, indeed, to almost any equation.

To solve the equation means to find a value of X that makes it true. Let's move all the terms to
the right hand side, and call the result "F(X)":
F(X) = X - ALPHA * sin ( X ) - M

Now our problem has become finding a value X for which F(X)=0.

Rewriting the equation as a problem involving a function F(X) helps a lot. It may be hard to
think about solving an equation, but it's easy to imagine the graph of the function F(X) as a
curve, and to see that F(X)=0 when the curve crosses the X axis. We can also see that the sign of
F(X), the size of F(X), and the derivative of F(X) might be useful pieces of information.

Exercise A: Write a MATLAB M file kepler.m which accepts a value for X, and returns the
value of F(X). Suppose that M = 1 and ALPHA = 2. Your file should have the form:

function f = kepler ( x )
f = ???

and you'll need to fill in the formula for F. Check that your function is working correctly by
typing
kepler ( 0 )

which should give you a value of -1.

Get a feeling for what this function looks like, by plotting it between -10 and 10. If you look at
this plot and at the formula, you should be able to guess an answer to the following questions:
 For our values of M and ALPHA, are we sure that there will be a solution to the problem
F(X)=0?
 Make a revised version of your Kepler function, called kepler2.m, in which M is 3.
Compare the data for kepler and kepler2 on one plot. What do you think M does to the
graph as it is changed? Do you think that for every value of M there will always be a
solution?
 Make a revised version of your Kepler function, called kepler3.m, in which ALPHA is
3.0. Compare the data for kepler and kepler2 on one plot. What do you think ALPHA is
doing to the curve? Do you think that for every value of ALPHA there will always be a
solution? For this value of ALPHA, how many solutions do there seem to be?

MATLAB Syntax: you might find it very helpful to have the X axis displayed on your plots. To
do so, you can use the LINE(X,Y) command, which plots a line connecting the points (X1,Y1) to
(X2,Y2). If my X values go from -5 to 5, then I might use the following commands:

plot ( x, y )
hold on
line ( [-5,5], [0,0] )
hold off

Well, now we've got our function F(X) set up so that MATLAB can evaluate it, and we have to
face the more serious problem of figuring out how to locate a root of F(X), and how to use
MATLAB to carry out our plan.

Here are three possible approaches to finding a solution to the problem. All of them are iterative.
That is, you begin with an estimate of the solution, and you carry out some operation. Now you
check to see if |F(X)| is small enough. If not, you carry out the operation again ...and again and
again.

1. The Table Method: Evaluate the function at a point. Based on that value, guess a better
value of X, and evaluate F there.
2. The Picture Method: Plot the function F(X). Estimate a range in which the root lies. Plot
the function again, using the smaller range.
3. The Bisection Method: Find a point where the function is positive, and one where it is
negative. This is your starting interval. Look at the average of the two endpoints. This is
your test point. Evaluate the function at the test point. Your new interval is the testpoint,
plus whichever of the old endpoints had a function value of opposite sign.

Exercise B: Using the "table method", the "picture method", and bisection, try to find an
approximate solution X. For the table and bisection methods, you should easily be able to get 10
digits of accuracy. For the picture method, just try to get 4 digits. For the picture and bisection
methods, start with the range [0,3]. Try to keep track of the number of steps you took, your final
value of X, and the corresponding value of |F(X)|.
For the table method, it might help a lot to have an M file do some of the work for you. I'm
thinking of a command that looks something like this:

function picture ( a, b )
x = ?
y = ?
plot ( x, y )
hold on
line ( [?,?], [?,?] )
hold off

This would automate the process, and all you'd have to do is look at the picture and estimate new
values for A and B.
Method ...Steps... ...Final X... ...|F(X)|...
Table      
Picture      
Bisection      

Exercise C: You probably carried out the bisection method "by hand". Now you need to write
down your work symbolically. Here's a first draft of an M file, called bisect_step.m, that takes a
single step of the bisection method:

function [ a2, b2 ] = bisect_step ( a, b )

See if you can fill in the rest of the file, and figure out what it's doing.
fa = ?;
fb = ?;
c = ?;
fc = ?;

if ( sign ( fa ) == sign ( fc ) ) then


a2 = ?;
b2 = ?;
else
a2 = ?;
b2 = ?;
end

Test out your code on the Kepler problem and make sure you get the same results.

Once you're happy with bisect_step, I have a suggestion for you. Let's try to improve it! The big
goal here is to make it so easy to use that all we have to do to take another step is hit the up
arrow key. So we're going to change the code to look like this:

function new_interval = bisect_step ( interval )


Now we add two more lines immediately after the first one, to get the values of A and B out of
INTERVAL:
a = interval(1);
b = interval(2);

Then the rest of the routine is the same, but at the very end, we have to take A2 and B2 and pack
them up into a single variable called NEW_INTERVAL:
new_interval = [ a2, b2 ];

Ready for the payoff? Type

interval = [ 0, 3 ];
interval = bisect_step ( interval )

and then just keep hitting the up arrow key and ENTER to take the next step of bisection. Can
you see what's happening here?

Exercise D: Now it's time to be a little more ambitious. We'd like to make an M file that takes as
many steps of the bisection method as necessary to get the accuracy we want. Also, we'd like to
be able to look for the roots of other functions. So we're going to write a fancier M file, called
bisect.m, that looks like this:

function root = bisect ( f, a, b, tol )

fa = f(a);
fb = f(b);

while ( abs ( fa ) > tol & abs ( fb ) > tol )

c = ( a + b ) / 2;
fc = f(c);

if ( sign ( fa ) == sign ( fc ) )
a = c;
fa = fc;
else
b = c;
fb = fc;
end

end

if ( abs ( fa ) <= tol )


root = a
else
root = b
end

Can you explain what the pieces of this routine are doing? Read it carefully, and ask your mentor
if you're confused.
Now, using this code, you should be able to type a command like

root = bisect ( 'kepler', 0, 3, 0.000001 )

and get an approximate root immediately.

Exercise E: Write three function files, f1.m, f2.m, and f3.m for the following functions, and then
use your new bisection code to seek roots with an accuracy of 6 digits.

Name Formula Interval ...Root...


F1(X) X2-9 [0,10]  
F2(X) COS(X)-X [0,3]  
F3(X) 2*X-e-X [-10,100]  

If you'd like to work a little more on this project, ask your mentor about the secant method. This
is a way to approximate the answer that is much faster than bisection.

Reference 1:
Kahaner, Moler and Nash,
Numerical Methods and Software,
Prentice Hall, 1988,
Library Call Number: TA345 K34.
Reference 2:
Charles Van Loan,
Introduction to Scientific Computing,
Prentice Hall, 1997,
Library Call Number: QA76.9 M35 V375.

You might also like