MATLAB Programming: M-Files, Scripts, and Functions

advertisement
MATLAB LECTURE 3
In MATLAB you write programs in M-files. M-files are ordinary ASCII text files written
in MATLAB language. They are called M-files because they must have a ‘.m’ extensionat
the end of their name. M-files can be crreated suing any editor or word-processing
application . However, MATLAB has a built-in M-file editor which can be accessed through
the Main Menu by
FILES > NEW> M-file
There are two types of M-files – Script files and function files. We now discuss their
purpose and syntax.
Script Files
A script file is an M-file with a set of valid MATLAB commands in it. A script file is
executed by typing the name of the file on the command line. This is equivalent to typing all
the commands in the script file one-by-one. Script files work on global variables, that is,
variables currently present in the workspace. Results obtained from executing a script file
are left in the workspace.
EXAMPLE
We will write a script file to solve the following system of equations.
r   x1  2
5 2r
3 6 2r  1  x 2   3
2 r  1 3r   x 3  5
or Ax = B.
Clearly, A depends on the parameter r, and we want to find the solution of the equation for
various values of the parameter r. We also want to find the determinant of the matrix A in
each case. We will write a Script file to do this and call it solvex.m which we will save in our
workspace.
% ----------This is the script file solvex.m ----------------------% It solves a set of three coupled equations for x and also
% determines the determinant of the matrix A.
A = [5 2*r r; 3 6 2*r-1; 2 r-1 3*r];
b = [2; 3; 5];
det_A = det(A)
x = A\b
%
%
%
%
create the matrix A
create the vector b
calculate determinant of A
solve for x
Note there is no colon at the end of that last two lines , therefore the results of executing
these two commands will be displayed in the command window. The results will be stored in
the variables det_A and x and these will be left in the workspace (Check this by typing who
or whos after executing the script file. )
If we execute the script by typing solvex we get an error,
» solvex
??? Undefined function or variable 'r'.
Error in ==> c:\matlab\toolbox\matlab\myprogs\solvex.m
On line 5 ==> A = [5 2*r r; 3 6 2*r-1; 2 r-1 3*r];
% create the matrix A
This error arises because we have not defined the variable r. So first we must put r into the
workspace and then execute the script file.
» r = 1;
» solvex;
% specify a value for r
% execute the script file
det_A =
64
x =
-0.0312
0.2344
1.6875
Note that the value of r is specified outside the script file. All variables in the workspace are
available for use within script files, and all variables in the script file are left in the work
space. Check this. So if you want to do a big set of operations but in the end you only want
a few outputs, then a script file is not the correct choice. In this case you should use a
function file.
Caution using a Script file:
Never name a script file the same name as the name of a variable it computes.
The name of a Script file must begin with a letter, the rest of the name may include digits
and the underscore character as well as letters. Names can be up to 19 characters long.
Aviod names that clash with built-in functions. It is a good idea to check if a file with the
proposed name already exists. You can do this with the command exist(‘filename’) this
returns a zero id nothing with the name filename exists. Type help exist for more detailed
information.
Function Files
A function file is also an M-file, like a script file except that the variables in a function
file are all local, that is they are not placed in the workspace after the file is executed.
Syntax:
A function file must begin with a function definition line, which has a well-defined list
of inputs and outputs:
function [output variables] = function_name(input variables);
Where the function_name must be the same as the filename in which the function is written.
For example, if the name of the function is projectile it must be written and saved in a file
named projectile.m. The function definition line may look slightly different depending on
whether there is no output, a single output, or multiple output.
EXAMPLES
Function definition line
File Name
function [rho, H, F] =
motion(x,y,t);
function [theta] = angleTH(x,y);
motion.m
function theta = THETA(x,y,z);
THETA.m
function [ ] =circle(r);
circle.m
function circle(r);
circle.m
angleTH.m
NOTES:
 the word function on the function definition line must be in lower case. A common
mistake is to type it as Function.
 A single output variable is not required to be enclosed in square brackets in the definition
line, but multiple output variables must be enclosed in [ ] . When there is no output
variables then the [ ] brackets and the equal sign can be omitted.
 The first comment line after the function definition is known as the H1 line and is used as
