Posts Tagged ‘cellfun’

Fun, fun fun! (array, cell and struct)

3rd October, 2010 Leave a comment

The other day I was asked what the point of MATLAB’s cellfun function was. “Surely I can do what it does with a for loop?”, they said. The quick answer is, “yes you can use a for loop, but it’s still very useful”. This post tells you why.

The three functions arrayfun, cellfun and structfun are for solving split-apply-combine problems. That is, you split your data up into chunks, you apply some function to each chunk, then you combine the results together. The difference between them is the type of input variable that they accept: arrayfun takes arrays, and so forth. (It should be noted that having just three functions for this is very restrained. R has half a dozen functions in the apply family, plus aggregate and by, not to mention the plyr package.)

A simple example is to try and get the number of characters in each string of a cell array. We start by defining some data (in this case, the first four metasyntactic variables).

msv = {'foo' 'bar' 'baz' 'quux'};

Now compare using a for loop

n = zeros(size(msv));
for i = 1:numel(msv)
   n(i) = numel(msv{i});

with cellfun

n = cellfun(@numel, msv)      %The @ symbol denotes a handle to numel 

Aside from the obvious benefit that we’ve hugely cut down on the amount of typing, I think the second method expresses the intent of the code much more clearly. The use of cellfun means that you must have a split-apply-combine problem, whereas for loops are more general concepts, so you need to study the code more closely to understand what is happening.

There is one little niggle with cellfun that I hope The MathWorks will correct one day. If the result of applying the function to each chunk can have a different size, then the result needs to be stored in a cell array rather than a vector. In this case, you need to explicitly set 'UniformOutput' to false. Ideally, cellfun would be able to automatically know when the output doesn’t have uniform size and act appropriately. Keep your fingers crossed that this gets sorted eventually.

Tags: ,