6 Branching & Looping I

The programs that we have presented up to this point have been completely linear – a fixed sequence of steps with no ability to change behavior based on conditions. Further, they sometimes contained duplicate code; to perform the same operation multiple times on different values, we repeated the instructions or ran the program multiple times.

This chapter presents structures to give your program intelligence, i.e. the ability to take different actions depending on conditions, and to repeat operations on a set of values without duplicating the code.

6.1 Conditional Execution – the if Statement

The simplest decision that a program can make is whether to execute a block of code or not, depending on conditions. For example, a banking program may deduct a payment from a customer’s account, but only if the account balance is at least as great as the payment amount. A MATLAB implementation of this operation is:

%Deduct payment from balance if account has sufficient funds

if payment_amount <= balance

balance = balance - payment_amount;

fprintf ('Your new balance is %.2f\n', balance);

end  

For this code to execute properly, the variables payment_amount and balance must have been assigned values earlier in the program.

An if statement has 3 required elements:

  1. The keyword if, followed by a conditional statement. The conditional typically contains one or more relational operators (>, <, ==, etc.). Often there will be equivalent ways of writing the same condition. In this example, the condition could just as well have been written as balance >= payment_amount
  2. A block of code to be executed if and only if the condition is true. While the example above is almost trivially short, this block can be arbitrarily complex – it can even contain other if statements or loops, as will be discussed later in this chapter.
  3. The keyword end. This indicates to MATLAB where the block of code that is conditionally executed ends. Any code that comes after the end statement is executed whether the condition is true or not.

Notice that the lines of code between the if and end have been indented. This is a standard practice to improve readability, but it is not required in MATLAB. (There are some languages, such as Python, which require indenting.)

 

Checkpoint 6.1 – 6.2: if Statement

 

 

6.2 Branching – the if...else Structure

The if statement described in the previous section executes or does not execute a single block of code, depending on a condition. Often, a program must choose which of two blocks of code to execute, depending on a condition. To make the banking program from the previous section more complete, a second block of code could be added to apply an overdraft penalty and display a suitable message if the account balance is less than the payment amount. One MATLAB implementation is:

%Assume that variables payment_amount, balance, and penalty have been defined previously

%Deduct payment from balance if account has sufficient funds

if payment_amount <= balance

balance = balance - payment_amount;

fprintf ('Your new balance is %.2f\n', balance);

else   %this block will be executed if the condition is false

balance = balance - penalty;

fprintf ('Insufficient funds. An overdaft penalty of %.2f has been applied.\n', balance);

fprintf ('Your new balance is %.2f\n', balance);

end  

In an if...else structure, one or the other of two blocks of code is executed. If the condition is true, the first block is executed; otherwise the second one is.

Some important syntax notes:

  1. There is only a single end statement after the else block. Do NOT put an end before the else statement.
  2. There should be no condition after else. The else block will be executed if and only if the condition in the if statement is false. Any condition that appears with the else is extraneous.

Checkpoint 6.3: if…else

 

6.3 Multiple Branches – the if...elseif...else Structure

In some cases a program must switch among 3 or more blocks of code (branches). One way to do this in MATLAB is with the if...elseif...else structure. The banking program can be expanded further so that it only deducts the overdraft penalty if the account has enough funds to cover the penalty, so that the balance does not become negative. (In reality, most banks are not this considerate – they will allow your balance to go negative!)

 

%Deduct payment from balance if account has sufficient funds

if payment_amount <= balance

balance = balance - payment_amount;

fprintf ('Your new balance is %.2f\n', balance);

elseif penalty <= balance   %if the balance cannot cover the payment, but it CAN cover the penalty 

balance = balance - penalty;

fprintf ('Insufficient funds. An overdaft penalty of %.2f has been applied.\n', penalty);

fprintf ('Your new balance is %.2f\n', balance);

else   %this will execute if neither of the two conditions are true 

balance = 0;

fprintf('Insufficient funds to cover the payment or the overdraft penalty.\n')

fprintf('Your new balance is 0.\n');

end  

Some important points about the if...elseif...else structure:

  1. Exactly one of the blocks of code will be executed. If the if condition is true, the first block of code is executed, and the remaining blocks are skipped, even if the elseif condition is also true.
  2. There can be multiple elseif clauses, each of which will have a conditional statement. If more than one of the conditions are true, the first one that is true is the one that matters. That is, when a true condition is encountered, the corresponding block of code is executed, and the subsequent blocks (up to the end statement) are skipped.

The following example illustrates the use of multiple elseif clauses to apply multiple conditions. The user is prompted to enter his height in inches and weight in pounds; the user’s body mass index is calculated, and depending on the range in which it falls, a weight classification is displayed.

