Sei sulla pagina 1di 12

CHEN 14010 Matlab II AJM & PC

1
0) Introduction

This hand-out contains the material you need to cover for the mid-semester online
assessment that will take place on Tuesday 1st March between 2 5 pm. Detailed
arrangements about this test will be given later.

Note the second online assessment will take place on Tuesday 5 April.

As before, it is advisable to save your answers to the exercises in My Documents
and/or a pen-drive, as then you will be able to make use of these programs when
doing the online test.

In what follows, use format short e unless told otherwise. You will also find it
helpful to have the first semester notes with you.

Finally, before starting, please note that:

i) Ctrl C stops a program (very useful if you are in an infinite loop!)

ii) You can clear the screen by typing clc. This does not, however, wipe out the values
and types of previously defined variables.

iii) To start completely afresh, type clear. This is like starting again from the
beginning. If you get strange error messages, one possible cure is to type clear and try
again!

1) Function M-files

Last semester, you wrote a program that would calculate an integral numerically using
the trapezium rule. It would have looked something like this (for Q25):

a = input( 'Value of a: ' );
b = input( 'Value of b: ' );
n = input( 'Value of n: ' );
h=(b-a)/n;
sum=0.5*(exp(a) + exp(b));
for i=1:n-1
sum=sum+exp(a+i*h);
end
answer=h*sum;
disp('answer is: ')
disp(answer);
truth=exp(b)-exp(a);
diff=abs(answer-truth);
disp(truth);
disp(diff);

This estimates
}
b
a
dx x) exp( using n strips and the result is given in the variable answer.

Suppose, however, we wanted to integrate something like

CHEN 14010 Matlab II AJM & PC
2


2x exp( x) + 3sin x / x ln(1+ x
2
)
| |
dx
a
b
}


We could easily edit the program to do this, replacing exp(x) by this lengthy
expression at all points in the program, but the end result would be rather messy with
long lines containing this lengthy integrand. There is also a danger that we would
make a mistake and forget to change all the lines that needed changing. Finally it
makes the program hard to follow.

A nice way round this is to define our own function in a separate procedure and then
let our main program call this. We introduce the idea of function M-files.

Type

function y = f(x)
y = 2*x*exp(-x)+3*sin(x)/x-log(1+x^2);

and save it in your directory (e.g. My Documents) as f.m.

If, in the workspace, you now type f(2), you get

ans =

2.9585e-001

which is just the value of | | ) 1 ln( / sin 3 ) exp( 2
2
x x x x x + + evaluated at x = 2.

You have created your own function!

We can now edit the trapezium program so that it integrates f(x), where we have
defined f(x) as our very own function.

Thus type:

a = input( 'Value of a: ' );
b = input( 'Value of b: ' );
n = input( 'Value of n: ' );
h=(b-a)/n;
sum=0.5*(f(a) + f(b));
for i=1:n-1
sum=sum+f(a+i*h);
end
answer=h*sum;
disp('answer is: ')
disp(answer);

and save this as trap.m in the same directory as f.m.

This is just the program for Q25 (except for the last few lines) but exp(x) is replaced
everywhere by f(x).

CHEN 14010 Matlab II AJM & PC
3
If you now type trap in the command window and then set a = 1, b = 3 and n = 8, you
get

answer is:
6.3939e-001

The important point is that you can integrate any function you like with this program.
You simply have to edit the f.m file. The trap program need not be altered at all.

Ex. 1: Edit f.m so you can integrate :

a)

1
1+ x + x
3
between 0 and 1, using 16 strips

answer is:
6.3050e-001

b)
4
1
) 1 ln(
x
x
+
+
between 2 and 3, using 12 strips.

answer is:
3.4371e-002

Important note

Let us now do the integral


1
c + x
1
2
}
dx

where we input the value of c into the main program.

Thus you might think the main program might look like this save it as trapc.m

a = input( 'Value of a: ' );
b = input( 'Value of b: ' );
c = input( 'Value of c: ' );

n = input( 'Value of n: ' );
h=(b-a)/n;
sum=0.5*(f(a) + f(b));
for i=1:n-1
sum=sum+f(a+i*h);
end
answer=h*sum;
disp('answer is: ')
disp(answer);



and the f.m program would be
CHEN 14010 Matlab II AJM & PC
4

function y = f(x)
y = 1/(c+x);

Make these changes and try running trapc with a = 1, b = 2, c = 1 and n=8.

It wont work you get an error message!

The problem is that the f.m procedure does not know the value of c. The main
program (trapc) knows what c is, but the main program has not told the function
anything about it! All f.m knows is what is given in its argument in this case, x.

What we need to do now is to edit the programs so f.m is told the value of c. To do
this we write

