Matlab bsxfun - 为什么bsxfun在这种情况下不能工作?

时间:2015-02-20 10:15:17

标签: performance matlab vectorization bsxfun

我的二进制函数大概看起来像

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.

很难说......

2 个答案:

答案 0 :(得分:3)

而不是Anonymous Functionsbsxfun一起使用的方式,您可以执行类似的操作,以更有效地使用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.

答案 1 :(得分:3)

根据documentation,当您使用任意函数bsxfun致电func时,

  

func必须能够接受两个相同大小的列向量,或一个列向量和一个标量作为输入,并返回与输入相同大小的列向量作为输出。

您的功能无法实现。要更正此问题,请将^替换为.^

func=@(i,j)exp(-32*(i-j).^2);

无论如何,您可以使用bsxfun的内置函数之一代替您的函数(请参阅@Divakar's answer)。这样就可以避免meshgrid,代码可能会更快。