When this example was run, the user entered values of 70 for height and 200 for weight, resulting in a BMI value of 28.7. Since the first condition (BMI > 30) is false, the second condition (BMI > 25) is checked; it is true, so the message ‘Your weight classification is overweight’ is displayed, and the remaining blocks are skipped.

A common misconception is that the elseif clauses should have compound conditions, e.g. elseif BMI > 25 && BMI <= 30.  The second condition is not necessary, since the elseif clause is not evaluated unless it has already been determined that BMI <= 30.

Lecture Video 6.1 – if Statements

 

6.4 Multiple Branches – the switch statement

There is an alternative to the if...elseif...else structure called the switch statement. The switch is used when the variable that is the basis for branching takes a finite number of discrete values. As a rule of thumb, if all of the conditional statements in an if...elseif...else structure use the == operator, it can be replaced by a switch.

Here is an example of the same functionality implemented two ways – with an if...elseif...else and with a switch. The variables a, b, and c contain the coefficients of a quadratic, and the program calculates the real roots. If the discriminant (b2 – 4ac) is less than 0, there are no real roots; if it is equal to 0, there is a double root; if it is greater than 0 there are two, distinct real roots. The if...elseif...else implementation is as follows:

 

%Calculating the real roots of a quadratic

%The values of a, b, and c have been assigned previously 

discriminant = b^2 - 4*a*c;

if discriminant < 0

fprintf ('There are no real roots.');

elseif discriminant == 0

root = -b / (2*a);

fprintf ('There is a double root with the value %.2f\n', root);

else

root1 = (-b + sqrt(discriminant)) / (2*a);

root2 = (-b - sqrt(discriminant)) / (2*a);

fprintf ('There are two roots with the values %.2f and %.2f\n', root1, root2);

end  

 

To use a switch statement, there must be a variable that takes discrete values. That can be accomplished in this case with the sign() function, which returns -1, 0, or +1, depending on the sign of its argument. The equivalent program is as follows:

 

%Calculating the real roots of a quadratic

%The values of a, b, and c have been assigned previously 

discriminant = b^2 - 4*a*c;

sign_of_D = sign(discriminant);  %this will be -1, 0, or 1, for discriminant negative, zero, or positive 

switch sign_of_D

case -1

fprintf ('There are no real roots.');

case 0

root = -b / (2*a);

fprintf ('There is a double root with the value %.2f\n', root);

case 1

root1 = (-b + sqrt(discriminant)) / (2*a);

root2 = (-b - sqrt(discriminant)) / (2*a);

fprintf ('There are two roots with the values %.2f and %.2f\n', root1, root2);

otherwise %this shouldn't happen; allows for errors such as a, b, or c not being defined correctly 

fprintf('Something went wrong in the calculations\n');

end  

 

The required elements of a switch statement are:

  1. The keyword switch followed by a variable name or expression
  2. One or more case statements, each with a value or list of values in { }
  3. OPTIONAL: the keyword otherwise, which functions similarly to else. The block of code following otherwise will be executed if the switch variable does not match any of the cases
  4. The keyword end

The most common mistake with the switch structure is to include a conditional expression in the case statement, for example:

%Don't include a conditional in the %case statement like this: 

switch

   case x == 1  %WRONG!

Some other key points:

  1. since the switch variable has to take discrete values, it is usually an integer, character or string. It should never be a floating-point number.
  2. If there is more than one value of the variable that corresponds to a given case, the values are listed in { }, e.g.   case {0, 1, 2}. (This cannot be written as a range, like {0 : 2})

The following example, a program to convert pressure units, shows a switch based on the value of a character array variable. It allows for some variation in the spelling and capitalization of units.

 

Lecture Video 6.2 – switch Statement

 

Checkpoint 6.4: if…elseif…else

6.5 Repetition – the for Loop

Computer programs typically involve much repetition. If a calculation only has to be done once, writing a program to do it might take longer than doing the calculation on a hand-held calculator. Performing the calculation hundreds or thousands of times is a different matter. A basic structure of programming that avoids unnecessary duplication of code or running a program multiple times is a loop. In MATLAB, as in many languages, there are two types of loops: the for or counted loop, and the while or conditional loop. At a fundamental level, the two types of loop are really equivalent – anything that can be done with a for can be done with a while and vice versa. In most circumstances one or the other will be a more natural solution to a given problem.

The for loop is typically used when the number of repetitions (or “iterations” in technical terminology) is known in advance, either because the operation has to be performed a fixed number of times, or because it is going to be applied to a fixed data array. If the number of iterations is not known in advance, because it depends on some condition being reached, a while loop is more appropriate.

The presentation below illustrates the operation of a for loop in the simplest application –  repeating an operation a fixed number of times. It is important to understand that fundamentally, a for loop in MATLAB iterates over an array. That is, it repeats the block of code (everything between the for and end statements) for each element of a provided array.

