Top Banner
MPR211 Notes Part 2 Schalk Kok 2005 Contents 1 Numerical integration 2 1.1 Numerical integration using a while loop ................... 5 2 Vectors and matrices 9 2.1 Defining a matrix using the input statement ................. 11 2.2 Matrix manipulations .............................. 11 2.3 Example: Norm of a vector .......................... 13 2.4 Example: Matrix-vector multiplication .................... 14 2.5 Example: Plots of functions of a single variable ............... 15 3 Revisiting previous programs 16 3.1 Taylor series using vectors ........................... 16 3.2 Numerical integration using vectors ...................... 18 4 Sorting algorithms 21 4.1 Bubble sort algorithm ............................. 23 5 Gauss elimination 26 5.1 Gauss elimination algorithm .......................... 28 5.1.1 Forward reduction step ......................... 28 5.1.2 Backsubstitution step .......................... 31 5.2 Solving linear systems using Matlab ...................... 32 6 Functions 35 1
55
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: MAtlab Notes

MPR211 Notes Part 2

�Schalk Kok

2005

Contents

1 Numerical integration 2

1.1 Numerical integration using a while loop . . . . . . . . . . . . . . . . . . . 5

2 Vectors and matrices 9

2.1 Defining a matrix using the input statement . . . . . . . . . . . . . . . . . 11

2.2 Matrix manipulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.3 Example: Norm of a vector . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.4 Example: Matrix-vector multiplication . . . . . . . . . . . . . . . . . . . . 14

2.5 Example: Plots of functions of a single variable . . . . . . . . . . . . . . . 15

3 Revisiting previous programs 16

3.1 Taylor series using vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.2 Numerical integration using vectors . . . . . . . . . . . . . . . . . . . . . . 18

4 Sorting algorithms 21

4.1 Bubble sort algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5 Gauss elimination 26

5.1 Gauss elimination algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . 28

5.1.1 Forward reduction step . . . . . . . . . . . . . . . . . . . . . . . . . 28

5.1.2 Backsubstitution step . . . . . . . . . . . . . . . . . . . . . . . . . . 31

5.2 Solving linear systems using Matlab . . . . . . . . . . . . . . . . . . . . . . 32

6 Functions 35

1

Page 2: MAtlab Notes

6.1 Creating new functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

6.1.1 Gauss elimination using functions . . . . . . . . . . . . . . . . . . . 40

6.1.2 Numerical integration using functions . . . . . . . . . . . . . . . . . 43

6.1.3 Persistent variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

6.1.4 Global variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

7 Vectorizing algorithms 46

7.1 Creating vectors and vector computations . . . . . . . . . . . . . . . . . . 47

7.1.1 Linear algebra vs. component-by-component computations . . . . . 48

7.2 Vectorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

7.2.1 Vectorizing Gauss elimination . . . . . . . . . . . . . . . . . . . . . 50

7.2.2 Vectorizing numerical integration . . . . . . . . . . . . . . . . . . . 53

1 Numerical integration

Let’s try to develop a program that can be used to integrate any function numerically.Recall that integration is imply finding the area under a function, as depicted in Figure 1.A simple method to approximate the integral is by adding the areas of rectangles thatapproximate the function f(x) at specific locations between a and b. I can think of atleast 3 methods:

1. A left-point method, where the interval [a, b] is divided in n equal intervals of width∆x and the height of each rectangle is computed at the left point of each interval.I.e. the first rectangle’s height is f(a), the next rectangles height is f(a + ∆x), andso on. The last rectangle’s height is given by f(b − ∆x). This method is depictedin Figure 1.

a b

f (x)

∆x

Figure 1: Numerical integration of∫ b

af(x)dx

2

Page 3: MAtlab Notes

2. A right point method where the rectangle heights are computed as f(a+∆x), f(a+2∆x), . . . , f(b).

3. A midpoint method where the rectangle heights are computed as f(a+ 1

2∆x), f(a+

3

2∆x), . . . , f(b − 1

2∆x).

Instead of approximating the integral with rectangles, the area can also be approximatedby trapeziums. The area of a trapezium is given by the product of the average of the twoparallel sides with the perpendicular height. For the trapezium between a and a + ∆x,the area is

Area = ∆x1

