2010-12-12 370 views
12

由於D很大,我沒有足夠的內存來簡單地創建對角線D-D矩陣。我不斷收到'內存不足'錯誤。MATLAB中非常大的矩陣的高效乘法

不是在第一次乘法中執行M×D×D操作,而是執行M×D操作,但我的代碼仍然需要很長時間才能運行。

任何人都可以找到更有效的方法來執行乘法A'*B*A?這是我到目前爲止已經嘗試:

D=20000 
M=25 

A = floor(rand(D,M)*10); 
B = floor(rand(1,D)*10); 

for i=1:D 
    for j=1:M 
     result(i,j) = A(i,j) * B(1,j); 
    end 
end  

manual = result * A'; 
auto = A*diag(B)*A'; 
isequal(manual,auto) 

alt text

+0

我很困惑。矩陣B應該是D-by-D還是M-by-M?你的形象說前者,但你的代碼暗示了後者。 – gnovice 2010-12-12 04:12:15

+0

斑點,現在糾正 – matcheek 2010-12-12 04:21:21

+0

另外,你是否試圖計算A'* B * A,這會給你一個M-M的結果? – gnovice 2010-12-12 04:47:38

回答

12

應該解決您的問題的一個選項是使用sparse matrices。下面是一個例子:

D = 20000; 
M = 25; 
A = floor(rand(D,M).*10); %# A D-by-M matrix 
diagB = rand(1,D).*10;  %# Main diagonal of B 
B = sparse(1:D,1:D,diagB); %# A sparse D-by-D diagonal matrix 
result = (A.'*B)*A;   %'# An M-by-M result 

另一種選擇是複製沿主對角線的B的d元件使用函數REPMAT創建一個M-d矩陣,然後使用element-wise multiplicationA.'

B = repmat(diagB,M,1); %# Replicate diagB to create an M-by-D matrix 
result = (A.'.*B)*A; %'# An M-by-M result 

而另一種選擇是使用功能BSXFUN

result = bsxfun(@times,A.',diagB)*A; %'# An M-by-M result 
+0

非常感謝,我花了幾個小時來到這裏 – matcheek 2010-12-12 05:34:19

+2

如果內存是一個問題,'bsxfun'優於'repmat',因爲它不生成複製矩陣。然而,'bsxfun'在Matlab 2006之前還沒有變得可用...... – shabbychef 2010-12-12 06:59:40

+0

比解釋了很多,每天都在學習 – matcheek 2010-12-12 07:10:55

3

也許我有一點這裏brainfart的,但不能你把你的DXD矩陣劃分成DXM矩陣(其中M份*最後兩個矩陣,而不是將它們相乘(然後,當然,通常將第一個矩陣乘以找到的產品數量)?

+0

由於'內存不足錯誤',我不會創建D x D,那麼很容易。您的解決方案几乎在現場發現「內存不足」錯誤,但需要更長的時間,但完全一樣。 他們都是正確的,但矩陣是巨大的。 – matcheek 2010-12-12 04:50:53

+0

我的解決方案和gnovice都只需要O(DxM)存儲。我不明白爲什麼我的解決方案不正確,而他很好。 事實上,他的repmat解決方案完全是我的(達到乘法的順序,這並不重要)。 – 2010-12-12 06:52:10

+0

感謝您的回答。爲了說清楚,我確實嘗試了您的解決方案,但無法克服「內存不足」錯誤。 – matcheek 2010-12-12 07:09:54

3
  1. 由於MATLAB無法找到足夠大的內存來容納整個矩陣,因此您正在「內存不足」。有不同的技術可以避免描述in MATLAB documentation這個錯誤。

  2. 在MATLAB中,你顯然不需要編程顯式循環,因爲你可以使用運算符*。如果使用顯式循環完成矩陣乘法存在一種技術,這裏是an example in C#。如何將(可能較大的)矩陣拆分爲更小的矩陣是一個好主意。要在MATLAB中包含這些較小的矩陣,可以使用單元矩陣。系統很可能找到足夠的RAM來容納兩個較小的子矩陣,然後生成大矩陣。

+1

我是一個很大的無知,對於緩存未命中,循環展開或分支預測,但感謝提醒 – matcheek 2010-12-12 08:29:58

+0

@matcheek:將大型矩陣拆分爲較小矩陣的技術可以應用於RAM,方式與應用於緩存的方式相同。對於你來說,緩存並不重要,但是RAM確實如此。 – Mikhail 2010-12-12 08:39:32