Presentation 6.1: Operation of a for Loop

 

The syntax of the for loop requires the following elements:

  1. the keyword for
  2. (on the same line as for) an assignment statement of the form variable_name = array. 
  3. a block of code to be executed on each iteration of the loop
  4. the keyword end

Important notes:

  1. In some applications of the for loop, the variable may serve no purpose other than to count the number of times that the loop has been executed, but it is required nonetheless.
  2. The array can be specified by any valid method, not just with the : operator, and it does not have to be a monotonic sequence. All of the following are valid:

for k = 1: 10

for j = 2: 2: 20

for name = ["Jim", "Joe", "Frank"]

for x = X   %where X is an array that was previously defined

for angle = linspace(-pi, pi, 100)   %where X is an array that was previously defined

 

As with the if statement, indentation of the code between the for and end statements is recommended for readability, but not required.

Lecture Videos 6.3-6.4 – for Loop

 

Checkpoint 6.5: for loop

6.6 Conditional Repetition – the while Loop

A while loop executes a block of code as long as some condition is true. It is typically used in cases where the number of times that the loop will be executed is not known (or cannot easily be calculated) in advance. Consider a more elaborate version of the banking program, which pays a list of bills in order of importance until the account runs out of money. The first version is rather incomplete – astute readers will notice that it has some flaws – but it is sufficient to introduce the basic structure.

%list of bills to pay in order of importance 

%values must have been assigned to the individual variables (mortgage, car, etc.) previously 

bills = [mortgage, car, electricity, water, gas, insurance, cable];

 

j = 1;  % a counter to indicate which bill will be paid next - start with the first 

while bills(j) <= balance  %keep paying bills as long account balance is enough to cover the next bill

  balance = balance - bills(j);  %deduct that amount from the account balance

   j = j + 1;  %go to the next bill

end 

 

The while loop has several essential elements:

  1. the keyword while followed by a conditional statement
  2. initialization of variables used in the conditional; in this example, the array bills and the variables j and balance must have been initialized before the while loop, or an “undefined variable” error will occur
  3. a block of code to be repeated. The code must take some action that could cause the condition to become false; otherwise the loop will never stop – what is known as an “infinite loop.” In this example, the balance is reduced on each iteration of the loop, so that eventually the balance may become less than the next bill. (But it may not, which is one of the flaws mentioned above.)
  4. the keyword end

Checkpoint 6.6: while loop

 

The last  implementation of the banking program has a fatal flaw – it assumes that the initial balance is not enough to pay all of the bills, so that the loop will stop when the remaining balance is less than the next bill to be paid. Think about what will happen if that assumption is wrong, and then we will discuss how to fix it.

Checkpoint 6.7: while loop

 

To fix this flaw in the banking program, a compound condition can be used to implement the following logic: “keep going as long there is another bill to pay and the remaining balance is sufficient to pay the next bill.” Think about how to add that second condition to the while statement, then try the next checkpoint question.

Lecture Video 6.5 – while Loop

 

Checkpoint 6.8: while loop with compound condition

 

6.7 Simple Interactive Programs; Combining Looping and Branching

A common use of the while loop is to control execution of the program based on input from the user. Consider an implementation of the “guess the number” game, in which the computer generates a random number between 1 and 100, and the user is asked to guess. On each iteration of the loop, the user is prompted for a new guess and given feedback about whether his guess is too high or too low. The loop terminates when the user guesses correctly. (A better version would impose a limit on the number of guesses, but we leave that as an exercise.)

 

 

This example illustrates how looping and branching can work together to build complex functionality. In the next chapter we will explore this in more detail, but for now let’s look at the banking program one last time and fix its remaining shortcoming.

It might have occurred to you that the program may not be paying as many bills as it can. The problem is that it stops if the next bill is greater than the remaining balance, without checking if there might be a lower-priority bill that could be paid. For example, suppose the values are:

balance = 2000;

mortgage = 1400;

car = 400;

electricity = 250;

water = 45;

gas = 75;

etc.

Our program will stop after paying the mortgage and car payments, since the remaining balance (200) would not be sufficient to pay the electricity bill. However the water and gas bills could be paid – the program gave up too soon.

There are several solutions to this problem; one is shown here, where the while loop is replaced by a for loop with an if statement. This version of the program looks at every bill, but only pays each one if the remaining balance is sufficient.

%list of bills to pay in order of importance 

%values must have been assigned to the individual variables (mortgage, car, etc.) previously 

bills = [mortgage, car, electricity, water, gas, insurance, cable];

for j = 1:length(bills)   %loop over all bills

    %if the balance is sufficient to pay the next bill, pay it

    %otherwise, just go to the next bill

    if balance > bills (j)

      balance = balance - bills(j);  %deduct that amount from the account balance

    end  %this is the end of the if statement

