Matlab利用子函数EuDist2函数,构建近邻图,EuDist2函数为构建欧几里得距离图
在学习关于如何构建下图公式所示近邻图时,有一个非常简答的调用函数: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
应该矩阵越大的话,肯定加速更明显吧。