在学习关于如何构建下图公式所示近邻图时,有一个非常简答的调用函数:EuDist2
下面有两种代码实现效果一样。
第一种:简单直接
clear all
clc
%% method 1
fea = rand(100,200);
num_sample = size(fea,1);
class_num = size(fea,1)/10;
tic
Ww = zeros(num_sample,num_sample);
Wb = ones(num_sample,num_sample);
G = zeros(num_sample,num_sample);
for i = 1:class_num
gnd((i-1)*10+1:i*10) = i;
Ww((i-1)*10+1:i*10,(i-1)*10+1:i*10) = 1;
Wb((i-1)*10+1:i*10,(i-1)*10+1:i*10) = 0;
end
k = 5;
for i = 1:num_sample
for j = 1:num_sample
F(i,j) = norm(fea(i,:)-fea(j,:));
end
[aa,bb] = sort(F(i,:));
for kk = 1:k
if gnd(bb(kk)) == gnd(i)
G(i,bb(kk)) = 1;
end
end
end
Ww = Ww.*G;
Wb = Wb.*G;
t1 = toc
第二种,快速,还用到了sparse稀疏矩阵,哎呀,理解比较麻烦,不过速度确实比第一种快
clear all
clc
%% method 1
fea = rand(100,200);
num_sample = size(fea,1);
class_num = size(fea,1)/10;
tic
uniqueLabels = unique(gnd);
Ww1 = zeros(num_sample,num_sample);
Wb1 = ones(num_sample,num_sample);
for idx = 1 : class_num
classIdx = find(gnd == uniqueLabels(idx));
Ww1(classIdx,classIdx) = 1;
Wb1(classIdx,classIdx) = 0;
end
distMat = EuDist2(fea,[],0);
[dump sortedIDs] = sort(distMat,2); % 逐行升序排列
clear dump
kIDs = sortedIDs(:,1 : k);
G1 = sparse(repmat([1 : num_sample]',[k,1]),kIDs(:),ones(prod(size(kIDs)),1),num_sample,num_sample);
G1 = full(max(G1,G1'));
Ww1 = full(Ww .* G1);
Wb1 = full(Wb .* G1);
t2 = toc
function D = EuDist2(fea_a,fea_b,bSqrt)
%EUDIST2 Efficiently Compute the Euclidean Distance Matrix by Exploring the
%Matlab matrix operations.
%
% D = EuDist(fea_a,fea_b)
% fea_a: nSample_a * nFeature
% fea_b: nSample_b * nFeature
% D: nSample_a * nSample_a
% or nSample_a * nSample_b
%
% Examples:
%
% a = rand(500,10);
% b = rand(1000,10);
%
% A = EuDist2(a); % A: 500*500
% D = EuDist2(a,b); % D: 500*1000
%
% version 2.1 --November/2011
% version 2.0 --May/2009
% version 1.0 --November/2005
%
% Written by Deng Cai (dengcai AT gmail.com)
if ~exist('bSqrt','var')
bSqrt = 1;
end
if (~exist('fea_b','var')) || isempty(fea_b)
aa = sum(fea_a.*fea_a,2);
ab = fea_a*fea_a';
if issparse(aa)
aa = full(aa); % transmit the sparse matrix into the full matrix
end
D = bsxfun(@plus,aa,aa') - 2*ab;
D(D<0) = 0;
if bSqrt
D = sqrt(D);
end
D = max(D,D');
else
aa = sum(fea_a.*fea_a,2);
bb = sum(fea_b.*fea_b,2);
ab = fea_a*fea_b';
if issparse(aa)
aa = full(aa);
bb = full(bb);
end
D = bsxfun(@plus,aa,bb') - 2*ab;
D(D<0) = 0;
if bSqrt
D = sqrt(D);
end
end
运行时间比较:
t1 =
0.0221
t2 =
0.0189
应该矩阵越大的话,肯定加速更明显吧。