matlab - Matlab 中的张量收缩

标签 matlab matrix vectorization matrix-multiplication

<分区>

Possible Duplicate:
MATLAB: How to vector-multiply two arrays of matrices?

有没有办法在 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 循环? (也许适用于任意维数的数组?)

最佳答案

这是一个解决方案(类似于 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 循环在这里要快得多:)

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

关于matlab - Matlab 中的张量收缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7265247/

相关文章:

matlab - 4 维网格 - matlab

c# - 设置透视图的缩放值等于透视图

matlab - 如何向量化二次型 (x' * A * x) 的求值?

c++ - 为什么std::count在使用MSVC编译器的循环中要慢得多,而在GCC中却如此?

r - "vectorize"具有不同参数长度的函数的最快方法

matlab - 为包含空格的 matlab 结构体字段名称赋值

matlab - MATLAB 中的高斯-赛德尔法

r - 成对加权距离矢量化

python - 列表矩阵 - Python

algorithm - cuda矩阵逆高斯乔丹