将3D矩阵与2D矩阵相乘

假设我有一个AxBxC矩阵X和一个BxD矩阵Y

有没有一种非循环方法,我可以乘以每个C AxB矩阵与Y


您可以使用NUM2CELL函数将矩阵X分解为单元阵列和CELLFUN以在单元中操作:

Z = cellfun(@(x) x*Y,num2cell(X,[1 2]),'UniformOutput',false);

结果Z1×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

上一篇: Multiply a 3D matrix with a 2D matrix

下一篇: Performance of Java matrix math libraries?