使用BSXFUN - MATLAB矢量化MANDIST(曼哈顿距离)

时间:2015-03-22 02:46:55

标签: matlab matrix lambda vectorization bsxfun

我正在尝试编写一个函数来计算所有行向量的一对一曼哈顿距离。有一个名为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

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

[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

现在我想一次性添加它们,是否可能?

2 个答案:

答案 0 :(得分:2)

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);

答案 1 :(得分:1)

是的,bsxfunmandist再次快 -

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.4f\n', 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.4f\n', toctime/maxrun);

和结果 -

>> mdtest
elapsed time: 1.1753
elapsed time: 0.7733