Matlab計算矩陣間距離


  夜深人靜時分,宿舍就我自己,只有蚊子陪伴着我,我慢慢碼下這段文字............

  感覺知識結構不完善:上學期看論文,發現類間離散度矩陣和類內離散度矩陣,然后百度,找不到,現在學模式識別,見了,發現是數學公司,不過老師不講........

一.問題來源

  今天有個意想不到的收貨,下午講課的時候遇到一個人主動加我,來自南京信息工程大學的某X(處於隱私保護,未經李某X同意,筆者不敢公開其信息),下面是他的話:很久沒去博客園了。。。。現在只有matlab版本的一些hash算法;我現在主要就是在研究基於hash的圖像檢索,如果你有需要的話,可以給你一些資料。

  我們倆交流了很多.......從實驗室,到研究課題,到LOL,筆者深深為他淵博的學識和不俗的談吐所打動,恩恩,遇到志同道合的人挺不容易的........最重要的是感謝他的開源精神,給我了很多我急需的資料和代碼。在此,也感謝博客園提供的這個平台,讓我們在這茫茫人海中有了相知相識的機會,哈哈,這其實就是局部敏感哈希的思想——在茫茫人海中發現相似的你啊,愛你們.............

  該篇博客來自於某X分享的代碼,我產生了寫此篇博文的靈感。

二.問題解析

  實現矩陣間任意行之間的歐式距離。通俗地說如下:兩個點的距離知道吧,矩陣是類似的原理,求X1和X2矩陣的距離,假設得到的結果矩陣為C,那么C的下標ij表示的是X1中的第i行和X2中的第j行的距離。

2.1 方法1

if nargin == 2
    P1 = double(P1);
    P2 = double(P2);
    
    X1=repmat(sum(P1.^2,2),[1 size(P2,1)]);%sum(x,2):橫向相加,得到列向量;sum(x),默認為豎向相加。
    X2=repmat(sum(P2.^2,2),[1 size(P1,1)]);
    R=P1*P2';
    D=real(sqrt(X1+X2'-2*R));
else
    P1 = double(P1);

    % each vector is one row
    X1=repmat(sum(P1.^2,2),[1 size(P1,1)]);
    R=P1*P1';
    D=X1+X1'-2*R;
    D = real(sqrt(D));
end

  加入p1:100*256,p2:5900*256,那么x1:100*5900,x25900*100,R:5900*100。

  repmat表示復制和平鋪,sum(P1.^2,2)就是每個元素先平方,然后每行求和,就變成一個列向量;求矩陣X1和X2的距離:類似於(A-B)^2 = A^2+B^2-2AB然后開根號;matlab里面調用repmat(a,m,n)命令:三個參數的含義:a:要被復制的矩陣或者向量,m復制成多少行,n復制成多少列。就是把a復制成m行,n列。[1 size(P2,1)]:這個就是將sum(P1.^2,2)得到的列向量復制一行,size(p2,1)列。

  不計算距離如何知道樣本是不是緊鄰呀,這個就是歐式距離度量緊鄰與否。緊鄰與否可以通過語意度量,也可以通過距離度量,歐式距就是其中一種。

2.2 方法2

  寫到上面,我想起了王老師寫的k-means(鏈接),那時候第一次接觸repmat函數。

%repmat 即 Replicate Matrix ,復制和平鋪矩陣,是 MATLAB 里面的一個函數。
%B = repmat(A,m,n)將矩陣 A 復制 m×n 塊,即把 A 作為 B 的元素,B 由 m×n 個 A 平鋪而成。B 的維數是 [size(A,1)*m, size(A,2)*n] 。
%點乘方a.^b,矩陣a中每個元素按b中對應元素乘方或者b是常數
%sum(x,2)表示矩陣x的橫向相加,求每行的和,結果是列向量。 而缺省的sum(x)就是豎向相加,求每列的和,結果是行向量。
 dist = sum((repmat(x(i,:),k,1)-nc).^2,2); 

2.3 方法3

  直接飲用小伙伴們的問題。

  比如說,A陣是20*10,B陣是30*10的,A陣的20個行向量和B陣中的30個行向量計算歐式距,得到20*30的歐式距離矩陣C這個應該怎么寫?
  我每次寫出來的C陣每行都是相同的 簡直郁悶死了,請教大牛~

clear all
%你可以定義自己的A,B矩陣,下面的矩陣僅作為例子
A=zeros(20,10);
B=ones(30,10);
%Dist距離矩陣
Dist=zeros(20,30);
for i=1:20
    for j=1:30
        Dist(i,j)=norm(A(i,:)-B(j,:));
    end
end

2.4 方法4

Dist = sqrt(A.^2*ones(size(B'))+ones(size(A))*(B').^2-2*A*B')

  這個和方法1,異曲同工。而且,據傳,此方法較快。

2.5 方法五

 

for i = 1:size(X,1)
    Distance(i,:) = diag((repmat(X(i,:),n,1)-X)*(repmat(X(i,:),n,1)-X)');
end

 

三.結束語

  看了這么久的LSH,苦於沒有合適的代碼,很痛苦,給國內的某些大牛寫信,從來沒收到過回信,給國外的大牛寫信基本當天就會回信..........這算是國內外學者的精神風貌不同吧........正式這個原因,我慢慢想着摒棄開源,恩恩,感謝某X,讓我有了繼續開源的精神動力,人生路上就是需要這類人的陪伴.....從長遠來源,筆者認為開源更有意義,也更能體現自己的價值.......每次我說我不懂,別人說我謙虛,其實我是真的不懂.....知道個大概,對面其實是一種誤導.......不過有時候也挺佩服自己能堅持下來...........筆者的目標是——互聯網行業布道者,歡迎志同道合的人和我聯系............晚安~~~

  參考文獻:IloveMatlab社區,百度知道,某X語錄。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM