recipes : programming : Writing better code : Avoiding nested loops

Problem

You have to iterate through a multi-dimensional array or structure and want to avoid nested loops.

Solution

Say you have a 3-dimensional matrix (e.g. MAT=randn([3,4,5])) and you want to apply a particular operation to each element in the matrix. For some reason you can't use vectorised code and a loop is your only option. However, you don't need to use three nested loops, there is another possibility.

%This is rather ugly but it works
for ii=1:size(MAT,1)
  for jj=1:size(MAT,2)
    for kk=1:size(MAT,3)
       doSomething(MAT(ii,jj,kk))
    end
  end
end


% This is more elegant
for ii=1:prod(size(MAT))
    doSomething(MAT(ii))
end
Discussion

It should be pretty obvious why the first example with nested loops works. If not, try making MAT and execute size(MAT) and size(MAT,2). See what's happening? for jj=1:size(MAT,2) iterates over the second dimension of MAT, which has a length of 4 in this case. So ii, jj, and kk index the first, second, and third dimensions respectively. MATLAB calls these values subscripts.

The second, more compact, example simply uses a different way of indexing an array. Rather than three subscript values it uses a single index value. The relationship between indexes and subscripts is described in the MATLAB help. Briefly, each "slot" in the matrix can be identified using three "coordinates" (the subscripts) or a single unique value (the index). The number of unique values is equal to prod(size(MAT)), which is why this appears in the for loop. Here, prod(size(MAT)) is 3*4*5=60.

Note that this is rather a toy example. In most cases if you want to perform the same operation on every element of a matrix then there is likely to be a faster, vectorised, way of achieving what you want. i.e. MATLAB's built in functions probably will allow you to work on your matrix without using loops at all. You are more likely to use the above approach if you're working with a multi-dimensional structure or cell array.