2(f(a) + f(a + ∆x), (1)

as depicted in Figure 2. Should we approximate the total area using trapeziums, theintegral is given as

∫ b

a

f(x)dx ≈ 1

2∆x (f(a) + f(a + ∆x)) + 1

2∆x (f(a + ∆x) + f(a + 2∆a)) +

· · ·+ 1

2∆x (f(b − ∆x + f(b)) (2)

= ∆x(

1

2f(a) + f(a + ∆x) + f(a + 2∆x) + . . .

+f(b − 2∆x) + f(b − ∆x) + 1

2f(b)

)

(3)

a b

f (x)

∆x ∆x

f(a) f(a+ x)∆

Figure 2: Numerical integration using the trapezium method.

Now that we have a few ideas of how to integrate a function numerically, let’s developthe program. First of all, I’ll list the information that has to be available to performnumerical integration:

1. The function f(x)

2. The bounds of integration

3. The number of intervals

4. The method i.e. left-point, right-point, mid-point or trapezium method

After we get the above information from the user (using a number of input statements),I’ll compute the interval size ∆x and then use a for loop to add all the areas. Here’s myimplementation of a numerical integration program:

3

Page 4: MAtlab Notes

1: % Get user inputs

2: F_string = input(’Please enter function to be integrated. ’,’s’);

3: Fcn = inline(F_string);

4: LB = input(’Enter the lower bound of integration. ’);

5: UB = input(’Enter the upper bound of integration. ’);

6: N = input(’How many equal intervals between LB and UB? ’);

7: disp(’1: Left-point 2: Right-point 3: Mid-point’);

8: disp(’4: Trapezium 5: Quit program’);

9: Method = input(’Please enter your option. ’);

10: % My program repeats until the user inputs option 5

11: while Method~=5

12: % Initialize the integral at zero

13: Int = 0;

14: % Compute the interval size Delta_x

15: Delta_x = (UB-LB)/N;

16: % Use the switch statement to branch to one of the 4 methods

17: switch Method

18: % Case 1: left-point method

19: case 1

20: % For loop to compute area of each rectangle and add it to Int

21: for i=1:N

22: x = LB + (i-1)*Delta_x;

23: Int = Int + Delta_x*Fcn(x);

24: end

25: % Case 2: right-point method

26: case 2

27: for i=1:N

28: x = LB + i*Delta_x;

29: Int = Int + Delta_x*Fcn(x);

30: end

31: % Case 3: mid-point method

32: case 3

33: for i=1:N

34: x = LB + (i-1)*Delta_x + 0.5*Delta_x;

35: Int = Int + Delta_x*Fcn(x);

36: end

37: % Case 4: trapezium method

38: case 4

39: for i=1:N

40: x_L = LB + (i-1)*Delta_x;

41: x_R = x_L + Delta_x;

42: Int = Int + 0.5*Delta_x*(Fcn(x_L) + Fcn(x_R));

43: end

44: end

45: % Display answer

46: disp([’Integrating ’,F_string,’ between ’,num2str(LB),’ and ’, ...

47: num2str(UB),’ = ’,num2str(Int)])

4

Page 5: MAtlab Notes

48: % Display options again

49: disp(’1: Left-point 2: Right-point 3: Mid-point’);

50: disp(’4: Trapezium 5: Quit program’);

51: Method = input(’Please enter your option. ’);

52: end; %End of the while loop

53: % Outside while loop, user entered option 5 = Quit

54: % Displays a friendly message.

55: disp(’Thanks for using the program. Have a good day.’)

Do you notice the use of an outer while loop that keeps on repeating the numericalintegration program as long as the variable Method is not equal to 5. So now I don’t haveto re-type all the inputs when I want to run my program again using a different method.

The program listed above is used to numerically integrate the sin function between 0 andπ2. The analytical answer is 1, so let’s see how the program performs using 20 intervals.

I ran the program once and entered option 1 to 5 in that order. The output follows:

Please enter function to be integrated. sin(x)

Enter the lower bound of integration. 0

Enter the upper bound of integration. pi/2

How many equal intervals between LB and UB? 20

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 1

Integrating sin(x) between 0 and 1.5708 = 0.96022

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 2

Integrating sin(x) between 0 and 1.5708 = 1.0388

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 3

Integrating sin(x) between 0 and 1.5708 = 1.0003

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 4

Integrating sin(x) between 0 and 1.5708 = 0.99949

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 5

Thanks for using the program. Have a good day.

1.1 Numerical integration using a while loop

As you can see from the example above 20 intervals is not very accurate for using either theleft-point or right-point methods, but it seems adequate for the mid-point and trapezium

5

Page 6: MAtlab Notes

methods. So how do we know in advance how many intervals we need to get an accuratenumerically integrated value? We don’t, so therefore I suggest the use of a while loop tokeep increasing the number of intervals until the numerically integrated result convergesto within some specified tolerance. Here follows the modified program:

1: % Get user inputs

2: F_string = input(’Please enter function to be integrated. ’,’s’);

3: Fcn = inline(F_string);

4: LB = input(’Enter the lower bound of integration. ’);

5: UB = input(’Enter the upper bound of integration. ’);

6: N_ini = input(’Initial number of intervals between LB and UB? ’);

7: acc = input(’Enter the required accuracy. ’);

8: disp(’1: Left-point 2: Right-point 3: Mid-point’);

9: disp(’4: Trapezium 5: Quit program’);

10: Method = input(’Please enter your option. ’);

11: % My program repeats until the user inputs option 5

12: while Method~=5

13: % Define initial Error greater as acc, to enter while loop

14: Error = 2*acc;

15: % Since the number of intervals change during program execution,

16: % reset N to the initial number of intervals

17: N = N_ini;

18: % Set Int to zero to have a value the first time

19: % the while loop is executed

20: Int = 0;

21: % Start while loop that checks if consecutive values converged

22: while Error>acc

23: % Make a copy of the previous integral just before the program

24: % section starts that computes the new value

25: Int_old = Int;

26: % Initialize the integral at zero

27: Int = 0;

28: % Compute the interval size Delta_x

29: Delta_x = (UB-LB)/N;

30: % Use the switch statement to branch to one of the 4 methods

31: switch Method

32: % Case 1: left-point method

33: case 1

34: % For loop to compute area of each rectangle and add it to Int

35: for i=1:N

36: x = LB + (i-1)*Delta_x;

37: Int = Int + Delta_x*Fcn(x);

38: end

39: % Case 2: right-point method

40: case 2

41: for i=1:N

42: x = LB + i*Delta_x;

6

Page 7: MAtlab Notes

43: Int = Int + Delta_x*Fcn(x);

44: end

45: % Case 3: mid-point method

46: case 3

47: for i=1:N

48: x = LB + (i-1)*Delta_x + 0.5*Delta_x;

49: Int = Int + Delta_x*Fcn(x);

50: end

51: % Case 4: trapezium method

52: case 4

53: for i=1:N

54: x_L = LB + (i-1)*Delta_x;

55: x_R = x_L + Delta_x;

56: Int = Int + 0.5*Delta_x*(Fcn(x_L) + Fcn(x_R));

57: end

58: end; % End of switch

59: % Compute Error i.e. difference between consecutive integrals

60: Error = abs(Int - Int_old);

61: % Double the number of intervals

62: N = 2*N;

63: end; % End of inner while

64: % Display answer

65: disp([’Integrating ’,F_string,’ between ’,num2str(LB),’ and ’, ...

66: num2str(UB),’ = ’,num2str(Int)])

67: % Also display the number of required intervals

68: disp([’Number of intervals required = ’,num2str(N/2)])

69: % Display options again

70: disp(’1: Left-point 2: Right-point 3: Mid-point’);

71: disp(’4: Trapezium 5: Quit program’);

72: Method = input(’Please enter your option. ’);

73: end; %End of outer while loop

74: % Outside while loop, user entered option 5 = Quit

75: % Displays a friendly message.

76: disp(’Thanks for using the program. Have a good day.’)

I’ll only discauss the changes I’ve made. In program line 6, I now call the number ofintervals N ini, to indicate that this is the initial number of intervals. As the programproceeds, the number of intervals increase. In program line 7 I also ask the user to enterthe required accuracy, which will be used in the while loop condition.

In program line 14 I define a variable Error, which is the difference between consecutivenumerical integrals (using a different number of intervals). The number of intervals isinitially set to the value specified by the user in program line 17.

In line 20 I set the variable Int to zero. This statement is required because I assign thevalue of Int to the variable Int old in program line 25. The very first time the while

loop in line 22 is executed no calculations have been performed and therefore no value isavailable in the variable Int. Hence I require line 20.

7

Page 8: MAtlab Notes

Program lines 27–58 compute the numerical integral, based on the chosen method. Thispart of the program is unchanged. In line 60 I compute the difference between the integraland the value obtained previously. I then double the number of intervals in line 62 andthe end statement in line 63 returns the program to the while statement in line 22. Ifthe difference between consecutive numerical integration values (computed in line 60) issmaller than acc the while loop terminates and the program continues at program line65. Answers are displayed in the Command Window and the options are re-displayed.Depending on the user’s input, the program is either re-run (Method = 1–4), or terminateswith a friendly message (Method = 5). If Error>acc, the while loop (program lines 25–62) is repeated again.

Here follows the output for the same example I presented earlier. An accuracy of 0.0001is specified. As you can see, the different methods require a different number of intervalsto achive this specified accuracy. Clearly the mid-point and trapezium methods (N=80)is much more efficient that the left-point and right-point methods (N=10240).

Please enter function to be integrated. sin(x)

Enter the lower bound of integration. 0

Enter the upper bound of integration. pi/2

How many equal intervals between LB and UB? 10

Enter the required accuracy. 0.0001

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 1

Integrating sin(x) between 0 and 1.5708 = 0.99992

Number of intervals required = 10240

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 2

Integrating sin(x) between 0 and 1.5708 = 1.0001

Number of intervals required = 10240

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 3

Integrating sin(x) between 0 and 1.5708 = 1

Number of intervals required = 80

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 4

Integrating sin(x) between 0 and 1.5708 = 0.99997

Number of intervals required = 80

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 5

Thanks for using the program. Have a good day.

8

Page 9: MAtlab Notes

2 Vectors and matrices

So far, we have only dealt with variables that contain a single value i.e. scalar variables.But how do we represent a quantity that contains more than a single value e.g. a vector?We can use scalar variables to represent each of the components of the vector, but thatwill require many variable names, especially if the vector has many components. Fortu-nately, there exists array variables (computer terminology for both vectors and matrices)in Matlab.

I’ll start of by showing an example of a vector in Matlab. A vector is defined by enclosingthe components in square brackets e.g.

a = [ 1

2

3 ];

defines a column vector a with three components and

b = [ 1 2 3 ];

defines a row vector b with the same three components. Different rows can also beindicated with semi-colons e.g.

a = [1; 2; 3];

also defines a column-vector a.

A matrix variable is also defined by enclosing the components in square brackets e.g.

A = [ 1 2 3

2 3 4

3 4 5 ];

defines a 3 × 3 symmetric matrix A. As before, different rows can be indicated with asemi-colon i.e.

A = [ 1 2 3; 2 3 4; 3 4 5];

defines the same 3 × 3 matrix A as above.

You do not need to define complete vectors and matrices as above. You can also definevectors and matrices component by component by using an index to specify the row andcolumn. As an example, the following three program lines defines three components of avector b:

b(1) = 1;

b(2) = 2;

b(3) = 3;

9

Page 10: MAtlab Notes

The above three program lines defines the same vector b as at the start of this section.Note that if we specify only a single index such as in the example above, Matlab definesa row vector. If we want to create a column vector, we have to explicitly state that weare assigning values to the first column of an array e.g.

a(1,1) = 1;

a(2,1) = 2;

a(3,1) = 3;

defines the same vector a as at the start of this section.

Note that if we do not assign all the components of a vecor, Matlab fills in the gaps withzeros. As an example, the two program lines

a(1) = 1;

a(4) = 4;

define a row vector a

a =

1 0 0 4

Matrices can also be defined component by component by specifying two indices (the firstindex refers to the row number and the second index refers to the column number). Asan example, the matrix A above is defined by:

A(1,1) = 1;

A(1,2) = 2;

A(1,3) = 3;

A(2,1) = 2;

A(2,2) = 3;

A(2,3) = 4;

A(3,1) = 3;

A(3,2) = 4;

A(3,3) = 5;

Note that if we define a matrix component by component, Matlab will fill in any non-specified entries with zeros. As an example, the three program lines

A(1,1) = 7;

A(1,3) = 2;

A(2,2) = 9;

define a 2 × 3 matrix

A =

7 0 2

0 9 0

As before, the components that are not explicitly defined are set to zero.

10

Page 11: MAtlab Notes

2.1 Defining a matrix using the input statement

A student asked me wether or not a matrix can be read in using the input statement. Aswe’ve seen before, the input statement is very convenient to read a single variable fromthe Command Window. But how can we read all the entries of a matrix using the input

statement? I can think of a simple program making use of two for loops:

1: % Ask the user how many rows the matrix has

2: Rows = input(’How many rows in the matrix? ’);

3: % Ask the user how many columns the matrix has

4: Columns = input(’How many columns in the matrix? ’);

5: % Initialize the matrix to all zeros

6: Matrix = zeros(Rows,Columns);

7: % For loop over the rows

8: for i = 1:Rows

9: % For loop over the columns

10: for j = 1:Columns

11: % Use input statement to read the i,j component

12: Matrix(i,j) = input([’Enter component (’,num2str(i),’,’, ...

13: num2str(j),’) please. ’]);

14: end

15: end

You’re supposed to be familiar with all the programming ideas I’ve used here. One exep-tion is the three dots at the end of program line 12. This is how to indicate continuationin Matlab i.e. any line that ends with three dots continues on the next line. This is veryconvenient if you are programming a complicated expression that doesn’t fit in one lineof the editing window. Whenever you use the continuation dots, make sure that you doit at an appropriate place in the program. I usually try to use it either before or afterany mathematical operation. DO NOT use it in the middle of a variable name e.g. thefollowing statement is NOT VALID

3: Value1 = Very_long_variable_name1 + Very_long_variable_name2 - Very ...

_long_variable_name3;

2.2 Matrix manipulations

Other than refer to a single matrix entry at a time, many other matrix manipulations arepossible in Matlab. I’ll illustrate the possibilities by using the 4 × 5 matrix

A =

1 2 3 4 5

6 7 8 9 10

11 12 13 14 15

16 17 18 19 20

11

Page 12: MAtlab Notes

1. C = A(2,3): this refers to the matrix component in row 2, column 3 i.e. C = 8.

2. C = A([1 4],[1 5]): this refers to the entries in matrix A in rows 1 and 4, andcolumns 1 and 5 i.e.

C =

1 5

16 20

3. C = A([2 4],[2 3 5]): refers to the entries in rows 2 and 4, and columns 2, 3 and5 i.e.

C =

7 8 10

17 18 20

4. C = A([1 1 1 1],[3 4]): refers to the entries in row 1 (repeated 4 times) andcolumns 3 and 4 i.e.

C =

3 4

3 4

3 4

3 4

5. C = A([4 3 2 1],[5 4 3 2 1]): refers to the entries in rows 4, 3, 2 and 1 (in thatorder) and columns 5, 4, 3, 2 and 1 (in that order) i.e.

C =

20 19 18 17 16

15 14 13 12 11

10 9 8 7 6

5 4 3 2 1

6. C = A(1:2:end,1:2:end): This refers to all the rows starting at 1 with incrementsof 2 to the end,and all the columns starting at 1 with increments of 2 to the end.Since A has 4 rows and 5 columns, this means rows 1 and 3, ansd columns 1, 3 and5 i.e.

C =

1 3 5

11 13 15

7. Matlab contains many built-in matrix manipulation commands. Examples are

� B=flipud(A): The rows of the matrix A are sorted in reversed order (the matrixis flipped in the up-down direction).

� B=fliplr(A): The columns of the matrix A are sorted in reversed order (thematrix is flipped in the left-right direction).

� B=A’: The rows and columns of matrix A are switched i.e. B is the transpose ofA.

12

Page 13: MAtlab Notes

2.3 Example: Norm of a vector

To further illustrate the use of vectors, let’s develop a program that computes the norm(magnitude or length) of a vector a. Let’s assume the vector has three components.

1: % Define the vector a

2: a = [ 1 2 3 ];

3: % Start the value of the norm at zero

4: Norm = 0.0;

5: for i = 1:3

6: % Add the square of each component to the norm

7: Norm = Norm + a(i)^2;

8: end

9: % Take the square root of the sum of squares

10: Norm = sqrt(Norm);

11: % Display the result

12: disp([’Norm of vector = ’,num2str(Norm)]);

The above program will only work for vectors with three components. Let’s rather changethe program to work for vectors of any length. We need the length statement to accom-plish this goal. The syntax of the length statement is

N = length(a);

which will assign the number of components of the vector a to the variable N. A programthat can compute the norm of a vector of any length follows:

1: % Define the vector a, in this case with 8 components

2: a = [ 2 4 3 1 2 3 7 6 ];

3: % Start the value of the norm at zero

4: Norm = 0.0;

5: % Get the number of components of a

6: N = length(a);

7: for i = 1:N

8: % Add the square of each component to the norm

9: Norm = Norm + a(i)^2;

10: end

11: % Take the square root of the sum of squares

12: Norm = sqrt(Norm);

13: % Display the result

14: disp([’Norm of vector = ’,num2str(Norm)]);

Program lines 1–2 defines the vector a (which can be anything, this particular examplecontains 8 components). The norm of any vector can be computed by just changingprogram line 2.

13

Page 14: MAtlab Notes

2.4 Example: Matrix-vector multiplication

Let’s develop a program that can multiply a matrix with a vector. Recall from your linearalgebra course that matrix-vector multiplication is defined as

ci =

n∑

j=1

Aijaj for i = 1, 2, . . . , m (4)

where the m× n matrix A is multiplied with the n× 1 vector a to give the m× 1 vectorc. I’ll also illustrate Eq.(4) with a numerical example. Let’s multiply a 2 × 3 matrix A

with a 3 × 1 vector a to obtain a 2 × 1 vector c:

[

3 2 52 3 1

]

123

=

{

3 × 1 + 2 × 2 + 5 × 32 × 1 + 3 × 2 + 1 × 3

}

=

{

2211

}

(5)

Now let’s try to write a program that can multiply a m×n matrix A with a n×1 vector.First of all, you must recognize that we will use for loops for our computations. This isbecause before we start multiplying a matrix with a vector, the matrix and vector must beknown. So we will know how many rows and columns the matrix has. Since the numberof rows and columns are known, we will use for loops.

We also need to know how many for loops are required. We take guidance directlyfrom Eq.(4). We see that two distinct counters are required, namely i = 1, 2, . . . , mand j = 1, 2, . . . , n. The i counter refers to the current component of the c vector I’mcomputing, while the j counter is used to sum the appropriate products.

The order in which these two for loops must appear is not unique, as long as the correctlogic is used. However, I prefer to use the for loop over the i counter as the outer loop,within which I use the for loop over the j counter to perform the addition of terms. Thereason for this choice is that my program now reflects the same method I use when Imultiply a matrix with a vector using pen and paper. I first decide which component Iwant to compute (a specific value for i), then I compute this component by adding theappropriate products (using the second for loop with j = 1, 2, . . . , n). If I use the j

counter in the outer loop and the i counter in the inner loop, I’m computing the firstcontribution to all the components of c, then adding the second contribution to all thecomponents of c and so on. I find such a program confusing, because this does not reflectthe usual method of multiplying a matrix and vector.

One last statement we need before we can write the program: the size statement is usedto get the number of rows and columns of a matrix. The usage is

[rows,columns]=size(Matrix);

where the function size assigns the number of rows and columns of the matrix Matrix

to the variables rows and columns. Now we are ready to write a program that multipliesa matrix with a vector:

1: % Create a random matrix A

14

Page 15: MAtlab Notes

2: A = rand(10,8);

3: % Create a random vector a

4: a = rand(8,1);

5: % Get the size of the matrix A

6: [Rows,Columns] = size(A);

7: % For loop over the number of rows

8: for i=1:Rows

9: % Initialize the i-th entry of the c-vector with zero

10: c(i,1) = 0.0;

11: % For loop over the number of columns

12: for j=1:Columns

13: % Add the appropriate term to the c-vector

14: c(i,1) = c(i,1) + A(i,j)*a(j);

15: end

16: end

17: % Displays output

18: disp(’The product of matrix A with vector a is’)

19: disp(c)

Program lines 1–4 creates a random matrix A and a random vector a, just to test ourprogram. Program lines 5–16 contain the actual matrix-vector multiplication and programlines 17–19 create the output to the Command Window.

2.5 Example: Plots of functions of a single variable

We can use vectors to generate plots of any function of one variable. First of all, you’ll needto generate a vector of all the x-values where you want the function to be evaluated. Thenyou compute the associated y-value at each of these x-values. A plot is then generatedby simply typing plot(x,y). Here’s an example to plot the function

y = sin(x) for x ∈ [−π; π] (6)

1: % I’ve decided I want 100 intervals between -pi and pi to

2: % plot the graph so I use a for loop that repeats 101 times

3: for i = 0:100;

4: % I compute the x component as x(1) = -pi for i=0

5: % all the way to x(101) = pi for i=100

6: x(i+1) = -pi + 0.01*i*2*pi;

7: % The y component is computed for every x component

8: y(i+1) = sin(x(i+1));

9: end

10: % Plot the vectors x vs. y

11: plot(x,y)

The program produces the image in Figure 3. Experiment with various other functionsand see if you can generate the associated graphs.

15

Page 16: MAtlab Notes

Figure 3: Plot of y = sin(x) generated by Matlab.

3 Revisiting previous programs

I’ll give a few more examples of the use of vectors. I’ll first use vectors to compute a Taylorseries approximation. Then I’ll illustrate how vectors can be used to perform numericalintegration.

3.1 Taylor series using vectors

I discussed Taylor series analyses in part 1 of the lecture notes. I used both for loops andwhile loop to perform the required computations. Revisit the notes before you continue.

You should have noticed that when we computed a Taylor series approximation at thestart of the year, we only used scalar variables. We kept on adding new terms in the seriesuntil the series converged.

Let’s compute a Taylor series approximation again, but now making use of two vectors.In the first vector, called Terms, I will save the Taylor series terms i.e. the first term in theseries is saved in the first component, the second term in the series is saved in the secondcomponent, and so on. In the second vector, called Taylor approx, I will save the currentvalue of the Taylor series approximation. The first component will contain the first term,the second component will contain the sum of the first two terms, and so on. We proceedlike this and save the n term Taylor series approximation in the n-th component of thevector Taylor approx. When the complete vectors are displayed, we should clearly see

16

Page 17: MAtlab Notes

how the components of the vector Terms become smaller, while the components of thevector Taylor approx should converge to the analytical result.

As an example, lets compute the Taylor series approximation to the exponential function,which is given by

ex = 1 + x + 1

2x2 + 1

6x3 + · · · =

∞∑

k=0

xk

k!(7)

Here’s a program that uses a while loop to compute the Taylor series approximation toex within a specified accuracy.

1: % Get value for x at which to compute exp(x)

2: x = input(’What value for x do you want to compute exp(x) at? ’);

3: % Get required accuracy

4: acc = input(’How accurate must exp(x) be computed? ’);

5: % 1-term Taylor series approximation = x^0 = 1

6: Terms(1) = 1;

7: Taylor_approx(1) = 1;

8: % Set term counter to 1

9: k = 1;

10: % Set initial Error>acc to make sure while loop is entered

11: Error = 2*acc;

12: while Error>acc

13: % Compute next term in series

14: Terms(k+1) = x^k/prod(1:k);

15: % Next component in vector equal to previous component plus new term

16: Taylor_approx(k+1) = Taylor_approx(k) + Terms(k+1);

17: % Error = difference between consecutive components

18: Error = abs(Taylor_approx(k+1)-Taylor_approx(k));

19: % Increment the counter k

20: k = k + 1;

21: end

22: % Displays the vectors Terms Series in Command Window

23: Terms

24: Taylor_approx

Here’s the output of the program listed above, using format long. You can clearly seehow the Taylor series converges to e = 2.718281828459 . . . as the number of terms in theseries increases.

What value for x do you want to compute exp(x) at? 1

How accurate must exp(x) be computed? 1e-7

Terms =

Columns 1 through 4

1.00000000000000 1.00000000000000 0.50000000000000 0.16666666666667

Columns 5 through 8

0.04166666666667 0.00833333333333 0.00138888888889 0.00019841269841

17

Page 18: MAtlab Notes

Columns 9 through 12

0.00002480158730 0.00000275573192 0.00000027557319 0.00000002505211

Taylor_approx =

Columns 1 through 4

1.00000000000000 2.00000000000000 2.50000000000000 2.66666666666667

Columns 5 through 8

2.70833333333333 2.71666666666667 2.71805555555556 2.71825396825397

Columns 9 through 12

2.71827876984127 2.71828152557319 2.71828180114638 2.71828182619849

Modify the above program to compute the Taylor series approximation to π. Be carefulnot to specify a very small accuracy. You’ll see that the π Taylor series converges veryslowly, so you need a large number of terms for an accurate approximation.

3.2 Numerical integration using vectors

Let’s revisit the numerical integration program developed in Section 1. In that section,the variable Int old is used to have the previous value of the numerical integral availableafter the new value is computed. Now I propose that we not only save the most recentvalue of the numerical integral, but that we save the numerical integral for every caseanalyzed. We can save all these values in a single vector.

I’m going to create two vectors. In the first vector, called N, I’ll save the number ofintervals. As the number of intervals change, I’ll save the new number of intervals in thenext component of the vector N. The second vector, called Int, will contain the numericalintegrals associated with the number of intervals in the vector N.

Here’s the modified numerical integration program:

1: % Get user inputs

2: F_string = input(’Please enter function to be integrated. ’,’s’);

3: Fcn = inline(F_string);

4: LB = input(’Enter the lower bound of integration. ’);

5: UB = input(’Enter the upper bound of integration. ’);

6: N_ini = input(’Initial number of intervals between LB and UB? ’);

7: acc = input(’Enter the required accuracy. ’);

8: disp(’1: Left-point 2: Right-point 3: Mid-point’);

9: disp(’4: Trapezium 5: Quit program’);

10: Method = input(’Please enter your option. ’);

11: % My program repeats until the user inputs option 5

12: while Method~=5

13: % Define initial Error greater as acc, to enter while loop

14: Error = 2*acc;

15: % Number of intervals is saved in a vector N. I start with component 2

16: % to correspond to the integrals in the vector Int

17: N(2) = N_ini;

18: % Set counter k to one

18

Page 19: MAtlab Notes

19: k = 1;

20: % Set component 1 of the Int vector to zero.

21: Int(1) = 0;

22: % Start while loop that checks if consecutive values converged

23: while Error>acc

24: % Increment the counter k with one

25: k = k + 1;

26: % Initialize the current component of the Int vector to zero

27: Int(k) = 0;

28: % Compute the interval size Delta_x

29: Delta_x = (UB-LB)/N(k);

30: % Use the switch statement to branch to one of the 4 methods

31: switch Method

32: % Case 1: left-point method

33: case 1

34: % For loop to compute area of each rectangle and add it to Int

35: for i=1:N(k)

36: x = LB + (i-1)*Delta_x;

37: Int(k) = Int(k) + Delta_x*Fcn(x);

38: end

39: % Case 2: right-point method

40: case 2

41: for i=1:N(k)

42: x = LB + i*Delta_x;

43: Int(k) = Int(k) + Delta_x*Fcn(x);

44: end

45: % Case 3: mid-point method

46: case 3

47: for i=1:N(k)

48: x = LB + (i-1)*Delta_x + 0.5*Delta_x;

49: Int(k) = Int(k) + Delta_x*Fcn(x);

50: end

51: % Case 4: trapezium method

52: case 4

53: for i=1:N(k)

54: x_L = LB + (i-1)*Delta_x;

55: x_R = x_L + Delta_x;

56: Int(k) = Int(k) + 0.5*Delta_x*(Fcn(x_L) + Fcn(x_R));

57: end

58: end; % End of switch

59: % Compute Error i.e. difference between consecutive integrals

60: Error = abs(Int(k) - Int(k-1));

61: % Component k+1 of N vector = 2 times component k value

62: N(k+1) = 2*N(k);

63: end; % End of inner while

64: % Display answer

65: disp([’Integrating ’,F_string,’ between ’,num2str(LB),’ and ’, ...

19

Page 20: MAtlab Notes

66: num2str(UB)])

67: disp(’Intervals Integral’);

68: % Display first k components of vectors N and Int

69: disp([num2str(N(1:k)’,’%8d\t\t’),num2str(Int(1:k)’,’%10.6f’)])

70: % Display options again

71: disp(’1: Left-point 2: Right-point 3: Mid-point’);

72: disp(’4: Trapezium 5: Quit program’);

73: Method = input(’Please enter your option. ’);

74: end; %End of outer while loop

75: % Outside while loop, user entered option 5 = Quit

76: % Displays a friendly message.

77: disp(’Thanks for using the program. Have a good day.’)

Very few changes were made compared to the previous version. I define a counter, k inthis program, which keep track of the number of components in the vectors N and Int.k is initialized in program line 19 and is incremented with 1 inside the while loop inprogram line 25.

Since the number of intervals N is now a vector, I need to specify which component of N

I need e.g. program lines 17, 29 and 35. Similarly the numerical integrals are now storedin the vector Int, so I need to refer to a specific component of Int, e.g. program lines 27,37 and 43.

I’ve also decided to change the output. Now I display the first k components of the vectorsN and Int. Program line 69 displays these vectors. I make use of the num2str commandto change the numerical values to strings. The number of intervals N is converted to astring by using

num2str(N(1:k)’,’%8d\t\t’)

which converts the first k components of N to a string. The d in the statement aboverefers to an integer conversion and the \t indicates a tab. So every component of N isconverted to an string and two tabs are added. The numerical integrals in the vector Intare converted to strings with the statement

num2str(Int(1:k)’,’%10.6f’)])

