STRUCTURED PROGRAMMING Applied Numerical Methods with MATLAB fo

where condition is a logical expression that is either true or false. For example, here is a simple M-file to evaluate whether a grade is passing: function gradergrade gradergrade: determines whether grade is passing input: grade = numerical value of grade 0-100 output: displayed message if grade = 60 disppassing grade end The following illustrates the result grader95.6 passing grade For cases where only one statement is executed, it is often convenient to implement the if structure as a single line, if grade 60, disppassing grade, end This structure is called a single-line if. For cases where more than one statement is implemented, the multiline if structure is usually preferable because it is easier to read. Error Function. A nice example of the utility of a single-line if is to employ it for rudi- mentary error trapping. This involves using the error function which has the syntax, errormsg When this function is encountered, it displays the text message msg , indicates where the error occurred, and causes the M-file to terminate and return to the command window. An example of its use would be where we might want to terminate an M-file to avoid a division by zero. The following M-file illustrates how this could be done: function f = errortestx if x == 0, errorzero value encountered, end f = 1x; If a nonzero argument is used, the division would be implemented successfully as in errortest10 ans = 0.1000 However, for a zero argument, the function would terminate prior to the division and the error message would be displayed in red typeface: errortest0 ??? Error using == errortest at 2 zero value encountered Logical Conditions. The simplest form of the condition is a single relational expres- sion that compares two values as in value 1 relation value 2 where the values can be constants, variables, or expressions and the relation is one of the relational operators listed in Table 3.2. MATLAB also allows testing of more than one logical condition by employing logical operators. We will emphasize the following: • ~ Not . Used to perform logical negation on an expression. ~expression If the expression is true, the result is false. Conversely, if the expression is false, the result is true. • And . Used to perform a logical conjunction on two expressions. expression 1 expression 2 If both expressions evaluate to true, the result is true. If either or both expres- sions evaluates to false, the result is false. • | Or . Used to perform a logical disjunction on two expressions. expression 1 | expression 2 If either or both expressions evaluate to true, the result is true. Table 3.3 summarizes all possible outcomes for each of these operators. Just as for arithmetic operations, there is a priority order for evaluating logical operations. These 3.3 STRUCTURED PROGRAMMING 59 TABLE 3.2 Summary of relational operators in MATLAB. Example Operator Relationship x == 0 == Equal unit ~= m ~= Not equal a 0 Less than s t Greater than 3.9 = a3 = Less than or equal to r = 0 = Greater than or equal to TABLE 3.3 A truth table summarizing the possible outcomes for logical operators employed in MATLAB. The order of priority of the operators is shown at the top of the table. Highest Lowest x y ~x x y x | y T T F T T T F F F T F T T F T F F T F F are from highest to lowest: ~ , and | . In choosing between operators of equal priority, MATLAB evaluates them from left to right. Finally, as with arithmetic operators, paren- theses can be used to override the priority order. Let’s investigate how the computer employs the priorities to evaluate a logical expres- sion. If a = -1 , b = 2 , x = 1 , and y = b , evaluate whether the following is true or false: a b 0 b == 2 x 7 | ~y d To make it easier to evaluate, substitute the values for the variables: -1 2 0 2 == 2 1 7 | ~b d The first thing that MATLAB does is to evaluate any mathematical expressions. In this example, there is only one: -1 2 , -2 0 2 == 2 1 7 | ~b d Next, evaluate all the relational expressions -2 0 2 == 2 1 7 | ~b d F T F | ~ F At this point, the logical operators are evaluated in priority order. Since the ~ has highest priority, the last expression ~F is evaluated first to give F T F | T The operator is evaluated next. Since there are two, the left-to-right rule is applied and the first expression F T is evaluated: F F | T The again has highest priority F | T Finally, the | is evaluated as true. The entire process is depicted in Fig. 3.1. The if...else Structure. This structure allows you to execute a set of statements if a logical condition is true and to execute a second set if the condition is false. Its general syntax is if condition statements 1 else statements 2 end The if...elseif Structure. It often happens that the false option of an if...else structure is another decision. This type of structure often occurs when we have more than two options for a particular problem setting. For such cases, a special form of decision structure, the if...elseif has been developed. It has the general syntax if condition 1 statements 1 elseif condition 2 statements 2 elseif condition 3 statements 3 . . . else statements else end EXAMPLE 3.4 if Structures Problem Statement. For a scalar, the built-in MATLAB sign function returns the sign of its argument −1, 0, 1. Here’s a MATLAB session that illustrates how it works: sign25.6 ans = 1 sign-0.776 ans = -1 sign0 ans = Develop an M-file to perform the same function. 3.3 STRUCTURED PROGRAMMING 61 a b 0 b == 2 x 7 | ~ y d T T F -1 2 0 2 == 2 1 7 | ~b d F T F | ~ F F F | Substitute constants Evaluate mathematical expressions Evaluate relational expressions Evaluate compound expressions T | -2 0 2 == 2 1 7 | ~b d FIGURE 3.1 A step-by-step evaluation of a complex decision. Solution. First, an if structure can be used to return 1 if the argument is positive: function sgn = mysignx mysignx returns 1 if x is greater than zero. if x 0 sgn = 1; end This function can be run as mysign25.6 ans = 1 Although the function handles positive numbers correctly, if it is run with a negative or zero argument, nothing is displayed. To partially remedy this shortcoming, an if...else structure can be used to display –1 if the condition is false: function sgn = mysignx mysignx returns 1 if x is greater than zero. -1 if x is less than or equal to zero. if x 0 sgn = 1; else sgn = -1; end This function can be run as mysign-0.776 ans = -1 Although the positive and negative cases are now handled properly, -1 is erroneously returned if a zero argument is used. An if...elseif structure can be used to incorporate this final case: function sgn = mysignx mysignx returns 1 if x is greater than zero. -1 if x is less than zero. 0 if x is equal to zero. if x 0 sgn = 1; elseif x 0 sgn = -1; else sgn = 0; end The function now handles all possible cases. For example, mysign0 ans = The switch Structure. The switch structure is similar in spirit to the if...elseif structure. However, rather than testing individual conditions, the branching is based on the value of a single test expression. Depending on its value, different blocks of code are im- plemented. In addition, an optional block is implemented if the expression takes on none of the prescribed values. It has the general syntax switch testexpression case value 1 statements 1 case value 2 statements 2 . . . otherwise statements otherwise end As an example, here is function that displays a message depending on the value of the string variable, grade . grade = B; switch grade case A dispExcellent case B dispGood case C dispMediocre case D dispWhoops case F dispWould like fries with your order? otherwise dispHuh end When this code was executed, the message “Good” would be displayed. Variable Argument List. MATLAB allows a variable number of arguments to be passed to a function. This feature can come in handy for incorporating default values into your functions. A default value is a number that is automatically assigned in the event that the user does not pass it to a function. As an example, recall that earlier in this chapter, we developed a function freefall , which had three arguments: v = freefallt,m,cd Although a user would obviously need to specify the time and mass, they might not have a good idea of an appropriate drag coefficient. Therefore, it would be nice to have the pro- gram supply a value if they omitted it from the argument list. MATLAB has a function called nargin that provides the number of input arguments supplied to a function by a user. It can be used in conjunction with decision structures like 3.3 STRUCTURED PROGRAMMING 63 the if or switch constructs to incorporate default values as well as error messages into your functions. The following code illustrates how this can be done for freefall : function v = freefall2t, m, cd freefall2: bungee velocity with second-order drag v=freefall2t,m,cd computes the free-fall velocity of an object with second-order drag. input: t = time s m = mass kg cd = drag coefficient default = 0.27 kgm output: v = downward velocity ms switch nargin case 0 errorMust enter time and mass case 1 errorMust enter mass case 2 cd = 0.27; end g = 9.81; acceleration of gravity v = sqrtg m cdtanhsqrtg cd m t; Notice how we have used a switch structure to either display error messages or set the default, depending on the number of arguments passed by the user. Here is a command window session showing the results: freefall212,68.1,0.25 ans = 50.6175 freefall212,68.1 ans = 48.8747 freefall212 ??? Error using == freefall2 at 15 Must enter mass freefall2 ??? Error using == freefall2 at 13 Must enter time and mass Note that nargin behaves a little differently when it is invoked in the command window. In the command window, it must include a string argument specifying the func- tion and it returns the number of arguments in the function. For example, narginfreefall2 ans = 3

