使用 MATLAB 单元格进行块矩阵乘法



我想使用 Matlab 中的单元格对 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

我们现在可以将 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))因为非零块是完全密集的,所以效率也很低。

有没有更好的方法来解决这个问题而不使用笨拙和缓慢的 for 循环?谢谢!

编辑:我写了一个小代码来说明我想做什么。但是,它很慢,我想知道是否有更好的方法。

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)))

您的 c 来自 a、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

相关内容

  • 没有找到相关文章

最新更新