在MatLab中将矩阵的列与3d矩阵的2d矩阵切片相乘

时间:2012-01-02 07:34:11

标签: matlab vectorization matrix-multiplication

基本上,我想执行以下计算:

    G is m x n x k
    S is n x k

    Answer=zeros(m,d)
    for Index=1:k
        Answer(:,Index)=G(:,:,Index)*S(:,Index)
    end

所以,答案是一个矩阵,其列是将3d矩阵的每一层与另一个矩阵的列相乘的结果。

这看起来似乎是一种简单的操作类型,我希望找出在Matlab中是否存在本机或矢量化(或至少>>更快)的方式来执行此类计算。 感谢。

3 个答案:

答案 0 :(得分:2)

尝试使用mtimesx from the Matlab File Exchange。这是迄今为止我发现的最好(快速/高效)工具来进行这种n维数组乘法,因为它使用mex。我认为你也可以使用bsxfun,但我的Matlab-fu还不足以做这类事情。

您有m x n x km x k,想要制作n x k

mtimesxi x j x kj x r x k等输入相乘以生成i x r x k

要将问题置于mtimesx表单中,请Gm x n x k,并将S展开为n x 1 x k。然后mtimesx(G,S)m x 1 x k,然后可以展平为m x k

m=3; 
n=4; 
k=2;
G=rand(m,n,k);
S=rand(n,k);

% reshape S
S2=reshape(S,n,1,k);

% do multiplication and flatten mx1xk to mxk
Ans_mtimesx = reshape(mtimesx(G,S2),m,k)

% try loop method to compare
Answer=zeros(m,k);
for Index=1:k
    Answer(:,Index)=G(:,:,Index)*S(:,Index);
end

% compare
norm(Ans_mtimesx-Answer)
% returns 0.

所以,如果你想要一个单行,你可以这样做:

Ans = reshape(mtimesx(G,reshape(S,n,1,k)),m,k)

顺便说一下,如果你在Matlab Newsreader forums上发布你的问题,那么就会有很多大师为你提供比我更优雅或更高效的答案!

答案 1 :(得分:1)

这是bsxfun()版本。如果A是m-by-n矩阵,x是n-by-1矢量 然后A * x可以计算为

sum(bsxfun(@times, A, x'), 2)

操作置换(S,[3 1 2])将取S的列并沿第3维分布为行。 [3 1 2]是S的维数的排列。

因此总和(bsxfun(@times,G,permute(S,[3 1 2])),2)实现答案,但 将结果留在第三维。为了得到你想要的形式 需要另一种置换。

permute(sum(bsxfun(@times, G, permute(S, [3 1 2])), 2), [1 3 2])

答案 2 :(得分:0)

您可以做的一件事是将3d矩阵表示为2d块对角矩阵,每层都是对角线块。在这种情况下,2d矩阵应表示为包含堆叠列的向量。如果矩阵很大,则将其声明为稀疏矩阵。