where the f in the statement above refers to a real number conversion, making use of amaximum of 10 digits of which 6 is used for the digits after the decimal point. In thelecture notes part 1 I also comment on the use of the formatted num2str command.

Here follows the output from the program. I only executed option 2 (right-point) andoption 4 (trapezium) before I quit the program (option 5). Note the tabular output, wherewe now clearly see the progress towards the analytical result as the number of intervalsis increased.

Please enter function to be integrated. sin(x)

Enter the lower bound of integration. 0

20

Page 21: MAtlab Notes

Enter the upper bound of integration. pi/2

Initial number of intervals between LB and UB? 10

Enter the required accuracy. 0.0001

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 2

Integrating sin(x) between 0 and 1.5708

Intervals Integral

0 0.000000

10 1.076483

20 1.038756

40 1.019506

80 1.009785

160 1.004901

320 1.002452

640 1.001227

1280 1.000613

2560 1.000307

5120 1.000153

10240 1.000077

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 4

Integrating sin(x) between 0 and 1.5708

Intervals Integral

0 0.000000

10 0.997943

20 0.999486

40 0.999871

80 0.999968

1: Left-point 2: Right-point 3: Mid-point

4: Trapezium 5: Quit program

Please enter your option. 5

Thanks for using the program. Have a good day.

4 Sorting algorithms

Let’s further develop our programming skills by trying to write a program that can sortthe components of a vector in ascending order (small to large). In order to develop asorting algorithm, you have to think of a simple operation that a computer can performthat will enable a vector te be sorted. If required, this operation can be repeated a largenumber of times (which will be the case).

