2

How to apply a function that returns non scalar output to arrays using arrayfun?

For example - How to vectorize the following code?

array = magic(5);
A = cell(size(array));
for i=1:5
    for j=1:5
      A{i,j} = 1:array(i,j);
    end
end

This naive attempt to vectorize does not work, because the output is not a scalar

array = magic(5);
result = arrayfun(@(x)(1:x),array);
0

2 Answers 2

6

There are 2 methods to achieve it:

It is possible to set 'UniformOutput' to false. Then, the result is a cell array.

   result = arrayfun(@(x)(1:x),array,'UniformOutput',false);

But there is a nice trick that I have found today, the function itself can return a cell. This removes the need of typing 'UniformOutput',false each and every time.

    result = arrayfun(@(x){1:x},array)

What is really interesting here that I don't have to type @(X)({1:x}) but I can define it only by using curly bracers @(X){1:x}

Edit(1): As @Jonas correctly points out, there is no wonder that the regular bracers () are not needed, as they are optional. For example, @(x) x+1 is a valid syntax.

Edit(2): There is a small difference between using the curly bracers method or the UniformOutput,false. When the input array is empty, their behavior is different.

Sign up to request clarification or add additional context in comments.

1 Comment

You never need the parentheses around the function. But it helps a lot with visibility. Also, arrayfun doesn't really vectorize the code, it just hides the loop (and will allow Matlab to multi-thread, if it's worth the time). Note that the cell "trick" is very useful with accumarray which doesn't have the uniformOutput option.
1

In addition to the answer of Andrey I want to note that it seems, that the first approach, using the option UniformOutput, is slightly faster:

>> tic; cellfun(@(x) {single(x)}, data); toc;
Elapsed time is 0.031817 seconds.

>> tic; cellfun(@(x) single(x), data,'UniformOutput',0); toc;
Elapsed time is 0.025526 seconds.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.