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 zero_site_H_psi(psi, L, R): psi = cytnx.from_numpy(psi) psi = psi.reshape(L.shape()[1], R.shape()[1]) psi = cyx.CyTensor(psi, 1) anet = cyx.Network("Network/C_L_R.net") anet.PutCyTensor("C", psi) anet.PutCyTensor("L", L) anet.PutCyTensor('R', R) H_psi = anet.Launch(optimal=True).get_block().reshape(-1).numpy() return H_psi
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 get_H_psi(psi, L, M1, M2, R): ''' psi is Tensor, while L,M1,M2,R are CyTensor. Return: h|psi> (Tensor)''' psi = cytnx.from_numpy(psi) psi = cyx.CyTensor(psi, 0) psi = psi.reshape(L.shape()[1], M1.shape()[2], M2.shape()[2], R.shape()[1]) anet = cyx.Network(path + "Network/psi_L_M1_M2_R.net") anet.PutCyTensor("psi", psi) anet.PutCyTensor("L", L) anet.PutCyTensor("M1", M1) anet.PutCyTensor('M2', M2) anet.PutCyTensor('R', R) H_psi = anet.Launch(optimal=True).reshape(-1).get_block().numpy() return H_psi
def one_site_H_psi(psi, L, W, R): ''' psi is Tensor, while L,M1,M2,R are CyTensor. Return: h|psi> (Tensor)''' psi = cytnx.from_numpy(psi) # print(psi.shape()) # print(L.shape(), W.shape(), R.shape()) psi = psi.reshape(L.shape()[1], W.shape()[2], R.shape()[1]) psi = cyx.CyTensor(psi, 2) anet = cyx.Network("Network/psi_L_W_R.net") anet.PutCyTensor("psi", psi) anet.PutCyTensor("L", L) anet.PutCyTensor("W", W) anet.PutCyTensor('R', R) H_psi = anet.Launch(optimal=True).get_block().reshape(-1).numpy() return H_psi
import numpy as np #### Set paramaters beta = 0.4 Tval = 1 / beta chi = 20 RGstep = 20 Q = cytnx.Tensor([2, 2]) p_beta = np.exp(beta) m_beta = np.exp(-beta) Q[0, 0] = Q[1, 1] = p_beta Q[1, 0] = Q[0, 1] = m_beta w, v = La.Eigh(Q) Q_sqrt_tmp = v @ La.Diag(w)**0.5 @ La.Inv(v) Q_sqrt = cyx.CyTensor(Q_sqrt_tmp, 0) delta_tmp = cytnx.zeros([2, 2, 2, 2]) delta_tmp[0, 0, 0, 0] = delta_tmp[1, 1, 1, 1] = 1 delta = cyx.CyTensor(delta_tmp, 0) 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]
def create_w_imp_cns_tms(ham,ten_a, ten_b, l_three_dir): 'Create weight, impurity, cns, and tms with the imput ten_a, ten_b, l_three_dir' D = l_three_dir[0].shape()[0] for i in ('weight', 'impurity'): ## Clone and prepare the tesnors needed for contraction ten_a1 = ten_a.clone(); ten_a2 = ten_a.clone() ten_b1 = ten_b.clone(); ten_b2 = ten_b.clone() lx1 = l_three_dir[0].clone(); lx2 = l_three_dir[0].clone() ly = l_three_dir[1].clone(); lz = l_three_dir[2].clone() ly_tmp = ly.get_block().numpy(); ly_tmp = cytnx.from_numpy(np.sqrt(ly_tmp)) ly_sqrt_a1 = cyx.CyTensor([cyx.Bond(D),cyx.Bond(D)],rowrank = 0, is_diag=True) ly_sqrt_a1.put_block(ly_tmp); ly_sqrt_a2 = ly_sqrt_a1.clone() ly_sqrt_b1 = ly_sqrt_a1.clone(); ly_sqrt_b2 = ly_sqrt_a1.clone() lz_tmp = lz.get_block().numpy(); lz_tmp = cytnx.from_numpy(np.sqrt(lz_tmp)) lz_sqrt_a1 = cyx.CyTensor([cyx.Bond(D),cyx.Bond(D)],rowrank = 0, is_diag=True) lz_sqrt_a1.put_block(lz_tmp); lz_sqrt_a2 = lz_sqrt_a1.clone() lz_sqrt_b1 = lz_sqrt_a1.clone(); lz_sqrt_b2 = lz_sqrt_a1.clone() ## Set labels lx1.set_labels([-3,-6]); lx2.set_labels([-9,-12]) ly_sqrt_a1.set_labels([-4,4]); ly_sqrt_b1.set_labels([-7,0]) lz_sqrt_a1.set_labels([-5,6]); lz_sqrt_b1.set_labels([-8,2]) ly_sqrt_a2.set_labels([-10,5]); ly_sqrt_b2.set_labels([-13,1]) lz_sqrt_a2.set_labels([-11,7]); lz_sqrt_b2.set_labels([-14,3]) if i == 'weight': ## Calculate weights ten_a1.set_labels([-1,-3,-4,-5]); ten_b1.set_labels([-2,-6,-7,-8]) ten_a2.set_labels([-1,-9,-10,-11]); ten_b2.set_labels([-2,-12,-13,-14]) ## Contract # a1_xyz = cyx.Contract(cyx.Contract(cyx.Contract(ten_a1, lx1), ly_sqrt_a1), lz_sqrt_a1) # b1_yz = cyx.Contract(cyx.Contract(ten_b1, ly_sqrt_b1), lz_sqrt_b1) # upper_half = cyx.Contract(a1_xyz, b1_yz) # # a2_xyz = cyx.Contract(cyx.Contract(cyx.Contract(ten_a2, lx2), ly_sqrt_a2), lz_sqrt_a2) # b2_yz = cyx.Contract(cyx.Contract(ten_b2, ly_sqrt_b2), lz_sqrt_b2) # # lower_half = cyx.Contract(a2_xyz, b2_yz) # weight = cyx.Contract(upper_half, lower_half.Conj()) # weight = sort_label(weight) # weight1 = weight.clone().get_block().numpy() anet = cyx.Network("Network/weight.net") # lz_sqrt_a1.print_diagram() anet.PutCyTensor("a1", ten_a1); anet.PutCyTensor("b1", ten_b1); anet.PutCyTensor("a2", ten_a2.Conj()); anet.PutCyTensor("b2", ten_b2.Conj()); anet.PutCyTensor("lx1", lx1); anet.PutCyTensor("lx2", lx2); anet.PutCyTensor("ly_sqrt_a1", ly_sqrt_a1); anet.PutCyTensor("ly_sqrt_b1", ly_sqrt_b1); anet.PutCyTensor("ly_sqrt_a2", ly_sqrt_a2.Conj()); anet.PutCyTensor("ly_sqrt_b2", ly_sqrt_b2.Conj()); anet.PutCyTensor("lz_sqrt_a1", lz_sqrt_a1); anet.PutCyTensor("lz_sqrt_b1", lz_sqrt_b1); anet.PutCyTensor("lz_sqrt_a2", lz_sqrt_a2.Conj()); anet.PutCyTensor("lz_sqrt_b2", lz_sqrt_b2.Conj()); weight = anet.Launch(optimal = True) # weight2 = weight.clone().get_block().numpy() # print(linalg.norm(weight1-weight2)) elif i == 'impurity': ## Calculate impurities d = ten_a.shape()[0] spin = constants_cy.physical_dimension_to_spin(d) sx,sy,sz,one = constants_cy.Get_spin_operators(spin) H = ham[0] #H = - k *cytnx.linalg.Kron(sx, sx) - h * (cytnx.linalg.Kron(sz, one) + cytnx.linalg.Kron(one, sz)) / 2 # H = cytnx.linalg.Kron(one,sx) H = H.reshape(d,d,d,d).permute(0,2,1,3) H = cyx.CyTensor(H,0) H.set_labels([-1,-15,-2,-16]) #op1 = cyx.CyTensor(1j*sx.clone(), 0) #op2 = op1.clone() #op1.set_labels([-1,-15]) #op2.set_labels([-2,-16]) # ten_a1.set_labels([-1,-3,-4,-5]); ten_b1.set_labels([-2,-6,-7,-8]) # ten_a2.set_labels([-15,-9,-10,-11]); ten_b2.set_labels([-16,-12,-13,-14]) # # ## Contract # a1_xyz = cyx.Contract(cyx.Contract(cyx.Contract(ten_a1, lx1), ly_sqrt_a1), lz_sqrt_a1) # b1_yz = cyx.Contract(cyx.Contract(ten_b1, ly_sqrt_b1), lz_sqrt_b1) # upper_half = cyx.Contract(cyx.Contract(a1_xyz, b1_yz), H) # # a2_xyz = cyx.Contract(cyx.Contract(cyx.Contract(ten_a2, lx2), ly_sqrt_a2), lz_sqrt_a2) # b2_yz = cyx.Contract(cyx.Contract(ten_b2, ly_sqrt_b2), lz_sqrt_b2) # lower_half = cyx.Contract(a2_xyz, b2_yz) # # weight_imp = cyx.Contract(upper_half, lower_half.Conj()) # weight_imp = sort_label(weight_imp) anet = cyx.Network("Network/impurity.net") # lz_sqrt_a1.print_diagram() anet.PutCyTensor("a1", ten_a1); anet.PutCyTensor("b1", ten_b1); anet.PutCyTensor("a2", ten_a2.Conj()); anet.PutCyTensor("b2", ten_b2.Conj()); anet.PutCyTensor("lx1", lx1); anet.PutCyTensor("lx2", lx2); anet.PutCyTensor("ly_sqrt_a1", ly_sqrt_a1); anet.PutCyTensor("ly_sqrt_b1", ly_sqrt_b1); anet.PutCyTensor("ly_sqrt_a2", ly_sqrt_a2.Conj()); anet.PutCyTensor("ly_sqrt_b2", ly_sqrt_b2.Conj()); anet.PutCyTensor("lz_sqrt_a1", lz_sqrt_a1); anet.PutCyTensor("lz_sqrt_b1", lz_sqrt_b1); anet.PutCyTensor("lz_sqrt_a2", lz_sqrt_a2.Conj()); anet.PutCyTensor("lz_sqrt_b2", lz_sqrt_b2.Conj()); anet.PutCyTensor('H', H) weight_imp = anet.Launch(optimal = True) #weight_imp.reshape_(D**2, D**2, D**2, D**2) w = weight.get_block().numpy() # print(w.shape) # Here we use np.einsum() to calculate cns and tms, for cytnx doesn't support contraction # itself. An alternative is using cytnx.linalg.Trace(); however, it is still not that # convenient dy = dz = w.shape[0] c1 = w.reshape((dy, dy, dz * dz, dy * dy, dz, dz)) c1 = np.einsum('i i j k l l->j k', c1) c2 = w.reshape((dy, dy, dz, dz, dy * dy, dz * dz)) c2 = np.einsum('i i j j k l->k l', c2) c3 = w.reshape((dy * dy, dz, dz, dy, dy, dz * dz)) c3 = np.einsum('i j j k k l->l i', c3) c4 = w.reshape((dy * dy, dz * dz, dy, dy, dz, dz)) c4 = np.einsum('i j k k l l->i j', c4) t1 = np.einsum('i i j k l->j k l', w.reshape((dy, dy, dz * dz, dy * dy, dz * dz))) t2 = np.einsum('i j j k l->k l i', w.reshape((dy * dy, dz, dz, dy * dy, dz * dz))) t3 = np.einsum('i j k k l->l i j', w.reshape((dy * dy, dz * dz, dy, dy, dz * dz))) t4 = np.einsum('i j k l l->i j k', w.reshape((dy * dy, dz * dz, dy * dy, dz, dz))) def normalize(x): return x / np.max(np.abs(x)) corners = tuple(map(normalize, (c1, c2, c3, c4))) corners = tuple(cyx.CyTensor(cytnx.from_numpy(c),0) for c in corners) transfer_matrices = tuple(map(normalize, (t1, t2, t3, t4))) transfer_matrices = tuple(cyx.CyTensor(cytnx.from_numpy(t),0) for t in transfer_matrices) return weight, weight_imp, corners, transfer_matrices
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
WL = cytnx.zeros([4, 1, 1]).astype(cytnx.Type.ComplexDouble) WR = cytnx.zeros([4, 1, 1]).astype(cytnx.Type.ComplexDouble) WL[0, 0, 0] = 1. WR[3, 0, 0] = 1. if model == 'Ising': W = cytnx.zeros([3, 3, d, d]).astype(cytnx.Type.ComplexDouble) W[0, 0, :, :] = W[2, 2, :, :] = eye W[0, 1, :, :] = sx * 2 W[0, 2, :, :] = -1.0 * (sz * 2) ## g W[1, 2, :, :] = sx * 2 WL = cytnx.zeros([3, 1, 1]).astype(cytnx.Type.ComplexDouble) WR = cytnx.zeros([3, 1, 1]).astype(cytnx.Type.ComplexDouble) WL[0, 0, 0] = 1. WR[2, 0, 0] = 1. W = cyx.CyTensor(W, 0) WR = cyx.CyTensor(WR, 0) WL = cyx.CyTensor(WL, 0) M = [0] * Nsites M[0] = cytnx.random.normal([1, d, min(chi, d)], 0., 1.) # A[0] = np.random.rand(1,chid,min(chi,chid)) for k in range(1, Nsites): dim1 = M[k - 1].shape()[2] dim2 = d dim3 = min(min(chi, M[k - 1].shape()[2] * d), d**(Nsites - k - 1)) M[k] = cytnx.random.normal([dim1, dim2, dim3], 0., 1.) ## Transform A to M = [cyx.CyTensor(M[i], 2) for i in range(len(M))] En1, A, sWeight, B = dmrg_two_sites(M, WL,
elif model == 'TFIM': Construct_hamiltonian = constants_cy.Construct_ising_hamiltonian ##### Prepare initial magnetized state ten_a = cytnx.zeros((d, 1, 1, 1)) ten_a = ten_a.astype(cytnx.Type.ComplexDouble) ten_b = cytnx.zeros((d, 1, 1, 1)) ten_b = ten_b.astype(cytnx.Type.ComplexDouble) w, v = cytnx.linalg.Eigh(-1 * (sx + sy + sz)) state = v[:, 0] # eigenvector with the smallest eigenvalues ten_a[:, 0, 0, 0] = state ten_b[:, 0, 0, 0] = state ####### Prepare initial LG state Q_LG = constants_cy.Create_loop_gas_operator(spin) Q_LG = cyx.CyTensor(Q_LG, 0) ## ten_a, ten_b ten_a = cyx.CyTensor(ten_a, 0) ten_b = cyx.CyTensor(ten_b, 0) ten_a = constants_cy.become_LGstate(ten_a, Q_LG) ten_b = constants_cy.become_LGstate(ten_b, Q_LG) # ten_a = np.random.randn(d,2,2,2) # ten_a = cytnx.from_numpy(ten_a) # ten_a = ten_a.astype(cytnx.Type.ComplexDouble) # ten_b = ten_a.clone() # ten_a = cyx.CyTensor(ten_a, 0); # ten_b = cyx.CyTensor(ten_b, 0); # ten_b.print_diagram() ## lambda x,y,z lx = cyx.CyTensor([cyx.Bond(2), cyx.Bond(2)], rowrank=0, is_diag=True)
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
import cytnx import cytnx.cytnx_extension as cyx J = 1.0 hx = 0.2 ## Spin 1/2 operator Sz = cytnx.zeros([2, 2]) Sz[0, 0] = 1 Sz[1, 1] = -1 Sx = cytnx.zeros([2, 2]) Sx[0, 1] = Sx[1, 0] = 1 I = cytnx.linalg.Diag(cytnx.ones(2)) ## construct MPO MPO = cytnx.zeros([3, 3, 2, 2]) MPO[0, 0, :, :] = I MPO[1, 0, :, :] = J * Sz MPO[2, 0, :, :] = -hx * Sx MPO[2, 1, :, :] = J * Sz MPO[2, 2, :, :] = I ## as CyTensor : MPO_T = cyx.CyTensor(MPO, 2) MPO_T.set_name("DMRG_MPO") MPO_T.print_diagram()
##### Import cytnx module from setting import * import cytnx from cytnx import cytnx_extension as cyx import numpy as np from numpy import linalg as LA ten_a = np.random.randn(2,3,3) ten_a = cytnx.from_numpy(ten_a) ten_a = ten_a.astype(cytnx.Type.ComplexDouble) s = 0.5 sy = cytnx.physics.spin(s, 'y') sx = cytnx.physics.spin(s, 'x') ten_a = cyx.CyTensor(ten_a, 0); # print(ten_a) # print(ten_a.Trace(1,2)) Test = cytnx.random.normal([2,3],0.,1.) print(Test) test2 = cytnx.Tensor([2,3]) print(test2) cytnx.random.Make_normal(test2, 0.,1.) test3 = cytnx.random.Make_normal(0.,1.) print(test2)
import cytnx as cy from cytnx import cytnx_extension as cyx ## spin-1 example bi = cyx.Bond(3, cyx.BD_KET, [[2], [0], [-2]], [cyx.Symmetry.U1()]) bo = cyx.Bond(3, cyx.BD_BRA, [[2], [0], [-2]], [cyx.Symmetry.U1()]) A = cyx.CyTensor([bi, bi, bo, bo], rowrank=2) A.print_diagram() B = A.clone() Heisenberg = cy.linalg.Kron(cy.physics.spin(1,'z'),cy.physics.spin(1,'z'))\ + cy.linalg.Kron(cy.physics.spin(1,'y'),cy.physics.spin(1,'y'))\ + cy.linalg.Kron(cy.physics.spin(1,'x'),cy.physics.spin(1,'x')) Heisenberg = Heisenberg.real() # it's real so let's truncate imag part. print(Heisenberg) Heisenberg.reshape_(3, 3, 3, 3) ## method 1, directly access element, even tho it is sparse storage. for i in range(3): for j in range(3): for k in range(3): for l in range(3): if A.elem_exists([i, j, k, l]): print(i, j, k, l) A.set_elem([i, j, k, l], Heisenberg[i, j, k, l].item()) ## method 2, use get_block_() to get reference and put it in. Block_q4 = Heisenberg[0, 0, 0, 0].reshape(1, 1)