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)))
从你的问题我不知道你想要达到的目标。更清楚正式地陈述你的问题。也许给一个例子和所有应该满足的条件。 – kostek
谢谢。对不起,我编辑它更清楚。 – harbm
从你的验证,你真的只是想找一个更快的方式来做'c = a * b'?如果是这样,你将无法执行任何比Matlab已经完成的更快的操作。从你原来的描述来看,这听起来不是你想要做的,所以验证可能是错误的? – Wolfie