【问题标题】:bsxfun-like for matrix productbsxfun-like 矩阵积
【发布时间】:2014-02-01 01:17:31
【问题描述】:

我需要将矩阵 A 与 n 个矩阵相乘,然后返回 n 矩阵。例如,将 2x2 矩阵与堆叠为 2x2x3 Matlab 数组的 3 个 2x2 矩阵相乘。 bsxfun 是我通常用于这种情况的,但它仅适用于元素操作。 我可以这样做:

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

但我需要任意n 的解决方案 - ?

【问题讨论】:

标签: matlab matrix-multiplication bsxfun


【解决方案1】:

您的解决方案可以使用从元胞数组获得的comma-saparated lists 调整为任意大小:

[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{:});

然后您可以使用 this answer 在 3D 阵列上堆叠块,并仅保留相关的块。

但在这种情况下,一个好的旧循环可能更快:

C = NaN(size(B));
for nn = 1:n
    C(:,:,nn) = A * B(:,:,nn);
end

【讨论】:

    【解决方案2】:

    您可以reshape 堆叠矩阵。假设您有k-by-k 矩阵a 和一堆m k-by-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
    

    【讨论】:

    • +1 好主意。但是你需要在重塑b之前存储size(sb,3),以便在最后使用它
    • @LuisMendo 如果你密切注意我有两个变量:sb 用于“堆叠”版本,b 用于调整大小的版本。
    • 哦,我明白了。我以为你在使用(并覆盖)b
    • @LuisMendo 但你是对的,当重塑和弄乱数组的大小时,最好跟踪正在发生的事情......
    • @Shai 在这种情况下应该是b = reshape( sb, sza(2), [] );
    【解决方案3】:

    对于要在其上执行矩阵乘法的大量矩阵和/或向量,速度可能会开始成为问题。为避免重新发明轮子,您可以简单地编译并使用以下快速 MEX 代码: MTIMESX - Mathworks。 根据经验,MATLAB 在执行大量操作的 for 循环时通常效率很低,这些操作看起来应该是可向量化的。我想不出一个简单的方法来概括 Shai 对此案的回答。

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • 鉴于链接本身是指向 mathworks 页面的用于下载由第三方开发的代码 (mtimesx - GitHub),因此我不适合将他们工作的任何部分作为我自己的答案.如果链接损坏,我自然会尝试替换它或删除我的答案。
    猜你喜欢
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多