Efficiently combine anonymous functions?
13 views (last 30 days)
Show older comments
Hi
I have an algorithm which has several anonymous functions passed as parameters which are then combined depending on flags. Since the resulting function is called many times, this slows down my program quite significantly. Is there a way to "explicitely combine" two anonymous functions?
Mini Example:
% Single anonymous function
full1 = @(x)sin(x) + 3*x;
% split anonymous function
g1 = @(x)sin(x);
g2 = @(x)3*x;
full2 = @(x)g1(x) + g2(x);
%%Speed Test
N = 100000;
disp('Explicit combination')
tic
for i = 1:N
full1(rand);
end
toc
disp('Multilevel combination')
tic
for i = 1:N
full2(rand);
end
toc
returns
Explicit combination
Elapsed time is 0.234414 seconds.
Multilevel combination
Elapsed time is 0.434422 seconds.
What I would like is to somehow have g1(x) + g2(x) be "combined explicitely" such that I end up with a version as "full1", and not "full2". Is there a way to do that?
Thanks!
0 Comments
Accepted Answer
Walter Roberson
on 6 Apr 2016
If you have the symbolic toolbox, then sometimes it works to call
syms x
full1 = matlabFunction( simplify(full2(x)), 'vars', x);
You can skip the simplify() for functions you do not expect will benefit from optimization such as finding common factors.
This will not always work as some functions cannot be called with symbolic parameters, or may have different results for symbolic parameters.
If you do not have the symbolic toolbox, then you can char() the individual anonymous functions, strip off the '@(x)', and combine remembering to put in parenthesis so you do not accidentally generate the wrong order of operations. Then put the @(x) back on and str2func()
0 Comments
More Answers (1)
Steven Lord
on 6 Apr 2016
Note that both g1 and g2 can accept either a scalar (as you're calling them) or a vector. In addition, your timing test is testing not only your anonymous function call but also N calls to the rand function. I've modified your script to focus on timing the anonymous function calls and included it below. You should notice that either of the last two options are much faster than the first two, and that their times are very similar.
% Single anonymous function
full1 = @(x)sin(x) + 3*x;
% split anonymous function
g1 = @(x)sin(x);
g2 = @(x)3*x;
full2 = @(x)g1(x) + g2(x);
%%Speed Test
N = 100000;
R = rand(1, N);
disp('Explicit combination')
tic
for k = 1:N
full1(R(k));
end
toc
disp('Multilevel combination')
tic
for k = 1:N
full2(R(k));
end
toc
disp('Vectorized full1')
tic
full1(R);
toc
disp('Vectorized full2')
tic
full2(R);
toc
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!