Arrayfun on an array of objects and multiple parameter function

12 views (last 30 days)
Hello,
I decided to replace some for loops of my code with the function arrayfun.
It should make the syntax more compact and speed-up the code.
I encountered 2 problems :
• Is it possible to call complex functions which have more than one parameter with the arrayfun function, the input parameters of my function are objects.
• I think it is not possible to use arrayfun on an array of objects. Is it possible to make arrayfun work even though it is an array of objects?
Thank your for your help

Accepted Answer

Guillaume
Guillaume on 6 Jan 2015
In term of performance arrayfun is probably slightly slower than a loop due to the overhead of the function call. So, don't change your code to arrayfun for performance reasons, it's probably not going to help.
It is however, in my opinion, a lot more descriptive of the purpose of the code than a loop. It clearly says "do that one same thing to all the elements of the array" without you having to worry to the bounds of the loop, the allocation of the output, the shape of the array, etc. So, if you change your code, do it for that reason.
arrayfun works on any kind of array (even cell arrays, struct arrays and object arrays). The function that you pass to arrayfun just need to know how to deal with indididual elements of the array.
It is possible to call complex functions which have more than one parameter. The simplest way is to create an anonymous function that does the job of passing the extra parameters. For example, let's say you have a function MyFunc whose arguments are an object, a scalar and a string. If you wanted to call MyFunc for each object in the object array arrObjects with the scalar value 5 and string 'up', you'd do:
arrayfun(@(o) MyFunc(o, 5, 'up'), arrObjects)
The anonymous function:
@(o) MyFunc(o, 5, 'up')
just acts as a stub to call MyFunc with the correct arguments.
Note that MyFunc could even be a member function of the objects.
  2 Comments
Kelly Kearney
Kelly Kearney on 6 Jan 2015
To clarify, in 2014b, you have to use set the 'UniformOutput' flag to false if the output array from the function consists of handle graphics objects. I don't really understand why that limitation is in place (I guess it just makes preallocation easier for arrayfun).
>> h = plot(rand(10));
>> h2 = arrayfun(@(x) x, h);
Error using arrayfun
matlab.graphics.chart.primitive.Line output type is not supported. Set
'UniformOutput' to false.
>> h2 = arrayfun(@(x) x, h, 'uni', 0)
h2 =
[1x1 Line]
[1x1 Line]
[1x1 Line]
[1x1 Line]
[1x1 Line]
[1x1 Line]
[1x1 Line]
[1x1 Line]
[1x1 Line]
[1x1 Line]
>> cat(1, h2{:})
ans =
10x1 Line array:
Line
Line
Line
Line
Line
Line
Line
Line
Line
Line
Guillaume
Guillaume on 6 Jan 2015
The documentation of arrayfun is pretty clear on this (under Output Arguments): if UniformOutput is true (the default), the individual outputs from function func must be scalar values (numeric, logical, character, or structure) or cell arrays. Object output is not supported with UniformOutput true.
This makes sense. In all likelyhood, behind the scene, arrayfun predeclare the output array, which is not guaranteed to succeed for classes (for example, the class hasn't got a default constructor).

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements 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!