# For loops

# Iterate over columns of matrix

If the right-hand side of the assignment is a matrix, then in each iteration the variable is assigned subsequent columns of this matrix.

some_matrix = [1, 2, 3; 4, 5, 6]; % 2 by 3 matrix
for some_column = some_matrix
    display(some_column)
end

(The row vector version is a normal case of this, because in Matlab a row vector is just a matrix whose columns are size 1.)

The output would display

1
4
2
5
3
6

i.e. each column of the iterated matrix displayed, each column printed on each call of display.

# Notice: Weird same counter nested loops.

This is not something you will see in other programming environments. I came across it some years back and I couldn't understand why it was happening, but after working with MATLAB for some time I was able to figure it out. Look at the code snippet below:

for x = 1:10
    for x = 1:10
        fprintf('%d,', x);
    end
    fprintf('\n');
end

you wouldn't expect this to work properly but it does, producing the following output:

1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,

The reason is that, as with everything else in MATLAB, the x counter is also a matrix—a vector to be precise. As such, x is only a reference to an 'array' (a coherent, consecutive memory structure) which is appropriatelly referenced with every consequent loop (nested or not). The fact that the nested loop uses the same identifier makes no difference to how values from that array are referenced. The only problem is that within the nested loop the outer x is hidden by the nested (local) x and therefore cannot be referenced. However, the functionality of the nested loop structure remains intact.

# Iterate over elements of vector

The right-hand side of the assignment in a for loop can be any row vector. The left-hand side of the assignment can be any valid variable name. The for loop assigns a different element of this vector to the variable each run.

other_row_vector = [4, 3, 5, 1, 2];
for any_name = other_row_vector
    display(any_name)
end

The output would display

4
3
5
1
2

(The 1:n version is a normal case of this, because in Matlab 1:n is just syntax for constructing a row vector of [1, 2, ..., n].)

Hence, the two following blocks of code are identical:

A = [1 2 3 4 5];
for x = A
  disp(x);
end

and

for x = 1:5
  disp(x);
end

And the following are identical as well:

A = [1 3 5 7 9];
for x = A
  disp(x);
end

and

for x = 1:2:9
  disp(x);
end

Any row vector will do. They don't have to be numbers.

my_characters = 'abcde';
for my_char = my_characters
    disp(my_char)
end

will output

a
b
c
d
e

# Loop 1 to n

The simplest case is just preforming a task for a fixed known number of times. Say we want to display the numbers between 1 to n, we can write:

n = 5;
for k = 1:n
    display(k)
end

The loop will execute the inner statement(s), everything between the for and the end, for n times (5 in this example):

1
2
3
4
5

Here is another example:

n = 5;
for k = 1:n
    disp(n-k+1:-1:1) % DISP uses more "clean" way to print on the screen
end

this time we use both the n and k in the loop, to create a "nested" display:


5     4     3     2     1

 4     3     2     1

 3     2     1

 2     1

 1

# Loop over indexes

my_vector = [0, 2, 1, 3, 9];
for i = 1:numel(my_vector)
    my_vector(i) = my_vector(i) + 1;
end

Most simple things done with for loops can be done faster and easier by vectorized operations. For example, the above loop can be replaced by my_vector = my_vector + 1.

# Nested Loops

Loops can be nested, to preform iterated task within another iterated task. Consider the following loops:

ch = 'abc';
m = 3;
for c = ch
    for k = 1:m
        disp([c num2str(k)]) % NUM2STR converts the number stored in k to a charachter,
                             % so it can be concataneted with the letter in c
    end
end

we use 2 iterators to display all combinations of elements from abc and 1:m, which yields:

a1
a2
a3
b1
b2
b3
c1
c2
c3

We can also use nested loops to combine between tasks to be done each time, and tasks to be done once in a several iterations:

N = 10;
n = 3;
a1 = 0; % the first element in Fibonacci series
a2 = 1; % the secound element in Fibonacci series
for j = 1:N
    for k = 1:n
        an = a1 + a2; % compute the next element in Fibonacci series
        a1 = a2;      % save the previous element for the next iteration
        a2 = an;      % save ht new element for the next iteration
    end
    disp(an) % display every n'th element
end

Here we want to compute all the Fibonacci series, but to display only the nth element each time, so we get


  3
   13
   55
   233
   987
   4181
   17711
   75025
   317811
   1346269

Another thing we can do is to use the first (outer) iterator within the inner loop. Here is another example:

N = 12;
gap = [1 2 3 4 6];
for j = gap
    for k = 1:j:N
        fprintf('%d ',k) % FPRINTF prints the number k proceeding to the next the line
    end
    fprintf('\n')        % go to the next line
end

This time we use the nested loop to format the output, and brake the line only when a new gap (j) between the elements was introduced. We loop through the gap width in the outer loop and use it within the inner loop to iterate through the vector:

1 2 3 4 5 6 7 8 9 10 11 12 
1 3 5 7 9 11 
1 4 7 10 
1 5 9 
1 7 

# Remarks

# Iterate over column vector

A common source of bugs is trying to loop over the elements of a column vector. A column vector is treated like a matrix with one column. (There is actually no distinction in Matlab.) The for loop runs once with the loop variable set to the column.

% Prints once: [3, 1]
my_vector = [1; 2; 3];
for i = my_vector
    display(size(i))
end

# Altering the iteration variable

Altering the iteration variable changes its value for the current iteration, but has no impact on its value in subsequent iterations.

% Prints 1, 2, 3, 4, 5
for i = 1:5
    display(i)
    i = 5; % Fail at trying to terminate the loop
end

# Special case performance of a:b in right-hand side

The basic example treats 1:n as a normal instance of creating a row vector and then iterating over it. For performance reasons, Matlab actually treats any a:b or a:c:b specially by not creating the row vector entirely, but instead creating each element one at a time.

This can be detected by slightly altering the syntax.

% Loops forever
for i = 1:1e50
end

% Crashes immediately
for i = [1:1e50]
end