the help line which is referenced by the lookfor command. Any blank lines before the %
sign in the first comment line disqualify it from becoming the H1 line.
Executing a Function
There are two ways to execute a function (both user written and built-in)
1). With explicit output: This is the full syntax of calling a function. Both input and output
variables are specified in the function call. For example if the function definition line of a
function is
function [rho, H, F] = motion(x,y,t);
then all of the following commands represent legal function calls:
 [r, angmom, force] = motion(xt,yt,time); The input variables xt, yt and
time must be defined before executing this command.
 [r, h, f] = motion(rx,ry,[0:100]); The input variables rx and ry must be
defined beforehand, the third input variable t is specified in the call statement.
 [r, h, f] = motion(2, 3.5, 0.01); All variables are specified in the call
statement.
 [radius, h] = motion(rx, ry); Call with a partial list of input and output
variables. The third input variable must then be assigned a default value within the
function if it is required in the calculations.
2) . Without any output: The output list can be omitted entirely if the computed quantities
are not of any interest. For example, this might be the case when the function displayes the
desired result graphically. To execute the function in theis mode, just type the name of the
function with the input list. For example:
motion(rx, ry, time);
this will execute the function motion without generating any explicit output. If the semicolon
at the end of the call is omitted the first variable in the output list of the function is displayed
in the default variable ans.
EXAMPLE
We will now write a function to solve the system of equations defined above. We give the
function a value of r as input and det_A and x will be output. We will call this function
solvexf.m
function [det_A, x]=solvexf(r);
%SOLVEXF - solves a 3 x 3 matrix equation with parameter r
% To execute the function type:
%
[det_A, x] = solvexf(r);
% Input:
%
r
% Output:
%
[det_A,x]
A = [5 2*r r; 3 6 2*r-1; 2 r-1 3*r];
% create
b = [2; 3; 5];
% create
det_A = det(A);
% calculate
x = A\b;
% solve for
the matrix A
the vector b
determinant of A
x
Now r, x and det_A are all local variables. Any other variable names can be used in their
place in the function call statement. Sample output would be as follows:
[detA, y] = solvexf(1);
detA
detA =
64
y
y =
-0.0312
0.2344
1.6875
% execute solvexf function with r = 1
% display the value of detA
% display value of y
The only variables left in the workspace after execution will be the variables in the
workspace.
Programming in MATLAB
For on-line help type : help lang
FOR LOOPS:
A for loop is used to repeat a statement or group of statements for a fixed number of
times. Here are two examples:
EXAMPLE-1
for m = 1:100
Num = 1/(m+1);
end
EXAMPLE-2
For n = 100:-2:0,
k = 1/(exp(n)),
The counter in the loop can also be given an explicit increment: for
end
p = m : k : n
to advance the counter p by k each time, for example for p = 2 : 0.1 : 4 ,
increments the counter by 0.1 on each loop. Note that the increment can also be negative.
It is also possible to have nested for-loops, that is for-loops within for loops. Every for,
however, must be matched with a corresponding end statement.
EXAMPLE:
The following matrix with three non-zero diagonals:
5 1 0 0 0 
1 5 1 0 0


A  0 1 5 1 0 


