将3D矩阵与2D矩阵相乘
假设我有一个AxBxC矩阵X
和一个BxD矩阵Y
有没有一种非循环方法,我可以乘以每个C AxB矩阵与Y
?
您可以使用NUM2CELL函数将矩阵X
分解为单元阵列和CELLFUN以在单元中操作:
Z = cellfun(@(x) x*Y,num2cell(X,[1 2]),'UniformOutput',false);
结果Z
是1×C单元阵列,其中每个单元包含A×D矩阵。 如果你想要Z
是一个逐个C的矩阵,你可以使用CAT函数:
Z = cat(3,Z{:});
注意:我的旧解决方案使用MAT2CELL而不是NUM2CELL,这不是简洁:
[A,B,C] = size(X);
Z = cellfun(@(x) x*Y,mat2cell(X,A,B,ones(1,C)),'UniformOutput',false);
作为个人偏好,我喜欢我的代码尽可能简洁易读。
这就是我会做的,尽管它不符合你的'无循环'的要求:
for m = 1:C
Z(:,:,m) = X(:,:,m)*Y;
end
这导致A x D x C矩阵Z.
当然,通过使用Z = zeros(A,D,C);
,您总是可以预分配Z来加快速度Z = zeros(A,D,C);
。
这是一个单线解决方案(如果你想分成三维的话,两个解决方案):
A = 2;
B = 3;
C = 4;
D = 5;
X = rand(A,B,C);
Y = rand(B,D);
%# calculate result in one big matrix
Z = reshape(reshape(permute(X, [2 1 3]), [A B*C]), [B A*C])' * Y;
%'# split into third dimension
Z = permute(reshape(Z',[D A C]),[2 1 3]);
因此现在: Z(:,:,i)
包含X(:,:,i) * Y
说明:
上面可能看起来很混乱,但这个想法很简单。 首先,我先从X
的第三维开始,沿第一个dim进行垂直连接:
XX = cat(1, X(:,:,1), X(:,:,2), ..., X(:,:,C))
......难点在于C
是一个变量,因此你不能用cat或者vertcat来概括这个表达式。 接下来我们乘以Y
:
ZZ = XX * Y;
最后我将它分解回第三维:
Z(:,:,1) = ZZ(1:2, :);
Z(:,:,2) = ZZ(3:4, :);
Z(:,:,3) = ZZ(5:6, :);
Z(:,:,4) = ZZ(7:8, :);
所以你可以看到它只需要一次矩阵乘法,但是你必须在之前和之后重塑矩阵。
链接地址: http://www.djcxy.com/p/85979.html