2016-01-19 60 views
0

我的代碼工作正常,但速度很慢,我需要多次運行,所以效率很低。我認爲有一個更有效的計算方法。如何在MATLAB中更快地創建矢量和矩陣的點積?

的代碼是這個等式的一個實現: MMD

其中k(X,Y)是兩個矢量 xi和yj的點積是i行中,兩個矩陣A的j和B,分別。

我還想指出,每個矩陣中的行數是以千計。

這裏是我的代碼

m=size(A,1); 
Kxx=0; 
for i=1:m 
    x=A(i,:); 
    X=A(i+1:end,:); 
    Kxx=Kxx+2*sum(dot(ones(m-i,1)*x,X,2)); 
end 
Kxx=Kxx/(m*(m-1)); 

n=size(B,1); 
Kyy=0; 
for j=1:n 
    y=B(j,:); 
    YY=B(j+1:end,:); 
    Kyy=Kyy+2*sum(dot(ones(n-j,1)*y,YY,2)); 
end 
Kyy=Kyy/(n*(n-1)); 

Kxy=0; 
for i=1:m 
    x=A(i,:); 
    for j=1:n 
     y=B(j,:); 
     Kxy=Kxy+dot(x,y); 
    end 
end 
Kxy=Kxy*2/(m*n); 

Dxy=Kxx+Kyy-Kxy; 
+3

加快,你需要消除所有的循環。你能描述每個循環在英語中的作用嗎? – John

+0

我認爲最後一個塊可以寫成'Kxy = sum(sum(A * B。'));',前面的塊比較難。如果有人不抓住機會,當我有時間考慮這些情況時,我會添加一個答案。 –

+0

這段代碼應該做什麼? – rayryeng

回答

5

你的編輯,使我們的JUB 容易。這裏是你只是有一個完全量化的解決方案做:

C=A*A'; %' 
Kxx=sum(sum(C-diag(diag(C))))/m/(m-1); 
C=B*B'; %' 
Kyy=sum(sum(C-diag(diag(C))))/n/(n-1); 
Kxy=2*mean(reshape(A*B.',[],1)); %' 

Dxy=Kxx+Kyy-Kxy; 

感謝@hiandbaii對指出的dot複雜的向量相當於涉及的共軛轉置,而不是轉。


原來,循環版本 歷史 感情上的原因:

我不知道是否第兩個循環可以在沒有巨大的內存開銷來量化。因此,雖然我想出解決辦法,這裏是其中的前兩個環路有點簡化版本,第三環是由矢量操作代替:

%dummy input data 
A=rand(5); 
B=rand(5); 

m=size(A,1); 
Kxx=0; 
for l=1:m 
    x=A(l,:); 
    X=A(l+1:end,:); 
    Kxx=Kxx+2*sum(X*x.');   %' 
end 
Kxx=Kxx/(m*(m-1)); 

n=size(B,1); 
Kyy=0; 
for l=1:n 
    y=B(l,:); 
    YY=B(l+1:end,:); 
    Kyy=Kyy+2*sum(YY*y.');   %' 
end 
Kyy=Kyy/(n*(n-1)); 

Kxy=2*mean(reshape(A*B.',[],1)); %' 

Dxy=Kxx+Kyy-Kxy; 
+0

這是一個很臭的小評論。 – Adriaan

+0

評論你的原始loopy版本。如果A具有複雜的元素,它不會產生與OP原始代碼相同的結果。需要使用共軛轉置。 – hiandbaii

+0

@hiandbaii你確定嗎?我在OP的代碼中看不到一個單一的結合,那麼它怎麼需要呢? Ooooh,由於'dot'? –