我有一个二进制函数,大致看起来像
func=@(i,j)exp(-32*(i-j)^2);
网格如下
[X Y]=meshgrid(-10:.1:10);
奇怪的是,arrayfun
产生正确的结果,而bsxfun
将产生Inf
的条目。
an1=arrayfun(func,X,Y);
an2=bsxfun(func,X,Y);
>> max(max(abs(an1-an2)))
ans =
Inf
为什么?
编辑:现在问题解决了。我包含了一些基准数据,以便于讨论bsxfun
的效率
假设电网已经使用生产
[X Y]=meshgrid(Grid.partition);
func=@(i,j)exp(-32*(i-j).^2);
(我打算在不同的地方多次重复使用网格。)
计时嵌套命名函数方法。
>> 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.
定时匿名函数方法
>> 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.
可以看出,匿名函数方法比嵌套函数方法更快(不包括meshgrid
上的时间)。
如果包括meshgrid
上的时间,
>> 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.
很难说。。。
根据文档,当您使用任意函数func
调用bsxfun
时,
func
必须能够接受大小相同的两个列向量或一个列向量和一个标量作为输入,并返回大小与输入相同的列向量作为输出。
你的职能不能实现这一点。要更正,请将^
替换为.^
:
func=@(i,j)exp(-32*(i-j).^2);
无论如何,您可以使用bsxfun
的一个内置函数来代替您的函数(请参阅@Divakar的回答)。这样可以避免meshgrid
,代码可能会更快。
为了更有效地使用bsxfun
-,您可以这样做,而不是将Anonymous Functions
与bsxfun
一起使用
arr1 = -10:.1:10
an2 = exp(-32*bsxfun(@minus,arr1.',arr1).^2)
基准
试图在这里澄清OP的运行时注释,将bsxfun的匿名函数功能与内置的@minus
进行比较,并进行一些基准测试。
基准代码
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
运行时间
---------------------------- Using Anonymous Functions with bsxfun
Elapsed time is 0.241312 seconds.
---------------------------- Using bsxfuns built-in "@minus"
Elapsed time is 0.221555 seconds.