Looking for help understanding arrayfun
Show older comments
Hello all,
I'm trying to write a function, myfun, that acts element-wise on a vector, rand_x. I've tried using arrayfun() but the problem in doing so stems from the fact that if I try to supply arrayfun() with three vectors, it tries to act element-wise on each. As a workaround, I tried the following:
arrayfun(@(x) myfun(v_1, v_2, x), rand_x)
Where I defined an anonymous function within arrayfun that consumes only the x and calls myfun with this x and the vectors v_1 and v_2. My thinking was that by doing it this way, arrayfun would work element-wise only on the vector rand_x. It doesn't seem to be working however.
I was wondering if anyone might clue me in as to why?
Thanks!
EDIT: I should follow up. I just checked quickly to see what the values being passed to myfun were. Turns out, they're all correct, v_1 and v_2 are being passed in their entirety each time, while the elements of rand_x are being passed one by one. Seems something went wrong...
8 Comments
Guillaume
on 5 Feb 2016
As you have written, myfun will be called as follow:
myfun(v_1, v_2, x(1))
myfun(v_1, v_2, x(2))
...
myfun(v_1, v_2, x(end))
which seems to be exactly what you want. arrayfun is certainly not going to iterate over the elements of v_1 or v_2.
So in what way "It doesn't seem to be working" ?
Mark Soric's "Answer" moved here:
Ok, So I think I've actually realized that there was nothing wrong with the code - I was making arithmetic mistakes when checking its functionality. Whoops.
That being said, as a follow up - is arrayfun faster than looping through the vector? If so, can anyone explain how?
Thanks!
Usually a loop (with array preallocation) is faster than arrayfun or cellfun, but the functions can be neater and easier to understand. Note that array preallocation is critical for fast and efficient code!
Steven Lord
on 5 Feb 2016
One advantage of ARRAYFUN is that it can be used to loop through an array inside an anonymous function. You can't use a FOR loop inside an anonymous function (barring some rather tricky coding.)
Adam
on 5 Feb 2016
It is always a good idea to write a quick script/function to test speed of different implementations if you are interested in speed. This is usually very simple and helps enormously with the understanding.
You can take other people's word for it, and what Stephen says is true in my experience also, but for your own individual case it is always worth checking. It is good practice too for getting into comparing the speed of implementations in other contexts where the answer is less obvious - e.g. comparing bsxfun with repmat with various other ways of achieving the same thing - in that case there does not tend to be one answer as to which is faster.
Guillaume
on 5 Feb 2016
arrayfun has the overhead of a function call, which you may not have in an explicit for loop, so yes it can be slower. However, you should worry about code clarity before worrying about optimisations.
I personally prefer arrayfun to an explicit loop as it expresses more clearly the concept: "Apply this function to all elements of the array".
Mohammad Abouali
on 5 Feb 2016
Edited: Mohammad Abouali
on 5 Feb 2016
I personally prefer arrayfun or cellfun because practically if you can write your code in the form of arrayfun, that's signalling that this is highly parallelizable procedure and it yearns for some sort of parallelism. ( I thought MATHWORKS harnesses this characterisitc)
It turns out that currently arrayfun does not make use of any parallelism once it is running on CPU (on GPU is a different story); hence, considering the cost of function call and other stuff, it could be almost the same or slower than a explicit for-loop.
I don't recall which post, but a MATHWORKS employee posted that once calculating on CPU (again GPU is different) using arrayfun will not have any advantages (speed-wise) relative to explicit loops.
I still keep using arrayfun though. Because if in future release of MATLAB they decide to use some sort of parallelism within arrayfun implementation, then your code automatically would run faster. (but this can be debated of course)
Adam
on 5 Feb 2016
Yes, I also favour arrayfun as my first port of call and only if I have a speed problem do I come back and take a closer look at its performance with a view to actually changing it.
My colleague prefers for loops though, I'm yet to persuade her on the readability of arrayfun so I guess it is personal preference there.
Answers (0)
Categories
Find more on Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!