The operation I’m referring to is to compare two numbers. If the number pair is in thecorrect order (1st value smaller than the 2nd), then move to a different number pair. Ifthe number pair is not in the correct order, swap the 2 numbers. This simple operation

21

Page 22: MAtlab Notes

is sufficient to order a vector.

I can think of a few sorting algorithms. I’ll start off with a method that is easy toexplain and implement, but not very efficient. Let’s compare the first component of thevector with all the other components, one by one (starting at component 2, ending at thelast component), i.e. compare component 1 with 2, then component 1 with 3 and so on.Whenever the 1st component is larger than the component it is compared to, we swap thecomponents. If not, we simply move to the next component of the vector. When we reachthe end of the vector, the smallest number will be in component 1. We start at the topagain but now we compare the 2nd component of the vector with all the components from3 to the end (It’s no use to start at 1 again, it already contains the smallest number). Werepeat this process till we compare the last two numbers. This process is implementedbelow. We need two nested for loops: the first loop provides the index of the 1st numberin the number pair, while the second loop provides the index of the 2nd number in thenumber pair.

1: % Create the vector a

2: a = [5 4 3 2 1];

3: % Get how many components the vector has

4: n = length(a);

5: % First for loop: position of first number in pair

6: for i=1:n-1

7: % Second for loop: position of second number in pair

8: for j=i+1:n

9: % Check if number pair is in ascending order

10: if a(i)>a(j)

11: % Swap numbers if they are in the wrong order

12: a_copy = a(i);

13: a(i) = a(j);

14: a(j) = a_copy;

15: end

16: end

17: % Display the vector each time the outer for loop is complete

18: a

19: end

In program line 2 I define the vector a. I’ve decided to use a vector that is sorted fromlarge to small. Such a vector will really test if my program can sort in ascending order.Program line 4 gets the number of components of the vector. The first for loop is codedin program line 6: do you see that the index of the first number in my number pair startsat 1 and ends at n-1, one from the end. The second for loop is coded in program line8. The 1st number in the number pair is given by index i. I now have to compare thisnumber with the remaining numbers below position i in the vector. That is why thesecond index j starts at i+1 (the very next component in the vector) and ends at n, thelast entry of the vector.

In program line 10 I check if the number pair is in the correct order. If the i-th component(1st number of the pair) is greater than the j-th component, I swap the pair of numbers.

22

Page 23: MAtlab Notes

This is done by first making a copy of the i-th component (program line 12), then assigningthe old j-th component to the new i-th component (program line 13). Finally the copyof the old i-th component is assigned to the new j-th component (program line 14).Program line 18 simply displays the vector every time the outer for loop is complete.This will provide output that will illustrate how the program proceeds to sort the vector.

Here follows the output of the above program:

a =

1 5 4 3 2

a =

1 2 5 4 3

a =

1 2 3 5 4

a =

1 2 3 4 5

As you can see, the program correctly sorts the random vector into acsending order. Afterthe for loop is executed once, the smallest number occupies the first vector position. Afterthe for loop is executed again, the first 2 numbers are in their correct positions. Thisprocess repeats until all the numbers are correct after the for loop has been executed 4times.

4.1 Bubble sort algorithm

Let’s also look at an alternative sorting algorithm. It will help to illustrate that manysolutions exist to the same problem. The bubble sorting algorithm also checks if a numberpair is in the correct order. The only difference with the algorithm above is that the bubblesort algorithm always compares a component with the very next component in the vector,i.e. compare component 1 with 2, then component 2 with 3, then component 3 with 4and so on. After the last number pair has been compared, the largest number will occupythe last position in the vector. Now we have to start at the top again and comparecomponent 1 with 2, 2 with 3 and so on. This time we stop 1 pair from the bottom,because we already know the largest number is in the correct position. This process isrepeated till only components 1 and 2 are compared. Here’s my implementation of thebubble sort algorithm:

1: % Create the vector a

2: a = [5 4 3 2 1];

3: % Get how many components the vector has

4: n = length(a);

5: % First for loop: how many times the vector

6: % has to be scanned from top to bottom

7: for i=1:n-1;

8: % The index to the first number of the pair

9: for j=1:n-i

23

Page 24: MAtlab Notes

10: % Compare the j-th and j+1-th vector components

11: if(a(j)>a(j+1))

12: % Swap component j and j+1 if in wrong order

13: a_copy = a(j);

14: a(j) = a(j+1);

15: a(j+1) = a_copy;

16: end

17: end

18: % Display the vector a every time the for loop is executed

19: a

20: end

The output of the bubble sort algorithm, using the same 5 component vector as before,follows:

a =

4 3 2 1 5

a =

3 2 1 4 5

a =

2 1 3 4 5

a =

1 2 3 4 5

As you can see the largest entry occupies the last vector position after the outer for loopis executed once. The largest two entries are in their correct positions after the outer forloop is executed again. This process repeats until all entries are correct after outer thefor loop is executed four times.

I’ll now run the bubble sort program again, but this time I replace program line 2 with

2: a = rand(1,8);

which will create a random 8 component vector a. I include the output of the bubble sortalgorithm for one of the cases I ran after the above change:

a =

0.0153 0.4451 0.7468 0.4660 0.4186 0.8462 0.5252 0.9318

a =

0.0153 0.4451 0.4660 0.4186 0.7468 0.5252 0.8462 0.9318

a =

0.0153 0.4451 0.4186 0.4660 0.5252 0.7468 0.8462 0.9318

a =

0.0153 0.4186 0.4451 0.4660 0.5252 0.7468 0.8462 0.9318

24

Page 25: MAtlab Notes

a =

0.0153 0.4186 0.4451 0.4660 0.5252 0.7468 0.8462 0.9318

a =

0.0153 0.4186 0.4451 0.4660 0.5252 0.7468 0.8462 0.9318

a =

0.0153 0.4186 0.4451 0.4660 0.5252 0.7468 0.8462 0.9318

The algorithm clearly works. For the 8 component vector above, the outer for loop isexecuted 7 times. However, the output for this particular example shows that the vectoris in the correct order after only 4 outer for loop executions. So how can we improve thebubble sort algorithm to stop once the vector is in the correct order?

The answer is quite simple. We have to keep track of number pair swapping. If we findthat we start at the top of the vector and scan all the way to the bottom and never finda number pair in the wrong order, we know the vector is sorted and the algorithm canstop. This type of logic requires a while loop.

1: % Create the vector a

2: a = rand(1,8);

3: % Get how many components the vector has

4: n = length(a);

5: % Start index at zero

6: i = 0;

7: % Set flag to 0 i.e. assume vector is not ordered

8: flag = 0;

9: % Start while loop: repeat loop while index i<n-1

10: % or the flag not equal to 0

11: while (flag == 0) & (i < n-1);

12: % Set flag to 1 i.e. assume vector is ordered

13: flag = 1;

14: % Increment index with 1

15: i = i + 1;

16: % The index to the first number of the pair

17: for j=1:n-i

18: % Compare the j-th and j+1-th vector components

19: if(a(j)>a(j+1))

20: % Swap component j and j+1 if in wrong order

21: a_copy = a(j);

22: a(j) = a(j+1);

23: a(j+1) = a_copy;

24: % Set flag to 0 to indicate vector is not ordered yet

25: flag = 0;

26: end

27: end

25

Page 26: MAtlab Notes

28: % Display the vector a every time the for loop is executed

29: a

30: end

31: % Display the number of times the while loop is executed

32: disp([’While loop repeated ’,num2str(i),’ times.’])

I’ll only explain the program lines that are new. The index i is set equal to zero inprogram line 6 and is incremented by one inside the while loop in program line 15. Thisreplaces the for loop that was repeated a predetermined number of times (n-1). I alsouse a new variable called flag to indicate whether the vector is sorted or not. I set flagequal to zero in program line 8, before the while loop starts. The while loop conditionin program line 11 states that the sorting loop is repeated as long as the variable flag

equals zero and the index i is less than n-1 (We know that the vector will be sorted oncei = n-1). As soon as the loop starts, I set the variable flag equal to 1 in program line13 i.e. I assume that the vector is already in the correct order. Should I find a pair ofnumbers that is not in the correct order, I change the value of the variable flag to zero(program line 25). The rest of the program is unchanged. At the end of the while loop Idisplay the value of the index i, the number of times the while loop was repated.

Here’s an example of the modified bubble sort algorithm. I chose a case in which theoriginal vector a was almost sorted already, so the while loop is repeated only 3 times fora vector of length 8. As you can see the program now terminates as soon as the vector isscanned from top to bottom without a number pair swapping. In fact, the while loop isrepeated only once for any vector that is already sorted in ascending order.

a =

0.1850 0.1852 0.6375 0.4383 0.6526 0.6605 0.8145 0.8526

a =

0.1850 0.1852 0.4383 0.6375 0.6526 0.6605 0.8145 0.8526

a =

0.1850 0.1852 0.4383 0.6375 0.6526 0.6605 0.8145 0.8526

While loop repeated 3 times.

5 Gauss elimination

The solution of a system of linear equations remains one of the numerical computationsperformed most often in all engineering disciplines. In your linear algebra course, you havealready mastered Gauss elimination. Gauss elimination remains one of the most efficientdirect methods to solve large systems of linear equations. Let’s revisit the method.

During the forward reduction step of Gauss elimination, the original system matrix is re-duced to a system that contains zeros below the diagonal. This is achieved by subtracting

26

Page 27: MAtlab Notes

a fraction of one row from the next. I’ll illustrate with a 4 × 4 system:

2 3 4 11 1 2 12 4 5 21 2 3 4

x1

x2

x3

x4

=

1051310

(8)

Replace Row 2 of the system with Row 2 -(

1

2

)

× Row 1 i.e.

2 3 4 10 −0.5 0 0.52 4 5 21 2 3 4

x1

x2

x3

x4

=

1001310

(9)

Then replace Row 3 with Row 3 -(

2

2

)

× Row 1 i.e.

2 3 4 10 −0.5 0 0.50 1 1 11 2 3 4

x1

x2

x3

x4

=

100310

(10)

Finally, we replace Row 4 with Row 4 -(

1

2

)

× Row 1 i.e.

2 3 4 10 −0.5 0 0.50 1 1 10 0.5 1 3.5

x1

x2

x3

x4

=

10035

(11)

We have succeeded in reducing the first column below the diagonal to zeros. Now weproceed to reduce the second column below the diagonal to zeros. This is achieved byreplacing Row 3 with Row 3 -

(

1

−0.5

)

× Row 2 i.e.

2 3 4 10 −0.5 0 0.50 0 1 20 0.5 1 3.5

x1

x2

x3

x4

=

10035

(12)

The last entry in column 2 is reduced to zero by replacinng Row 4 with Row 4 -(

0.5−0.5

)

×Row 2 i.e.

2 3 4 10 −0.5 0 0.50 0 1 20 0 1 4

x1

x2

x3

x4

=

10035

(13)

We complete the forward reduction step by reducing the column 3 entries below thediagonal (there is only 1) to zero i.e. Row 4 = Row 4 -

(

1

1

)

× Row 3 i.e.

2 3 4 10 −0.5 0 0.50 0 1 20 0 0 2

x1

x2

x3

x4

=

10032

(14)

27

Page 28: MAtlab Notes

We are now done with the forward reduction step. All the entries of the matrix below thediagonal is zero. Now we proceed to solve the unknowns x4, x3, x2 and x1, in that order.This part of the Gauss elimination process is called backsubstitution.

The 4th equation in the above system reads

2x4 = 2 (15)

which is solved to provide x4 = 1. The 3rd equation reads

x3 + 2x4 = 3 (16)

which is used to solve x3 asx3 = 3 − 2x4 = 1 (17)

We continue with this process to solve x2 from the 2nd equation:

x2 =0 − 0x3 − 0.5x4

−0.5= 1 (18)

Finally, x1 is solved from the 1st equation:

x1 =10 − 3x2 − 4x3 − x4

2= 1 (19)

5.1 Gauss elimination algorithm

Now that we have reviewed the Gauss elimination process, let’s attempt to program it.You will find this program quite challenging, and will have to review the steps numeroustimes before you finally understand them all.

To perform Gauss elimination, we require a linear system to solve. I’ll use the same linearsystem as above during the program development.

First of all, we have to decide what type of computations are required during Gausselimination. You should be able to recognize that a predetermined number of operationsare performed, based on the size of the linear system. So we’ll use for loops, since thesize of the matrix has to be known.

The next challenge is to decide how many for loops are required. This is not a trivialdecision. We must use the numerical example of the previous section to help us out. Tryto identify processes/computations that repeat and attempt to write these computationsas a repeating for loop.

5.1.1 Forward reduction step

Gauss elimination required three nested for loops during the forward reduction step.Here is what each loop will do:

1. One index (loop) tracks the diagonal term we are currently using to make all otherterms below it zero. This row is called the pivot row and the entry on the diagonalis called the pivot element.

28

Page 29: MAtlab Notes

2. A second index (loop) will track which row we are currently working on. All therows below the pivot row will be changed by adding or subtracting an appropriatefraction of the pivot row.

3. The last index (loop) is used to perform the required computation for all the columnsof the rows below the pivot row.

Let’s implement the forward reduction step of Gauss elimination. This will illustrate thenecessity of the three required loops more clearly.

1: % Gauss elimination program that solves x

2: % in the linear system Ax = a.

3: % Create left hand side matrix A

4: A = [ 2 3 4 1

5: 1 1 2 1

6: 2 4 5 2

7: 1 2 3 4 ];

8: % Create right hand side vector a

9: a = [10

10: 5

11: 13

12: 10 ];

13: % Compute size of matrix

14: n = length(A);

15: % Start of 1st loop: pivot row counter

16: for i=1:n-1

17: % Start of second loop: which row to reduce

18: for j=i+1:n

19: % Compute the multiplier i.e. which fraction of the

20: % pivot row i has to be subtracted from row j

21: mult = A(j,i)/A(i,i);

22: % Start of 3rd loop: re-assign all columns of row j

23: % i.e. Row_j = Row_j - mult*Row_i for columns 1 to n

24: for k=1:n

25: A(j,k) = A(j,k) - mult*A(i,k);

26: end

27: % Also modify the RHS vector

28: a(j) = a(j) - mult*a(i);

29: end

30: end

31: A

32: a

In program lines 1–12, the matrix A and vector a are defined. Program line 14 gets thenumber of rows of the matrix A and this is assigned to the variable n. The actual forwardreduction step of Gauss elimination starts at program line 16.

29

Page 30: MAtlab Notes

Since we use the index i to indicate the pivot element, what must the bounds be on thisindex? You should be able to recognize that we will start this index at 1 (recall that wemake all the entries of the matrix below the (1,1) entry equal to zero?). After all theentries below the (1,1) entry are zero, we make all the entries below the (2,2) entry zero(so the pivot element index = 2). The pivot element index keeps on incrementing by onetill it reaches the value n-1. Does this make sense to you? We have to stop at this value,because a pivot element of (n,n) makes no sense: there are no entries in the matrix belowthe (n,n) entry to make zero. I hope you now understand program line 16 which startsthe pivot element index at 1 and increments with one till the final pivot element index ofn-1.

Program line 18 defines the row index j. It’s initial value is set to i+1, and it incrementswith one till a final row index of n. Does this make sense? If the pivot element index is i,we must reduce all entries below the (i,i) entry to zero. So we start with row i+1 andcontinue to row n.

Program line 21 defines the multiplier i.e. which fraction of the i-th row must be subtractedfrom the j-th row in order to set the A(j,i) term to zero. The multiplier is simply theA(j,i) term divided by the pivot element A(i,i).

Program lines 24–26 simply subtracts the appropriate fraction of row i from row j andassigns this to row j. A for loop is required to repeat this for all columns (1 to n).Program line 28 performs the same computation on the right hand side vector a.

Note that the order of the three nested for loops is fixed. The outer for loop sets thepivot row counter (i). Once i is known, the next for loop sets the lower bound of therow counter j in terms of i. Once i and j are known, the forward reduction step can beperformed on row j for all columns k (the third and final for loop).

Save the above program as Gauss.m. Type Gauss in the Command Window and pressenter. The following will appear:

A =

2.00000 3.00000 4.00000 1.00000

0.00000 -0.50000 0.00000 0.50000

0.00000 0.00000 1.00000 2.00000

0.00000 0.00000 0.00000 2.00000

a =

10

0

3

2

As you can see, the forward reduction step is implemented correctly. The matrix A andvector a agree with Eq.(14).

30

Page 31: MAtlab Notes

5.1.2 Backsubstitution step

After we reduced the system to an upper triangular system, we are ready to start thebacksubstitution process. As before, we first have to decide what type of computationsare required. for loops are again required, because the number of operations we have toperform is directly related to the size of the matrix (which is known).

Just to illustrate the required steps more clearly, consider a general 4 × 4 system that isalready upper-triangular:

A11 A12 A13 A14

0 A22 A23 A24

0 0 A33 A34

0 0 0 A44

x1

x2

x3

x4

=

a1

a2

a3

a4

(20)

The four unknowns x4, x3, x2 and x1 are solved in this order from

x4 =a4

A44

(21)

x3 =a3 − A34x4

A33

(22)

x2 =a2 − A23x3 − A24x4

A22

(23)

x1 =a1 − A12x2 − A13x3 − A12x2

A11

(24)

You should be able to recognize the pattern in Eqs.(21)– (24):

xn =an

Ann

(25)

xi =

ai −n

j=i+1

Aijxj

Aii

for i = n − 1, n − 2, . . . , 1. (26)

From Eq.(26) you should be able to recognize the need for two for loops: i = n − 1, n −2, . . . , 1 and j = i + 1, i + 2, . . . , n. The i counter points to the current component of thevector x we are solving, while the j counter keeps track of the sum of products we mustsubtract from ai. The order in which the for loops appear is fixed: the outer for loopmust contain the variable i, and the inner for loop the variable j. This is because the j

for loop lower bound is defined in terms of the current value of the i counter.

I’ll go ahead an program the backsubstitution step of the Gauss elimination algorithm.

31: % Define a n x 1 vector of zeros

32: x = zeros(n,1);

31: % Solve the last unknown

32: x(n,1) = a(n)/A(n,n);

33: % Start for loop: solve from row n-1, using

34: % increments of -1 all the way to row 1

31

Page 32: MAtlab Notes

35: for i=n-1:-1:1

36: % Start computation with the right hand side vector value

37: x(i,1) = a(i);

38: % Now subtract from that the product of A and the

39: % x terms that are already solved: use a for loop

40: for j=i+1:n

41: x(i,1) = x(i,1) - A(i,j)*x(j);

42: end

43: % Now divide by the diagonal A(i,i) to get the x term

44: x(i,1) = x(i,1)/A(i,i);

45: end

46: x

Append the backsubstitution part to the Gauss.m file. Type Gauss in the CommandWindow and press enter. The following should appear:

x =

1

1

1

1

which is the correct solution to this 4 × 4 linear system of equations.

5.2 Solving linear systems using Matlab

We’ve just developed our own implementation of Gauss elimination. It can solve anyn × n system of linear equations. I believe that Gauss elimination is quite a challengingalgorithm to understand, so if you manage you are well on your way to becoming aproficient programmer.

Since Matlab was originally developed to perform linear algebra, you probably expectthat Matlab has built-in capability to solve large linear systems. This is the case. In fact,more than one method exists to solve linear systems. If the linear system

Ax = a (27)

has a unique solution, the inverse of A exists and we can premultiply Eq.(27) with A−1

to obtainx = A

−1a (28)

This operation is performed in Matlab using the inv statement i.e.

x = inv(A)*a;

Another Matlab method to solve linear systems is the backslash operation i.e.

32

Page 33: MAtlab Notes

x = A\a;

solves x using a factorization and backsubstitution algorithm similar to the Gauss elimi-nation algorithm we implemented.

So let’s compare the efficiency of our algorithm with that of Matlab’s built-in functions.This can be done by using the tic and toc statements. The tic statement simply starts astopwatch, and the toc statement stops the stopwatch and displays the time expired sincethe tic statement was executed. So here follows a complete program that solves a 500× 500 system using the three methods i) our Gauss elimination algorithm, ii) Matlab’sinv(A)*a method and iii) Matlab’s A\a method.

1: % Create matrix A and vector a

2: A = rand(500,500);

3: a = rand(500,1);

4: % make copies of A and a to use later

5: A_copy = A;

6: a_copy = a;

7: % Start the stopwatch

8: tic

9: % Forward reduction step as before

10: n = length(a);

11: for i=1:n-1

12: for j=i+1:n

13: mult = A(j,i)/A(i,i);

14: for k=1:n

15: A(j,k) = A(j,k) - mult*A(i,k);

16: end

17: a(j) = a(j) - mult*a(i);

18: end

19: end

20: % Backsubstitution step as before

21: x = zeros(n,1);

22: x(n) = a(n)/A(n,n);

23: for i=n-1:-1:1

24: x(i)=a(i);

25: for j=i+1:n

26: x(i) = x(i) - A(i,j)*x(j);

27: end

28: x(i) = x(i)/A(i,i);

29: end

30: % Stops stopwatch and displays time in Command Window

30: toc

31: % Starts stopwatch again

32: tic

33: % Solve system using inverse of A_copy*a_copy

34: x_Mat1 = inv(A_copy)*a_copy;

33

Page 34: MAtlab Notes

35: % Stops stopwatch and displays time in Command Window

36: toc

37: % Starts stopwatch third and final time

38: tic

39: % Solve system using backslash operation

40: x_Mat2 = A_copy\a_copy;

41: % Stops stopwatch and displays time in Command Window

42: toc

The output of the above program is

elapsed_time =

8.5223

elapsed_time =

0.2420

elapsed_time =

0.1125

for computations on a 2.4 GHz Intel Celeron processor running Matlab Student VersionRelease 13 under the Mandrake Linux operating system. As you can see the inversemethod is about 35 times faster than our method and the backslash method is about 75times faster than our method. The output of the same program on the same computer,running Matlab 6.1 under the Windows XP operating system is:

elapsed_time =

363.1320

elapsed_time =

0.2700

elapsed_time =

0.1100

Our Gauss elimination program is more than 40 times slower in Matlab 6.1 comparedto Matlab 6.5 (Student Edition)! This is due to a recent major improvement in theperformance of for loops in Matlab. But you’ll notice that Matlab’s built-in functionsperform similarly, independent of the Matlab version. We’ll revisit the performance offor loops is a later section.

For now, we’ll focus on improving the performance of our algorithm, regardless of whichMatlab version we’re using. We can make a dramatic improvement in our algorithms’efficiency by making a subtle change during the forward reduction step. Refer to programline 14 above: you’ll see that we subtract a fraction of line i from line j, for columns 1to n. But is this really necessary? As we perform the forward reduction step of Gausselimination, we know that the entries to the left of the diagonal will become zeros. And

34

Page 35: MAtlab Notes

we never use these zeros during the backsubstitution step of the algorithm. So why dowe bother computing them at all? Computers take the same amount of time to multiplyzeros with some other number as compared to non-zero number multiplication, so we arewasting valuable time. All that we have to do to improve our algorithm, is to changeprogram line 14 to

14: for k=1+i:n

This new program line will only subtract those columns that will end up as non-zeros, sowe aren’t computing the zeros anymore. You can check that this change doesn’t affectthe solution, and the times required to solve a 500 × 500 system now becomes

elapsed_time =

5.0185

using Matlab 6.5 and

elapsed_time =

235.9200

using Matlab 6.1. This simple change has improved the speed of our algorithm by ap-proximately 40%, regardless of the Matlab version! In the weeks to come we’ll make morechanges to improve the performance of our algorithm.

6 Functions

