【问题标题】:Multiplying arrays of matrices in MATLAB在 MATLAB 中将矩阵数组相乘
【发布时间】:2017-08-25 01:47:08
【问题描述】:

我有一个由两个 1800 x 900 x 3 x 3 数组组成的数据集,每个数组都应解释为 3x3 矩阵的 1800x900 数组。作为分析的一部分,有一次我需要通过在 1800x900 数组的每个点将相应的 3x3 矩阵相乘来创建另一个这样的数组。

我能想到的似乎有两种方法可以做到这一点。显而易见的方法是

C = zeros(size(A))
for i = 1:900
    for j = 1:1800
        C(i,j,:,:) = A(i,j,:,:)*B(i,j,:,:)
    end
end

但这是一个相当长的循环,并没有真正利用 MATLAB 的矢量化。另一种方法是

C = zeros(size(A))
for i = 1:3
    for j = 1:3
        for k = 1:3
            C(:,:,i,j) = C(:,:,i,j) + A(:,:,i,k).*B(:,:,k,j)
        end
    end
end

大尺寸被矢量化的地方,我基本上使用 for 循环来实现爱因斯坦求和约定。不过,这似乎真的很不雅,这让我认为应该有更好的方法。有吗?

【问题讨论】:

    标签: arrays matlab matrix


    【解决方案1】:

    bsxfun 和 permute 的完美工作:

    C = permute(sum(bsxfun(@times, A, permute(B, [1 2 5 3 4])), 4), [1 2 3 5 4]);
    

    在 R2016b 以后,您可以避免使用 bsxfun,感谢 implicit singleton expansion:

    C = permute(sum(A .* permute(B, [1 2 5 3 4]), 4), [1 2 3 5 4]);
    

    【讨论】:

    • 您可能需要更详细地向我解释该代码发生了什么。我以前没有使用过 bsxfun 或 permute。而且我想我忘记了第一个示例中的挤压,不是吗?
    • @eyeballfrog 关于bsxfun,我很难比linked post 更好地解释它。请阅读它,如果您有任何问题,请告诉我。 permute 在这里用于“对齐”尺寸,以便根据需要进行单例扩展
    • @eyeballfrog 是的,你忘了squeeze。或者更好的是使用permute。在你的情况下没关系,但如果矩阵是1x3 而不是3x3 squeeze 函数将变成A(i,j,:,:)(大小1x1x 1x4) 根据需要转换为4x1,而不是1x4。所以使用permute(..., [3 4 1 2]) 将第三和第四维度移动到“前面”
    • 哦,所以您将 B(常规 3x3 矩阵)的第 3(第 1)维旋转 90 度,找到元素乘积,然后将其相对于第 4(第 2)暗度求和A(另一个常规矩阵)和 B 的第 3(第 1)个暗度。太棒了!
    猜你喜欢
    • 2017-09-23
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多