2011-09-01 116 views
4

可能重复:
MATLAB: How to vector-multiply two arrays of matrices?张量收缩在Matlab

有没有办法在Matlab合同高维张量?

例如,假设我有两个3维阵列,与这些尺寸:

size(A) == [M,N,P] 
size(B) == [N,Q,P] 

欲收缩在第二和第一指数AB到,分别。换句话说,我想考虑A是一个大小为[M,N]B的矩阵的阵列,它是等长阵列的[N,Q]矩阵;我想要将这些数组逐个(逐个矩阵)地乘以得到大小为[M,Q,P]的东西。

我可以通过一个for循环做到这一点:

assert(size(A,2) == size(B,1)); 
assert(size(A,3) == size(B,3)); 

M = size(A,1); 
P = size(A,3); 
Q = size(B,2); 

C = zeros(M, Q, P); 
for ii = 1:size(A,3) 
    C(:,:,ii) = A(:,:,ii) * B(:,:,ii); 
end 

有没有办法做到这一点,避免for循环? (也许可以和尺寸的任意数量的阵列工作?)

+2

可能复制[MATLAB:如何向量乘两个矩阵数组?](http://stackoverflow.com/questions/6580656/matlab-how-to-vector-multiply-two-arrays-of-matrices)。也相关:[用2D矩阵乘以3D矩阵](http://stackoverflow.com/questions/1745299/multiply-a-3d-matrix-with-a-2d-matrix) – Amro

回答

4

这里是一个解决方案(类似于做here),计算在一个单一的矩阵乘法运算的结果,尽管它涉及到矩阵的重操作把它们变成所需的形状。然后,我把它比作简单的for循环计算(这点我承认是一个很大的可读性)

%# 3D matrices 
A = rand(4,2,3); 
B = rand(2,5,3); 
[m n p] = size(A); 
[n q p] = size(B); 

%# single matrix-multiplication operation (computes more products than needed) 
AA = reshape(permute(A,[2 1 3]), [n m*p])';  %'# cat(1,A(:,:,1),...,A(:,:,p)) 
BB = reshape(B, [n q*p]);       %# cat(2,B(:,:,1),...,B(:,:,p)) 
CC = AA * BB; 
[mp qp] = size(CC); 

%# only keep "blocks" on the diagonal 
yy = repmat(1:qp, [m 1]); 
xx = bsxfun(@plus, repmat(1:m,[1 q])', 0:m:mp-1); %' 
idx = sub2ind(size(CC), xx(:), yy(:)); 
CC = reshape(CC(idx), [m q p]); 

%# compare against FOR-LOOP solution 
C = zeros(m,q,p); 
for i=1:p 
    C(:,:,i) = A(:,:,i) * B(:,:,i); 
end 
isequal(C,CC) 

注意上面的比需要多进行乘法,但有时"Anyone who adds, detracts (from execution time)"。可悲的是这种情况并非如此,因为for循环的速度要快得多这里:)

我的观点是要表明,量化是不容易的,而基于循环的解决方案并不总是坏...