Matlab中的张量收缩 [英] Tensor contraction in Matlab

查看:212
本文介绍了Matlab中的张量收缩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
MATLAB:如何对两个矩阵进行矢量乘积? a>

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

在Matlab中是否可以收缩高维张量?

Is there a way to contract higher-dimensional tensors in Matlab?

例如,假设我有两个具有以下大小的3维数组:

For example, suppose I have two 3-dimensional arrays, with these sizes:

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

我想分别在第二个和第一个索引上收缩AB.换句话说,我想将A视为大小为[M,N]的矩阵的数组,并将B视为等长长度的[N,Q]矩阵的数组;我想将这些数组逐个元素地相乘以得到大小为[M,Q,P]的东西.

I want to contract A and B on the second and first indices, respectively. In other words, I want to consider A to be an array of matrices of size [M,N] and B to be equal length array of [N,Q] matrices; I want to multiply these arrays element-by-element (matrix-by-matrix) to get something of size [M,Q,P].

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

I can do this via a for-loop:

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循环? (也许可以处理任意维数的数组?)

Is there a way to do this that avoids the for-loop? (And perhaps works with arrays of an arbitrary number of dimensions?)

推荐答案

这是一个解决方案(类似于

Here is a solution (similar to what was done here) that computes the result in a single matrix-multiplication operation, although it involves heavy manipulation of the matrices to put them into desired shape. I then compare it to the simple for-loop computation (which I admit is a lot more readable)

%# 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)

请注意,上面执行的乘法比所需的更多,但有时 任何人谁添加,会(从执行时间开始)减损". .遗憾的是事实并非如此,因为这里的FOR循环要快得多:)

Note that the above is performing more multiplications than needed, but sometimes "Anyone who adds, detracts (from execution time)". Sadly this is not the case, as the FOR-loop is much faster here :)

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

My point was to show that vectorization is not easy, and that loop-based solutions are not always bad...

这篇关于Matlab中的张量收缩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