def create_projectors_corboz(c1, c2, c3, c4, dim_cut): c1_tmp = c1.clone(); c2_tmp = c2.clone(); c3_tmp = c3.clone(); c4_tmp = c4.clone() c1_tmp.set_labels([-1, 1]); c2_tmp.set_labels([0, -1]) upper_half = sort_label(cyx.Contract(c1_tmp, c2_tmp)).get_block().contiguous() c4_tmp.set_labels([1, -1]); c3_tmp.set_labels([-1, 0]) lower_half = sort_label(cyx.Contract(c4_tmp, c3_tmp)).get_block().contiguous() _, r_up = cytnx.linalg.QR(upper_half) _, r_down = cytnx.linalg.QR(lower_half) rr = cytnx.linalg.Matmul(r_up.contiguous(), r_down.permute(1, 0).contiguous()) s, u, vt = cytnx.linalg.Svd(rr) vt = vt.Conj(); u = u.Conj() dim_new = min(s.shape()[0], dim_cut) s = s[:dim_new] s_inv2 = 1 / s ** 0.5 s_inv2 = cytnx.linalg.Diag(s_inv2); u_tmp = cytnx.linalg.Matmul(u[:, :dim_new], s_inv2); v_tmp = cytnx.linalg.Matmul(s_inv2, vt[:dim_new, :]).permute(1, 0).contiguous(); p_up = cytnx.linalg.Matmul(r_down.permute(1, 0).contiguous(), v_tmp) p_down = cytnx.linalg.Matmul(r_up.permute(1, 0).contiguous(), u_tmp) p_up = cyx.CyTensor(p_up, 0); p_down = cyx.CyTensor(p_down, 0) return p_up, p_down
def coarse_grain(c1t1, t4w, c4t3, u_up, u_down): u1 = u_up.clone(); c1t1.set_labels([0, -1]); u1.set_labels([-1, 1]); c1 = sort_label(cyx.Contract(c1t1, u1)) u2 = u_down.clone() c4t3.set_labels([-1, 1]); u2.set_labels([-1, 0]); c4 = sort_label(cyx.Contract(c4t3, u2)) t4w.set_labels([-1, 1, -2]); u3 = u_down.clone(); u4 = u_up.clone(); u3.set_labels([-1, 0]); u4.set_labels([-2, 2]); t4 = sort_label(cyx.Contract(cyx.Contract(u3, t4w), u4)) return c1, t4, c4
def create_projectors_Orus(c1t1, c4t3, dim_cut): c1t1_tmp1 = c1t1.clone(); c1t1_tmp2 = c1t1.clone(); c4t3_tmp1 = c4t3.clone(); c4t3_tmp2 = c4t3.clone(); c1t1_tmp1.set_labels([-1, 1]); c1t1_tmp2.set_labels([-1, 0]); c4t3_tmp1.set_labels([1, -1]); c4t3_tmp2.set_labels([0, -1]) m1 = sort_label(cyx.Contract(c1t1_tmp1, c1t1_tmp2.Conj())).get_block() m2 = sort_label(cyx.Contract(c4t3_tmp1, c4t3_tmp2.Conj())).get_block() w, u = cytnx.linalg.Eigh(m1 + m2) u = u[:, ::-1].Conj() u = cyx.CyTensor(u[:, :dim_cut], 0) u_up = u; u_down = u.Conj() return u_up, u_down
def become_LGstate(ten_a, Q_LG): ten_a.set_labels([-1, 2, 4, 6]) Q_LG.set_labels([0, -1, 1, 3, 5]) ten_a = cyx.Contract(ten_a, Q_LG) ten_a.permute_(np.arange(7), by_label=True) #ten_a.print_diagram() ten_a.reshape_(-1, 2, 2, 2) return ten_a
def extend_tensors(c1, t1, t4, weight, c4, t3): ## c1t1 c1_tmp = c1.clone(); t1_tmp = t1.clone(); c1_tmp.set_labels([-1, 1]); t1_tmp.set_labels([0, 2, -1]); c1t1 = sort_label(cyx.Contract(c1_tmp, t1_tmp)); chi0 = t1.shape()[0]; chi2 = t1.shape()[1]; chi1 = c1.shape()[1] c1t1.reshape_(chi0, chi1 * chi2); ## c4t3 c4_tmp = c4.clone(); t3_tmp = t3.clone(); c4_tmp.set_labels([0, -1]); t3_tmp.set_labels([-1, 1, 2]); c4t3 = sort_label(cyx.Contract(c4_tmp, t3_tmp)); chi0 = c4.shape()[0]; chi1 = t3.shape()[1]; chi2 = t3.shape()[2]; c4t3.reshape_(chi0 * chi1, chi2) ## t4w t4_tmp = t4.clone(); w_tmp = weight.clone(); t4_tmp.set_labels([0, -1, 3]); w_tmp.set_labels([1, 2, 4, -1]); t4w = sort_label(cyx.Contract(t4_tmp, w_tmp)) chi0 = t4w.shape()[0] * t4w.shape()[1]; chi1 = t4w.shape()[2]; chi2 = t4w.shape()[3] * t4w.shape()[4] t4w.reshape_(chi0, chi1, chi2) return c1t1, t4w, c4t3
def simple_update(ten_a, ten_b, l_three_dir, D, u_gates): for i in range(3): #u_gates[i].set_labels([-1,-5,0,3]) ## first set_labels, which will be used for contraction later #ten_a.set_labels([-1,-2,-3,-4]); #ten_b.set_labels([-5,-6,-7,-8]); lx = l_three_dir[0].clone() #lx.set_labels([-2,-6]) ## those will contract with ten_a later ly_a = l_three_dir[1].clone() #ly_a.set_labels([1,-3]) lz_a = l_three_dir[2].clone() #lz_a.set_labels([2,-4]) ## those will contract with ten_b later ly_b = l_three_dir[1].clone() #ly_b.set_labels([4,-7]) lz_b = l_three_dir[2].clone() #lz_b.set_labels([5,-8]) # pair contraction + apply gate #ten_axyz = cyx.Contract(cyx.Contract(cyx.Contract(ten_a, lx), ly_a),lz_a) #ten_byz = cyx.Contract(cyx.Contract(ten_b, ly_b), lz_b) #pair_ten = cyx.Contract(ten_axyz, ten_byz) #apply_ten = cyx.Contract(pair_ten, u_gates[i]) #apply_ten.permute_([4,0,1,5,2,3]) # Not trivial, please use print_diagram() #apply_ten = sort_label(apply_ten) anet = cyx.Network("Network/ite.net") anet.PutCyTensor("u", u_gates[i]) anet.PutCyTensor("a", ten_a) anet.PutCyTensor("b", ten_b) anet.PutCyTensor("lx", lx) anet.PutCyTensor("ly_a", ly_a) anet.PutCyTensor("ly_b", ly_b) #print('test') #lz_a.print_diagram() #print('test') anet.PutCyTensor("lz_a", lz_a) anet.PutCyTensor("lz_b", lz_b) apply_ten = anet.Launch() apply_ten.set_Rowrank(3) # apply_ten.print_diagram() ## SVD truncate d = ten_a.shape()[0] #print(d) dim_new = min(2 * 2 * d, D) lx, ten_a, ten_b = cyx.xlinalg.Svd_truncate(apply_ten, dim_new) ten_a.set_labels([0, -1, -2, 1]) ten_b.set_labels([1, 0, -1, -2]) ly_a_inv = 1. / ly_a lz_a_inv = 1. / lz_a ly_a_inv.set_labels([2, -1]) lz_a_inv.set_labels([3, -2]) ten_a = cyx.Contract(cyx.Contract(ten_a, ly_a_inv), lz_a_inv) ten_a.permute_([0, 1, 2, 3], by_label=True) ten_a.set_Rowrank(0) ly_b_inv = 1. / ly_b lz_b_inv = 1. / lz_b ly_b_inv.set_labels([2, -1]) lz_b_inv.set_labels([3, -2]) ten_b = cyx.Contract(cyx.Contract(ten_b, ly_b_inv), lz_b_inv) #ten_b.permute_([1,0,2,3]) ## not so trivial, please use print_diagram() # ten_b = sort_label(ten_b) # ten_b.print_diagram() ten_b.permute_([0, 1, 2, 3], by_label=True) # ten_b.print_diagram() ten_b.set_Rowrank(0) Norm = sum(lx.get_block().numpy()) lx.set_Rowrank(0) l_three_dir[0] = lx / Norm l_three_dir = Lambdas_rotate(l_three_dir) ten_a = Tensor_rotate(ten_a) ten_b = Tensor_rotate(ten_b) return ten_a, ten_b, l_three_dir
anet = cyx.Network('Network/Q4_delta.net') anet.PutCyTensors(["Q1", "Q2", "Q3", "Q4", "delta"], [Q_sqrt] * 4 + [delta]) T = anet.Launch(optimal=True) lnz = 0.0 for k in range(RGstep): print('RGstep = ', k + 1, 'T.shape() = ', T.shape()) Tmax = La.Max(La.Abs(T.get_block())).item() T = T / Tmax lnz += 2**(-k) * np.log(Tmax) chiT = T.shape()[0] chitemp = min(chiT**2, chi) ## Construct U1, V1 stmp, utmp, vtmp = cyx.xlinalg.Svd_truncate(T, chitemp) s_sqrt = stmp**0.5 U1 = cyx.Contract(utmp, s_sqrt) V1 = cyx.Contract(s_sqrt, vtmp) V1.permute_([1, 2, 0]) ## Construct U2, V2 T.permute_([3, 0, 1, 2]) stmp, utmp, vtmp = cyx.xlinalg.Svd_truncate(T, chitemp) s_sqrt = stmp**0.5 U2 = cyx.Contract(utmp, s_sqrt) V2 = cyx.Contract(s_sqrt, vtmp) V2.permute_([1, 2, 0]) anet = cyx.Network('Network/vuvu.net') anet.PutCyTensors(['U1', 'V1', 'U2', 'V2'], [U1, V1, U2, V2]) T = anet.Launch(optimal=True) lnz += T.Trace(0, 2).Trace(0, 1).item() / 2**(RGstep)
def dmrg_two_sites(A, ML, M, MR, dim_cut, numsweeps=10, dispon=2, updateon=True, maxit=2, krydim=4): ''' :param A: list of initial CyTensor :param ML: Left boundary :param M: MPO, M.shape() = (D,D,d,d) :param MR: Right boundary :return: Ekeep, A, s_weight, B ''' d = M.shape()[2] # physical dimension Nsites = len(A) # A is a list L = [0] * Nsites # Left boundary for each MPS L[0] = ML R = [0] * Nsites # Right boundary for each MPS R[Nsites - 1] = MR ''' ########## Warm up: Put A into left orthogonal form ########## ''' for p in range(Nsites - 1): s_diag, A[p], vt = cyx.xlinalg.Svd(A[p]) A[p + 1] = absorb_right(s_diag, vt, A[p + 1]) L[p + 1] = get_new_L(L[p], A[p], M, A[p].Conj()) ## Initialiaze s_weight s_weight = [0] * (Nsites + 1) ## Specify A[final] and s[final] dim_l = A[Nsites - 1].shape()[0] dim_r = A[Nsites - 1].shape()[2] # =1 A[Nsites - 1] = A[Nsites - 1].get_block().reshape( dim_l * d, dim_r) ## CyTensor -> Tensor # This is because A[Nsites-1].shape() = [dim_l*d,1] _, A[Nsites - 1], _ = cytnx.linalg.Svd(A[Nsites - 1]) ##[1], [4,1], [1,1] = svd([4,1) ## Just to make A[final] left orthogonal and renorm s to 1 A[Nsites - 1] = cyx.CyTensor(A[Nsites - 1].reshape(dim_l, d, dim_r), 2) s_weight[Nsites] = cyx.CyTensor([cyx.Bond(1), cyx.Bond(1)], rowrank=1, is_diag=True) s_weight[Nsites].put_block(cytnx.ones(1)) Ekeep = [] # Store the energy of each two sites B = [0] * Nsites ''' ########## DMRG sweep begin ########## ''' for k in range(1, numsweeps + 2): ##### final sweep is only for orthogonalization (disable updates) if k == numsweeps + 1: updateon = False dispon = 0 print('-' * 50, k) ''' ########## Optimization sweep: right-to-left ########## ''' for p in range(Nsites - 2, -1, -1): ##### two-site update dim_l = A[p].shape()[0] dim_r = A[p + 1].shape()[2] psi_gs = get_psi_from_left(A[p], A[p + 1], s_weight[p + 2]) if updateon: ## put psi_gs to Tensor for Lanczos algorithm psi_gs = psi_gs.reshape(-1).get_block().numpy() # psi_gs2 = copy.deepcopy(psi_gs) # psi_gs2, Entemp2 = gs_Arnoldi_numpy(psi_gs2, get_H_psi, (L[p], M, M, R[p + 1]), maxit=maxit, # krydim=krydim) # print(psi_gs.shape) psi_gs, Entemp = gs_Lanczos_numpy(psi_gs, get_H_psi, (L[p], M, M, R[p + 1]), maxit=maxit, krydim=krydim) # print(Entemp2 - Entemp) Ekeep.append(Entemp) psi_gs = cytnx.from_numpy(psi_gs) psi_gs = cyx.CyTensor(psi_gs.reshape(dim_l, d, d, dim_r), 2) dim_new = min(dim_l * d, dim_r * d, dim_cut) s_weight[p + 1], A[p], B[p + 1] = cyx.xlinalg.Svd_truncate( psi_gs, dim_new) norm = s_weight[p + 1].get_block().Norm().item() s_weight[p + 1] = s_weight[p + 1] / norm # ##### new block Hamiltonian R[p] = get_new_R(R[p + 1], B[p + 1], M, B[p + 1].Conj()) if dispon == 2: print('Sweep: %d of %d, Loc: %d,Energy: %f' % (k, numsweeps, p, Ekeep[-1])) ###### left boundary tensor Btemp = cyx.Contract(A[0], s_weight[1]) dim_l = A[0].shape()[0] ## dim_l = 1 dim_r = A[0].shape()[2] Btemp = Btemp.get_block().reshape(dim_l, d * dim_r) _, _, B[0] = cytnx.linalg.Svd(Btemp) ##[1], [1,1], [1,4] = svd([1,4) ## Just to make A[final] left orthogonal and renorm s to 1 B[0] = B[0].reshape(1, d, dim_r) B[0] = cyx.CyTensor(B[0], 1) s_weight[0] = cyx.CyTensor([cyx.Bond(1), cyx.Bond(1)], rowrank=1, is_diag=True) s_weight[0].put_block(cytnx.ones(1)) ''' ########## Optimization sweep: left-to-right ########## ''' for p in range(Nsites - 1): ##### two-site update dim_l = s_weight[p].shape()[0] dim_r = B[p + 1].shape()[2] psi_gs = get_psi_from_right(s_weight[p], B[p], B[p + 1]) if updateon: ## put psi_gs to Tensor for Lanczos algorithm psi_gs = psi_gs.reshape(-1).get_block().numpy() psi_gs, Entemp = gs_Lanczos_numpy(psi_gs, get_H_psi, (L[p], M, M, R[p + 1]), maxit=maxit, krydim=krydim) Ekeep.append(Entemp) psi_gs = cytnx.from_numpy(psi_gs) psi_gs = cyx.CyTensor(psi_gs.reshape(dim_l, d, d, dim_r), 2) dim_new = min(dim_l * d, dim_r * d, dim_cut) s_weight[p + 1], A[p], B[p + 1] = cyx.xlinalg.Svd_truncate( psi_gs, dim_new) norm = s_weight[p + 1].get_block().Norm().item() s_weight[p + 1] = s_weight[p + 1] / norm ##### new block Hamiltonian L[p + 1] = get_new_L(L[p], A[p], M, A[p].Conj()) ##### display energy if dispon == 2: print('Sweep: %d of %d, Loc: %d,Energy: %f' % (k, numsweeps, p, Ekeep[-1])) ###### right boundary tensor Atemp = cyx.Contract(B[Nsites - 1], s_weight[Nsites - 1]) # Atemp.print_diagram() dim_l = B[Nsites - 1].shape()[0] dim_r = B[Nsites - 1].shape()[2] # dim_r = 1 Atemp = Atemp.get_block().reshape(dim_l * d, dim_r) _, A[Nsites - 1], _ = cytnx.linalg.Svd(Atemp) ##[1], [4,1], [1,1] = svd([4,1) # print(A[Nsites-1].shape()) A[Nsites - 1] = A[Nsites - 1].reshape(dim_l, d, 1) A[Nsites - 1] = cyx.CyTensor(A[Nsites - 1], 2) s_weight[Nsites] = cyx.CyTensor([cyx.Bond(1), cyx.Bond(1)], rowrank=1, is_diag=True) s_weight[Nsites].put_block(cytnx.ones(1)) if dispon == 1: print('Sweep: %d of %d, Energy: %.8f, Bond dim: %d' % (k, numsweeps, Ekeep[-1], dim_cut)) return Ekeep, A, s_weight, B
def tdvp_one_site(M, WL, W, WR, dt, numsweeps=10, dispon=2, updateon=True, maxit=1, krydim=10): d = M[0].shape()[2] # physical dimension Nsites = len(M) # M is a list A = [None] * Nsites # left orthogonal tensor B = [None] * Nsites # right orthogonal tensor # EE = [[None]*Nsites]*(2*numsweeps+1) # EE = np.zeros([Nsites-2, 2*numsweeps+1]) EE_all_time = [] EE = np.zeros([Nsites - 1]) L = [None] * Nsites # Left boundary for each MPS L[0] = WL R = [None] * Nsites # Right boundary for each MPS R[Nsites - 1] = WR ''' ########## Warm up: Put M into right orthogonal form ########## ''' for p in range(Nsites - 1, 0, -1): stemp, utemp, B[p] = cyx.xlinalg.Svd(M[p]) M[p - 1] = absorb_remain(M[p - 1], utemp, stemp) R[p - 1] = get_new_R(R[p], B[p], W, B[p].Conj()) dim_l = 1 dim_r = M[0].shape()[2] Mtemp = M[0].get_block().reshape(dim_l, d * dim_r) _, _, B[0] = cytnx.linalg.Svd(Mtemp) B[0] = B[0].reshape(dim_l, d, dim_r) B[0] = cyx.CyTensor(B[0], 1) Ac = B[0] ## One-site center to do update ''' ########## TDVP sweep begin ########## ''' for k in range(1, numsweeps + 2): ##### final sweep is only for orthogonalization (disable updates) if k == numsweeps + 1: updateon = False dispon = 0 print('-' * 50, k) ''' ########## Optimization sweep: left-to-right ########## ''' for p in range(Nsites - 1): ##### two-site update # print('p = ', p) if updateon: ## put psi_gs to Tensor for Lanczos algorithm dim_l = Ac.shape()[0] # Used to reshape Ac_new later dim_r = Ac.shape()[2] ############ Numpy Begin: Update one site Ac_old = Ac.get_block().reshape(-1).numpy() Ac_new, E = exp_Lanczos_numpy(Ac_old, one_site_H_psi, (L[p], W, R[p]), dt, maxit=maxit, krydim=krydim) Ac_new = cytnx.from_numpy(Ac_new) ############ Numpy End Ac_new = cyx.CyTensor(Ac_new.reshape(dim_l, d, dim_r), 2) stemp, A[p], vTtemp = cyx.xlinalg.Svd(Ac_new) ############ Entanglement entropy s_np = stemp.get_block().numpy() s_np[s_np < 1.e-20] = 0. assert abs(np.linalg.norm(s_np) - 1.) < 1.e-14 S2 = s_np**2 EE[p] = -np.sum(S2 * np.log(S2)) # print(EE[2*k-2,p]) C_old = cyx.Contract(stemp, vTtemp) dim_l = C_old.shape()[0] dim_r = C_old.shape()[1] L[p + 1] = get_new_L(L[p], A[p], W, A[p].Conj()) ############ Numpy Begin: Update zero site C_old = C_old.get_block().reshape(-1).numpy() C_new, E = exp_Lanczos_numpy(C_old, zero_site_H_psi, (L[p + 1], R[p]), -dt) C_new = cytnx.from_numpy(C_new) ############ Numpy End C_new = C_new.reshape(dim_l, dim_r) C_new = cyx.CyTensor(C_new, 1) C_new.set_labels([0, -2]) if p == Nsites - 2: B[Nsites - 1].set_labels([-2, 2, 3]) Ac = cyx.Contract(C_new, B[p + 1]) ##### display energy if dispon == 2: print('Sweep: %d of %d, Loc: %d,Energy: %f' % (k, numsweeps, p, E[0])) EE_all_time.append(EE.copy()) # print(EE_all_time) # C_new.print_diagram() # B[p+1].print_diagram() # Ac.print_diagram() dim_l = Ac.shape()[0] dim_r = Ac.shape()[2] # print(Ac.shape()) Ac_old = Ac.get_block().reshape(-1).numpy() Ac_new, E = exp_Lanczos_numpy(Ac_old, one_site_H_psi, (L[Nsites-1], W, R[Nsites-1]),\ 0, maxit=maxit, krydim=krydim) Ac_new = cytnx.from_numpy(Ac_new) Ac = cyx.CyTensor(Ac_new.reshape(dim_l, d, dim_r), 1) for p in range(Nsites - 2, -1, -1): if updateon: stemp, utemp, B[p + 1] = cyx.xlinalg.Svd(Ac) ############ Entanglement entropy s_np = stemp.get_block().numpy() s_np[s_np < 1.e-20] = 0. assert abs(np.linalg.norm(s_np) - 1.) < 1.e-14 S2 = s_np**2 EE[p] = -np.sum(S2 * np.log(S2)) C_old = cyx.Contract(stemp, utemp) dim_l = C_old.shape()[0] dim_r = C_old.shape()[1] R[p] = get_new_R(R[p + 1], B[p + 1], W, B[p + 1].Conj()) ############ Numpy Begin: Update zero site C_old = C_old.get_block().reshape(-1).numpy() C_new, E = exp_Lanczos_numpy(C_old, zero_site_H_psi, (L[p + 1], R[p]), -dt) C_new = cytnx.from_numpy(C_new) ############ Numpy Enf C_new = C_new.reshape(dim_l, dim_r) C_new = cyx.CyTensor(C_new, 1) C_new.set_labels([-1, 2]) Ac_old = cyx.Contract(A[p], C_new).get_block() dim_l = Ac_old.shape()[0] dim_r = Ac_old.shape()[2] ############ Numpy Begin: Update one site Ac_old = Ac_old.reshape(-1).numpy() Ac_new, E = exp_Lanczos_numpy(Ac_old, one_site_H_psi, (L[p], W, R[p]),\ dt, maxit=maxit, krydim=krydim) Ac_new = cytnx.from_numpy(Ac_new) ############ Numpy End Ac_new = cyx.CyTensor(Ac_new.reshape(dim_l, d, dim_r), 1) Ac = Ac_new if dispon == 1: print('Sweep: %d of %d, Energy: %.8f, Bond dim: %d' % (k, numsweeps, E[0], chi)) EE_all_time.append(EE.copy()) # EE = 0 # EE_all_time.append(EE) # print(EE_all_time) # exit() return EE_all_time, A, B