基本上,我想执行以下计算:
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中是否存在本机或矢量化(或至少>>更快)的方式来执行此类计算。 感谢。
答案 0 :(得分:2)
尝试使用mtimesx from the Matlab File Exchange。这是迄今为止我发现的最好(快速/高效)工具来进行这种n维数组乘法,因为它使用mex
。我认为你也可以使用bsxfun
,但我的Matlab-fu还不足以做这类事情。
您有m x n x k
和m x k
,想要制作n x k
。
mtimesx
将i x j x k
和j x r x k
等输入相乘以生成i x r x k
。
要将问题置于mtimesx
表单中,请G
为m 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矩阵应表示为包含堆叠列的向量。如果矩阵很大,则将其声明为稀疏矩阵。