0

Suppose we have an 3-D array (tensor) and we want to apply in each slice a function, e.g., myFun = @(x)mean(x). Is there any way to do this without for loop using build-in functions (possibly withbsxfun, or arrayfun, or accumarray)?

For loop example:

inputA = rand(10,5,20);
for sl = 1:size(A,3)
   inputB = myFun(inputA(:,:,sl));  
end

Thank you.

EDIT: inputB = arrayfun(@(iterSlice) myFun(inputA(:,:,iterSlice), 1:size(inputA,3))

PS: I would like to mention, that the handler function applied is more complicated in each slice, mean was an example included in the handler function.

Darkmoor
  • 862
  • 11
  • 29
  • Same issue [like in this question](http://stackoverflow.com/questions/35940500/vectorize-accelerate-looping-through-a-struct-of-struct-in-matlab), you have to rewrite `myFun` to accept 3d input arguments. If this is not possible, a for loop is the fastest choice. – Daniel Mar 11 '16 at 13:23
  • I do not want to do this in `z`-direction but per slice. So why should I accept a `3d` input? – Darkmoor Mar 11 '16 at 13:25
  • 1
    You already chose the fastest way to iterate. The only way to further improve the performance would be to get rid of the individual function calls. – Daniel Mar 11 '16 at 13:28
  • `basxfun` accepts only built-ins as function arguments, `arrayfun` is slower than the `for` statement in the latest MATLAB versions, `accumarray` doesn't really make sense, at least not to me. So I'd say: take Daniel's advice. –  Mar 11 '16 at 13:36
  • `arrayfun` is said to be slow. If you are looking for performance, you can use `parfor`. – ssinad Mar 11 '16 at 19:35

1 Answers1

0

A for loop is already the best possibility to iterate. The only way to further improve the performance is to get rid of the iteration and have a single function call of myFun which processes all data in a vectorized way. For your example function that very simple:

myFun=@(x)permute(mean(x,1),[3,2,1])

Now it accepts 3d inputs and in the rows you find the results of the previous iterative code. You have to modify your function, there is no generic wrapper on top which can do this for you.

Regarding your edit: arrayfun is known to be slow

Community
  • 1
  • 1
Daniel
  • 36,610
  • 3
  • 36
  • 69
  • Thanks for answering, the function I applied is more complicated in each slice, `mean` was an example included in a handler function . So, any changes helpful. – Darkmoor Mar 11 '16 at 13:43
  • As I mentioned, there is no generic wrapper which can be put on top of your existing function. You have to modify your function to vectorize it. – Daniel Mar 11 '16 at 13:47