0 0 1 5 1 
0 0 0 1 5
can be created with three nested for loops as follows
A = [];
for k = 1:5
for j = 1:5
if k == j
A(k,k) = 5;
elseif abs(k-j)==1
A(k,j) = 1;
else
A(k,j) = 0;
end
end
end
(we will discuss if-else statements below:
WHILE LOOPS
A while loop is used to execute a statement or group of statements for an indefinite
number of times until the condition specified by the while loop is no longer satisfied.
EXAMPLE
% Find all of the powers of 2 below 10000
v = 1; num = 1; i = 1;
while num < 10000
num = 2^i;
v = [v;num];
i = i+1;
end
Again, every while statement must have a matching end statement.
IF-ELSEIF-ELSE STATEMENTS
This construction provides a logical branching for computations. The basic form of an
if statement is:
if logical expressiom
commands;
end
An if statement can be written on a single line as
if logical expression,
commands, end
EXAMPLE
The following statements remove the irst column of a matrix A if all the elements of the first
column are zero
if A(:, 1) == 0
A = A(1:m, 2:n)
end
The if statement can be used in more complex contexts in combination with elseif and
else. There are many structures possible:
if logical expression
statements 1
else
statements 2
end
or
if logical expression 1
statements 1
elseif logical expression 2
statements 2
end
Note elseif must be written as one word and does not require a separate end statement.
Another example of an if-elseif structure
if logical expression 1
statements 1
elseif logical expression 2
statements 2
else
statements 3
end
EXAMPLE
i = 6;
j = 21;
if i > 5
k = i;
elseif (i > 1) & (j == 20)
k = 5*i+j;
else
k = 1;
end
SWITCH-CASE-OTHERWISE Statement
These constructions provide another logical branching for computation. A flag (any variable)
is used as a switch and the values of the flag make up the different cases for execution.
The general syntax is
Switch flag
Case value 1
Block 1 computation
Case value 2
Block 2 computation
Case value 3
Block 3 computation
…
otherwise
last block of computation
end
Again the switch command must have a corresponding end statement. The switch can be
a numeric variable or a string variable. Let us look at an example using a string variable as
the switch:
EXAMPLE
color = input('color = ','s');
switch color
case 'red'
c = [1 0 0]
case 'green'
c = [0 1 0]
case 'blue'
c = [0 0 1]
otherwise
c = [0 0 0]
end
BREAK COMMAND
The command break inside a for or while loop terminates the execution of the loop even if
the condition for execution of the loop is true.
EXAMPLE
x = exp(sqrt(163));
while 1
n = input('Enter max. number of iterations ')
if n <= 0
break
end
for i = 1:n
x = log(x)
end
end
If the loops are nested then the break terminates only the innermost loop.
ERROR COMMAND
The command error('message') inside a function or a script aborts the execution, displays
the error message message , and returns control to the keyboard,
EXAMPLE
function w = crossprod(u,v);
% crossprod(u,v) calculates the crossproduct u X v
if nargin ~=2
error('Sorry, you need two input vectors')
end
if length(u) > 3 | length(v) > 3
error('vector too big, must have dimension <= 3')
end
w = [u(2)*v(3)-u(3)*v(2); u(3)*v(1)-u(1)*v(3);…
u(1)*v(2)-u(2)*v(1)];
RETURN COMMAND
The command return simply returns the control to the invoking function.
EXAMPLE
function animatebar(t0,tf,x0);
% animate the bar of a pendulum.
.
.
.
disp('Do you want to see the phase portrait? ')
ans = input('Enter 1 for YES or 0 for NO');
if ans == 0
return
else
plot(....)
end
Numerical Differentiation
The derivative of a function f(x) is defined as a function f’(x) which is equal to the rate of
change of f(x) with respect to x
df ( x )
f ' ( x )
dx
Numerical differentiation techniques estimate the derivative of a function at a point x k by
approximating the slope of the tangent line at xk using values of the function at points near
xk. The approximation of the slope of the tangent line can be done in several ways:
f(Xk+1)
The method shown on the left assumes that the derivative at xk
is estimated by computing the slope of the line between f(xk-1)
and f(xk) as in
f(Xk)
f(Xk-1)
f ' (x k ) 
f ( x k )  f ' ( x k 1 )
x k  x k 1
This type of approximation is called a backward difference
approximation.
Xk-1
Xk
Xk+1
f(Xk+1)
f(Xk)
f(Xk-1)
Xk-1
Xk
Xk+1
f(Xk+1)
f(Xk)
f(Xk-1)
Xk-1
Xk
The method shown in this figure assumes that the
derivative at xk is estimated by computing the slope of
the line between f(xk) and f(xk+1) as
f ( x k 1 )  f ( x k )
f ' (x k ) 
x k 1  x k
This type of approximation is called a forward
difference approximation
Xk+1
The method shown in this figure assumes that the
derivative at xk is estimated by computing the slope of
the line between f(xk-1) and f(xk+1) as
f ( x k 1 )  f ( x k 1 )
f ' (x k ) 
x k 1  x k 1
This type of approximation is called a central
difference approximation
The quality of all of these types of derivative computations depends on the distance
between the points used to estimate the derivative, the estimate improves as the distance
between the two points decreases.
The second derivative of a function f(x) is the derivative of the first derivative and this
function can be evaluated using the slopes of the first derivatives. Thus if we use the
backward difference method we have:
df ( x) f ' ( x k )  f ' (x k 1 )
f ' ' (x k ) 

dx
x k  x k 1
Similar expressions can be used for higher order derivatives;
The diff function
The diff function computes differences between adjacent values in a vector,
generating a new vector with one less value. If the diff function is applied to a matrix, it
operates on the columns of the matrix as if each column was a vector. Thus the matrix
returned has the same number of columns but one less row.
EXAMPLE:
» x = [ 0, 1, 2, 3, 4, 5, 6, 7];
» y = [ 2, 3, 1, 5, 8, 10, 9, 8];
» diff(x)
ans = 1
1
1
1
1
1
1
» diff(y)
ans = 1 -2
4
3
2
-1
-1
» dy = diff(y)./diff(x)
dy = 1 -2 4 3
% note array division (./)
2
-1
-1
EXAMPLE:
Differentiate the following function
f (x ) x5  3x 4  11x3  27 x 2  10x  24
in the range –4 to 5
A Matlab script to do this is the following:
% evaluate and plot f(x) and f'(x)
»%
» x = -4 : 0.1 : 5;
» f = x.^5 - 3*x.^4 - 11*x.^3 +27*x.^2 + 10*x-24;
» df = diff(f)./diff(x);
» xd = x(2:length(x));
» plot(x,f,'r',xd,df,'b:')
150
0
100
0
500
0
500
1000-4
-3
-2
-1
0
1
2
3
4
5
We can find the critical points (approximately) using the following MATLAB script:
% Find the location of the critical points of f'(x)
»%
» product = df(1:length(df)-1).*df(2:length(df));
» critical = xd(find(product < 0))
critical = -2.3000 -0.2000 1.5000 3.4000
»
The find function finds the indices of the locations in the array product that are negative
because these points indicate a change in sign of the derivative i.e they locate the points
where the derivative crosses zero, (the critical points). These indices are then used with the
vector xd to find the approximate locations of the critical points.
Higher order differences can be calculated by applying the diff function multiple times, as in
diff(diff(f))
EXAMPLE
» df2 = diff(diff(f))./diff(xd);
» xdd = x(2:length(xd));
» plot(x, f, 'r', xd, df, 'g.' , xdd, df2, 'b:' )
»
150
0
100
0
500
0
500
1000-4
-3
-2
-1
0
1
2
3
4
5
EXERCISES
For each of the following, plot the function, its first derivative, and its second
derivative, over the interval [-10, 10] and then find the locations of the critical points.
g1x   x 3  5x 2  2 x  8
g 2 x   x 2  4 x  4
g3 x   x 3  4 x 2  2 x  2
Summary of difference functions:
Numerical Integration
In MATLAB we can solve definite integrals of the kind
b
I   f ( x )dx
a
numerically. MATLAB has several functions for numerical integration. If we want MATLAB to
take care of the whole computation then the quad command can be used.
COMMAND
quad(fcn, a, b)
quad(fcn, a, b, tol)
quad8(fcn, a, b, tol)
DESCRIPTION
Returns an approximation of the integral of f(x) on the interval
[a, b] The string fcn contains the name of a matlab function,
that can either be a built-in function or a user defined M-file.
The function must return a vector when a vector is passed to it.
Returns an approximation of the integral of f(x) where the
relative error is defined by the parameter tol. Otherwise the
same as above
Same as quad but uses a method with a higher order of
accuracy.
Both quad and quad8 demand that the integral be finite over the interval [a, b].
When the tolerance is defined, the quad algorithm continues to refine its estimate of the
integral until
(previous estimate - current estimate)/previous estimate < tol
To find information on these commands type help quad , help quad8 or help funfun.
EXAMPLE:
Compute the following integral
1
2
 exp(  x )dx
0
we first have to create the function in an M-file. The file integrand.m contains this function
function y = integrand(x)
y = exp(-x.^2);
return
We first calculate the integral using the quad command as
» format long
» integralstd = quad('integrand',0,1)
integralstd =
0.74682612052747
we now specify the tolerance as
» integraltol = quad('integrand',0,1,0.00001)
integraltol =
0.74682414517798
and using the quad8 command
» integral8std = quad8('integrand',0,1)
integral8std =
0.74682413281243
A second set of commands for performing integrals is the trapz command. This uses the
trapezoidal rule.
Command
Description
trapz(x,y)
Computes the integral of y as a function of x. The vectors x
and y must have the same length and (xi, yi ) represents a
point on the curve to be integrated. The spacing between the
points do not have to be equidistant and the x values do not
have to be sorted.
trapz(y)
Computes integral of y as above but assumes that the xvalues are equispaced with distance 1 between successive x
values
trapz(x,A)
Computes the integral of each column of A as a function of x
and returns a row vector containing the result of the
integration. The columns of A must have the same length as
the vectors x
EXAMPLE
1
We woill look at the same integral as above  exp(  x 2 )dx .
0
We first have to create the x-values, we try two cases using 5 and 10 values
» x5 = linspace(0, 1, 5);
» x10 = linspace(0, 1, 10);
we then create the vector y as a function of x.
» y5 = exp(-x5.^2);
» y10 = exp(-x10.^2);
we now use the trapz command to evaluate the integral
»integral_5 = trapz(x5,y5)
integral_5 =
0.74298409780038
» integral_10 = trapz(x10,y10)
integral_10 =
0.74606686791267
The bigger we make the vector x the more accurate our result, however, the bigger x the
longer the time taken to perform the trapz command.
EXERCISE
Evaluate the following integrals using both the traps, and quad commands. Eveluate the
integrals by hand and check your results.
0.6
1)  x dx
0.5
0.5
1
2)  x dx
3)
0
 x dx
