使用 BSXFUN - MATLAB 对 MANDIST(曼哈顿距离)进行矢量化
Vectorizing MANDIST (Manhattan distance) with 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
的源代码声明如下:
The Manhattan distance between two vectors P(:,i) and P(:,j) is
calculated as out(i,j) = sum(abs(data(:,i) - data(:,j))).
要创建 mandist
的矢量化版本,您可以使用 permute
to create singleton dimensions
and then let 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.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
我正在尝试编写一个函数来计算所有行向量的一对一曼哈顿距离,有一个名为 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
的源代码声明如下:
The Manhattan distance between two vectors P(:,i) and P(:,j) is calculated as out(i,j) = sum(abs(data(:,i) - data(:,j))).
要创建 mandist
的矢量化版本,您可以使用 permute
to create singleton dimensions
and then let 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.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