function y = g(x,c)
y = 1/(c+x);

and save this as g.m. You can give your own name to functions (within certain
restrictions) it does not always have to be f.m!

trapc.m is then given by

a = input( 'Value of a: ' );
b = input( 'Value of b: ' );
c = input( 'Value of c: ' );

n = input( 'Value of n: ' );
h=(b-a)/n;
sum=0.5*(g(a,c) + g(b,c));
for i=1:n-1
sum=sum+g(a+i*h,c);
end
answer=h*sum;
disp('answer is: ')
disp(answer);

Now try running trapc with a = 1, b = 2, c = 1 and n=8.

answer is:
4.0565e-001


Now the program works g.m now knows what c is.

Ex. 2:

(a) Integrate

f (x) =exp(cx) between 0 and 1 for n = 8, reading in the value of
c = 2 into the main program.

answer is:
4.3458e-001
CHEN 14010 Matlab II AJM & PC
5
(b) Repeat the above for

f (x) =
1
c
2
+ x
2
, between 0 and 1, n = 8, reading in c = 2.

answer is:
2.3172e-001
(c) Repeat the above for

f (x) =
1
c
2
+ dx + x
2
, between 0 and 1, n = 8, reading in
c = 2 and d = 3.

answer is:
1.7857e-001


The message is that f.m is in a watertight bubble the only information it has is what
you put in its argument. It has no knowledge of any other variable that might happen
to exist in the calling program.

Let us now go a stage further with our trapezium rule program and create a function
trap.m. We return to integrating a function f(x) contained in f.m viz.

function y = trap(a, b, n)
h=(b-a)/n;
sum=0.5*(f(a) + f(b));
for i=1:n-1
sum=sum+f(a+i*h);
end
y=h*sum;

This is very like our previous main program, but is now itself a function. You tell it
the limits of the integral, a and b, and the number of strips, n, and it goes away and
uses the trapezium rule to estimate the integral of f(x). It then returns the value to the
main program.

Note we assign the final answer in the last line to the variable y. The important thing
is that the variable at the beginning and the end should be the same.


Edit the f.m program so f(x) = 1/x.

The main program might be:

a = input( 'Value of a: ' );
b = input( 'Value of b: ' );
n = input( 'Value of n: ' );
answer = trap(a,b,n);
disp(answer);

Save this as quad.m, in the same directory as trap.m and f.m.

If you run quad in the command window, then quad will call trap and trap will call
f, ending up integrating f(x) between a and b using n strips.

CHEN 14010 Matlab II AJM & PC
6
Check this by running quad and then setting a = 1, b = 2 and n = 8.

Value of n: 8
6.9412e-001

Why do this?

One reason is, in practice, you do not know the true answer to your integral and thus
you do not know what value of n to choose in order to get the right answer.

Now it is very easy to edit quad.m so it prints out the trapezium rule results for a
range of n-values.

Ex. 3: Set

f (x) =
1
x
, and let a = 1 and b = 2. Calculate the value of this integral
analytically i.e. add in lines to calculate truth in the program above.

Now use the trapezium rule to calculate this integral using n = 4, 8 and 16 strips and
check you are steadily approaching the right answer.

e.g.

Value of a: 1
Value of b: 2
Value of n: 16
1.6000e+001 6.9339e-001 6.9315e-001

Ex. 4: Modify the program by introducing a for loop into the main program, so that
the program prints out a table, showing how the trapezium result varies for n = 4, 6, 8,
10, up to n = 20.

To print out the numbers a, b &c on one line, type disp([a, b, c]).

Ex. 5: Further modify the program so that for each value of n, you get a print out of
the error, i.e. the absolute value of the difference between the trapezium value and
truth. The MatLab function abs(x) returns the absolute value of x.

i.e. error = abs(truth-answer);

Ex. 6: Use MatLab to plot the error against

1 n
2
. Do you get a straight line for
reasonably large values of n?

To do this, it is helpful to have two arrays, x and y. You will need to think of
providing a counter, step for example, so that step is incremented by one each time
you go round the loop. Then x(step) will contain the value of

1 n
2
for that loop and
y(step) will contain the corresponding error.

At the end of the loop, you have: plot(x,y).

CHEN 14010 Matlab II AJM & PC
7
Ex. 7: Now modify the program so that at each iteration, n is doubled. Thus you
should get a print out for n = 4, 8, 16, 32 up to n = 1024.

Of course what we really want to do is to have a loop in quad.m that keeps on going
until we have calculated the integral to the accuracy we want, rather than a for end
loop that just carries on for a set number of iterations. We return to this problem later,
but first here are some more examples to practice functions.

