2017-05-22 152 views
0

我想在Matlab中用單元格對A和B進行塊矩陣乘法。更具體地假設:用matlab單元塊矩陣乘法

a= 

1  1  2  2 
1  1  2  2 
3  3  4  4 
3  3  4  4 

b= 

2  2  4  4 
2  2  4  4 
6  6  8  8 
6  6  8  8 

我們現在可以將a和b轉換爲包含它們的塊的單元數組。

A = mat2cell(a,[2,2],[2,2]) 

ans = 

[2x2 double] [2x2 double] 
[2x2 double] [2x2 double] 

B = mat2cell(b,[2,2],[2,2]) 

ans = 

[2x2 double] [2x2 double] 
[2x2 double] [2x2 double] 

我需要一個函數C = FOO(A,B),將返回這樣的小區列C即C的塊是矩陣乘積A * B的塊,例如在這種情況下:

C{1,1} = A{1,1}*B{1,1} + A{1,2}*B{2,1} 
C{1,2} = A{1,1}*B{1,2} + A{1,2}*B{2,2} 
... 

cell2mat(C)應該返回:

ans = 

28 28 40 40 
28 28 40 40 
60 60 88 88 
60 60 88 88 
  • 的原因,我不能只是做cell2mat(A)*cell2mat(B)是因爲在我的應用程序中,大多數塊都是零,而且效率不高。

  • 即使大部分塊都是零,我也不能這樣做sparse(cell2mat(A))*sparse(cell2mat(B)),因爲非零塊是完全密集的,因此也是低效的。

有沒有更好的方法來做到這個問題,而不使用笨拙和緩慢的循環?謝謝!

編輯:我寫了一個小代碼,說明我想要做什麼。然而,這很慢,我想知道是否有更好的方法。

function C = celltimes(A,B,nn,blocksize) 

C = cell(nn); 
[C{:}] = deal(sparse(blocksize,blocksize)); 

for ii = 1:nn 
    for jj = 1:nn 
     row = A(ii,:); 
     col = B(:,jj); 
     for kk = 1:nn 
     if (nnz(row{kk}~=0) && nnz(col{kk}~=0)) 
      C{ii,jj} = C{ii,jj}+row{kk}*col{kk}; 
     end 
     end 
    end 
end 

和測試代碼:

%test 

nn = 3; %number of blocks 
blocksize = 3; %block size 

a = randi([0,10],nn*blocksize) 
b = randi([0,10],nn*blocksize) 

A = mat2cell(a,repmat(blocksize,[1,nn]),repmat(blocksize,[1,nn])); 
B = mat2cell(b,repmat(blocksize,[1,nn]),repmat(blocksize,[1,nn])); 

C = celltimes(A,B,nn,blocksize); 

%verify result 
c = a*b; 
max(max(abs(cell2mat(C)-c))) 
+0

從你的問題我不知道你想要達到的目標。更清楚正式地陳述你的問題。也許給一個例子和所有應該滿足的條件。 – kostek

+0

謝謝。對不起,我編輯它更清楚。 – harbm

+1

從你的驗證,你真的只是想找一個更快的方式來做'c = a * b'?如果是這樣,你將無法執行任何比Matlab已經完成的更快的操作。從你原來的描述來看,這聽起來不是你想要做的,所以驗證可能是錯誤的? – Wolfie

回答

0

你從C,將使用獲得B:

C = a*b ; 

a=[ 1  1  2  2 
1  1  2  2 
3  3  4  4 
3  3  4  4] ; 

b=[ 2  2  4  4 
2  2  4  4 
6  6  8  8 
6  6  8  8] ; 

C = a*b