1
0.5
4)
 x dx
0.5
DOUBLE (MULTIPLE) INTEGRATION:
11
Suppose we wanted to compute the double integral   exp( x 2  y 2 ) dx dy . We can do this
00
by applying the quad function twice as follows:
First an M-file containing the function is defined
function f = integrand2(x)
f = exp(-x.^2-y.^2);
return
Then we compute a number of integrals in the y direction for fixed x-values with quad.
for ii = 1:15
integral(ii) = quad('integrand2',0,1,[],[],x(ii))
end
This gives the following results for the 15 integrals:
integral =
Columns 1 through 4
0.74682612052747
0.71330851045335
0.74302548691621
0.73173924249212
Columns 5 through 8
0.68828275499294
0.58162876748497
0.65739257538019
0.62151429921440
Columns 9 through 12
0.53877701036768
0.40281824243537
0.49401559303449
0.44837426922748
Columns 13 through 15
0.35821684313254
0.31531984029313
0.27474197587188
Now we have computed 15 integrals in the y-direction. The results of these integrations can
be used together with the trapz command to obtain the double integral.
» dintegral = trapz(x,integral)
dintegral =
0.55751410597318
ORDINARY DIFFERENTIAL EQUATIONS (ODE)
MATLAB has a whole built-in suite of differential equation solvers. The most commonly used
ones are ode23 and ode45 . These are implementations of 2nd /3rd order and 4th /5th order
Runge-Kutta Methods, respectively. Solving most differential equations using one or other of
these functions in their simplest forms, involves the following steps:
1) Write the differential equations as a set of first order differential equations:
For ODE's of order  2 this step involves introducing new variables and recasting the
original equation(s) in terms of 1st order ODEs in the new variables. Basically you need the
equations in the vector form
dx
 x  f x, t 
