高效计算多个张量内积

Efficiently computing multiple tensor inner products

我正在使用一个 k x k x k x k 张量(比如 S)和一个大小为 (n, k) 的数组 X。粗略地说,X 的行对应于图形的节点特征。对于每对边(比如 e = (u, v)e' = (u_, v_)),我想按如下方式计算一个新元素:

elt = np.sum(S * np.multiply.outer(np.outer(X[u, :], X[v, :]), np.outer(X[u_, :], X[v_, :])))

我想知道是否有一种方法可以更有效地执行此操作,而不是对索引进行 4 次嵌套循环。 如果我只处理节点对并且 S 只是一个 k x k 矩阵,则可以简单地写成

all_elts = X @ S @ X.T

但是,我不确定这如何在多个维度上进行概括。非常感谢任何帮助!

这里有一个例子来说明如何使用 einsum():

import numpy as np
from itertools import product

n = 4
x = np.random.randn(n, n)
S = np.random.randn(n, n, n, n)

res = np.zeros((n, n, n, n))
for i, j, k, l in product(range(n), range(n), range(n), range(n)):
    res[i, j, k, l] = np.sum(S * np.multiply.outer(np.outer(x[i, :], x[j, :]), np.outer(x[k, :], x[l, :])))

res2 = np.einsum("efgh,ae,bf,cg,dh->abcd", S, x, x, x, x)
np.allclose(res, res2)