Ex. 8: Consider a sphere, radius r. Write two functions area.m and volume.m that
return values of the spheres area and volume respectively, given the value of r. Write
a main program - sphere.m - to which you input the r-value and which then calls
area(r) and volume(r) and prints out the values. Remember pi gives 3.14159 in
MatLab. What are the values for r = 2?

(area = 5.0265e+001; volume = 3.3510e+001)

Ex. 9: Now consider a cylinder, height h and radius r. Repeat the above, this time
writing a main program cylinder.m to which you input h and r and which then
calls area(h, r) and volume(h, r). What are they for h = 2 and r = 3?

(area = 9.4248e+001; volume = 5.6549e+001)

2) Making decisions with if

Often a program branches, depending on whether two numbers are the same, or
whether one exceeds the other. These tests use relational operators. Here are some of
those used in MATLAB:

< less than
<= less than or equal
= = equal
~ = not equal
> greater than
> = greater than or equal

Type the following on the command line

x = 2;
if x < 0
disp( 'neg' )
else
disp ( 'non-neg' )
end

Did you get the non-neg message? Repeat the exercise, this time with x = 1.

This is the basic if else end construction. You must remember to put in end, or
MATLAB will wait forever!

We can also write programs using this facility.

CHEN 14010 Matlab II AJM & PC
8
Try the following:

r = rand % MATLAB random number between 0 and 1
if r < 0.5
disp ( 'move left' )
else
disp ( 'move right')
end


This is the basis for doing a random walk along a line.

Suppose, however, you wanted to do a random walk on a square lattice. An efficient
way to do it makes use of the elseif construction.

Try this:

r = rand % Matlab random number between 0 and 1
if r < 0.25
disp ( 'move left' )
elseif r < 0.5
disp ( 'move up')
elseif r < 0.75
disp ( 'move right')
else
disp ( 'move down')
end

Run this a few times to check you see how it works. Note that if, for example, r = 0.1,
so r < 0.25, then you only get the move left message, even though r < 0.5, etc. as
well!

Ex. 10: Modify this program so the particle does a random walk on a cubic lattice
i.e. each step can be along one of three perpendicular directions, so there are a total of
six possible steps.

Ex. 11: Write a program to solve the quadratic equation 0
2
= + + c bx ax , where the
values of a, b and c are read into the program.

In this program calculate

disc = b^2 - 4*a*c;

Then use an if construction, so that if disc < 0, the program prints out No real
roots, but otherwise calculates the two roots and prints them out.

Ex. 12: Strictly you should also allow for the possibility disc = 0 and there is only one
root. Use an if elseif end construction to allow for this.

Ex. 13: One way to solve non-linear equations is to use a numerical method called the
bisection method (you will do this later in your mathematics unit). A key element of
the routine is to call a function, f(x), at two points x
1
and x
1
and decide whether the
product f(x
1
)*f(x
1
) is positive or negative.
CHEN 14010 Matlab II AJM & PC
9

Firstly write a function program fun.m to calculate fun(x) = exp(-x) x.

Then write a main program in which you enter x1 and x2. You then use an if
construction , so that if fun(x1)*fun(x2) > 0, you write positive product, else you
write negative product.

Test this on (a) x1 = 0 x2=1, (b) x1 = 1, x2=2, (c) x1=-1, x2 = 0.

3) While loops

Sometimes you do not know how many times you will need to repeat some lines of
program, so a for end loop is not well-suited for the task.

For example, suppose you had 1000 in an investment and the compound interest on
it was 10%. How many years must you wait for the investment to double?

Here is a MATLAB program to do this.

a = 1000; % initial investment
r = 0.1; % rate of interest
bal = a;
year = 0;
disp( 'year balance' )

while bal < 2*a
bal = bal + r * bal;
year = year + 1;
disp( [year bal] )
end

The program keeps on advancing the years and adding on the interest until the
statement bal < 2*a is false, whereupon the loop ends.

Let us do another example.

Consider the series + + + =

=
3
1
2
1
1
1
1 n
n
Use the while-end construction to find the
minimum number of terms you need in this series for the sum to be greater than 3.

sum = 0.0; % Initialise the sum to zero
n = 0; % Initialise the counter in the sum to be zero
disp('n sum')

while sum < 3
n = n+1; % Increment the counter
sum = sum + 1/n; %Accumulate the sum
disp( [n sum])
end



CHEN 14010 Matlab II AJM & PC
10
Again the loop keeps on going until the condition sum < 3 is false. The last value
printed gives the sum and the value of n when the sum first exceeds 3.


Ex. 14: A population of bacteria doubles its size every hour. Starting from 1
bacterium, how many hours are needed for the population to first exceed 1,000,000 ?
use a while end loop to do this.

(21 hours. Population is 1048576)

Ex. 15: Consider the series + + + =

=
2 2
1
2
3 2 1
n
n Use the while-end construction to
find the minimum number of terms you need in this series for the sum to be greater
than 100,000.

(n = 67 sum = 102510)

Now that we have understood the while end construction, we can return to the
trapezium rule programs and answer the question about how to calculate an unknown
integral to a desired level of accuracy.

We return to the program you wrote for ex. 7 and we are integrating f(x) = 1/x. We
now use the while construction, so that the computer keeps on doubling n until the
value of the error gets less than a user defined tolerance, tol. What value of n is
needed, for example, to get the error less that 1.0e-3, 1.0e-6 or 1.0e-8 ?

Ex. 16: Write a program to integrate 1/x between a = 1 and b = 2, doubling the
number of strips (starting from n = 4) until tol < 1.0e-8.

(n = 4.0960e+003 answer = 6.9315e-001 error = 3.7253e-009)

You need to alter the main program so it has a structure like

User provides value of tol.
error = 100*tol % make sure error>tol before you start!
truth = ??? % provide the true answer for the integral
n = 2;
Provide values of a and b
while error > tol
n = 2*n; % double the value of n. The first value is 4.
get trapezium value of integral
calculate the error = abs(answer truth)
print out n and the error
end;
print out n, error

Please note you cannot type in the above and expect it to work. You
have to translate the English phrases into MatLab!

CHEN 14010 Matlab II AJM & PC
11
Make sure you understand how the while loop works. The computer will carry on
doubling n until the condition error > tol is false, whereupon it will leave the loop.
The value of n finally printed out is the value you need. Along with the first value of
the error that is less than the tolerance.

Ex. 17: A problem with while loops is that if something goes wrong, the condition
that stops the loop might never be met and the loop will never stop. If you run a
program and it never stops, type ctrl c to end it!

It is good practice to prevent while loops lasting for ever. To do this you can have a
counter in the loop and ensure that the counter never exceeds a certain value.

Modify your quadrature program so the while loop cannot do more than nmax
iterations.

You will need some extra lines like:

User provides nmax
steps = 0;
while error > tol & (steps < nmax)
steps = steps + 1;
Etc.
end;
if (steps >= nmax)
Print message saying nmax steps exceeded.
else
Print out n and error
end if

Usually you do not use numerical methods to work out an integral you already know!
If you do not know the value of truth, then you usually estimate the accuracy of your
estimate by comparing the difference between two successive iterations.

Ex. 18: Modify your program so that it keeps on doubling n until the difference
between the estimates from two successive iterations (diff) is less than tol = 1.0e-6.

To do this, you could save in an array the trapezium estimate for each value of n used,
but this is a bit wasteful in terms of storage and is not very elegant.

Better is just to use two variables and continually update them. Try something along
these lines:

Provide normal input data including tol;
diff = 100*tol; % we need to ensure diff > tol at the start
n=4;
old = trap (a, b, n); % this contains the first estimate
while diff > tol and (steps < nmax)
n = 2*n; %double n
new = value of trap with new value of n;
diff = absolute difference between old and new;
CHEN 14010 Matlab II AJM & PC
12
old = new;
% we copy the last estimate, new, into old
End;

Make sure you understand how this old/new business works! Each time, when you go
into an iteration, old contains the previous value of the estimate and new contains the
new one. The while loop keeps on going until diff becomes less than tol (or you
exceed the maximum number of iterations if something has gone wrong!).

Test your program by working out how many iterations are needed to get

diff < 1.0e-3, 1.0e-6 and 1.0e-8.

You are now in a position to calculate the integral of whatever function you like to
your specified accuracy!

Value of a: 1
Value of b: 2
Value of tol: 1.0e-6
n = 5.1200e+002 old = 6.9315e-001 new = 6.9315e-001 diff = 3.7253e-009

Ex. 19: Calculate the following integrals to a tolerance of 1.0e-6. Note the value of
the integral as given in the final value for new and the number of strips used to
calculate this value.

a) ( )dx x
}
1
0
2
exp

Value of tol: 1.0e-6
n = 2.0480e+003 old = 1.4627e+000 new = 1.4627e+000 diff = 3.2404e-007
b) ( )dx x
}
+
5
1
2
1 ln

Value of tol: 1.0e-6
n = 2.0480e+003 old = 8.7733e+000 new = 8.7733e+000 diff = 5.8688e-007
c) ( )dx x
}
3
1
sin
Value of tol: 1.0e-6
n = 1.0240e+003 old = 1.9279e+000 new = 1.9279e+000 diff = 3.0184e-007

Potrebbero piacerti anche