dt
where x = [x1, x2, x3, ….xn]T. In expanded form the equation is
x 1  f1x1, x 2,  xn, t  
  

x 2  f2 x1, x 2,  xn, t 

  

  

x n  fn x1, x 2,  xn, t 
EXAMPLE
Suppose we have the following second order differential equation
d2
d2 
 2 sin   0 
 2 sin 
2
2
dt
dt
with the initial conditions
d
0   1,
0
dt t 0
We must recast this second-order ODE as two first order ODE's. To do this we introduce the
variables
d
z1  
z2 
dt
then
dz 2 d2
dz1 d

 2 sinz1 
and

 z2
2
dt
dt
dt
dt
So our 2nd order ODE can be written in vector form as
 dz1 
 dt  z 2



  2

 dz 2    sinz1 
 dt 
two first order differential equations of the form z  f z  .
2) Write a function to compute the derivatives:
You must write a function that evaluates f1(x,t), f2(x,t),  fn(x,t) given the input (x, t) where x
is a column vector. The function must return the derivatives as a column vector.
EXAMPLE
Following on with the same example started above
function zdot = pend(t,z);
% call syntax: zdot = pend(t,z);
% Inpute are: t = time
%
z = [z(1); z(2)] = [theta, thetadot]
% Output is
zdot = [z(2); -w^2sin(z1)]
%
wsq = 1.56;
% specify a value for w^2
zdot = [z(2);-wsq*sin(z(1))];
note that the returned vector zdot is a 2 x 1 column vector.
3) Use the built-in ODE solvers to solve the equations:
The function defined in step-2 is used as an input to ode23 or ode45. The syntax used in
calling these commands is
[time, solution] = ode23('function name', tspan, x0)
Time vector
Solution
vector
User written function
Time Span
containing the
equations you wish [t0, tfinal]
to solve
Initial Conditions
EXAMPLE
Again using the ODE defined above, we can write a Script file that solves this equation and
plots the results. Remember that the output z contains two columns z1 (which is actually )
and z2 (which is actually d/dt). A script would look something like
% Script file to integrate the pendulum equation
%
%
tspan = [0 20];
% start and stop time
z0 = [1;0];
% Initial conditions, note column vector
[t,z] = ode23('pend',tspan,z0); % run ode23 (could use ode45)
x = z(:,1);
% x = first column of z (theta)
y = z(:,2);
% y = second column of z (theta_dot)
plot(t,x,t,y)
% plot t versus x and t versus y on same graph
xlabel('t'), ylabel('theta and theta dot')
figure(2)
% open a new figure window
plot(x,y)
% plot phase diagram
xlabel('Displacement'), ylabel('Velocity')
4) Extract desired variables from the output and interpret the results:
For a system of n first order ODEs the output martix solution contains n columns. You need
to understand which column corresponds to which variable in order to extract the results.
For the above set of equations we obtain the following plots:
1.5
theta and theta dot
1
0.5
0
-0.5
-1
-1.5
0
2
4
6
-0.8
-0.6
-0.4
8
10
t
12
14
16
18
20
-0.2
0
0.2
Displacement
0.4
0.6
0.8
1
1.5
1
Velocity
0.5
0
-0.5
-1
-1.5
-1
EXERCISES
1) . Beats and Resonance: Consider the following second order ODE
d2 x
 x  F0 cost 