3.3.2 Loops

As the name implies, loops perform operations repetitively. There are two types of loops, depending on how the repetitions are terminated. A for loop ends after a specified number of repetitions. A while loop ends on the basis of a logical condition. The for...end Structure. A for loop repeats statements a specific number of times. Its general syntax is for index = start:step:finish statements end The for loop operates as follows. The index is a variable that is set at an initial value, start . The program then compares the index with a desired final value, finish . If the index is less than or equal to the finish , the program executes the statements . When it reaches the end line that marks the end of the loop, the index variable is increased by the step and the program loops back up to the for statement. The process continues until the index becomes greater than the finish value. At this point, the loop terminates as the program skips down to the line immediately following the end statement. Note that if an increment of 1 is desired as is often the case, the step can be dropped. For example, for i = 1:5 dispi end When this executes, MATLAB would display in succession, 1, 2, 3, 4, 5 . In other words, the default step is 1 . The size of the step can be changed from the default of 1 to any other numeric value. It does not have to be an integer, nor does it have to be positive. For example, step sizes of 0.2 , –1 , or –5 , are all acceptable. If a negative step is used, the loop will “countdown” in reverse. For such cases, the loop’s logic is reversed. Thus, the finish is less than the start and the loop terminates when the index is less than the finish . For example, for j = 10:-1:1 dispj end When this executes, MATLAB would display the classic “countdown” sequence: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 . EXAMPLE 3.5 Using a for Loop to Compute the Factorial Problem Statement. Develop an M-file to compute the factorial. 2 0 = 1 1 = 1 2 = 1 × 2 = 2 3.3 STRUCTURED PROGRAMMING 65 2 Note that MATLAB has a built-in function factorial that performs this computation. 3 = 1 × 2 × 3 = 6 4 = 1 × 2 × 3 × 4 = 24 5 = 1 × 2 × 3 × 4 × 5 = 120 . . . Solution. A simple function to implement this calculation can be developed as function fout = factorn factorn: Computes the product of all the integers from 1 to n. x = 1; for i = 1:n x = x i; end fout = x; end which can be run as factor5 ans = 120 This loop will execute 5 times from 1 to 5. At the end of the process, x will hold a value of 5 meaning 5 factorial or 1 × 2 × 3 × 4 × 5 = 120. Notice what happens if n = 0. For this case, the for loop would not execute, and we would get the desired result, 0 = 1. Vectorization. The for loop is easy to implement and understand. However, for MATLAB, it is not necessarily the most efficient means to repeat statements a specific number of times. Because of MATLAB’s ability to operate directly on arrays, vectorization provides a much more efficient option. For example, the following for loop structure: i = 0; for t = 0:0.02:50 i = i + 1; yi = cost; end can be represented in vectorized form as t = 0:0.02:50; y = cost; It should be noted that for more complex code, it may not be obvious how to vectorize the code. That said, wherever possible, vectorization is recommended. Preallocation of Memory. MATLAB automatically increases the size of arrays every time you add a new element. This can become time consuming when you perform actions such as adding new values one at a time within a loop. For example, here is some code that sets value of elements of y depending on whether or not values of t are greater than one: t = 0:.01:5; for i = 1:lengtht if ti1 yi = 1ti; else yi = 1; end end For this case, MATLAB must resize y every time a new value is determined. The follow- ing code preallocates the proper amount of memory by using a vectorized statement to assign ones to y prior to entering the loop. t = 0:.01:5; y = onessizet; for i = 1:lengtht if ti1 yi = 1ti; end end Thus, the array is only sized once. In addition, preallocation helps reduce memory frag- mentation, which also enhances efficiency. The while Structure. A while loop repeats as long as a logical condition is true. Its general syntax is while condition statements end The statements between the while and the end are repeated as long as the condition is true. A simple example is x = 8 while x 0 x = x - 3; dispx end When this code is run, the result is x = 8 5 2 -1 The while...break Structure. Although the while structure is extremely useful, the fact that it always exits at the beginning of the structure on a false result is somewhat constraining. For this reason, languages such as Fortran 90 and Visual Basic have special structures that allow loop termination on a true condition anywhere in the loop. Although such structures are currently not available in MATLAB, their functionality can be mimicked 3.3 STRUCTURED PROGRAMMING 67 by a special version of the while loop. The syntax of this version, called a while... break structure, can be written as while 1 statements if condition, break, end statements end where break terminates execution of the loop. Thus, a single line if is used to exit the loop if the condition tests true. Note that as shown, the break can be placed in the middle of the loop i.e., with statements before and after it. Such a structure is called a midtest loop. If the problem required it, we could place the break at the very beginning to create a pretest loop. An example is while 1 If x 0, break, end x = x - 5; end Notice how 5 is subtracted from x on each iteration. This represents a mechanism so that the loop eventually terminates. Every decision loop must have such a mechanism. Other- wise it would become a so-called infinite loop that would never stop. Alternatively, we could also place the if...break statement at the very end and cre- ate a posttest loop, while 1 x = x - 5; if x 0, break, end end It should be clear that, in fact, all three structures are really the same. That is, depend- ing on where we put the exit beginning, middle, or end dictates whether we have a pre-, mid- or posttest. It is this simplicity that led the computer scientists who developed Fortran 90 and Visual Basic to favor this structure over other forms of the decision loop such as the conventional while structure. The pause Command. There are often times when you might want a program to tem- porarily halt. The command pause causes a procedure to stop and wait until any key is hit. A nice example involves creating a sequence of plots that a user might want to leisurely peruse before moving on to the next. The following code employs a for loop to create a sequence of interesting plots that can be viewed in this manner: for n = 3:10 meshmagicn pause end The pause can also be formulated as pausen , in which case the procedure will halt for n seconds. This feature can be demonstrated by implementing it in conjunction with several other useful MATLAB functions. The beep command causes the computer to emit a beep sound. Two other functions, tic and toc , work together to measure elapsed time. The tic command saves the current time that toc later employs to display the elapsed time. The following code then confirms that pausen works as advertised complete with sound effects: tic beep pause5 beep toc When this code is run, the computer will beep. Five seconds later it will beep again and dis- play the following message: Elapsed time is 5.006306 seconds. By the way, if you ever have the urge to use the command pauseinf , MATLAB will go into an infinite loop. In such cases, you can return to the command prompt by typing Ctrl+c or Ctrl+Break. Although the foregoing examples might seem a tad frivolous, the commands can be quite useful. For instance, tic and toc can be employed to identify the parts of an algo- rithm that consume the most execution time. Further, the Ctrl+c or Ctrl+Break key com- binations come in real handy in the event that you inadvertently create an infinite loop in one of your M-files.

