Reputation: 9875
I have a binary function roughly looks like
func=@(i,j)exp(-32*(i-j)^2);
with mesh as follows
[X Y]=meshgrid(-10:.1:10);
Strangely, arrayfun
produces the right result while bsxfun
would produce entries that are Inf
.
an1=arrayfun(func,X,Y);
an2=bsxfun(func,X,Y);
>> max(max(abs(an1-an2)))
ans =
Inf
Why?
EDIT: now that the question is resolved. I am including some benchmark data to facilitate the discussion on efficiency with bsxfun
Assuming the grid is already produced with
[X Y]=meshgrid(Grid.partition);
func=@(i,j)exp(-32*(i-j).^2);
(I intend to re-use the grid many times in various places.)
Timing the nested named functions approach.
>> tic;for i=1:1000;temp3=exp(-32*bsxfun(@minus,Grid.partition.',Grid.partition).^2);end;toc,clear temp
Elapsed time is 1.473543 seconds.
>> tic;for i=1:1000;temp3=exp(-32*bsxfun(@minus,Grid.partition.',Grid.partition).^2);end;toc,clear temp
Elapsed time is 1.497116 seconds.
>> tic;for i=1:1000;temp3=exp(-32*bsxfun(@minus,Grid.partition.',Grid.partition).^2);end;toc,clear temp
Elapsed time is 1.816970 seconds.
Timing the anonymous function approach
>> tic;for i=1:1000;temp=bsxfun(func,X,Y);end;toc,clear temp
Elapsed time is 1.134980 seconds.
>> tic;for i=1:1000;temp=bsxfun(func,X,Y);end;toc,clear temp
Elapsed time is 1.171421 seconds.
>> tic;for i=1:1000;temp=bsxfun(func,X,Y);end;toc,clear temp
Elapsed time is 1.180998 seconds.
One can see that the anonymous function approach is faster than the nested function approach (excluding the time on meshgrid
).
If the time on meshgrid
is included,
>> tic;[X Y]=meshgrid(Grid.partition);for i=1:1000;temp=bsxfun(func,X,Y);end;toc,clear X Y temp
Elapsed time is 1.965701 seconds.
>> tic;[X Y]=meshgrid(Grid.partition);for i=1:1000;temp=bsxfun(func,X,Y);end;toc,clear X Y temp
Elapsed time is 1.249637 seconds.
>> tic;[X Y]=meshgrid(Grid.partition);for i=1:1000;temp=bsxfun(func,X,Y);end;toc,clear X Y temp
Elapsed time is 1.208296 seconds.
Hard to say...
Upvotes: 4
Views: 224
Reputation: 221504
Instead of that way of using Anonymous Functions
with bsxfun
, you could do something like this for a more efficient usage of bsxfun
-
arr1 = -10:.1:10
an2 = exp(-32*bsxfun(@minus,arr1.',arr1).^2)
Trying to clarify on OP's runtime comments here to compare bsxfun's Anonymous Functions capabilities against the built-in @minus
with some benchmarking.
Benchmarking code
func=@(i,j)exp(-32.*(i-j).^2);
num_iter = 1000;
%// Warm up tic/toc.
for k = 1:100000
tic(); elapsed = toc();
end
disp('---------------------------- Using Anonymous Functions with bsxfun')
tic
for iter = 1:num_iter
[X Y]=meshgrid(-10:.1:10);
an2=bsxfun(func,X,Y);
end
toc, clear X Y an2
disp('---------------------------- Using bsxfuns built-in "@minus"')
tic
for iter = 1:num_iter
arr1 = -10:.1:10;
an2 = exp(-32*bsxfun(@minus,arr1',arr1).^2);
end
toc
Runtimes
---------------------------- Using Anonymous Functions with bsxfun
Elapsed time is 0.241312 seconds.
---------------------------- Using bsxfuns built-in "@minus"
Elapsed time is 0.221555 seconds.
Upvotes: 3
Reputation: 112659
Acording to the documentation, when you call bsxfun
with an arbitrary function func
,
func
must be able to accept as input either two column vectors of the same size, or one column vector and one scalar, and return as output a column vector of the same size as the input(s).
Your function does not fulfill that. To correct it, replace ^
by .^
:
func=@(i,j)exp(-32*(i-j).^2);
Anyway, instead of your function you could use one of bsxfun
's built-in functions (see @Divakar's answer). That way you avoid meshgrid
, and the code will probably be faster.
Upvotes: 3