Numpy 带einsum的张量积
我有一个张量Numpy 带einsum的张量积,numpy,numpy-einsum,Numpy,Numpy Einsum,我有一个张量phi=np.random.rand(n,n,3)和一个矩阵D=np.random.rand(3,3)。我想将矩阵D沿着phi的最后一个轴相乘,这样输出就具有形状(n,n,3)。我试过这个 np.einsum("klj,ij->kli", phi, D) 但我对这个符号一点也不自信。基本上我想做 res = np.zeros_like(phi) for i in range(n): for j in range(n):
phi=np.random.rand(n,n,3)
和一个矩阵D=np.random.rand(3,3)
。我想将矩阵D
沿着phi
的最后一个轴相乘,这样输出就具有形状(n,n,3)
。我试过这个
np.einsum("klj,ij->kli", phi, D)
但我对这个符号一点也不自信。基本上我想做
res = np.zeros_like(phi)
for i in range(n):
for j in range(n):
res[i, j, :] = D.dot(phi[i, j, :])
您将
phi
视为向量的n,n
数组,每个向量都要左乘以D
。因此,您希望保持形状的n,n
部分保持原样。向量的最后(唯一)维度应与矩阵的最后维度相乘并求和(向量隐式为3x1):
或
使用np.matmul
(@
操作员)进行广播可能要简单得多:
如果您不介意末尾的额外单位尺寸,可以省略挤压。哪些轴应相乘,哪些轴应通过求和减少?从所需的输出形状来看,似乎要将每个数组中的最后一个轴相乘,并减少
D
中的第一个轴?这个问题的符号应该是ijk,lk->ijk
(这几乎与您所写的相同)。您在问题中所写的是将两个数组中的最后一个轴相乘,同时减少两个数组中的最后一个轴。什么是转换?从特定轴的乘法和求和的角度考虑。每个下标将表示一个轴。通过在两个操作数中重复一个下标,可以告诉einsum将这两个轴相乘。通过在所需输出中省略一个下标,您告诉einsum沿此轴求和。谢谢,但预期的操作不正是您使用einsum解决方案所做的吗?np.einsum(“klj,ij->kli”,phi,D)
?或者,您是在寻找有关其工作原理的解释吗?对于一个小的n
,您可以比较两种计算。@dba。在第一个einsum中有一个拼写错误,现在已修复。
np.einsum('ijk,lk->ijl', phi, D)
np.einsum('ij,klj->kli', D, phi)
np.squeeze(D @ phi[..., None])