dt 2
a) Convert the given equation to a set of first order ODEs and then programm the set of
equations in a function to be used for numerical solution with ode45.
b) Set Fo = 0 and solve the system of equations with the initial conditions x(0) = 0, dx/dt(0)
=1. By plotting the solution, make sure that you get a periodic solution
c) Let Fo = 1 and  = 0.9. Starting with zero initial conditions x(0) = 0, dx/dt(0) =0, find the
solution ( x and dx/dt) for 0  t  70. Plot x against t. How is the amplitude of the rapidly
oscillating solution modulated? (You should see beats)
d) Let Fo = 1 and  = 1.0 Again starting with zero initial conditions, find the solution for 0 
t  40. How does the amplitude f the solution, x change with time in this case? (You
should see resonance).
e) Experiment with the solution of this system by adding a damping term proportional to the
velocity (  dx/dt ) on the left hand size of the equation. Investigate solutions for various
values of .
2) Non-linear ODEs, Phase Plots and limit cycles:
Consider the following set of coupled first order, nonlinear ODEs
dx
 x  y  x( x 2  y 2 )
dt
dy
  x  y  y( x 2  y 2 )
dt
a) Solve the set of equations with initial conditions x(0) = 2 and y(0) = 2 over the time
interval 0  t  20. Plot x vs t and y vs t in two different figures. Use hold on to keep the
plots and graphs of subsequent solutions as overlay plots. Save the solutions x and y in,
say x1 and y1 for later use.
b) Solve the given set of equations for the following set of initial conditions and plot the
solutions as above (over-layed on the old solutions). (I) (xo,yo) = (1,0) (ii) (xo,yo) =
(0.1,0) and (iii) (xo,yo) = (0, 1). Save the solution in each case for later use. Do the plots
suggest a particular long term behaviour of the system?
c) The ultimate periodic solution that all solutions seem to get attracted to is called a limit
cycle. It is much easier to visualise the limit cycle in phase space, that is, the plane of x
and y. Plot x versus y for all solutions on the same figure. You should clearly see the limit
cycle on this phase plot. Make sure the axis have equal lengths
d) Try solutions with some other initial conditions.
Download