3.3.3 Animation

There are two simple ways to animate a plot in MATLAB. First, if the computations are sufficiently quick, the standard plot function can be employed in a way that the animation can appear smooth. Here is a code fragment that indicates how a for loop and standard plotting functions can be employed to animate a plot, create animation with standard plot functions for j=1:n plot commands end Thus, because we do not include hold on , the plot will refresh on each loop iteration. Through judicious use of axis commands, this can result in a smoothly changing image. Second, there are special functions, getframe and movie , that allow you to capture a sequence of plots and then play them back. As the name implies, the getframe function captures a snapshot pixmap of the current axes or figure. It is usually used in a for loop to assemble an array of movie frames for later playback with the movie function, which has the following syntax: moviem,n,fps where m ⫽ the vector or matrix holding the sequence of frames constituting the movie, n ⫽ an optional variable specifying how many times the movie is to be repeated if it is omitted, the movie plays once, and fps ⫽ an optional variable that specifies the movie’s frame rate if it is omitted, the default is 12 frames per second. Here is a code 3.3 STRUCTURED PROGRAMMING 69 fragment that indicates how a for loop along with the two functions can be employed to create a movie, create animation with standard plot functions for j=1:n plot commands Mj = getframe; end movieM Each time the loop executes, the plot commands create an updated version of a plot, which is then stored in the vector M . After the loop terminates, the n images are then played back by movie. EXAMPLE 3.6 Animation of Projectile Motion Problem Statement. In the absence of air resistance, the Cartesian coordinates of a pro- jectile launched with an initial velocity v and angle θ can be computed with x = v cos θ t y = v sin θ t ⫺ 0.5gt 2 where g = 9.81 ms 2 . Develop a script to generate an animated plot of the projectile’s trajectory given that v = 5 ms and θ = 45⬚. Solution. A script to generate the animation can be written as clc,clf,clear g=9.81; theta0=45pi180; v0=5; t1=0;x=0;y=0; plotx,y,o,MarkerFaceColor,b,MarkerSize,8 axis[0 3 0 0.8] M1=getframe; dt=1128; for j = 2:1000 tj=tj-1+dt; x=v0costheta0tj; y=v0sintheta0tj-0.5gtj2; plotx,y,o,MarkerFaceColor,b,MarkerSize,8 axis[0 3 0 0.8] Mj=getframe; if y=0, break, end end pause movieM,1 Several features of this script bear mention. First, notice that we have fixed the ranges for the x and y axes. If this is not done, the axes will rescale and cause the animation to jump around. Second, we terminate the for loop when the projectile’s height y falls below zero. When the script is executed, two animations will be displayed we’ve placed a pause between them. The first corresponds to the sequential generation of the frames within the loop, and the second corresponds to the actual movie. Although we cannot show the results here, the trajectory for both cases will look like Fig. 3.2. You should enter and run the fore- going script in MATLAB to see the actual animation. 3.4 NESTING AND INDENTATION 71 FIGURE 3.2 Plot of a projectile’s trajectory.

