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