def Ising_exact(N,beta,dpp): CyDtype = mappingDtype2Cytnx(dpp) Ten = cy.zeros((N,N,N,N),dtype=CyDtype) iTen = cy.zeros((N,N,N,N),dtype=CyDtype) for ii in range(N**4): Lab = dNb(N,ii,4) if np.mod(np.sum(Lab),N)==0: N0 = 0 for jj in range(len(Lab)): if Lab[jj]==0: N0+=1 NL = 4-N0 VAL =np.exp(-2*beta)*( (np.sqrt(np.exp(beta*2.)+N-1))**(N0)*\ (np.sqrt(np.exp(beta*2.)-1))**(NL) )/N Ten[Lab[0],Lab[1],Lab[2],Lab[3]]= VAL if np.mod(np.sum(Lab),N)==1: N0 = 0 for jj in range(len(Lab)): if Lab[jj]==0: N0+=1 NL = 4-N0 VAL =np.exp(-2*beta)*( (np.sqrt(np.exp(beta*2.)+N-1))**(N0)*\ (np.sqrt(np.exp(beta*2.)-1))**(NL) )/N iTen[Lab[0],Lab[1],Lab[2],Lab[3]]= VAL return Ten, iTen
def eig_Lanczos(psivec, linFunct, functArgs, maxit=2, krydim=4, Cvgcrit=1.0e-14): """ Lanczos method for finding smallest algebraic eigenvector of linear \ operator defined as a function""" #print(eig_Lanczos) psi_columns = cytnx.zeros([len(psivec), krydim + 1]) krylov_matrix = cytnx.zeros([krydim, krydim]) Elast = 0 cvg = False for ik in range(maxit): norm = psivec.Norm().item() psi_columns[:, 0] = psivec / norm for ip in range(1, krydim + 1): psi_columns[:, ip] = linFunct(psi_columns[:, ip - 1], *functArgs) for ig in range(ip): krylov_matrix[ip - 1, ig] = cytnx.linalg.Dot(psi_columns[:, ip], psi_columns[:, ig]) krylov_matrix[ig, ip - 1] = krylov_matrix[ip - 1, ig] for ig in range(ip): # print(cytnx.linalg.Dot(psi_columns[:, ig], psi_columns[:, ip])) vp = psi_columns[:, ip] vg = psi_columns[:, ig] vp = vp - cytnx.linalg.Dot(vg, vp).item() * vg # print('psi_columns[:,ip].reshape(-1).Norm().item() = ', psi_columns[:,ip].reshape(-1).Norm().item()) norm = vp.Norm().item() psi_columns[:, ip] = vp / norm ## only access set() once!! [energy, psi_columns_basis] = cytnx.linalg.Eigh(krylov_matrix) psivec = cytnx.linalg.Matmul( psi_columns[:, :krydim], psi_columns_basis[:, 0].reshape(krydim, 1)).flatten() if (abs(energy[0].item() - Elast) < Cvgcrit): cvg = True break Elast = energy[0].item() if (cvg == False): print("[WARNING!!] Lanczos does not fully converge!") norm = psivec.Norm().item() psivec = psivec / norm gs_energy = energy[0].item() return psivec, gs_energy
def Create_loop_gas_operator(spin): """Returns loop gas (LG) operator Q_LG for spin=1/2 or spin=1 Kitaev model.""" tau_tensor = cytnx.zeros( (2, 2, 2), dtype=cytnx.Type.ComplexDouble) # tau_tensor_{i j k} if '/' in spin: tau_tensor[0, 0, 0] = -1j else: tau_tensor[0, 0, 0] = 1 tau_tensor[0, 1, 1] = tau_tensor[1, 0, 1] = tau_tensor[1, 1, 0] = 1 sx, sy, sz, one = Get_spin_operators(spin) d = one.shape()[0] Q_LG = cytnx.zeros((d, d, 2, 2, 2), dtype=cytnx.Type.ComplexDouble) # Q_LG_{s s' i j k} u_gamma = None if '/' in spin: u_gamma = list( map(lambda x: -1j * cytnx.linalg.ExpM(1j * np.pi * x), (sx, sy, sz))) else: u_gamma = list( map(lambda x: cytnx.linalg.ExpM(1j * np.pi * x), (sx, sy, sz))) for i in range(2): for j in range(2): for k in range(2): temp = cytnx.eye(d) if i == 0: temp = cytnx.linalg.Matmul(temp, u_gamma[0]) if j == 0: temp = cytnx.linalg.Matmul(temp, u_gamma[1]) if k == 0: temp = cytnx.linalg.Matmul(temp, u_gamma[2]) for s in range(d): for sp in range(d): Q_LG[s, sp, i, j, k] = tau_tensor[i, j, k] * temp[s, sp] return Q_LG
def matvec(self,v): out = cy.zeros(v.shape()[0],v.dtype(),v.device()); for a in range(v.shape()[0]): for i in range(self.L): oid,amp = self.SzSz(i,(i+1)%self.L,a) out[oid] += amp*self.J*v[a] oid,amp = self.Sx(i,a) out[oid] += amp*(-self.Hx)*v[a] return out
def Ising_exact2(N,beta,dpp,weightMatrix=None): """ N: vertex of each node ; beta: J/(KB*T),dpp: datatype --> tensor Ten/iTen, try to construct the whole partition function with tensor Ten and iTen(impurity). For Ising model the weight is given by (assume kB=J=1) [ [exp(beta),exp(-beta)], [exp(-beta),exp(beta)]] """ if not weightMatrix : # default will be Ising weight weightMatrix = np.array([[np.exp(beta),np.exp(-1*beta)], [np.exp(-1*beta),np.exp(beta)]]) weightMatrix = cy.form_numpy(weightMatrix) CyDtype = mappingDtype2Cytnx(dpp) NetworkConstruct = PartitionNetwork('square') pureNode = cy.zeros((N,N,N,N),dtype=CyDtype) pureNode[0,0,0,0] = pureNode[1,1,1,1] = 1 impureNode = cy.zeros((N,N,N,N),dtype=CyDtype) impureNode[0,0,0,0] = 1;impureNode[1,1,1,1] = -1 Ten = NetworkConstruct(pureNode,weightMatrix).next() iTen = NetworkConstruct(impureNode,weightMatrix).next() return Ten, iTen
# Author: Kai-Hsin Wu ## #Example of 1D Ising model ## iTEBD ##------------------------------------- chi = 20 J = 1.0 Hx = 1.0 CvgCrit = 1.0e-10 dt = 0.1 ## Create onsite-Op Sz = cytnx.zeros([2,2]) Sz[0,0] = 1 Sz[1,1] = -1 Sx = cytnx.zeros([2,2]) Sx[0,1] = Sx[1,0] = Hx I = Sz.clone() I[1,1] = 1 #print(Sz,Sx) ## Build Evolution Operator TFterm = cytnx.linalg.Kron(Sx,I) + cytnx.linalg.Kron(I,Sx) ZZterm = cytnx.linalg.Kron(Sz,Sz)
#### 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] chitemp = min(chiT**2, chi) ## Construct U1, V1
Nsites = 20 numsweeps = 4 # number of DMRG sweeps maxit = 2 # iterations of Lanczos method krydim = 4 # dimension of Krylov subspace ## Initialiaze MPO ##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> d = 2 s = 0.5 sx = cytnx.physics.spin(0.5, 'x') sy = cytnx.physics.spin(0.5, 'y') sp = sx + 1j * sy sm = sx - 1j * sy eye = cytnx.eye(d) M = cytnx.zeros([4, 4, d, d]) M[0, 0] = M[3, 3] = eye M[0, 1] = M[2, 3] = 2**0.5 * sp.real() M[0, 2] = M[1, 3] = 2**0.5 * sm.real() M = cytnx.UniTensor(M, 0) L0 = cytnx.UniTensor(cytnx.zeros([4, 1, 1]), 0) #Left boundary R0 = cytnx.UniTensor(cytnx.zeros([4, 1, 1]), 0) #Right boundary L0.get_block_()[0, 0, 0] = 1. R0.get_block_()[3, 0, 0] = 1. ## Init MPS train # # 0-A[0]-2 2-A[1]-4 4-A[2]-6 ... 2k-A[k]-2k+2 # | | | | # 1 3 5 2k+1
OPTS_updateon = True # level of output display OPTS_maxit = 2 # iterations of Lanczos method OPTS_krydim = 4 # dimension of Krylov subspace ''' ########## Initialiaze MPO (quantum XX model) and random MPS ########## ''' d = 2 s = 0.5 sx = cytnx.physics.spin(0.5, 'x') sy = cytnx.physics.spin(0.5, 'y') sz = cytnx.physics.spin(0.5, 'y') sp = sx + 1j * sy sm = sx - 1j * sy eye = cytnx.eye(d).astype(cytnx.Type.ComplexDouble) if model == 'XX': W = cytnx.zeros([4, 4, d, d]).astype(cytnx.Type.ComplexDouble) W[0, 0, :, :] = W[3, 3, :, :] = eye W[0, 1, :, :] = W[2, 3, :, :] = 2**0.5 * sp W[0, 2, :, :] = W[1, 3, :, :] = 2**0.5 * sm 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)
model = args.model h = args.hz tau = 0.01 refresh = 100 ITEsteps = 5 d = constants_cy.spin_to_physical_dimension(spin) sx, sy, sz, _ = constants_cy.Get_spin_operators(spin) if model == 'Kitaev': Construct_hamiltonian = constants_cy.Construct_kitaev_hamiltonian elif model == 'Heisenberg': Construct_hamiltonian = constants_cy.Construct_heisenberg_hamiltonian 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)
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 numpy as np """ References: https://arxiv.org/pdf/1201.1144.pdf https://journals.aps.org/prb/pdf/10.1103/PhysRevB.81.174411 Author: Kai-Hsin Wu """ ## 2D Ising model: chi = 8 Cvg_crit = 1.0e-12 Maxiter = 100 ## init the local tensor: beta = 5 W = cytnx.zeros([2,2]) W[0,0] = W[1,0] = np.sqrt(np.cosh(beta)) W[0,1] = np.sqrt(np.sinh(beta)) W[1,1] = -np.sqrt(np.sinh(beta)) ## Method-1 (faster): T = cLA.Kron(cLA.Kron(W[0],W[0]),cLA.Kron(W[0],W[0]))+\ cLA.Kron(cLA.Kron(W[1],W[1]),cLA.Kron(W[1],W[1])) T.reshape_(2,2,2,2) ## Method-2 (slower in python): #Tchk = cytnx.zeros([2,2,2,2]) #for i in range(2): # for j in range(2): # for k in range(2): # for l in range(2):
Ta_mul_2 = 3. * Ta Ta_mul_3 = Ta * Ta Ta_div = Ta / 3. Ta_div_2 = 3. / Ta Ta_div_3 = Ta / Ta Ta_div_int = Ta / 3 Ta_div_int_2 = 3 / Ta Ta_div_int_3 = Ta / Ta ##=========================== ## Generator ##=========================== Tn = cytnx.zeros(10) Tn2 = cytnx.zeros(10, dtype=cytnx.Type.Float) Tn3 = cytnx.zeros(10, device=cytnx.Device.cpu) print(Tn) print(Tn2) print(Tn3) Tna = cytnx.zeros((2, 3)) Tn2a = cytnx.zeros((2, 3), dtype=cytnx.Type.Float) Tn3a = cytnx.zeros((2, 3), device=cytnx.Device.cpu) print(Tna) print(Tn2a) print(Tn3a) ##============================= ## Bond
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) Block_q2 = cy.zeros([2, 2]) Block_q2[0, 0] = Heisenberg[0, 1, 0, 1] Block_q2[0, 1] = Heisenberg[0, 1, 1, 0] Block_q2[1, 0] = Heisenberg[1, 0, 0, 1] Block_q2[1, 1] = Heisenberg[1, 0, 1, 0] Block_q0 = cy.zeros([3, 3]) Block_q0[0, 0] = Heisenberg[0, 2, 0, 2] Block_q0[0, 1] = Heisenberg[0, 2, 1, 1] Block_q0[0, 2] = Heisenberg[0, 2, 2, 0] Block_q0[1, 0] = Heisenberg[1, 1, 0, 2] Block_q0[1, 1] = Heisenberg[1, 1, 1, 1] Block_q0[1, 2] = Heisenberg[1, 1, 2, 0] Block_q0[2, 0] = Heisenberg[2, 0, 0, 2] Block_q0[2, 1] = Heisenberg[2, 0, 1, 1] Block_q0[2, 2] = Heisenberg[2, 0, 2, 0]