A function is a list of program statements that perform a specific task. Functions arecalled from other programs, or from other functions. We have encountered a numberof Matlab functions so far. The first is the rand functions, which is a function thatcan generate random matrices. Do you recall the syntax of the rand statement? Thestatement

Matrix = rand(Rows,Columns);

generates a variable Matrix that is a Rows × Columns random matrix. As you can see,the rand function requires two scalar inputs (in the example above Rows and Columns)and it generates a single matrix as output (Matrix in the example above).

We have also encountered the inv function, which generates the inverse of a matrix. Theinv functions requires a single square matrix as input and it generates the inverse of thismatrix as output. The statement

A_inv = inv(A);

35

Page 36: MAtlab Notes

will generate the matrix A inv which is the inverse of the matrix A.

A special type of functions we have used is the inline function, which a function thatgenerates other functions. The inline function requires a single string variable as inputand it generates a function. This is unusual, since most functions take variables (scalar,matrices or strings) as input and generate other variables (again scalars, matrices orstrings) as output.

The trigonometric functions sin, cos, tan and the exponential function exp are otherexamples of functions that we have used so far. All of these functions require a singlevariable as input and it produces a single variable as output (You’ll see in the next sectionthat the variable may be a vector or matrix).

The final example of a function we have encountered so far is the size function. Thisfunction requires a single input (the matrix A in the example to follow), while it producestwo outputs (the scalars Rows and Columns in the example to follow):

[Rows,Columns]=size(A);

6.1 Creating new functions

Programming will be a very difficult task if we could only make use of existing funtions.Not only will our programs become very long and difficult to keep track of, but it willalso be impossible for a group of programmers to develop different components of a newprogram simultaneously. Fortunately, all programming languages allow for creating newfunctions.

In Matlab, new functions are created by storing the list of required programming com-mands in a seperate file and then indicate that this is a new function by typing

function [Output1,Output2,...] = FunctionName(Input1,Input2,...)

in the very first line of the program. The word function is compulsory, it tells Matlabthat what follows is a function. Then the list of variables (outputs) that the function willgenerate follows, enclosed in square brackets. Different outputs are seperated by commas.These output variables can have any name, as long as you obey the variable name rules.After the equal sign, the name of your function follows. The function name must alsoobey the usual variable and program name rules. The function statement is completed bythe list of input variables, enclosed in parentheses. The function file must be saved usingthe same name as the as function itself, FunctionName.m for this example.

The variable names that you use within the function is local variables, i.e. these variablevalues are only known inside the function. The values of the variables used in yourfunction will not be available to the calling program (or in the Command Window). Ifyou want a variable value to be available to a calling program, send the variable valueback to the calling program by adding this variable to the list of output arguments.

I’ll now give numerous examples of functions. I’ll start of by writing a function that canadd two numbers. My functions will need 2 inputs (the two numbers I want to add) and it

36

Page 37: MAtlab Notes

will produce a single output (the sum of these two numbers). So I decide that the syntaxof my function Add.m is:

Num3 = Add(Num1,Num2);

where the variable Num3 will be the sum of the variables Num1 and Num2. Now I need towrite the function Add.m:

function [Number_out] = Add(Number1_in,Number2_in)

Number_out = Number1_in + Number2_in;

For this example, the function Add.m contains only 2 program lines. The first line definesthe inputs, outputs and the name of the function. The remaining program lines in afunction computes the outputs, making use of the inputs. In this case a single programline is sufficient. Notice that inside the function, you assume that the input variablesare available (i.e. these values will be passed in from the calling program, so you shouldnot define these values). Any other variables that you require during computations haveto be defined within the function. Also note that the variable names you use inside thefunction are independent from the variable names you use when calling the function.

You can call the new function Add from any program or other functions. You can alsocall the function from the Command Window. I’ll illustrate calling the function Add froma program Main.m:

1: % Define the inputs that the function Add requires

2: Num1 = 4.0;

3: Num2 = 5.0;

4: % Call the function, passing the input variables Num1 and Num2

5: % into the function and getting the output Num3 back

6: Num3 = Add(Num1,Num2);

7: % Display output

8: disp([’The sum of ’,num2str(Num1),’ and ’,num2str(Num2),...

9: ’ is ’,num2str(Num3)])

The function Add is called in program line 6 and the output of the program listed aboveis:

The sum of 4 and 5 is 9

Let’s consider another example. Suppose we want to write a function that takes twonumbers as inputs, and then performs the simple operations addition, subtraction, multi-plication and division to provide four outputs. I decide the function name is Arithmetic,so the syntax of such a function is:

[Add,Subtract,Multiply,Divide] = Arithmetic(Num1,Num2)

37

Page 38: MAtlab Notes

where the two scalar inputs are Num1 and Num2 and the four scalar outputs are Add,Subtract, Multiply and Divide. The function Arithmetic.m follows:

function [A,S,M,D]=Arithmetic(Number1,Number2)

A = Number1 + Number2;

S = Number1 - Number2;

M = Number1 * Number2;

D = Number1 / Number2;

I can call the above function from programs, other functions or the Command Window.I’ll illustrate calling the Arithmetic function from the Command Window:

EDU>> [A,B,C,D] = Arithmetic(3.0,4.0)

A =

7

B =

-1

C =

12

D =

0.7500

You should notice that the variable names used to call the function has nothing to dowith the variable names used inside the function.

As the programmer, you can choose whether or not the inputs and outputs of your functionare scalars, vectors or matrices. As an example, let’s assume you prefer that the input toyour Arithmetic function is a single vector, with two components:

function [A,S,M,D]=Arithmetic(Numbers)

A = Numbers(1) + Numbers(2);

S = Numbers(1) - Numbers(2);

M = Numbers(1) * Numbers(2);

D = Numbers(1) / Numbers(2);

Notice that the input is now a single vector variable Numbers that contain two components.The function Arithmetic cannot be called using two inputs anymore, it now has to becalled using a single vector containing two components as input. The four scalar outputscould also be replaced by a single vector variable:

function [Outputs]=Arithmetic(Numbers)

Outputs(1) = Numbers(1) + Numbers(2);

Outputs(2) = Numbers(1) - Numbers(2);

38

Page 39: MAtlab Notes

Outputs(3) = Numbers(1) * Numbers(2);

Outputs(4) = Numbers(1) / Numbers(2);

To illustrate this last version of the Arithmetic function, I called it from the CommandWindow:

EDU>> Answer=Arithmetic([3.0 4.0])

Answer =

7.0000 -1.0000 12.0000 0.7500

As you can see, I called the Arithmetic function using the [3 4] vector as input. Iobtained a single vector Answer as output, with the four computed values available in thefour components.

The final simple function we’ll write is a function that computes the components of avector, if the length and angle of the vector is provided. Let’s decide that the angle canbe specified in either degrees or radians. I choose the name of the function as Decompose(meaning a function that decomposes a vector into it’s components). The syntax of thefunction is

[Comp_x,Comp_y,Message] = Decompose(Length,Angle,Option)

where the inputs are the length of the vector (length), the vector’s angle (Angle) and thevariable Option, which must distinguish between degrees or radians. The outputs are thetwo components Comp x and Comp y, and a string variable Message that can conatain anerror message. As the programmer, you decide how you want to use the Option variable.You can decide that the Option variable can have a value of 1 or 2, where 1 indicatesthe angle is expressed in degrees and 2 indicates the angle is expressed in radians. Oryou can decide that the variable Option is a string variable that can either contain a’D’ to indicate degrees or a ’R’ to indicate radians. I’ll use the latter option. If theOption variable doesn’t contain either a ’R’ or ’D’, I set the Message variable equal to’Incorrect input’ and then use the return statement. The return statement existsthe function immediately and returns to the calling program.

Here follows the function Decompose.m:

1: function [Comp1,Comp2,Message] = Decompose(Magnitude,Angle,Option)

2: % Assign blanks to outputs

3: Message = [];

4: Comp1 = [];

5: Comp2 = [];

6: % Check if the angle is expressed in degrees: if so, convert to radians

7: if Option==’D’

8: Angle = Angle*pi/180;

9: % If Option not equal to ’R’, incorrect input was provided

10: elseif Option~=’R’

39

Page 40: MAtlab Notes

11: Message=’Incorrect input’;

12: % Since input was incorrect, exit function and return to calling program

13: return

14: end

15: % 1st component the cosine of angle times magnitude

16: Comp1 = Magnitude*cos(Angle);

17: % 2nd component the sine of angle times magnitude

18: Comp2 = Magnitude*sin(Angle);

I called the new function from the Command Window to produce the following output.I used both options i.e. expressed the angle as 45 degrees and as π

4radians. I also called

the function using incorrect input. As you can see, the first two cases produce the sameoutput (as it should) and the last case produces the error message.

EDU>> [C1,C2,M]=Decompose(10,pi/4,’R’)

C1 =

7.0711

C2 =

7.0711

M =

[]

EDU>> [C1,C2,M]=Decompose(10,45,’D’)

C1 =

7.0711

C2 =

7.0711

M =

[]

EDU>> [C1,C2,M]=Decompose(10,45,1)

C1 =

[]

C2 =

[]

M =

Incorrect input

6.1.1 Gauss elimination using functions

I’ll revisit the Gauss elimination program to further illustrate the use of functions. Asthe programmer, you can decide how to organize your program. In this case, I’ve decidedto make use of two functions. The first, called Reduction, is a function that performsthe forward reduction step of the Gauss elimination process. The second function, calledBacksub, performs the backsubstitution step. The inputs that the forward reduction steprequires is the matrix (A in this case) and the vector (a in this case). The outputs that

40

Page 41: MAtlab Notes

the forward reduction step produces are the modified matrix A and modified vector a.Hence the syntax of the Reduction function is

[A,a]=Reduction(A,a);

The Backsub function takes the reduced natrix A and the vector a as input and it producesthe solution to the linear system as output (x in this case). Hence the syntax of theBacksub function is

[x]=Backsub(A,a);

The final version of the Gauss elimination program listed in Section 5.2 now reads:

1: % Create matrix A and vector a

2: A = rand(500,500);

3: a = rand(500,1);

4: % make copies of A and a to use later

5: A_copy = A;

6: a_copy = a;

7: % Start the stopwatch

8: tic

9: % Call the forward reduction function

10: [A,a] = Reduction(A,a);

11: % Call the backsubstitution function

12: [x] = Backsub(A,a);

13: % Stops stopwatch and displays time in Command Window

14: toc

15: % Starts stopwatch again

16: tic

17: % Solve system using inverse of A_copy*a_copy

18: x_Mat1 = inv(A_copy)*a_copy;

19: % Stops stopwatch and displays time in Command Window

20: toc

21: % Starts stopwatch third and final time

22: tic

23: % Solve system using backslash operation

24: x_Mat2 = A_copy\a_copy;

25: % Stops stopwatch and displays time in Command Window

26: toc

The two functions Reduction.m and Backsub.m follows:

Reduction.m

1: function [Matrix,Vector]=Reduction(Matrix,Vector)

2: n = length(Vector);

3: for i=1:n-1

41

Page 42: MAtlab Notes

4: for j=i+1:n

5: mult = Matrix(j,i)/Matrix(i,i);

6: for k=1+i:n

7: Matrix(j,k) = Matrix(j,k) - mult*Matrix(i,k);

8: end

9: Vector(j) = Vector(j) - mult*Vector(i);

10: end

11: end

Backsub.m

1: function [Solution]=Backsub(Matrix,Vector)

2: n = length(Vector)

3: Solution = zeros(n,1);

4: Solution(n) = Vector(n)/Matrix(n,n);

5: for i=n-1:-1:1

6: x(i)=Vector(i);

7: for j=i+1:n

8: Solution(i) = Solution(i) - Matrix(i,j)*Vector(j);

9: end

10: Solution(i) = Solution(i)/Matrix(i,i);

11: end

The performance of the new version of the Gauss elimination program is similar to theoriginal program. This example is useful as an educational example, but is probably notrealistic. I can’t imagine a scenario where we would like to only perform forward reductionor only backsubstitution. Rather, a single function Gauss makes more sense. It takes thematrix A and vector a as input and it produces the vector x as output i.e.

