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. g1x 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 f1x1, 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 sinz1 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 sinz1 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 cost 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.