3

I store some functions in cell, e.g. f = {@sin, @cos, @(x)x+4}.

Is it possible to call all those functions at the same time (with the same input). I mean something more efficient than using a loop.

Stewie Griffin
  • 14,889
  • 11
  • 39
  • 70
user1666938
  • 73
  • 1
  • 9

3 Answers3

3

As constructed, the *fun family of functions exists for this purpose (e.g., cellfun is the pertinent one here). They are other questions on the use and performance of these functions.

However, if you construct f as a function that constructs a cell array as

f = @(x) {sin(x), cos(x), x+4};

then you can call the function more naturally: f([1,2,3]) for example. This method also avoids the need for the ('UniformOutput',false) option pair needed by cellfun for non-scalar argument.

You can also use regular double arrays, but then you need to be wary of input shape for concatenation purposes: @(x) [sin(x), cos(x), x+4] vs. @(x) [sin(x); cos(x); x+4].

Community
  • 1
  • 1
TroyHaskin
  • 8,361
  • 3
  • 22
  • 22
  • Nice =) +1! I provided some benchmarking results that show that your approach is indeed fast (and that loops aren't that slow)! =) – Stewie Griffin Dec 04 '14 at 12:58
3

I'm just posting these benchmarking results here, just to illustrate that loops not necessarily are slower than other approaches:

f = {@sin, @cos, @(x)x+4};
x = 1:100;
tic
for ii = 1:1000
    for jj = 1:numel(f)
        res{jj} = f{jj}(x);
    end
end
toc

tic
for ii = 1:1000
    res = cellfun(@(arg) arg(x),functions,'uni',0);
end
toc

Elapsed time is 0.042201 seconds.
Elapsed time is 0.179229 seconds.

Troy's answer is almost twice as fast as the loop approach:

tic
for ii = 1:1000
    res = f((1:100).');
end
toc
Elapsed time is 0.025378 seconds.
Stewie Griffin
  • 14,889
  • 11
  • 39
  • 70
0

This might do the trick

functions = {@(arg) sin(arg),@(arg) sqrt(arg)}
x = 5;
cellfun(@(arg) arg(x),functions)

hope this helps.

Adrien.

Adrien
  • 1,455
  • 9
  • 12