[x] = Gauss(A,a);

The main program now reads:

1: % Create matrix A and vector a

2: A = rand(500,500);

3: a = rand(500,1);

4: % Start the stopwatch

5: tic

6: % Call the Gauss elimination function

7: [x] = Gauss(A,a);

8: % Stops stopwatch and displays time in Command Window

9: toc

10: % Starts stopwatch again

11: tic

12: % Solve system using inverse of A*a

13: x_Mat1 = inv(A)*a;

14: % Stops stopwatch and displays time in Command Window

42

Page 43: MAtlab Notes

15: toc

16: % Starts stopwatch third and final time

17: tic

18: % Solve system using backslash operation

19: x_Mat2 = A\a;

20: % Stops stopwatch and displays time in Command Window

21: toc

and the function Gauss reads:

1: function [Solution]=Gauss(Matrix,Vector)

2: n = length(Vector);

3: for i=1:n-1

4: for j=i+1:n

5: mult = Matrix(j,i)/Matrix(i,i);

6: for k=i+1:n

7: Matrix(j,k) = Matrix(j,k) - mult*Matrix(i,k);

8: end

9: Vector(j) = Vector(j) - mult*Vector(i);

10: end

11: end

12: Solution = zeros(n,1);

13: Solution(n) = Vector(n)/Matrix(n,n);

14: for i=n-1:-1:1

15: x(i)=Vector(i);

16: for j=i+1:n

17: Solution(i) = Solution(i) - Matrix(i,j)*Vector(j);

18: end

19: Solution(i) = Solution(i)/Matrix(i,i);

20: end

6.1.2 Numerical integration using functions

I conclude this section on functions by giving a final example. Consider the numericalintegration program in Section 1. I propose that each of the four methods of integrationcan become a function. So all we have to determine is the inputs and outputs of thesefunctions. As the programmer, I decide that as outputs I want the numerical value of theintegral as well as the required number of intervals. Regarding the inputs, here we haveno choice. A function that must perform numerical integration needs i) the function tobe integrated, ii) the lower and upper bounds of integration iii) the number of intervalsand iv) the required accuracy. All other values can be defined within the function. Sothe syntax of the integration functions is

[Int,N]=Leftpoint(Fcn,LB,UB,N_ini,Acc);

where the inputs are the functions Fcn, the lower bound LB, upper bound UB, initialnumber of intervals N ini and the required accuracy Acc. The function will then provide

43

Page 44: MAtlab Notes

the intergal Int and the required number of intervals N. Here’s the listing of the modifiednumerical integration program Integrate.m and only the Leftpoint.m function. Theother functions only differ in the details of the area computation.

Integrate.m

1: % Get user inputs

2: F_string = input(’Please enter function to be integrated. ’,’s’);

3: Fcn = inline(F_string);

4: LB = input(’Enter the lower bound of integration. ’);

5: UB = input(’Enter the upper bound of integration. ’);

6: N_ini = input(’Initial number of intervals between LB and UB? ’);

7: acc = input(’Enter the required accuracy. ’);

8: disp(’1: Left-point 2: Right-point 3: Mid-point’);

9: disp(’4: Trapezium 5: Quit program’);

10: Method = input(’Please enter your option. ’);

11: % My program repeats until the user inputs option 5

12: while Method~=5

13: % Depending on method chosen, call appropriate function

14: switch Method

15: case 1

16: [Int,N]=Leftpoint(Fcn,LB,UB,N_ini,acc);

17: case 2

18: [Int,N]=Rightpoint(Fcn,LB,UB,N_ini,acc);

19: case 3

20: [Int,N]=Midpoint(Fcn,LB,UB,N_ini,acc);

21: case 4

22: [Int,N]=Trapezium(Fcn,LB,UB,N_ini,acc);

23: end

24: % Get length of the integration vector

25: k = length(Int);

26: % Display answer

27: disp([’Integrating ’,F_string,’ between ’,num2str(LB),’ and ’, ...

28: num2str(UB)])

29: disp(’Intervals Integral’);

30: % Display first k components of vectors N and Int

31: disp([num2str(N(1:k)’,’%8d\t\t’),num2str(Int(1:k)’,’%10.6f’)])

32: % Display options again

33: disp(’1: Left-point 2: Right-point 3: Mid-point’);

34: disp(’4: Trapezium 5: Quit program’);

35: Method = input(’Please enter your option. ’);

36: end; %End of outer while loop

37: % Outside while loop, user entered option 5 = Quit

38: % Displays a friendly message.

39: disp(’Thanks for using the program. Have a good day.’)

Leftpoint.m

1: function [Int,N]=Leftpoint(Fcn,LB,UB,N_ini,acc)

44

Page 45: MAtlab Notes

2: % Define initial Error greater as acc, to enter while loop

3: Error = 2*acc;

4: % Number of intervals is saved in a vector N. I start with component 2

5: % to correspond to the integrals in the vector Int

6: N(2) = N_ini;

7: % Set counter k to one

8: k = 1;

9: % Set component 1 of the Int vector to zero.

10: Int(1) = 0;

11: % Start while loop that checks if consecutive values converged

12: while Error>acc

13: % Increment the counter k with one

14: k = k + 1;

15: % Initialize the current component of the Int vector to zero

16: Int(k) = 0;

17: % Compute the interval size Delta_x

18: Delta_x = (UB-LB)/N(k);

19: % For loop to compute area of each rectangle and add it to Int

20: for i=1:N(k)

21: x = LB + (i-1)*Delta_x;

22: Int(k) = Int(k) + Delta_x*Fcn(x);

23: end

24: Error = abs(Int(k) - Int(k-1));

25: % Component k+1 of N vector = 2 times component k value

26: N(k+1) = 2*N(k);

27: end; % End of inner while

6.1.3 Persistent variables

The local variables inside your function cease to exist once the function is executed andreturns to the calling program. However, in certain cases you may want the value of yourlocal function variables to be remembered whenever the function is called again. Thiscan be achieved by declaring a variable as persistent. Immediately after your function

definition line, include the line

persistent VariableName

to declare the variable VariableName as persistent. Persistent variables can save a lot oftime in certain cases, where we don’t have to recompute values that have been computedbefore. A simple example is to set a counter to zero and increment it by one every timea function is called. We can use this idea to count how many times a function is calledwhen we perform numerical integration.

45

Page 46: MAtlab Notes

6.1.4 Global variables

The basic philosophy of functions is that they communicate with the calling programonly through the input and output arguments. The function only has access to the valuespassed to it from the calling program, and the calling program only receives the functionoutput. In very rare circumstances, it might be required that a function must also haveaccess to a variable that is not passed in as one of the arguments. In such a case, youmake use of the global statement.

Whenever the need arises in a function to know the value of some variable, but for somereason that value cannot be passed to the function as part of the input variables, thatvariable is declared as a global variable in the second line of the function. As an example,consider the function Gauss in Section 1.1.1. Let’s assume that we do not want to passthe size of the matrix n in as an argument, but we also do not want to recompute it usingthe length statement. Then we can define n as a global variable as follows:

function [Solution]=Gauss(Matrix,Vector)

global n

for i=1:n-1

:

The variable n must also be defined as a global variable in the calling program, so themain program’s first line now reads

global n

Now, the value of the variable n in known at all times in the main program and thefunction Gauss. Should the value of n be changed inside the function Gauss, the valuewill also be changed inside the main program. So the basic philosophy of functions nolonger holds, since a computation inside a function can affect the value of a variableoutside that function. Because of this, the use of global variables is strongly discouraged.If you really require access to a variable value inside some function, rather pass that valuein as one of the input variables.

7 Vectorizing algorithms

Although we are using Matlab in this programming course, I believe that the materialI have presented so far is general in that the ideas are common to most programminglanguages. The remainder of this course will however be Matlab specific.

One of the most important characteristics that sets Matlab apart from most other pro-gramming languages is it’s ability to deal with vectors and matrices. This goes back to theoriginal purpose of Matlab i.e. to perform linear algebra on large systems. So it should beno surprise that Matlab in fact ‘prefers’ to perform vector and matrix operations ratherthan scalar operations. What I mean with ‘prefer’ is that Matlab is more efficient when it

46

Page 47: MAtlab Notes

performs vector and matrix operations compared to the same operations performed com-ponent by component. So whenever we program in Matlab, we should avoid componentby component vector and matrix computations using for loops. Rather, ‘vectorize’ thecomputations, as will be shown in this section.

7.1 Creating vectors and vector computations

So far in this course, whenever we created a vector we used a for loop to assign thecomponents. For example, a vector x containing 100 equal intervals between a lowerbound LB and an upper bound UB is created by

LB = -10;

UB = 10;

for i=0:100

x(i+1) = LB + i*(UB-LB)/100;

end

Instead of using the above program, there are two more efficient methods in Matlab tocreate evenly spaced vectors. In the first method, the start value, increment and endvalue is specified i.e. the statement

x = Start:Increment:End;

will create a vector x with the first component equal to Start, the second componentequal to Start+Increment, the third component equal to Start+2*Increment etc. withthe last component equal to or less than End if Increment>0, or equal to or greater thanEnd if Increment<0. Consider the following examples I ran from the Command Window:

EDU>> x=0:1:5

x =

0 1 2 3 4 5

EDU>> x=0:2:5

x =

0 2 4

EDU>> x=2:-0.5:0

x =

2.0000 1.5000 1.0000 0.5000 0

EDU>> x=2:-0.7:0

x =

2.0000 1.3000 0.6000

So the program on page 1 that uses a for loop can be replaced with:

47

Page 48: MAtlab Notes

LB = -10;

UB = 10;

x = LB:0.2:UB;

Another built-in Matlab method to create linearly spaced vectors is the linspace com-mand. Here we specify the start value, end value and the total number of datapoints. Forthe example considered here (LB=-10, UB=10), the statement

x = linspace(LB,UB,101);

is equivalent to the program line x = LB:0.2:UB;

Now that we know how to create vectors efficiently, I’ll show you how to perform vectorcomputations. Let’s assume we want to plot the function

y = sin(x) for x ∈ [−π, π] (29)

as was considered in Section 2.5. Before we can plot the function, we have to define a x

vector from −π to π. Then we compute the associated y vector by simply taking the sin

of the x vector. Compare the program

x = linspace(-pi,pi,100);

y = sin(x);

plot(x,y)

with the program in Section 2.5. Experiment with other functions and produce theirgraphs.

7.1.1 Linear algebra vs. component-by-component computations

You’ve just witnessed how we can perform a computation on a complete vector to produceanother vector. You might think that we can use these methods to produce the graph ofy = x2, let’s say for x ∈ [−2, 2]. The program

x = linspace(-2,2,100);

y = x^2;

plot(x,y)

will however produce the error statement

??? Error using ==> ^

Matrix must be square.

or if program line 2 is y = x*x; the error statement reads

??? Error using ==> *

Inner matrix dimensions must agree.

48

Page 49: MAtlab Notes

So why aren’t these statements correct? Recall that Matlab was originally developed toperform linear algebra. So Matlab interprets statements such as x^2 or x*x in terms oflinear algebra operations. In the above example, the vector x is defined as a 1 × 100vector. Therefore the statement x*x is interpreted as the multiplication of a 1 × 100vector with another 1 × 100 vector, which is not defined. Therefore the error messageInner matrix dimensions must agree.

But when we want to calculate the associated y-values for a x vector between -2 and 2, wedon’t want linear algebra operations to be performed. Rather, we want to calculate a yvector where every component is simply equal to the square of the associated x component.In Matlab, this type of computation is performed by using a period immediately before themultiplication symbol. Whenever a mathematical operation is preceded by a period (.),Matlab is given instruction to perform that operation component by component, insteadof the usual linear algebra rules. So the correct method to compute the y vector is:

x = linspace(-2,2,100);

y = x.^2; or y = x.*x;

plot(x,y)

Let’s consider another example. Suppose I want to plot the function

y = ex sin(πx) −e2x

