Matlab bsxfun - 为什么 bsxfun 在这种情况下无法工作?

Matlab bsxfun - Why does bsxfun fail to work in this case?

我有一个二元函数大致看起来像

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.

很难说...

与使用 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.

根据 documentation,当您使用任意函数调用 bsxfunfunc

funcmust 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).

你的功能不满足。要更正它,请将 ^ 替换为 .^:

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

无论如何,您可以使用 bsxfun 的内置函数之一来代替您的函数(参见 )。这样你就可以避免 meshgrid,并且代码可能会更快。