Matlab利用自定義的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

應該矩陣越大的話,肯定加速更明顯吧。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章