[英]Product of a multi-dimensional array (or tensor) and vectors
我想寻求一种快速的方法来执行以下操作,无论是在本机Matlab,C ++中还是使用工具箱/库,无论哪种方法都能提供最快的解决方案。
令M
为D维的张量: n1 x n2 x... x nD
,令v1
, v2
,..., vD
为维数分别为n1
, n2
,..., nD
D
向量。
M*vi
(1 <= i <= D)。 结果是(D-1)维的多维数组。 vi
以外的所有向量计算M
的乘积。 例如,D = 3:
M
和v1
的乘积是2维的张量N
(即矩阵),其中 N[i2][i3] = Sum_over_i1 of M[i1][i2][i3]*v1[i1]
M
和v2
的乘积是矩阵N
,其中 N[i1][i3] = Sum_over_i2 of M[i1][i2][i3]*v2[i2]
M
与v2
和v3
的乘积是向量v
,其中 v[i1] = Sum_over_i2 of (Sum_over_i3 of M[i1][i2][i3]*v2[i2]*v3[i3]
)
进一步的问题:以上但针对稀疏张量。
下面给出了Matlab代码的示例。
预先非常感谢您的帮助!
n1 = 3;
n2 = 5;
n3 = 4;
M = randn(n1,n2,n3);
v1 = randn(n1,1);
v2 = randn(n2,1);
v3 = randn(n3,1);
%% N = M*v2
N = zeros(n1,n3);
for i1=1:n1
for i3=1:n3
for i2=1:n2
N(i1,i3) = N(i1,i3) + M(i1,i2,i3)*v2(i2);
end
end
end
%% v = M*v2*v3
v = zeros(n1,1);
for i1=1:n1
for i2=1:n2
for i3=1:n3
v(i1) = v(i1) + M(i1,i2,i3)*v2(i2)*v3(i3);
end
end
end
我注意到您正在描述的操作采用M
(D-1)维切片,并通过vi
的相应条目对其进行缩放,然后将结果求和到vi
的索引上。 这段代码似乎可以在您的示例中获得N
:
N2 = squeeze(sum(M.*(v2)', 2));
要在代码中获得v
,您要做的就是将N
乘以v3
:
v2 = N2*v3;
编辑
在较旧的MatLab版本中,按元素运算符.*
不能像我在上面使用它的方式那样工作。 一种替代方法是bsxfun
:
N2 = squeeze(sum(bsxfun(@times, M, v2'), 2));
刚刚检查过:就性能而言, bsxfun
方法看起来与大型阵列的.*
方法一样快,至少在R2016b上是如此。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.