测试设置:
In [274]: lis = np.zeros((6,6),int)
In [275]: matrix1 = np.arange(36).reshape(6,6)
In [276]: matrix2 = np.arange(36*36).reshape(6,6,6,6)
In [277]: for i in range(6):
...: for j in range(6):
...: for k in range(6):
...: for l in range(6):
...: lis[i,j] += matrix1[k,l] * (2 * matrix2[i,j,k,l] - mat
...: rix2[i,k,j,l])
...:
In [278]: lis
Out[278]:
array([[-51240, -9660, 31920, 73500, 115080, 156660],
[ 84840, 126420, 168000, 209580, 251160, 292740],
[220920, 262500, 304080, 345660, 387240, 428820],
[357000, 398580, 440160, 481740, 523320, 564900],
[493080, 534660, 576240, 617820, 659400, 700980],
[629160, 670740, 712320, 753900, 795480, 837060]])
对吗?
我不确定 tensordot 是不是正确的工具;至少可能不是最简单的。它肯定无法处理matrix2 的差异。
让我们从一个明显的替换开始:
In [279]: matrix3 = 2*matrix2-matrix2.transpose(0,2,1,3)
In [280]: lis = np.zeros((6,6),int)
In [281]: for i in range(6):
...: for j in range(6):
...: for k in range(6):
...: for l in range(6):
...: lis[i,j] += matrix1[k,l] * matrix3[i,j,k,l]
测试正常 - 相同 lis。
现在很容易用einsum 表达这一点 - 只需复制索引
In [284]: np.einsum('kl,ijkl->ij', matrix1, matrix3)
Out[284]:
array([[-51240, -9660, 31920, 73500, 115080, 156660],
[ 84840, 126420, 168000, 209580, 251160, 292740],
[220920, 262500, 304080, 345660, 387240, 428820],
[357000, 398580, 440160, 481740, 523320, 564900],
[493080, 534660, 576240, 617820, 659400, 700980],
[629160, 670740, 712320, 753900, 795480, 837060]])
两个轴上的元素乘积加总和也可以;和等效的tensordot(指定要对哪些轴求和)
(matrix1*matrix3).sum(axis=(2,3))
np.tensordot(matrix1, matrix3, [[0,1],[2,3]])