def SimpleUpdate_down(A, B, C, R, la, lb, lc, U): # # 0 1 # \| |/ \| # A B A index 0: outgoing # \ | / \2 index 2: ingoint # R # | 0 1 # C/ \R/ # | | # 2 # # A = A * la[:, None, None] B = B * lb[:, None, None] C = C * lc[:, None, None] T = np.transpose( np.tensordot( A, np.tensordot(B, np.tensordot(C, R, ([2], [2])), ([2], [3])), ([2], [4])), [0, 2, 4, 1, 3, 5]) V = np.tensordot(T, U, ([3, 4, 5], [3, 4, 5])) Tmp = np.tensordot(V, V, ([1, 2, 4, 5], [1, 2, 4, 5])) ## (0,3) #uA, la_new = tensor_eigh(Tmp, (0,1),(2,3),D_cut) uA, la_new, _ = tensor_svd(Tmp, (0, 1), (2, 3), D_cut) la_new = np.sqrt(la_new) la_new = la_new / np.sqrt(np.dot(la_new, la_new)) A = uA * (1 / la)[:, None, None] Tmp = np.tensordot(V, V, ([0, 2, 3, 5], [0, 2, 3, 5])) ## (1,4) #uB, lb_new = tensor_eigh(Tmp, (0,1),(2,3),D_cut) uB, lb_new, _ = tensor_svd(Tmp, (0, 1), (2, 3), D_cut) lb_new = np.sqrt(lb_new) lb_new = lb_new / np.sqrt(np.dot(lb_new, lb_new)) B = uB * (1 / lb)[:, None, None] Tmp = np.tensordot(V, V, ([0, 1, 3, 4], [0, 1, 3, 4])) ## (2,5) #uC, lc_new = tensor_eigh(Tmp, (0,1),(2,3),D_cut) uC, lc_new, _ = tensor_svd(Tmp, (0, 1), (2, 3), D_cut) lc_new = np.sqrt(lc_new) lc_new = lc_new / np.sqrt(np.dot(lc_new, lc_new)) C = uC * (1 / lc)[:, None, None] R_new = np.tensordot( uA, np.tensordot(uB, np.tensordot(V, uC, ([2, 5], [0, 1])), ([0, 1], [1, 3])), ([0, 1], [1, 2])) R_new /= np.max(abs(R_new)) return A, B, C, R_new, la_new, lb_new, lc_new
def SimpleUpdate_up(B,C,A,R,lb,lc,la,U): # B =B*lb[None,None,:] C =C*lc[None,None,:] A =A*la[None,None,:] T = np.transpose( np.tensordot( B, np.tensordot( C, np.tensordot( A, R, ([0], [2]) ), ([0], [3]) ), ([0], [4]) ), [1, 3, 5, 0, 2, 4] ) V = np.tensordot( T, U, ([3, 4, 5], [3, 4, 5]) ) Tmp = np.tensordot(V, V.conj(),([1,2,4,5], [1,2,4,5]) ) ## (0,3) uB, lb_new, _ = tensor_svd(Tmp,(0,1),(2,3),D) lb_new = np.sqrt(lb_new) lb_new = lb_new/np.sqrt(np.dot(lb_new,lb_new)) B = np.transpose(uB*(1/lb)[:,None,None],[2,1,0]) Tmp = np.tensordot(V, V.conj(),([0,2,3,5], [0,2,3,5]) ) ## (1,4) uC, lc_new, _ = tensor_svd(Tmp,(0,1),(2,3),D) lc_new = np.sqrt(lc_new) lc_new = lc_new/np.sqrt(np.dot(lc_new,lc_new)) C = np.transpose(uC*(1/lc)[:,None,None],[2,1,0]) Tmp = np.tensordot(V, V.conj(),([0,1,3,4], [0,1,3,4]) ) ## (2,5) uA, la_new, _ = tensor_svd(Tmp,(0,1),(2,3),D) la_new = np.sqrt(la_new) la_new = la_new/np.sqrt(np.dot(la_new,la_new)) A = np.transpose(uA*(1/la)[:,None,None] ,[2,1,0]) R_new = np.tensordot( uB.conj(), np.tensordot( uC.conj(), np.tensordot( V, uA.conj(), ([2, 5], [0, 1]) ), ([0, 1], [1, 3]) ), ([0, 1], [1, 2]) ) R_new /=np.max(abs(R_new)) return B, C, A, R_new, lb_new, lc_new, la_new
def SimpleUpdate_up(B, C, A, R, lb, lc, la, U): # B = B * lb[None, None, :, None] C = C * lc[None, None, :, None] A = A * la[None, None, :, None] T = np.transpose( np.tensordot( B, np.tensordot(C, np.tensordot(A, R, ([0], [2])), ([0], [4])), ([0], [6])), [0, 3, 6, 2, 5, 8, 1, 4, 7]) V = np.tensordot(U, T, ([3, 4, 5], [0, 1, 2])) Tmp = np.tensordot(V, V.conj(), ([1, 2, 4, 5, 7, 8], [1, 2, 4, 5, 7, 8])) ## (0,3,6) uB, lb_new, _ = tensor_svd(Tmp, (0, 1, 2), (3, 4, 5), D) lb_new = lb_new / np.sqrt(np.dot(lb_new, lb_new)) lb_new = lb_new[~(lb_new < args.eps_TEBD)] uB = uB[:, :, :, :lb_new.shape[0]] B = np.transpose(uB * (1 / lb)[None, None, :, None], [3, 0, 2, 1]) Tmp = np.tensordot(V, V.conj(), ([0, 2, 3, 5, 6, 8], [0, 2, 3, 5, 6, 8])) ## (1,4,7) uC, lc_new, _ = tensor_svd(Tmp, (0, 1, 2), (3, 4, 5), D) lc_new = np.sqrt(lc_new) lc_new = lc_new / np.sqrt(np.dot(lc_new, lc_new)) lc_new = lc_new[~(lc_new < args.eps_TEBD)] uC = uC[:, :, :, :lc_new.shape[0]] C = np.transpose(uC * (1 / lc)[None, None, :, None], [3, 0, 2, 1]) Tmp = np.tensordot(V, V.conj(), ([0, 1, 3, 4, 6, 7], [0, 1, 3, 4, 6, 7])) ## (2,5,8) uA, la_new, _ = tensor_svd(Tmp, (0, 1, 2), (3, 4, 5), D) la_new = la_new / np.sqrt(np.dot(la_new, la_new)) la_new = la_new[~(la_new < args.eps_TEBD)] uA = uA[:, :, :, :la_new.shape[0]] A = np.transpose(uA * (1 / la)[None, None, :, None], [3, 0, 2, 1]) R_new = np.tensordot( uB.conj(), np.tensordot(uC.conj(), np.tensordot(uA.conj(), V, ([0, 1, 2], [2, 5, 8])), ([0, 1, 2], [2, 4, 6])), ([0, 1, 2], [2, 3, 4])) R_new /= np.max(abs(R_new)) return B, C, A, R_new, lb_new, lc_new, la_new
def SimpleUpdate_down(A, B, C, R, la, lb, lc, U): # # 0 1 # \| |/ \| # A B A index 0: outgoing # \ | / \2 index 2: ingoint # R # | 0 1 # C/ \R/ # | | # 2 # # A = A * la[:, None, None, None] B = B * lb[:, None, None, None] C = C * lc[:, None, None, None] T = np.transpose( np.tensordot( A, np.tensordot(B, np.tensordot(C, R, ([2], [2])), ([2], [4])), ([2], [6])), [1, 4, 7, 2, 5, 8, 0, 3, 6]) V = np.tensordot(U, T, ([3, 4, 5], [0, 1, 2])) Tmp = np.tensordot(V, V.conj(), ([1, 2, 4, 5, 7, 8], [1, 2, 4, 5, 7, 8])) ## (0,3,6) #uA, la_new = tensor_eigh(Tmp, (0,1),(2,3),D) uA, la_new, _ = tensor_svd(Tmp, (0, 1, 2), (3, 4, 5), D) la_new = la_new / np.sqrt(np.dot(la_new, la_new)) la_new = la_new[~(la_new < 1e-8)] uA = uA[:, :, :, :la_new.shape[0]] A = uA * (1 / la)[None, None, :, None] A = A.transpose(2, 0, 3, 1) Tmp = np.tensordot(V, V.conj(), ([0, 2, 3, 5, 6, 8], [0, 2, 3, 5, 6, 8])) ## (1,4,7) #uB, lb_new = tensor_eigh(Tmp, (0,1),(2,3),D) uB, lb_new, _ = tensor_svd(Tmp, (0, 1, 2), (3, 4, 5), D) lb_new = lb_new / np.sqrt(np.dot(lb_new, lb_new)) lb_new = lb_new[~(lb_new < 1e-8)] uB = uB[:, :, :, :lb_new.shape[0]] B = uB * (1 / lb)[None, None, :, None] B = B.transpose(2, 0, 3, 1) Tmp = np.tensordot(V, V.conj(), ([0, 1, 3, 4, 6, 7], [0, 1, 3, 4, 6, 7])) ## (2,5,8) #uC, lc_new = tensor_eigh(Tmp, (0,1),(2,3),D) uC, lc_new, _ = tensor_svd(Tmp, (0, 1, 2), (3, 4, 5), D) lc_new = lc_new / np.sqrt(np.dot(lc_new, lc_new)) lc_new = lc_new[~(lc_new < 1e-8)] uC = uC[:, :, :, :lc_new.shape[0]] C = uC * (1 / lc)[None, None, :, None] C = C.transpose(2, 0, 3, 1) R_new = np.tensordot( uA, np.tensordot(uB, np.tensordot(V, uC, ([2, 5, 8], [0, 1, 2])), ([0, 1, 2], [1, 3, 5])), ([0, 1, 2], [1, 2, 3])) R_new /= np.max(abs(R_new)) return A, B, C, R_new, la_new, lb_new, lc_new