cos(2πx)for x ∈ [0, 2] (30)

The appropriate Matlab program is:

x = linspace(0,2,100);

y = exp(x).*sin(pi*x) - exp(2*x)./(cos(2*pi*x));

plot(x,y)

I’ll now explain the use of the periods: The result of the computation exp(x) is a vector,as is the result of the computation sin(pi*x). So a period is required before the multi-plication sign, to prevent Matlab from attempting linear algebra multiplication. Similarlythe result of the exp(2*x) computation is a vector, as is the result of the cos(2*pi*x)

computation. Standard division of these two vectors aren’t even defined, so the periodpreceding the division symbol (/) tells Matlab to perform this operation component bycomponent. Notice that addition and subtraction never requires a period, since vectorand matrix addition and subtraction are performed component by component.

As a final example of the use of the period, consider the following:

A = [1 2

3 4];

B = A*A;

C = A.*A;

The period operation is interpreted exactly the same when dealing with matrices. Sincethe matrix A is square, the operation A*A is defined as usual matrix-matrix multiplicationand will result in

49

Page 50: MAtlab Notes

B =

6 10

15 20

The operation A.*A will perform multiplication component by component, resulting in

C =

1 4

9 16

7.2 Vectorization

‘Vectorization’ of an algorithm means that instead of computing a vector or matrix com-ponent by component by making use or for loops (or nested for loops), we attempt tocompute a complete vector with a single program line (or compute a complete row orcolumn in a matrix by using a single program line). This is frequently possible, subjectto certain limitations.

The condition that has to be true in order to vectorize a computation, is that the particularcomponents that are computed as the for loop proceeds do not depend on the value ofthe preceding components. If this is the case, vectorization is not possible since all thecomponents cannot be computed simulataneously.

The reason for vectorizing an algorithm is purely for computational speed. Older versionsof Matlab are notorious for the slow execution of for loops, but the recent releases aremuch improved. So you will have to experiment with your particular Matlab version andsee what the effect is when you vectorize an algorithm.

7.2.1 Vectorizing Gauss elimination

To illustrate vectorization, I’ll revisit the Gauss elimination program of Section 5.2. I’vealready incorporated the change in program line 14, to avoid computing the zeros to theleft of the diagonal.

1: % Create matrix A and vector a

2: A = rand(500,500);

3: a = rand(500,1);

4: % make copies of A and a to use later

5: A_copy = A;

6: a_copy = a;

7: % Start the stopwatch

8: tic

9: % Forward reduction step as before

10: n = length(a);

11: for i=1:n-1

12: for j=i+1:n

13: mult = A(j,i)/A(i,i);

14: for k=1+i:n

50

Page 51: MAtlab Notes

15: A(j,k) = A(j,k) - mult*A(i,k);

16: end

17: a(j) = a(j) - mult*a(i);

18: end

19: end

20: % Backsubstitution step as before

21: x = zeros(n,1);

22: x(n) = a(n)/A(n,n);

23: for i=n-1:-1:1

24: x(i)=a(i);

25: for j=i+1:n

26: x(i) = x(i) - A(i,j)*x(j);

27: end

28: x(i) = x(i)/A(i,i);

29: end

30: % Stops stopwatch and displays time in Command Window

30: toc

31: % Starts stopwatch again

32: tic

33: % Solve system using inverse of A_copy*a_copy

34: x_Mat1 = inv(A_copy)*a_copy;

35: % Stops stopwatch and displays time in Command Window

36: toc

37: % Starts stopwatch third and final time

38: tic

39: % Solve system using backslash operation

40: x_Mat2 = A_copy\a_copy;

41: % Stops stopwatch and displays time in Command Window

42: toc

I’ll now start eliminating for loops. Whenever nested for loops are used, it is usuallybest to start at the innermost for loop since the innermost for loop is executed mostoften.

Let’s start at the forward reduction step. Three nested for loops are used here. I’ll firstattempt to eliminate the innermost loop. Before we do so, we have to check whether ornot the computations performed in this loop depend on one another. If so, we will not beable to vectorize.

The for loop in program lines 14–16 subtracts the appropriate fraction of row i from rowj, from the index k refers to the column: from i+1 to n. The various column computationsdo not depend on one another, so we can vectorize. This is achieved by simply substitutingthe lines

14: for k=1+i:n

15: A(j,k) = A(j,k) - mult*A(i,k);

16: end

51

Page 52: MAtlab Notes

with the single program line

A(j,1+i:n) = A(j,1+i:n) - mult*A(i,1+i:n);

In essence, we replace the index k which started at 1+i and ended at n with the vector1+i:n. After this simple change, the time required to solve a 500 × 500 system reducesfrom 235.92 seconds (Matlab 6.1) to:

elapsed_time =

15.9430

but increases from 5.0185 seconds (Matlab 6.5) to

elapsed_time =

9.4705

So eliminating the innermost for loop during the forward reduction step reduces com-putational time by 93% using Matlab 6.1, but increases the computational time by 89%using Matlab 6.5. This clearly illustrates the difference between Matlab versions, as wellas the potential benefit (or downside) of vectorization. So we eliminate the innermost forloop when we use Matlab 6.1, but we retain it if we use Matlab 6.5.

The for loop is program line 12 can also be removed by vectorization. We replace all j’sin program lines 13-17 with 1+i:n. The forward reduction step now reads:

% Forward reduction step as before

n = length(a);

for i=1:n-1

mult = A(i+1:n,i)/A(i,i);

A(i+1:n,1+i:n) = A(i+1:n,1+i:n) - mult*A(i,1+i:n);

a(i+1:n) = a(i+1:n) - mult*a(i);

end

if we use Matlab 6.1 (both for loops eliminated with vectorization), or we retain theinnermost for loop if we use Matlab 6.5 and only eliminate the second for loop:

% Forward reduction step as before

n = length(a);

for i=1:n-1

mult = A(i+1:n,i)/A(i,i);

for k=1+i:n

A(i+1:n,k) = A(i+1:n,k) - mult*A(i,k);

end

a(i+1:n) = a(i+1:n) - mult*a(i);

end

52

Page 53: MAtlab Notes

These modifications reduce the time to solve a 500 × 500 linear system from 15.943 secondsto 5.1570 seconds in the case of Matlab 6.1, and from 5.0185 seconds to 3.3328 seconds ifwe use Matlab 6.5.

The outermost for loop during the forward reduction step cannot be eliminated, since allthe columns cannot be reduced to zero’s below the diagonal simultaneously.

The last for loop we can eliminate is the inner for loop used during the backsubstitutionstep. As before, we simply replace all j’s with i+1:n. The backsubstitution step nowreads:

% Backsubstitution step as before

x = zeros(n,1);

x(n) = a(n)/A(n,n);

for i=n-1:-1:1

x(i) = (a(i) - A(i,i+1:n)*x(i+1:n))/A(i,i);

end

This change further reduces the time required to solve a 500 × 500 linear system from5.1570 seconds to only 4.4570 seconds using Matlab 6.1. In the case of Matlab 6.5, thetime is increased slightly from 3.3328 seconds to 3.4717 seconds.

In conclusion, depending on the version of Matlab you are using, vectorization can greatlyincrease the speed of program execution. Every vectorization leads to greater efficiency inthe case of Matlab 6.1, but only certain vectorizations are beneficial in the case of Mat-lab 6.5. For the example considered here, execution time decreased from 235.92 seconds to4.457 seconds for Matlab 6.1, and from 5.0185 seconds to 3.3328 seconds for Matlab 6.5.

7.2.2 Vectorizing numerical integration

As a last example of vectorization, I’ll illustrate how to vectorize the numerical integrationprogram presented in Section 1. I’m listing the program again for convenience:

1: % Get user inputs

2: F_string = input(’Please enter function to be integrated. ’,’s’);

3: Fcn = inline(F_string);

4: LB = input(’Enter the lower bound of integration. ’);

5: UB = input(’Enter the upper bound of integration. ’);

6: N_ini = input(’Initial number of intervals between LB and UB? ’);

7: acc = input(’Enter the required accuracy. ’);

8: disp(’1: Left-point 2: Right-point 3: Mid-point’);

9: disp(’4: Trapezium 5: Quit program’);

10: Method = input(’Please enter your option. ’);

11: % My program repeats until the user inputs option 5

12: while Method~=5

13: % Define initial Error greater as acc, to enter while loop

14: Error = 2*acc;

15: % Number of intervals is saved in a vector N. I start with component 2

53

Page 54: MAtlab Notes

16: % to correspond to the integrals in the vector Int

17: N(2) = N_ini;

18: % Set counter k to one

19: k = 1;

20: % Set component 1 of the Int vector to zero.

21: Int(1) = 0;

22: % Start while loop that checks if consecutive values converged

23: while Error>acc

24: % Increment the counter k with one

25: k = k + 1;

26: % Initialize the current component of the Int vector to zero

27: Int(k) = 0;

28: % Compute the interval size Delta_x

29: Delta_x = (UB-LB)/N(k);

30: % Use the switch statement to branch to one of the 4 methods

31: switch Method

32: % Case 1: left-point method

33: case 1

34: % For loop to compute area of each rectangle and add it to Int

35: for i=1:N(k)

36: x = LB + (i-1)*Delta_x;

37: Int(k) = Int(k) + Delta_x*Fcn(x);

38: end

39: % Case 2: right-point method

40: case 2

41: for i=1:N(k)

42: x = LB + i*Delta_x;

43: Int(k) = Int(k) + Delta_x*Fcn(x);

44: end

45: % Case 3: mid-point method

46: case 3

47: for i=1:N(k)

48: x = LB + (i-1)*Delta_x + 0.5*Delta_x;

49: Int(k) = Int(k) + Delta_x*Fcn(x);

50: end

51: % Case 4: trapezium method

52: case 4

53: for i=1:N(k)

54: x_L = LB + (i-1)*Delta_x;

55: x_R = x_L + Delta_x;

56: Int(k) = Int(k) + 0.5*Delta_x*(Fcn(x_L) + Fcn(x_R));

57: end

58: end; % End of switch

59: % Compute Error i.e. difference between consecutive integrals

60: Error = abs(Int(k) - Int(k-1));

61: % Component k+1 of N vector = 2 times component k value

62: N(k+1) = 2*N(k);

54

Page 55: MAtlab Notes

63: end; % End of inner while

64: % Display answer

65: disp([’Integrating ’,F_string,’ between ’,num2str(LB),’ and ’, ...

66: num2str(UB)])

67: disp(’Intervals Integral’);

68: % Display first k components of vectors N and Int

69: disp([num2str(N(1:k)’,’%8d\t\t’),num2str(Int(1:k)’,’%10.6f’)])

70: % Display options again

71: disp(’1: Left-point 2: Right-point 3: Mid-point’);

72: disp(’4: Trapezium 5: Quit program’);

73: Method = input(’Please enter your option. ’);

74: end; %End of outer while loop

75: % Outside while loop, user entered option 5 = Quit

76: % Displays a friendly message.

77: disp(’Thanks for using the program. Have a good day.’)

This program can be vectorized by eliminating the for loops in program lines 35, 41, 47and 53. Program lines 35 to 38 is replaced by

35: x = LB:Delta_x:UB-Delta_x;

36: Heights = Fcn(x);

37: Areas = Delta_x*Heights;

38: Int(k) = sum(Areas);

As you can see, we now compute the complete vector x in program line 35 instead of it’sindividual components. The vector x starts at LB, increments with Delta x and ends atUB-Delta x. The rectangle heights is then evaluated by passing the complete vector x tothe function Fcn. Multiplying with the rectangle width Delta x gives all the rectangleareas in the vector variable Areas. I then use the sum statement in program line 38 to sumall the components of Areas to obtain the integral Int. Using Matlab 6.5, the leftpointmethod (which I have already modified) takes 0.0167 seconds to integrate sin(x) between0 and π

2for an accuracy of 0.0001 and 10 initial intervals, compared to 12.1847 seconds

before vectorization!

You can practise vectorization by eliminating the other for loops in this program.

55