end  %This is the end of the for loop

 

Take note that in a for loop initialization and incrementing of the loop counter ( j in this example) happens automatically – it is not necessary to do these steps explicitly, as with a while loop.

Checkpoint 6.9: Looping with Branching

 

Iterative Calculations

A common application of the while loop is iterative calculations – that is, performing successive refinements to a calculation until the desired precision is reached. A simple example is summing a power series. Terms are added to the sum until the contribution from the next term is small enough to be ignored. The following example gives a function to calculate the Taylor series for [latex]e^x[/latex]:

[latex]e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!}[/latex]

This function uses a tolerance of 10-6; that is, terms smaller than this are regarded as negligible.

function y = e_to_the_x(x)
y = 0;  %initial value of the sum is 0, since no terms have been added
n=0;   %start with the 0th term
next_term = x^n/factorial(n);  %calculate the first term 
           %continue adding terms until the next term is negligible 
while abs(next_term) > 1e-6  
   y = y + next_term;             %add the nth term to the sum
   n = n+1;                       %increment the value of n (go to the next term)
     next_term = x^n/factorial(n);  %calculate the next term
end
end 

For an example of applying an iterative method to a mechanics problem, watch this video. (Note: in previous semesters, the problem being discussed was assigned as an application assignment. You may or may not have been assigned this problem.)

 

Lecture Video 6.6: Iterative Calculation

(If the video does not load, try logging into mediasite.osu.edu in a separate tab, then reload the page. Or you can use this direct link.)

6.8 Equivalence of for and while loops; the break Statement

For a given for loop it is fairly straightforward to write a while loop to perform the same function. Here are some examples of equivalent for and while loops.

%simple counted loop

for k = 1:10

do_something(k);

end

 

k = 1:

while k <= 10

do_something(k);

k = k + 1;

end

 

%iterating over a data array without indexing

X = [3, 11, 23, 37, 53]

for x = X

disp (isprime(x))

end

 

X = [3, 11, 23, 37, 53]

j = 1;

while j <= length(X)

disp (isprime (X(j))

j = j + 1;

end

 

%iterating over a data array with indexing

for k = 1:length(data_array)

perform_some_operation(data_array(k));

end

 

k =1;

while k <= length(data_array)

perform_some_operation(data_array(k));

k = k + 1;

end

 

It should be apparent that a for loop is typically simpler than the equivalent while loop. When the number of iterations is known in advance, the for loop is preferred.

It is not as obvious that any while loop can be replaced by an equivalent for loop, but it is true, although it may be necessary to use an additional instruction, break. The break statement aborts the execution of a loop, as shown in the next example, which revisits the bill paying program. It might have occurred to you that if the account balance reaches zero, there is no point in looking at the remaining bills. In fact, if the balance becomes less than the smallest remaining bill, continuing is pointless. This version aborts the loop using a break statement if that condition occurs.

%list of bills to pay in order of importance 

%values must have been assigned to the individual variables (mortgage, car, etc.) %previously 

bills = [mortgage, car, electricity, water, gas, insurance, cable];

for j = 1:length(bills)   %loop over all bills

    %if the balance is sufficient to pay the next bill, pay it

    %otherwise, just go to the next bill

    if balance > bills (j)

      balance = balance - bills(j);  %deduct that amount from the account balance

    elseif balance < min(bills(j:end)) 

        %if remaining balance is too small to pay any of the remaining bills, quit 

        break;

    end  %this is the end of the if statement 

end  %This is the end of the for loop

 

Of course, the same functionality could be achieved with a while loop as follows:

%list of bills to pay in order of importance

%values must have been assigned to the individual variables (mortgage, car, etc.) previously

bills = [mortgage, car, electricity, water, gas, insurance, cable];

j = 1;

%loop over all bills as long as balance is sufficient to pay

%at least one more bill

while j <= length(bills) && balance >= bills(j:end) 

    %if the balance is sufficient to pay the next bill, pay it

%otherwise, just go to the next bill

    if balance > bills (j)

      balance = balance - bills(j);  %deduct that amount from the account balance

    end  %this is the end of the if statement 

    j = j + 1;

end  %This is the end of the loop

Which of these two approaches to use is a matter of style. One school of thought is that the break statement should be avoided whenever possible, since it tends to break up the flow of the program. On the other hand, a break is often a convenient way to accommodate a special case without having to completely restructure the code.

Lecture Video 6.7 – Loops vs. Vectorized Code

 

6.9 Mathworks Resources

For more details about MATLAB capabilities for branching and looping, see these Mathworks web pages:

Conditional Statements

Loop Control Statements

 

Find an error? Have a suggestion for improvement? Please submit this survey.

License

MATLAB Programming for Engineering Applications Copyright © by James Toney and jayakumar5. All Rights Reserved.

Share This Book