If programs consist solely of a fixed sequence of arithmetic operations, certain algorithms become quite difficult (if not impossible) to write (e.g. a program to sort numbers)
In particular, the idea of choice is hard to express. Try to write a function of one real argument x that returns 1 if x < 10, and 5 otherwise, using only arithmetic statements. (It's actually possible to do this, using some matlab built-ins, but it's pretty baroque, e.g.)
function out = gte10(x)
% returns 1 for x < 10, 5 otherwise
out = 1 + 4 * floor(0.5 * tanh(x - 10) + 1);
end
(Figure that one out!!)
Much easier to understand, is something of the form
function out = gte10_better(x)
% returns 1 for x < 10, 5 otherwise
if x < 10
out = 1;
else
out = 5;
end
end
Constructions such as the one involving
if
above are known as
selection statements, and provide a means of
writing programs that have different exection paths to be followed
depending on the circumstances.
In other words,
selection statements allow programs to make choices.
Most programming languages provide a couple of selection statements. (It turns out you don't need many.) Matlab provides four forms, (though the first three are basically variants of the same structure).
if
statement.
if else
statement.
if elseif ...
statement.
case
statement.
The idea of a selection statement is to test some condition and transfer control (instruction execution) to different program sections depending on the outcome.
At the machine level, and in some lower-level languages, such selection
has the semantic form
if (low-level-condition) goto (address)
and is thus
refered to as a conditional branch instruction
Goto-based code is difficult to follow, analyze, and debug so high-level languages typically start with forms of the if (or if-then) statement, and the if-else (or if-then-else) statement.
The basic form of the if statement in pseudo-matlab code is
if condition % is true
perform these actions
end
The form of the if-else statement in pseudo-matlab code is
if condition % is true
perform these actions
else % condition is not true
perform those actions
end
Note: A newline, or a semicolon, is generally needed after the condition, and before the else and end keywords. Occasionally some combination may work without this, but it should be standard policy.
Relational expressions are the "conditions" in the selection statements. They are also called boolean expressions, because they are expressions that evaluate to either true or false.
Relational expressions are composed of
Logical operations can be considered as boolean functions, all of which can be defined by truth tables:
4 of the 16 boolean functions of two variables: P Q | P&&Q P||Q ~P xor(P,Q) ------|----------------------- T T | T T F F T F | F T F T F T | F T T T F F | F F T F
>> 5 < 10
ans = 1
>> [1 2 11; 12 -1 13] > 10
ans = 0 0 1
1 0 1
In Matlab, there is a large collection of pre-defined "is-functions" that test the truth of particular conditions, or 'predicates'. For example:
In LISP the analogous function names end in p, as in zerop, minusp, numberp etc., leading to 'hacker-speak' like "Foodp?", to which you could answer "t".
Basically, just about any expression that can be evaluated can be used as a conditional, as Matlab takes any non-zero value to be TRUE. Any set of executable statements can be included in the "do if" and "else" blocks, including other if statements, although this can rapidly become confusing...
New reserved words: if, else, end,elseif.
Simple if statements.
if (x >= 5) && (x <= 7) % NOT x (>= 5 && <= 7)
disp('variable x is between 5 and 7')
end
if alarm_clock == RINGING && wake_state == SLEEPING
% Variables in all caps (e.g. RINGING)
% implement user-defined constants.
wake_state = AWAKE;
alarm_clock = SILENT;
mood = ANNOYED;
end
Simple two-choice if-else statements.
if number_of_enemy > 0
attack_closest_enemy(current_weapon);
else
disp('I''VE WON!!!!!');
perform_victory_dance();
end
if homework_done == TRUE
drink_beer();
watch_tv();
else
watch_tv();
drink_beer();
end
A single choice (two mutually exclusive conditions) can be handled with a simple if, if-else construction. Often, however, there is a set of three or more mutually exclusive conditions that we want to effect program execution. There are several ways of handling this.
The first is to use a nested if-else construction,
where we place if-else statements inside other if-else statements.
The following implements what is known as a "bounded, dead-zone"
controller for a velocity controlled robot joint.
distance_from_goal = abs(goal_position - cur_position);
if distance_from_goal < 0.5
% Close enough to goal, we don't move.
cur_velocity = 0;
else
if distance_from_goal < 10.0
% At intermediate distances, we set
% velocity proportional to distance from goal,
% here with time-constant 2 sec
cur_velocity = distance_from_goal / 2.0;
else % distance >= 10
% Far from the goal, set to max velocity
cur_velocity = 5.0;
end % of inner if
end
This construction can get confusing as it is easy to lose track of what end goes with what if and what else, especially if clear indenting policies are not followed.
For situations where the choices can be presented in a simple sequence, Matlab provides the somewhat clearer if-elseif-...-else construction, which avoids explicit nesting by imposing the particular nesting structure suggested by the syntax. Only one end is required, and typically all choices are indented to the same level.
Using this construction, the previous controller can be written as follows:
distance_from_goal = abs(goal_position - cur_position);
if distance_from_goal < 0.5
cur_velocity = 0;
elseif distance_from_goal < 10.0
cur_velocity = distance_from_goal / 2.0;
else % distance >= 10
cur_velocity = 5.0;
end
if-elseif-...-else is not the same as a sequence of if statements, one after the other. Above, note that if distance is < 0.5 it is also < 10.0, so two of the in-sequence if conditions would be met and the associated code for both executed. Above, only the first one is.
Also note that the final else clause can be very general and hard to write down ("every case not covered by previous conditions"). Above it is simple ( distance >=10) but note that we don't even use it. That's the power and glory of else!
Finally, for the common situation where we want to test whether a variable has one of several specific values, Matlab provides the switch statement. (Other languages have analogous constructions) The general form is as follows:
switch switch_expr
case case_expr
statement; ...; statement;
case {case_expr1, case_expr2, case_expr3,...}
statement; ...; statement;
otherwise
statement; ...; statement;
end
The switch_expr is evaluated, and compared against the various case_exprs in the cases. Only one case has its statements executed -- the first one with a matching case_expr. Specifically, if any expression in the case{ ...} list is true the case matches.
The following code implements a partial food classifier (for an apparently very carnivorous, and slightly taxonomically challenged critter). Dealing with natural language is not easy...
switch food_word
case {'beef', 'pork', 'venison', 'warthog'}
food_class = 'meat';
case {'salmon', 'shark', 'carp', 'whale', 'seal'}
food_class = 'fish';
case {'chicken', 'ostrich', 'flamingo', 'bat'}
food_class = 'bird';
case {'clam', 'snail', 'sea-urchin', 'boat'}
food_class = 'shellfish';
case {'lobster', 'shrimp', 'crab', 'diver'}
food_class = 'water-bug';
otherwise
food_class = 'unknown food';
end
Before GUIs, switch statements used to be common in "command loops" in which user types a command or its first letter, program does a chunk of code and loops back to ask for another command.
World's simplest GUI is given in Matlab by
returned_value = menu('menu title', 'opt1', ..., 'optN');
This displays a menu with the given title and buttons labled with opt1 -- optN, and returns an integer from 1 to N, depending on which button the user clicks on. Perfect input to a switch statement (though it would be more readable if the function returned strings).
Demo1 .