3.4 NESTING AND INDENTATION

We need to understand that structures can be “nested” within each other. Nesting refers to placing structures within other structures. The following example illustrates the concept. EXAMPLE 3.7 Nesting Structures Problem Statement. The roots of a quadratic equation f x = ax 2 + bx + c can be determined with the quadratic formula x = −b ± √ b 2 − 4ac 2a Develop a function to implement this formula given values of the coeffcients. Solution. Top-down design provides a nice approach for designing an algorithm to com- pute the roots. This involves developing the general structure without details and then refining the algorithm. To start, we first recognize that depending on whether the parameter a is zero, we will either have “special” cases e.g., single roots or trivial values or conven- tional cases using the quadratic formula. This “big-picture” version can be programmed as function quadrootsa, b, c quadroots: roots of quadratic equation quadrootsa,b,c: real and complex roots of quadratic equation input: a = second-order coefficient 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.5 1 1.5 2 2.5 3 b = first-order coefficient c = zero-order coefficient output: r1 = real part of first root i1 = imaginary part of first root r2 = real part of second root i2 = imaginary part of second root if a == 0 special cases else quadratic formula end Next, we develop refined code to handle the “special” cases: special cases if b ~= 0 single root r1 = -c b else trivial solution dispTrivial solution. Try again end And we can develop refined code to handle the quadratic formula cases: quadratic formula d = b 2 - 4 a c; if d = 0 real roots r1 = -b + sqrtd 2 a r2 = -b - sqrtd 2 a else complex roots r1 = -b 2 a i1 = sqrtabsd 2 a r2 = r1 i2 = -i1 end We can then merely substitute these blocks back into the simple “big-picture” frame- work to give the final result: function quadrootsa, b, c quadroots: roots of quadratic equation quadrootsa,b,c: real and complex roots of quadratic equation input: a = second-order coefficient b = first-order coefficient c = zero-order coefficient output: r1 = real part of first root i1 = imaginary part of first root