University of Waterloo Faculty of Engineering Department of Electrical and Computer Engineering ECE 204A Pre-Laboratory 8 Prepared by Surname/Last Name, Legal Given Name(s) UW Student ID Number: 2NNNNNNN UW User ID: uwuserid @uwaterloo.ca 2A Electrical/Computer Engineering 23 March 2016 8.1a Write each of the following in the alternate form: a:h:b [3 3.5 4 4.5 5 5.5 6] [1 1.1 1.2 ... 1.9 2.0] [2 2.3333 2.6667 3] :: :: :: linspace( a, b, n ) linspace(,,) linspace(,,) linspace(,,) 8.1b Write the function f8b(t, y) which implements f8b : t , y y 2e2t . function [dy] = f8b( t, y ) % enter your implementation return; end Test your function by evaluating the following: f8a( 0.5, 0:10 ) 8.1c The function line plots line segments in Matlab. By reading help line, determine how you can plot three lines: 1. One from (1, 5) to (3, 11), 2. One from (2, –1) to (4, 9), and 3. One from (10, 8) to (6, 0). Your output should look something like that seen in Figure 1. Figure 1. A plot of three line segments. Enter your Matlab commands here. the function line( X, Y ). There must be only one call to 8.1d What Matlab function is the inverse tangent function or arctangent? Given a line with slope s, the inverse tangent of that slope will give the angle between horizontal axis and that line. What should the inverse tangents of 1 and infinity be and validate this using Matlab. Your answer here. Copy and paste your Matlab commands and the output here. 2 8.1e We will create a field plot of the ordinary differential equation described by y (1) t f t , y t . Recall that this says that the slope of a solution passing through a point t0 , y0 may be T determined simply by evaluating f t0 , y0 . What we will do is select a number of points of the form tk , yk and draw a straight line with the slope f tk , yk at those points. T Create the function fieldplot that has the signature: function fieldplot( f, t_rng, y_rng, n ) where f is a function handle, trng and yrng are 2-dimensional vectors storing the values (tinitial, tfinal) and (ymin, ymax), respectively and where n is a vector of two integers (nt, ny). Of course, rather than always referring to t_rng(1), it might be useful to initially assign these to other local variables. 1. Create two 2 × (nt · ny) matrices T and Y of zeros, 2. Set a counter k to 0, t t y yinitial 3. Set (that is, delta) to be the minimum of final initial and final , 4nt 4n y 4. Create a for loop where t runs from tinitial to tfinal with nt points where a. In the body of that loop, create another loop where y runs from yinitial to yfinal with ny points which has a body that i. increments the counter k by 1, ii. creates the vector v = (, 0)T which will define the end-points of a line segment, iii. determine the slope s = f(t, y), iv. determine the angle of that slope: = tan-1(s), cos sin v. create the rotation matrix R , sin cos vi. rotate the vector v by multiplying the rotation matrix: v = Rv, vii. set the kth column of T (i.e., T(:,k)) to be (t – v1, t + v1)T, and viii. set the kth column of Y to be (y – v2, y + v2)T. 5. Call line( T, Y ) and return. 3 In order to help you with your implementation, if you print out the matrices T and Y after the outer for-loop is completed, you will get the output >> fieldplot( @f8b, [0, 2], [-1, 1], [3 2] ) T = -0.1179 -0.0527 0.8653 0.8969 1.8800 0.1179 0.0527 1.1347 1.1031 2.1200 1.8843 2.1157 Y = -0.8821 -1.1179 1.1200 0.8800 1.1581 0.8419 -1.0982 -0.9018 1.1310 0.8690 -1.1156 -0.8844 and the plot will be as shown in Figure 2. Figure 2. The output of fieldplot( @f8a, [0,2], [-1,1], [3 2] ). 8.1e Plot the output of fieldplot( @f8b, [0, 2], [-1, 1], [17 17] ) and observe that the solution to the initial-value problem y 1 t f8b t , y t y t 2e 2t y 0 1 is the function y t 2e2t et while the solution to the initial-value problem 4 y 1 t f8b t , y t y t 2e 2t is the function y t 2e 2t y 0 0.5 3 et . 2 If we plot hold on ts = linspace( 0, 2, 100 ); plot( ts, 2*exp(-2*ts) - exp(-ts), 'r' ) plot( ts, 2*exp(-2*ts) - 1.5*exp(-ts), 'b' ) you will see that the two solutions follow the flow defined by our plot of points. Replace the image in Figure 3 with the output. Do not close the plot window. Figure 3. Two solutions of the differential equati y t f8b t , y t y t 2e 2t with the initial conditions y(0) = 1 (red) and y(0) = 0.5 (blue). 1 5 8.1e You will recall from Laboratory 3 that Euler’s method can be used to approximate the solution to an initial-value problem. The following commands plot solutions using a step size of h = 0.5. hold on % The approximation to the solution with y(0) = 1 on [0, 2] [ts, ys] = euler( @f8b, [0, 2], 1, 5 ); plot( ts, ys, 'ro-' ) % The approximation to the solution with y(0) = 0.5 on [0, 2] [ts, ys] = euler( @f8b, [0, 2], 0.5, 5 ); plot( ts, ys, 'bo-' ) By specifying the option 'o-', this indicates that both lines and circles should be used the plot these points. Replace Figure 4 with the output. Do not close the plot window. Figure 4. The solutions to two initial-value problems with two approximations using Euler’s method. 8.1f You will notice that the two approximations are not very good: they significantly undershoot the actual solutions! We could improve this by using more points (say, 8, rather than 4); however, there are better algorithms: we will start with Heun’s method which attempts to correct for this. Recall that in Euler’s method, you approximated the value y(tk + 1) (that is, the same as y(tk + h)) by using the approximation yk of the value y(tk ), calculating the slope at the point (tk, yk) and then calculating yk + 1 = yk + h f(tk, yk): ys(k + 1) = ys(k) + h*f(ts(k), ys(k)); We can reinterpret this as first approximating the slope, and then adding on the slope: 6 K0 = f(tk, yk) yk + 1 = yk + h K0 This only approximates the slope at time tk; however, the slope will be changing across the entire interval [tk, tk + 1] (again, that is, [tk, tk + h]) and thus, sampling the slope only at one end point is clearly sub-optimal. Heun suggests that you sample the slope twice and then use the average of these two samples to approximate the slope across the entire interval: K0 = f(tk, yk) K1 = f(tk + h, yk + hK0) K K1 yk + 1 = yk + h 0 2 Make this change to your function euler and call the new function heun. Continue plotting these two solutions and replace Figure 5 with your image. hold on % The approximation to the solution with y(0) = 1 on [0, 2] [t8b, y8b] = heun( @f8b, [0, 2], 1, 5 ); plot( t8b, y8b, 'mx-' ) % The approximation to the solution with y(0) = 0.5 on [0, 2] [ts, ys] = heun( @f8b, [0, 2], 0.5, 5 ); plot( t8b, y8b, 'cx-' ) Figure 5. The solutions to two initial-value problems with two approximations using Euler’s method and two approximations using Heun’s methods. 7 8.2 In the laboratory, you will implement a PLU decomposition: that is, given a matrix M, you will find three matrices P, L and U where: 1. P is a permutation matrix (a matrix such that PM or Pv permutes the rows of the matrix M or vector v), 2. L is a lower-triangular matrix with all 1s on the diagonal and all entries below the diagonal are less than or equal to 1, and 3. U is an upper-triangular matrix. 8.2a Recall that the determinant of an upper-triangular matrix or a lower-triangular matrix is the product of the entries on the diagonal. What is the determinant of the following two matrices? 0 0 5 3 9 1 0 0 6 2 and 0.3 1 0.7 0.4 1 0 0 4 Your answers here. Check your answer with Matlab using the function det. Copy and paste your Matlab commands and the output here. 8 8.2b Recall that the determinant of a product of matrices is the product of the determinants: |MN| = |M| |N| Thus, if we can write M = PLU, then the determinant of the matrix M may be found by taking the product of the determinants |P|, |L| and |U|. What is the determinant of the matrix 0 1 2 3 4 5 6 7 8 if you know the PLU decomposition (that is, M = PLU) is >> [L U Pt] = lu( M ) L = 1.0000 0 0 1.0000 0.5000 0.5000 0 0 1.0000 U = 6 0 0 7 1 0 8 2 0 0 1 0 0 0 1 1 0 0 >> P = Pt' 0 1 0 0 1 0 0 1 0 Pt = Enter your answer here including an explanation. You will now implement Gaussian elimination to help you get ready for PLU decomposition which you will implement in class. 9 8.2c We will implement the function gauss_elim which will take two arguments: an n × n matrix M and an n-dimensional column vector b and it will return an augmented matrix in row-echelon form; that is, it will have the following characteristics: 1. It will be an n × (n + 1) matrix and 2. The first non-zero entry of row i + 1 must be in a column greater than the first non-zero entry of row i. We may have to use pivoting to achieve this. function [Maug] = gauss_elim( M, b ) return; end 8.2d Begin with error checking: use size to determine if the matrix M is not square, throw the exception: throw( MException( 'MATLAB:illegal_argument', ... 'The matrix must be square' ) ); If M is an n × n matrix and b is not an n-dimensional column vector, throw the exception throw( MException( 'MATLAB:illegal_argument', ... 'The vector must be a %d-dimensional column vector', n ... ) ); The first four commands should return errors, the last should not: gauss_elim( gauss_elim( gauss_elim( gauss_elim( gauss_elim( [1 [1 [1 [1 [1 2 3; 2 3; 2; 4 2; 4 2 3; 4 5 4 5 5], 5], 4 5 6], [1 2 3]' ) 6; 7 8 9], [1 2 3] ) [1 2 3] ) [1 2; 3 4] ) 6; 7 8 9], [1 2 3]' ) Copy and paste your Matlab commands and the output here. 10 8.2e Next, create the matrix named Maug which is the augmented matrix (M | b). Now, the following gauss_elim( [1 2 3; 4 5 6; 7 8 9], [10 11 12]' ) should simply return the augmented matrix 1 4 7 2 3 5 8 6 9 10 11 12 Copy and paste your Matlab commands and the output here. 11 8.2f We will begin by assuming we don’t have to pivot. Recall the general algorithm: Going through the rows in order, for a given row i, find the first column j in that row that has a non-zero value and the appropriate multiple of that row onto each row below it so as to cancel out any non-zero value below the (i,j)th entry. In order to prepare for this, recall how to do the following (this was covered in Laboratory 3): >> M = [1 2 3; 4 5 6; 7 8 9]; 1. Extract the Row 3. 2. Add -7 times Row 1 onto Row 3. >> M(3,:) = M(3,:) + -7*M(1,:) M = 1 2 3 4 5 6 0 -6 -12 Perform a similar operation to place a 0 at M(2,1). Copy and paste your Matlab commands and the output here. 12 8.2g We will now implement Gaussian elimination: create a loop that cycles i going from Row 1 to Row n – 1: 1. In Row i, we will first check if there is a non-zero entry in that row. We can do this by extracting the ith row of Maug and calling ~any(Maug(i,:)). If none of the entries are non-zero, we return from the function (we are done). 2. Otherwise, create a loop start from column j = i and goes to column n + 1. As soon as you find a non-zero entry (you must find a non-zero entry, as you checked ~any( Maug(i,:)) that indicated that there was a non-zero value), break out of the loop; j is now assigned the column containing the non-zero entry in Row i. We will now create a second loop that where ii goes from i + 1 to n. In each iteration of this loop, we will: m a. Calculate the ratio c aug; ii , j , and maug; i , j b. Replace Row ii with c times Row i added onto Row ii. This is all that is necessary. Some examples include the following: >> gauss_elim( [1 2 3; 4 5 6; 7 8 9], [10 12 16]' ) ans = 1 2 3 10 0 -3 -6 -28 0 0 0 2 >> gauss_elim( [4 2 -1; 4 8 5; 2 9 1], [1 4 3]' ) ans = 4.0000 2.0000 -1.0000 1.0000 0 6.0000 6.0000 3.0000 0 0 -6.5000 -1.5000 Create a random 4 × 4 matrix and name it Mr and a random 4-dimensional column vector named br. Solve the system as follows and both soln1 and soln2 should be equal or close to equal: Soln1 = Mr \ br Mraug = gauss_elim( Mr, br ) soln2 = Mraug(1:4, 1:4) \ Mraug( :, 5 ); Copy and paste your Matlab commands and the output here. 13 8.2h The last operation which we will require is swapping rows. Fortunately, this can be done relatively easily in Matlab. We know that M( 3, : ) extracts the 3rd row of the matrix M. What do you think that M( [2 3], : ) extracts? Create an example in Matlab with your own matrix that demonstrate that you are correct (or one that corrects your previous misconception): Your answer here. Copy and paste your Matlab commands and the output here. Now, what do you think M( [2 3], : ) = M( [3 2], : ); does? Again, create a Matlab example that demonstrates that you are correct: Your answer here. Copy and paste your Matlab commands and the output here. 14