Polyglot
Languages MATLAB loops
MATLAB § loops

Loops

MATLAB has two loop forms: the for loop, which iterates over the columns of a matrix, and the while loop, which iterates while a condition is true. Both are conventional in shape — keyword-introduced, end-terminated, with break and continue for early exit. The MATLAB-specific corners are the for-iterates-over-columns rule and the strong advice to prefer vectorisation to either loop form whenever possible.

The for loop

for k = 1:5
    disp(k)
end
% 1
% 2
% 3
% 4
% 5

The loop variable k takes the value of each column of the right-hand side in turn. The right-hand side 1:5 is a 1×5 row vector, so each column is a scalar, and k takes the values 1, 2, 3, 4, 5. This is the standard form and the one almost everyone writes.

The fact that for iterates over columns rather than elements is a small surprise that matters when the RHS is a multi-row matrix:

A = [1 4; 2 5; 3 6];        % 3×2
for v = A
    disp(v)                  % a 3×1 column vector each iteration
end
% [1; 2; 3]
% [4; 5; 6]

The first iteration binds v to the first column; the second iteration binds it to the second. The mechanism is occasionally useful — iterating over the columns of a matrix is a frequent need — and is occasionally a trap when the programmer expected element-wise iteration.

To iterate explicitly over elements, the conventional form is for k = 1:numel(A) with A(k):

A = [1 4; 2 5; 3 6];
for k = 1:numel(A)
    disp(A(k))               % column-major linear indexing: 1, 2, 3, 4, 5, 6
end

Iteration over cells

Iterating over a cell array binds the loop variable to a 1×1 cell containing the contents; the brace {1} extracts the contents:

names = {"Ada", "Grace", "Donald"};
for n = names
    disp(n{1})              % the contents of the cell
end

The form is the closest MATLAB offers to a for-each loop and is widely used.

Iteration over structs

A struct array does not have a direct iteration form; the conventional pattern is to iterate over an index:

arr = struct('x', {1, 2, 3});
for k = 1:numel(arr)
    disp(arr(k).x)
end

For functional-style application, arrayfun(@(s) s.x, arr) returns a numeric array of all the .x fields without an explicit loop.

while

A while loop runs while its condition evaluates to true:

x = 1;
while x < 1e6
    x = x * 2;
end
disp(x)                     % 1048576

The condition follows the same truthiness rule as if (the entire condition must be a non-empty array of all non-zero entries). The pattern is conventional in iterative numerical methods — Newton’s method, fixed-point iteration, root-finding — where the loop runs to convergence rather than for a known number of steps.

break and continue

break exits the innermost loop immediately; continue skips the rest of the current iteration and proceeds to the next.

for k = 1:10
    if k == 5
        break               % exit the for entirely
    end
    if mod(k, 2) == 0
        continue            % skip even k
    end
    disp(k)                 % 1, 3
end

There is no break N to exit several nested loops at once; the standard escape is a flag variable or a refactor into a function with return.

return

return exits the enclosing function immediately. In a script, return exits the script. It is sometimes used inside a loop as a coarser version of break:

function out = findFirstPositive(x)
    for k = 1:numel(x)
        if x(k) > 0
            out = x(k);
            return
        end
    end
    out = [];
end

parfor

The Parallel Computing Toolbox provides parfor — a for loop whose iterations are dispatched to worker processes. Iterations must be independent: the body cannot rely on the order of execution and cannot share state across iterations except through the special reduction and broadcast variable forms.

parfor k = 1:1000
    out(k) = process(data(k));
end

parfor requires a parallel pool (created with parpool) and works only on the loop forms that the parser can analyse for safety; the constraints are documented at mathworks.com/help/parallel-computing/parfor.html and are discussed on the Parallelism page.

Prefer vectorisation

The most-emphasised piece of MATLAB advice is: avoid loops when possible. The vectorised form is almost always clearer and is usually faster, even with the JIT. Examples of the transformation:

% Imperative loop
y = zeros(size(x));
for k = 1:numel(x)
    y(k) = sin(x(k))^2 + cos(x(k))^2;
end

% Vectorised
y = sin(x).^2 + cos(x).^2;          % = 1 in exact arithmetic
% Imperative loop summing a series
s = 0;
for k = 1:n
    s = s + 1 / k^2;
end

% Vectorised
s = sum(1 ./ (1:n).^2);
% Imperative loop computing a dot product
d = 0;
for k = 1:numel(u)
    d = d + u(k) * v(k);
end

% Vectorised
d = dot(u, v);                       % or u(:).' * v(:)

The remaining legitimate uses of loops:

  • Iterative algorithms whose state evolves: Newton’s method, EM, gradient descent.
  • I/O loops: reading lines of a file, processing user input, awaiting events.
  • Recursive structures: tree walks, graph traversals.
  • Code clarity: a small loop is sometimes clearer than a fused vectorised expression.

For the inner loops of an algorithm — and especially loops over the elements of an array — vectorisation is the right default.

Preallocation

If a loop must be written, preallocate the output. Growing an array by indexed assignment in a loop is O(n²) in the array length:

% Bad: O(n^2) total work because of repeated growth.
y = [];
for k = 1:1e6
    y(k) = k^2;
end

% Good: O(n) — the storage is allocated once.
y = zeros(1, 1e6);
for k = 1:1e6
    y(k) = k^2;
end

The MATLAB editor highlights the bad form with the warning “The variable ‘y’ appears to change size on every loop iteration”; the recommendation is to heed it.