Python 减少张量收缩的标度
我想收缩这样的张量: J^{A}{ir}D^{A}{js}D^{C}{kr}F^{C}{ls}+F^{A}{kr}D^{C}ls}-D^{C}{C}{kr}F} 如果我将J^{A}{ir}与D^{A}{js}联系起来,并将结果从中得到,我会得到类似N^{5}的缩放。 我可以更聪明地先用D^{A}{kr}收缩J^{A}{ir},用F^{A}{ls}收缩D^{A}{js},等等来获得N^{4}操作 然而,我无法理解为什么第一种方法比第二种更快 这是第一种方法的实施:Python 减少张量收缩的标度,python,numpy,Python,Numpy,我想收缩这样的张量: J^{A}{ir}D^{A}{js}D^{C}{kr}F^{C}{ls}+F^{A}{kr}D^{C}ls}-D^{C}{C}{kr}F} 如果我将J^{A}{ir}与D^{A}{js}联系起来,并将结果从中得到,我会得到类似N^{5}的缩放。 我可以更聪明地先用D^{A}{kr}收缩J^{A}{ir},用F^{A}{ls}收缩D^{A}{js},等等来获得N^{4}操作 然而,我无法理解为什么第一种方法比第二种更快 这是第一种方法的实施: DF_krls = np.ein
DF_krls = np.einsum("Ckr,Cls->krls",D_Air,F_Ajs)
DF_krls += np.einsum("Ckr,Cls->krls",F_Air,D_Ajs)
part1 = np.einsum("Ckr,CD->Dkr",D_Air,F_AB)
DF_krls -= np.einsum("Dkr,Dls->krls",part1,D_Ajs)
part1 = np.einsum("Air,Ajs->irjs",J_Air,D_Ajs)
V = np.einsum("irjs,krls->ikjl",part1,DF_krls)
V = np.einsum("ikjl->ij")
第二:
G_Cls = np.einsum('CD,Dls->Cls',F_AB,D_Ajs)
tmp1 = F_Ajs - G_Cls
JF_ACi_r = np.einsum('Air,Ckr->ACi',J_Air,F_Air)
JD_ACi_r = np.einsum('Air,Ckr->ACi',J_Air,D_Air)
DD_ACj_s = np.einsum('Ajs,Cls->ACj',D_Ajs,D_Ajs)
Dtmp1_ACj_s = np.einsum('Ajs,Cls->ACj',D_Ajs,tmp1)
V_ij = np.einsum('ACi,ACj->ij',JF_ACi_r,DD_ACj_s)
V_ij += np.einsum('ACi,ACj->ij',JD_ACi_r,Dtmp1_ACj_s)
其中指数i和j表示维度5;r和s表示92;A和C表示212
你知道我做错了什么吗?第二条路会慢一些
DF_krls = np.einsum("Ckr,Cls->krls",D_Air,F_Ajs) # sums C - 212
DF_krls += np.einsum("Ckr,Cls->krls",F_Air,D_Ajs) # sums C
part1 = np.einsum("Ckr,CD->Dkr",D_Air,F_AB) # sums C
DF_krls -= np.einsum("Dkr,Dls->krls",part1,D_Ajs) # sums D ?
part1 = np.einsum("Air,Ajs->irjs",J_Air,D_Ajs) # sums A - 212
V = np.einsum("irjs,krls->ikjl",part1,DF_krls) # sums r and s - 92
V = np.einsum("ikjl->ij") # sums kl unknown
及
有一个优化参数,当给定2个以上的数组时,它试图找到一个最佳的求值顺序-首先在最大维度上执行点和。您的EINSUM都使用2个数组,所以这没有帮助。但它表明,先对C和A执行约简比先对r和s执行约简更快地减少问题大小
查看文档中的np.einsum\u路径。尝试将optimize=True或optimize=optimize传递给einsum。理想情况下,您可以只调用一次einsum来替换所有内容。此外,您还可以查看每个einsum输出的arr.size。第二种方法可能会创建更大的中间数组。@hpauij np.einsum_path这是一个非常有用的工具。谢谢你的回答,这非常有帮助。
G_Cls = np.einsum('CD,Dls->Cls',F_AB,D_Ajs) # sums D unknown
tmp1 = F_Ajs - G_Cls
JF_ACi_r = np.einsum('Air,Ckr->ACi',J_Air,F_Air) # sums r - 92
JD_ACi_r = np.einsum('Air,Ckr->ACi',J_Air,D_Air) # sums r
DD_ACj_s = np.einsum('Ajs,Cls->ACj',D_Ajs,D_Ajs) # sums s - 92
Dtmp1_ACj_s = np.einsum('Ajs,Cls->ACj',D_Ajs,tmp1) # sums s
V_ij = np.einsum('ACi,ACj->ij',JF_ACi_r,DD_ACj_s) # sums A, C 212
V_ij += np.einsum('ACi,ACj->ij',JD_ACi_r,Dtmp1_ACj_s) # sums A, C