说我有以下矩阵
B = [1 2 3;4 5 6;7 8 9;10 11 12]
和另一个矩阵
A = [a b c;d e f;g h i]
如何将矩阵B的每一行乘以矩阵A(不使用for循环),即
for i = 1:4 c(i) = B(i,:)*A*B(i,:)' end
提前谢谢了 .
您可以使用:
c = diag(B*A*B.');
然而,这仅计算整个4×4矩阵以提取其对角线,因此效率不高 .
只计算所需值的更有效方法是:
c = sum(bsxfun(@times, permute(sum(bsxfun(@times, B, permute(A, [3 1 2])), 2), [1 3 2]), B), 2);
以下是上述代码的细分:
c1 = sum(bsxfun(@times, B, permute(A, [3 1 2])), 2); % B(i,:)*A c = sum(bsxfun(@times, permute(c1, [1 3 2]), B), 2); % (B(i,:)*A)*B(i,:)'
使用第一个 permute ,以便 B 中的列数与 A 中的列数相匹配 . 在 bsxfun() 中逐个元素的乘法之后,每一行被总结(记住, permute 将行移动到第二维),再现了 for 循环中出现的向量矩阵乘法 B(i,:) * A 的效果 .
permute
bsxfun()
for
在第一个 sum 之后,第二维是单个维度 . 因此,我们使用第二个 permute 将第二维移动到第三维并生成二维矩阵 . 现在, c1 和 B 都是相同的大小 . 按照第二个 bsxfun() 中的逐元素乘法,每列总结(记住, permute 将列移回第二维),再现 B(i,:) * A * B(i,:)' 的效果 .
sum
注意这种方法的隐藏优势 . 由于我们使用逐元素乘法来复制矩阵乘法的结果,因此参数的顺序在 bsxfun() 调用中无关紧要 . 少担心一件事!
或者,从Matlab R2016b开始,你可以用 .* 替换 bsxfun(@times,...) ,感谢implicit expansion:
.*
bsxfun(@times,...)
c = sum(permute(sum(B.*permute(A, [3 1 2]), 2), [1 3 2]).*B, 2);
1 回答
您可以使用:
然而,这仅计算整个4×4矩阵以提取其对角线,因此效率不高 .
只计算所需值的更有效方法是:
以下是上述代码的细分:
使用第一个
permute
,以便 B 中的列数与 A 中的列数相匹配 . 在bsxfun()
中逐个元素的乘法之后,每一行被总结(记住,permute
将行移动到第二维),再现了for
循环中出现的向量矩阵乘法 B(i,:) * A 的效果 .在第一个
sum
之后,第二维是单个维度 . 因此,我们使用第二个permute
将第二维移动到第三维并生成二维矩阵 . 现在, c1 和 B 都是相同的大小 . 按照第二个bsxfun()
中的逐元素乘法,每列总结(记住,permute
将列移回第二维),再现 B(i,:) * A * B(i,:)' 的效果 .注意这种方法的隐藏优势 . 由于我们使用逐元素乘法来复制矩阵乘法的结果,因此参数的顺序在
bsxfun()
调用中无关紧要 . 少担心一件事!或者,从Matlab R2016b开始,你可以用
.*
替换bsxfun(@times,...)
,感谢implicit expansion: