Euler Method - Mathematica - Analyzing the Program
Numerical Methods for Solving Differential Equations
Euler's Method
Analyzing the Euler Program
Instructions
(continued from last page...)
To view this page under optimal conditions you should stretch the display window to fill your entire screen. This can be done by dragging on the Resize Handle located at the bottom right corner of this window, as shown in this picture.
You may also adjust the width of the two display panels by dragging the vertical separator bar.
On the left is a complete listing of the euler program that we'll be using for the remainder of this laboratory. You're probably a little foggy on the purpose of many of the commands used within the program, and we're going to try and clear things up a little for you here.
Analyzing the Euler Program
In order to find out the purpose of each of the commands used within the program, simply click on the command that you wish to find out about within the program listing.
euler[f_,{x_,x0_,xn_},{y_,y0_},steps_]:=
Block[
{xold=x0,
yold=y0,
sollist={{x0,y0}},
x,y,h
},
h=N[(xn-x0)/steps];
Do[
xnew=xold+h;
ynew=yold+h*(f/.{x->xold,y->yold});
sollist=Append[sollist,{xnew,ynew}];
xold=xnew;
yold=ynew,
steps
];
Return[sollist]
]
1. The Function Definition
The first line:
euler[f_,{x_,x0_,xn_},{y_,y0_},steps_]:=
is pretty much what we described earlier, when we designed the form of the input, but there are a few twists. What about all of those underline characters after each of the variable names? Well, this is Mathematica's way of designating the variables as "dummy" or "wild-card" variables within the function's definition. It tells Mathematica that the names of the variables aren't really important—they're just place-holders in the pattern of use that we are defining.
2. The Block Command
The Block command here is enormous. If you inspect its brackets, you'll see that it spans 15 lines of code. To find out more about it, we could jump back to Mathematica and ask it for the syntax of the Block command. I've done this for you in the command displayed below, and I've done a little color-coding to help us discuss things a bit more clearly.
?Block
Block[{x, y, ...}, expr] specifies that expr is to be evaluated with local values for the symbols x, y, ... .
Block[{x = xo, ...}, expr] defines initial local values for x, ... . >>
Now let me display a color-coded version of the Block command from the program:
Block[
{xold=x0,
yold=y0,
sollist={{x0,y0}},
x,y,h
},
h=N[(xn-x0)/steps];
Do[ xnew=xold+h;
ynew=yold+h*(f/.{x->xold,y->yold});
sollist=Append[sollist,{xnew,ynew}];
xold=xnew;
yold=ynew,
{steps}
];
Return[sollist]
]
Comparing the color-coded portions of this display with the syntax help we displayed at the top of this frame, you should be able to see that the Block command that we are using in our program best fits the second form of our syntax request:
Block[{x = xo, ...}, expr]defines initial local values for x, ... .
Instead of {x = xo, ...}, we have:
{xold=x0,
yold=y0,
sollist={{x0,y0}},
x,y,h
}
The fact that it covers multiple lines is unimportant! I typed it this way just to make it easier to read. This list is still taken to be a list of local variables, xold, yold, sollist, x, y, and h. The first three of these also define initial values for the variables, as mentioned in the syntax description. Notice that the initial value of sollist, which is the variable in which I'm going to store a list of the solution points, is actually the initial condition point.
So what is meant by a local variable? Essentially this means that that any values assigned to these variables within our program won't be carried over to any use of these variables outside our program. It is especially important to be careful about this issue if the program is being used by a third party (not you) who is unaware of what variable names should be avoided. With the use of local variables, it doesn't matter. Even though we're using x within the program, it can also be used later in our session without any values we assign to it within the program affecting our later calculations. (By the way, non-local variables are called global variables.)
The other part of the syntax request:
Block[{x = xo, ...}, expr] defines initial local values for x, ... .
refers to expr. In our program we have several lines of code in place of expr:
h=N[(xn-x0)/steps];
Do[ xnew=xold+h;
ynew=yold+h*(f/.{x->xold,y->yold});
sollist=Append[sollist,{xnew,ynew}];
xold=xnew;
yold=ynew,
{steps}
];
Return[sollist]
3. The Local Variable Declarations
The variables listed in braces in the form:
{xold=x0,
yold=y0,
sollist={{x0,y0}},
x,y,h
}
are simply being declared as local to the program, as discussed under the Block command.
xold=x0 sets the initial value of xold to x0.
yold=y0 sets the initial value of yold to y0.
sollist={{x0,y0}} sets the initial value of the list representing the numerical solution, sollist, to be the initial point {{x0,y0}}.
x,y,h are not given any initial values, but are still declared as local to the program.
Once you're done, we can go and see the program in action ...
4. The Step-size Calculation
The command:
h=N[(xn-x0)/steps];
is a simple calculation command whose purpose should be quite obvious to you. The step-size, h, is found by taking the length of the x-interval, xn-x0, and dividing this length by the number of steps that the user requested, steps. The N command wrapped around the calculation assures that the answer will be made into a decimal.
5. The Do Loop
A Mathematica syntax request on this command would reveal the following:
?Do
Do[expr, n] evaluates expr n times.
Do[expr,{i, imax}] evaluates expr with the variable i successively taking on the values 1 through imax (in steps of 1).
Do[expr,{i, imin, imax}] starts with i=imin.
Do[expr, {i, imin, imax, di}] uses steps di.
Do[expr, {i, i1, i2,…}}] uses the successive values i1, i2, … .
Do[expr,{i, imin, imax}, {j, jmin, jmax},…] evaluates expr looping over different values of j, etc. for each i. >>
Now, looking at a color-coded version of the Do loop in our euler program:
Do[ xnew=xold+h;
ynew=yold+h*(f/.{x->xold,y->yold});
sollist=Append[sollist,{xnew,ynew}];
xold=xnew;
yold=ynew,
steps
]
you should be able to see that the version of Do that we are using is actually the simplest one of all—the first one described in the syntax request:
Do[expr, n] evaluates expr n times.
Once again, what the syntax description refers to as expr actually consists of several lines of code, which you can investigate by clicking on them individually in the program listing in the left-hand panel. The n that it refers to is what we have called steps. In other words, our Do loop will repeat itself steps times.
6. The Euler Iteration Formulas
The two lines of code:
xnew=xold+h;
ynew=yold+h*(f/.{x->xold,y->yold});
are clearly meant to be using the Euler iteration formulas that we described back in the Introduction. The new values of x and y are found from the old values by using Euler's formulas. The code-segment:
f/.{x->xold,y->yold}
simply says to substitute xold for x and yold for y in the function f. In other words, we are evaluating the function at the old x- and y-values.
7. Building the Solution Point List
The command:
sollist=Append[sollist,{xnew,ynew}]
tells Mathematica to append (or add) to the end of sollist the newest point that's been calculated (the one found in the previous two lines of code.)
8. Resetting the Point Variables
The commands:
xold=xnew;
yold=ynew
make Mathematica put the values for the coordinates of our newly calculated point into the variables representing the old point's coordinates. The reason for this is to prepare xold and yold for the next run through the loop, when the point we've just found will actually be thought of as the old point.
9. The Return Statement
The command:
Return[sollist]
tells Mathematica to send the user of the program the list of solution points, sollist, as their result. Notice that this command is only executed once because the loop statement has been closed on the previous line of code.
Once you're done, we can go and see the program in action ...