类似bsxfun的矩阵乘积函数

5

我需要将矩阵A与n个矩阵相乘,并得到n个矩阵作为结果。例如,将一个2x2的矩阵与3个2x2的矩阵堆叠成一个2x2x3的Matlab数组进行乘法运算。bsxfun通常用于这种情况,但它只适用于逐元素操作。

我可以采用以下方式:

blkdiag(a, a, a) * blkdiag(b(:,:,1), b(:,:,2), b(:,:,3))

但我需要一个针对任意的n的解决方案 - ?


2
请查看http://www.mathworks.com/matlabcentral/newsreader/view_thread/311944中的评论以获取FEX链接。 - Dan
现在无法进行测试,但在示例中使用了 times,也许可以在这里替换为 mtimes - Dennis Jaheruddin
3个回答

7

您可以重新塑形堆叠的矩阵。假设您有一个k×k矩阵a和一堆mk×k矩阵sb,您希望对于ii = 1..m,得到乘积a*sb(:,:,ii)。那么您所需要的就是:

sza = size(a);
b = reshape( b, sza(2), [] ); % concatenate all matrices aloong the second dim
res = a * b; 
res = reshape( res, sza(1), [], size(sb,3) ); % stack back to 3d

很好的想法。但是在重塑b之前,你需要存储size(sb,3),以便在最后使用它。 - Luis Mendo
@LuisMendo 如果你仔细看的话,我有两个变量:sb代表“堆叠”版本,而b则代表调整大小后的版本。 - Shai
哦,我明白了。我以为你在使用(并覆盖)b - Luis Mendo
@LuisMendo 但你说得对,当重新塑形和改变数组大小时,最好跟踪正在发生的事情... - Shai
@Shai 在这种情况下,应该使用 b = reshape( sb, sza(2), [] ); - user1618022
顺便问一下,如果我想计算 sb(:,:,ii)*a 怎么办? - user1618022

3

使用从单元数组获得的逗号分隔列表,您的解决方案可以适应任意大小:

[k m n] = size(B);
Acell = mat2cell(repmat(A,[1 1 n]),k,m,ones(1,n));
Bcell = mat2cell(B,k,m,ones(1,n));
blkdiag(Acell{:}) * blkdiag(Bcell{:});

你可以使用这个答案将块堆叠在3D数组上,并仅保留相关的块。
但在这种情况下,传统的循环可能更快:
C = NaN(size(B));
for nn = 1:n
    C(:,:,nn) = A * B(:,:,nn);
end

1

对于需要执行矩阵乘法的大型矩阵和/或向量堆栈,速度可能成为一个问题。为了避免重复造轮子,您可以编译并使用以下快速MEX代码:MTIMESX - Mathworks。作为经验法则,MATLAB在执行看起来应该可向量化的大量操作的for循环时通常效率较低;我无法想到一种简单的方法将Shai的答案推广到这种情况。


1
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。仅有链接的答案如果链接页面发生更改可能会变得无效。 - Ryan M
鉴于链接本身是指向第三方开发的代码下载页面(mtimesx - GitHub),因此我不应该声称他们的任何部分作为我的答案。如果链接失效,我自然会尝试替换它或删除我的答案。 - user9725627

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接