繁体   English   中英

多维数组(或张量)和向量的乘积

[英]Product of a multi-dimensional array (or tensor) and vectors

我想寻求一种快速的方法来执行以下操作,无论是在本机Matlab,C ++中还是使用工具箱/库,无论哪种方法都能提供最快的解决方案。

M为D维的张量: n1 x n2 x... x nD ,令v1v2 ,..., vD为维数分别为n1n2 ,..., nD D向量。

  1. 计算乘积M*vi (1 <= i <= D)。 结果是(D-1)维的多维数组。
  2. vi以外的所有向量计算M的乘积。

例如,D = 3:

  • Mv1的乘积是2维的张量N (即矩阵),其中

N[i2][i3] = Sum_over_i1 of M[i1][i2][i3]*v1[i1]

  • Mv2的乘积是矩阵N ,其中

N[i1][i3] = Sum_over_i2 of M[i1][i2][i3]*v2[i2]

  • Mv2v3的乘积是向量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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM