Week 2 Coding Lecture 2: Conditional statements

When you are programming, you will often encounter situations where you want your code to do one thing in some contexts and another thing in other contexts. We already saw one example in the last lecture: We wanted to be able to stop our loop if fib(n) was too large. For a simpler example, you might want to calculate the absolute value of a number. The absolute value is defined as
In English, this means that the absolute value of x is the same value if x is not negative, but you have to flip the sign if x is negative. This is such a common problem that MATLAB has a special syntax called an "if statement" set up to handle it. In its simplest form, an if statement looks like this:
if condition
% Code to run if the condition is true
end
The words if and end are not variables - they are reserved words that tell MATLAB that this is an if statement. The word "condition" should be a number or (much more commonly) some code that evaluates to a number. Any (arbitrarilly complicated) code can go in between the if and end. When MATLAB encounters an if statement it does one of two things. If the condition is 0, then MATLAB skips everything in the if statement and goes directly to the line after end. If the condition is not zero, then MATLAB runs the code in between if and end and then continues as usual. Here are a couple examples:
x = 3;
disp("The code before the if statement is always run")
The code before the if statement is always run
if x
disp("The code in the if statement is run because x is not zero");
end
The code in the if statement is run because x is not zero
disp("The code after the if statement is always run")
The code after the if statement is always run
or
y = 0;
disp("The code before the if statement is always run")
The code before the if statement is always run
if y
disp("The code in the if statement is not run because y is zero")
end
disp("The code after the if statement is always run")
The code after the if statement is always run
There are a few operators that are used extremely often in conditions:
x = 3;
y = 3;
z = 2;
x == y
ans = logical
1
x == z
ans = logical
0
x = 3; y = 4;
x > y
ans = logical
0
y > x
ans = logical
1
x > x
ans = logical
0
x = 3; y = 4;
x < y
ans = logical
1
y < x
ans = logical
0
x < x
ans = logical
0
x = 3; y = 4;
x >= y
ans = logical
0
y >= x
ans = logical
1
x >= x
ans = logical
1
x = 3; y = 4;
x <= y
ans = logical
1
y <= x
ans = logical
0
x <= x
ans = logical
1

Absolute value

We are now in a position to calculate absolute value in code.
x = 10;
if x >= 0
absolute_value_of_x = x;
end
if x < 0
absolute_value_of_x = -x;
end
absolute_value_of_x
absolute_value_of_x = 10
We chose a positive value for x in above example, but it works just as well with a negative value.
x = -5;
if x >= 0
absolute_value_of_x = x;
end
if x < 0
absolute_value_of_x = -x;
end
absolute_value_of_x
absolute_value_of_x = 5
Notice that we had two mutually exclusive conditions (either x is non-negative or it is negative) and we wanted to run different code in either case. Our solution is perfectly fine, but this comes up so often that MATLAB has a shortcut: The else statement. In general, else statements work like this:
if condition
% code block 1
else
% code block 2
end
When MATLAB encounters a block like this, it first checks the value of condition. If condition is not zero, then Matlab executes code block 1, then jumps to the next line after end. If condition is zero, then Matlab executes code block 2, then jumps to the next line after end. We can therefore clean up our absolute value code like this:
x = -12;
if x >= 0
absolute_value_of_x = x;
else
absolute_value_of_x = -x;
end
There is actually one more level of generality for if statements. If we have more than two cases, but we only ever want to run one block of code, we can use the keyword elseif. The general case looks like this:
if condition_1
% code block 1
elseif condition_2
% code block 2
....
elseif condition_n
% code block n
else
% code block n+1
end
When MATLAB encounters a block like this, it checks each of the conditions in turn. The first time it encounters a condition that is non-zero, it executes the corresponding code block and then jumps to the code after end. If all of the conditions evaluate to zero, then MATLAB executes the last code block (after else) and then goes on to the code after end. You can have as many elseif conditions as you want after an if.

Combining conditions

There are two very common ways to combine conditions: The and operator && and the or operator ||. The and operator evaluates to 1 if both the left and right condition are nonzero and evaluates to 0 otherwise. For instance,
0 && 0
ans = logical
0
1 && 0
ans = logical
0
0 && 5
ans = logical
0
2 && 3
ans = logical
1
The or operator evaluates to 1 if either the left or right condition is nonzero and evaluates to 0 otherwise. For example,
0 || 0
ans = logical
0
1 || 0
ans = logical
1
0 || 5
ans = logical
1
2 || 3
ans = logical
1
If you look in the workspace, you can see that these answers are a different type than we are used to. Before today, all the variables we made were "doubles", which essentially means a decimal number, but these answers are called "logicals". Logicals are only allowed to be 1 or 0, and we typically think of logical 1 as representing "true" and logical 0 as representing "false". In fact, MATLAB has two builtin variables for logical 1 and logical 0 called true and false.
true
ans = logical
1
false
ans = logical
0
That said, there is no requirement that you use logical variables in your if statements. Any number that is not zero counts as true and zero counts as false, even if the numbers are doubles.

