利用BSXFUN-MATLAB对曼哈顿距离进行矢量化



我正试图写一个函数来计算所有行向量的一对一曼哈顿距离,有一个内置的函数mandist(),属于ANN工具箱——

data = rand(4,2);
disp(data)
mandist(data')
>> mdtest
    0.7996    0.8884
    0.5735    0.4954
    0.9732    0.3516
    0.6341    0.7142
ans =
         0    0.6191    0.7104    0.3397
    0.6191         0    0.5435    0.2793
    0.7104    0.5435         0    0.7018
    0.3397    0.2793    0.7018         0

我想知道是否可以用bsxfun优化mandist()bsxfun版本如下所示--

[r,~] = size(rand);
abs(bsxfun(@minus, ...
    repmat(permute(data, [1 3 2]),1,r), ...
    repmat(permute(data, [3 1 2]),r,1)))

上面的语句可以生成所有计算abs(a - b)-的矩阵

ans(:,:,1) =
         0    0.2261    0.1736    0.1656
    0.2261         0    0.3997    0.0605
    0.1736    0.3997         0    0.3392
    0.1656    0.0605    0.3392         0
ans(:,:,2) =
         0    0.3930    0.5368    0.1742
    0.3930         0    0.1438    0.2188
    0.5368    0.1438         0    0.3626
    0.1742    0.2188    0.3626         0

现在我想一次把它们全部加起来,有可能吗?

mandist.m的源代码声明如下:

两个向量p(:,i)和p(::,j)之间的曼哈顿距离为计算为out(i,j)=sum(abs(data(:,i)-data(:,j))。

要创建mandist的矢量化版本,您可以使用permute创建singleton dimensions,然后让bsxfun在它们身上施展魔咒,以获得最终输出-

out = sum(abs(bsxfun(@minus,permute(data,[1 3 2]),permute(data,[3 1 2]))),3);

是的,bsxfun再次比mandist快--

clear all 
data = rand(500,500);
[~,col] = size(data);
maxrun = 20 ;
%warm up
for k = 1:50000
    tic(); elapsed = toc();
end
toctime = 0 ;
for i = 1:maxrun
    tic
    mandist(data');
    toctime = toctime + toc ;
end
fprintf('elapsed time: %0.4fn', toctime/maxrun);
toctime = 0 ;
for i = 1:maxrun
    tic
    sum(abs(bsxfun(@minus,permute(data,[1 3 2]),...
                          permute(data,[3 1 2]))),3);
    toctime = toctime + toc ;
end
fprintf('elapsed time: %0.4fn', toctime/maxrun);

结果——

>> mdtest
elapsed time: 1.1753
elapsed time: 0.7733

相关内容

  • 没有找到相关文章

最新更新