1
votes

Consider the following function, which takes a gray image (2D matrix) as input:

function r = fun1(img)
r = sum(sum(img));

I'm thinking of using arrayfun to process a series of images(3d matrix), thus eliminating the need for a for loop:

arrayfun(@fun1, imgStack);

But arrayfun tries to treat every element of imgStack as an input to fun1, the result of the previous operation also being a 3D matrix. How can I let arrayfun know that I want to repeat fun1 only on the 3rd dimension of imgStack?

Another question, does arrayfun invoke fun1 in parallel?

2
you might want to simplify your original function to r=sum(img(:)) - Adrien

2 Answers

5
votes

In this case, you don't need arrayfun to perform your calculation, you can simply do this:

imgStack = rand( 10, 10, 4 ); % 4 10x10 images
r = sum( sum( imgStack, 1 ), 2 ); % sum along both dimensions 1 and 2

In general, lots of MATLAB operations will operate on a whole array at once, that's the usual way of avoiding loops.

MATLAB's normal "arrayfun" is not parallel. However, for GPUArrays (with Parallel Computing Toolbox), there is a parallel version of arrayfun.

0
votes

On your first question: You might try accumarray for this. One suggestion

function ds = applyfun_onfirstdim(arr, h_fun)

dimvec = size(arr);
indexarr = repmat( (1:dimvec(1))', [1, dimvec(2:end)] );

ds = accumarray(indexarr(:), arr(:), [], h_fun);

This creates an auxiliary index-array of the same dimensions as the input "arr". Every slice you want to apply h_fun to gets the same index-number. In this example it is the first.