簡體   English   中英

減少張量收縮的縮放

[英]reducing scaling of tensor contraction

我想收縮這樣的張量:J ^ {A} _ {ir} D ^ {A} __ {js}(D ^ {C} _ {kr} F ^ {C} _ {ls} + F ^ {A} _ {kr} D ^ {C} _ {ls} -D ^ {C} _ {kr} F _ {AB} D ^ {C} _ {ls})

如果我用D ^ {A} _ {js}收縮J ^ {A} _ {ir}並使用()的結果,我將像N ^ {5}那樣縮放。 我可以更聰明地將第一個J ^ {A} _ {ir}與D ^ {A} _ {kr},D ^ {A} __ {js}與F ^ {A} _ {ls}簽訂合同,以此類推獲得N ^ {4}個運算。

但是,我不明白為什么第一種方法比第二種方法更快。

這是第一種方法的實現:

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

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

有一個optimize參數,當給定兩個以上的數組時,它試圖找到最佳的評估順序-首先對最大尺寸執行dot求和。 您的einsums都使用2個數組,因此無濟於事。 但是它表明,首先對CA進行約簡比對rs首先進行約簡的速度更快。

查看有關np.einsum_path的文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM