在MatLab中,将矩阵的列与3d矩阵的二维矩阵切片相乘



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

    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

所以,答案是一个矩阵,它的列是一个三维矩阵的每一层与另一个矩阵的列相乘的结果。

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

尝试使用Matlab文件交换中的mtimesx。它是迄今为止我发现的最好的(快速/高效)工具来做这种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论坛上发布你的问题,会有很多大师竞相给你比我更优雅或更有效的答案!

下面是bsxfun()的版本。如果A是一个m × n矩阵x是一个n × 1向量则A*x可以计算为

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

操作permute(S,[3 1 2])将取S的列,并将它们作为行沿第三维分布。[3 1 2]是s的维数的排列。

则sum(bsxfun(@times, G, permute(S,[3 1 2])), 2)得到答案but把结果留在三维空间。为了得到你想要的形式需要另一种排列方式。

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

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

最新更新