Fibonacci numbers

We are now in a position to solve the last problem from the previous lecture. Recall that we were trying to calculate all of the Fibonacci numbers less than 1,000,000. We already have code to calculate the first N Fibonacci numbers, where N is a fixed number:
N = 20;
fib = zeros(N, 1);
fib(1) = 1;
fib(2) = 1;
for k = 3:N
fib(k) = fib(k - 1) + fib(k - 2);
end
We now want to adjust this code so that it stops once we find a number larger than 1,000,000. To solve this, we really just have to add a statement to our loop sayng "if fib(k) is at least 1,000,000 then stop the loop". Translating this into an if statement is pretty straightforward. The only other thing we need to know is that the keyword break tells MATLAB to stop whatever loop it is running. We can now write
N = 20;
fib = zeros(N, 1);
fib(1) = 1;
fib(2) = 1;
for k = 3:N
fib(k) = fib(k - 1) + fib(k - 2);
if fib(k) >= 1000000
break
end
end
This code is almost done, but there are a couple of small issues. Most obviously, if you look at the vector fib you will discover that we don't actually have the right answer:
fib
fib = 20×1
1 1 2 3 5 8 13 21 34 55
The issue is that there are two reasons our loop might stop. One reason is if fib(k) is ever over 1,000,000. The other is that k gets to 20 and the loop ends as usual. In our case, we just went through all 20 steps of our for loop without ever finding a large enough Fibonacci number. We can mostly solve this by making N larger. For example, we already saw in the last lecture that the 200th Fibonacci number is larger than 1,000,000, so if we set N to 200 we know that we will calculate enough values.
N = 200;
fib = zeros(N, 1);
fib(1) = 1;
fib(2) = 1;
for k = 3:N
fib(k) = fib(k - 1) + fib(k - 2);
if fib(k) >= 1000000
break
end
end
If you look at the vector fib now, you will see a different issue. Now the vector has all of the Fibonacci numbers we wanted, but it also has more than 100 trailing zeros. This is because there are actually only 30 Fibonacci numbers less than 1,000,000, not 200. We could of course just set N to 30, but that would destroy the point of using the if statement. A better solution is just to cut off the extra zeros once we are done. How do we know how many entries of our vector to keep? The trick to notice is that k is still defined after the loop ends, so the final value of k tells you how many steps were completed. In our case it is easy to check that k is 31 at the end of this code block, which means that we filled in 31 non-zero Fibonacci numbers. We actually don't want the last one either, because fib(31) is over 1,000,000, so we only want to keep the first 30 entries of fib. We can therefore use the solution:
N = 200;
fib = zeros(N, 1);
fib(1) = 1;
fib(2) = 1;
for k = 3:N
fib(k) = fib(k - 1) + fib(k - 2);
if fib(k) >= 1000000
break
end
end
fib = fib(1:(k-1));
You should take some time to study the above code - it is a very common method and we will use the same structure repeatedly in this class. The general idea is to initialize storage (in this case the fib vector) for our results, then use a loop to calculate each value in turn, then use a combination of if and break to stop our loop once we have all the answers we need.
There is still one small nuisance with this code: We need to make sure that we make N large enough. Our solution was essentially just to guess and check until we found a sufficiently large value of N, but MATLAB has another coding construct for this purpose.

While loops

Up until now, we have been using for loops, but MATLAB actually has another type of loop called the while loop. The general syntax for a while loop is
while condition
% Code to repeat
end
When MATLAB encounters a while loop, it checks to see if the condition is non-zero. If it is, then MATLAB runs the code between the while and end. MATLAB then returns to the top of the while loop and starts over. If the condition is ever zero, then MATLAB will instead skip to the next line of code after the end.
You should think of a while loop as a repeating if statement. MATLAB repeats the if statement over and over until the condition becomes false.
The big advantage of a while loop is that you don't have to know the maximum number of steps beforehand. The disadvantage is that MATLAB does not automatically track a loop variable for you. For example, in the Fibonacci numbers problem we will have to track k ourselves.
We can rewrite our previous solution using a while loop as follows:
fib = zeros(200, 1);
fib(1) = 1;
fib(2) = 1;
k = 2;
while fib(k) < 1000000
k = k + 1;
fib(k) = fib(k - 1) + fib(k - 2);
end
fib = fib(1:(k - 1));
Notice that we still have to guess a size for fib when we initialize it. This code would still work if we ended up needing more than 200 values because MATLAB would automatically resize fib for us, but we would prefer to make fib large enough at the beginning because such resizing tends to be fairly slow.

Infinite loops

There is one very important point that you have to keep in mind when working with while loops. It is possible that the condition in your while loop never becomes false. If this happens, then the loop will just repeat forever and your code will never stop running. As a silly example, this code prints the number 1 forever:
while true
disp(1)
end
We call such an example an infinite loop. If you ever accidentally create one, you can force MATLAB to stop with the hot key "Ctrl+C" (or "Command+." for mac).