def get_thermal_average(eigenvals,eigenvect,linear_op,Temp,aiao_OP,s1,s2): average=0 #Average of the linear operator Z=0 #Partition function eigenvals-=np.ones(len(eigenvals))*min(eigenvals) contributing=0 sites=[] for i in range(N): sites.append(i) sites=np.array(sites) for val,vect in zip(eigenvals,eigenvect.T): use=1 for operator in aiao_OP: #Get states in the all in all out state coefficient=[[operator[i],i] for i in range(N)] linear_op=quantum_LinearOperator([['z',coefficient]], basis=basis, check_herm=False, check_symm=False) val=np.dot(vect.conj(),linear_op.matvec(vect)) if(abs(val)==4): use=0 break if(use==1): contributing+=1 average+=np.dot(vect.conj(),linear_op.matvec(vect))*np.exp(-val/(KB*Temp)) Z+=np.exp(-val/(KB*Temp)) if(s1==0 and s2==0): print(str(contributing)+" out of " + str(len(eigenvals)) ) return average/Z
def get_H(L, pblock=None, zblock=None): p = np.arange(L)[::-1] z = -(np.arange(L) + 1) blocks = {} if pblock is not None: blocks["pblock"] = (p, pblock) if zblock is not None: blocks["zblock"] = (z, zblock) basis = spin_basis_general(L, m=0, pauli=False, **blocks) Jzz_list = [[1.0, i, (i + 1) % L] for i in range(L)] Jxy_list = [[0.5, i, (i + 1) % L] for i in range(L)] static = [[op, Jxy_list] for op in ["+-", "-+"]] + [["zz", Jzz_list]] kwargs = dict(basis=basis, dtype=np.float64, check_symm=False, check_herm=False, check_pcon=False) H_LO = quantum_LinearOperator(static, **kwargs) H = hamiltonian(static, [], **kwargs) return H_LO, H
def find_aiao( c, N, basis ): #Find the configurations that have an all-in or an all-out state OPERATORS = [] #Stores the sites to get the all in all out state L = 2**N print("L=", L) # print "Nearest neighbors", NN # print "Site types",ST # print "Positions",Positions # if (c > 0): min_num = min(c, 4) print("finding positions") for t in range(min_num): sites_of_z = np.zeros(N) for index in range(4): sites_of_z[index + 3 * t] = 1 if (t > 0): sites_of_z[3 * t] = -1 OPERATORS.append(sites_of_z) indices = [] for index in range( L): #Produce the state to verify which is in the aiao state state = np.zeros(L).T state[index] = 1 for operator in OPERATORS: #Get states in the all in all out state coefficient = [[operator[i], i] for i in range(N)] # if(index==0): # print(coefficient) # linear_op = quantum_LinearOperator([['z', coefficient]], basis=basis, check_herm=False, check_symm=False) val = np.dot(state.conj(), linear_op.matvec(state)) if (val == 4 or val == -4): indices.append(index) print("Positions found") print(basis) print(indices) return np.array(indices) return []
def _quspin_make_heisenberg(basis, nearest, next_nearest=None, j2=None, dtype=np.float64, matrix=False): from quspin.operators import quantum_LinearOperator, hamiltonian static = [ ["+-", [[0.5, i, j] for (i, j) in nearest]], ["-+", [[0.5, i, j] for (i, j) in nearest]], ["zz", [[1.0, i, j] for (i, j) in nearest]], ] if next_nearest is not None: assert j2 is not None static += [ ["+-", [[0.5 * j2, i, j] for (i, j) in next_nearest]], ["-+", [[0.5 * j2, i, j] for (i, j) in next_nearest]], ["zz", [[1.0 * j2, i, j] for (i, j) in next_nearest]], ] if matrix: return hamiltonian(static, [], basis=basis, dtype=dtype) return quantum_LinearOperator(static, basis=basis, dtype=dtype)
### Correction term ### J1_correction = J_perp**2 - (4. / 3) * (2 * N_Neighbours - 6) * J * beta * (J_perp)**2 J2_correction = +2 * (8 * J * beta * (J_perp)**2) / 3. J3_correction = +2 * (8 * J * beta * (J_perp)**2) / 3. J_1_correction = [[J1_correction, i, j] for (i, j) in NN] J_2_correction = [[J2_correction, i, j] for (i, j) in NN2] J_3_correction = [[J3_correction, i, j] for (i, j) in NN3] static_effective_correction = [["zz", J_1_correction], ["zz", J_2_correction], ["zz", J_3_correction]] dH_eff = quantum_LinearOperator(static_effective_correction, basis=basis, check_herm=False, check_symm=False) E_effective_val=average_energy(eigenvals_effective,eigenvect_effective,beta)+\ beta*thermal_average(eigenvals_effective,eigenvect_effective,dH_eff,beta)-\ beta*(J_perp**2)*N_sites*N_Neighbours ### Constant value that must be added, it is added twice because of the \beta factor. if (E_effective_val.imag > 1E-10): print("Imaginary part is too big", E_effective_val.imag) break elif (E_effective_val.imag != 0): print("Imaginary part ", E_effective_val.imag) E_effective[i] = E_effective_val.real
L = 4 # system size J = 1.0 # spin interaction g = 0.809 # transverse field h = 0.9045 # parallel field # ##### construct basis basis = spin_basis_1d(L=L) # define PBC site-coupling lists for operators x_field = [[g, i] for i in range(L)] z_field = [[h, i] for i in range(L)] J_nn = [[J, i, (i + 1) % L] for i in range(L)] # PBC # static list static = [["zz", J_nn], ["z", z_field], ["x", x_field]] # ##### construct Hamiltonian, NO dynamic list passed H = quantum_LinearOperator(static, basis=basis, dtype=np.float64) # ##### apply operator ono state # compute domain wall initial state dw_str = "".join("1" for i in range(L // 2)) + "".join("0" for i in range(L - L // 2)) i_0 = basis.index(dw_str) # find index of product state in basis psi = np.zeros(basis.Ns) # allocate space for state psi[i_0] = 1.0 # set MB state to be the given product state # apply H on psi psi_new = H.dot(psi) # diagonalise operator E, V = H.eigsh(k=1, which='SA') # calculate operator squared H_squared = H.dot(H)
zblock=(Z, 0)) #basis_2d = spin_basis_general(N=N_2d,Nup=N_2d//2,S="1/2",pauli=0) # ###### setting up hamiltonian ###### # setting up site-coupling lists Jzzs = [[J, i, T_x[i]] for i in range(N_2d)] + [[J, i, T_y[i]] for i in range(N_2d)] Jpms = [[0.5 * J, i, T_x[i]] for i in range(N_2d)] + [[0.5 * J, i, T_y[i]] for i in range(N_2d)] Jmps = [[0.5 * J, i, T_x[i]] for i in range(N_2d)] + [[0.5 * J, i, T_y[i]] for i in range(N_2d)] # static = [["zz", Jzzs], ["+-", Jpms], ["-+", Jmps]] # build hamiltonian #H = hamiltonian(static,[],static_fmt="csr",basis=basis_2d,dtype=np.float64) #H = quantum_LinearOperator(static,basis=basis_2d,dtype=np.float64) no_checks = dict(check_symm=False, check_pcon=False, check_herm=False) #H = hamiltonian(static,[],static_fmt="csr",basis=basis_2d,dtype=np.float64,**no_checks) H = quantum_LinearOperator(static, basis=basis_2d, dtype=np.float64, **no_checks) # diagonalise H #ene,vec = H.eigsh(time=0.0,which="SA",k=2) #ene,vec = H.eigsh(which="SA",k=2) #ene = H.eigsh(which="SA",k=2,return_eigenvectors=False); ene = np.sort(ene) ## https://weinbe58.github.io/QuSpin/parallelization.html#parallel-support-in-the-operator-module-hamiltonian-quantum-operator-and-quantum-linearoperator ene = scipy.sparse.linalg.eigsh(H, which="SA", k=2, return_eigenvectors=False) ene = np.sort(ene) print(J, ene[0] / N_2d, ene[1] / N_2d)
break print("Contributing eigen vectors") print(str(int(sum(contributing)))+" out of " +str(len(contributing))) for i in eigenvect: if(list(i).count(1)+list(i).count(-1)!=1): print("%%%%%%%%%%%%%%%%%%%%%%There's a non classical contribution!!!%%%%%%%%%%%%%%%%%%%%%%") #Finding all the correlation coefficients for s1,s2 in it.product(range(N),range(N)): #Generating the coefficient of the quantum operator coefficient=[[(U_B*gz)**2,s1,s2]]# [[value,site1,site2 ]] linear_op=quantum_LinearOperator([['zz',coefficient]], basis=basis, check_herm=False, check_symm=False) #Average value of the operator #Op_T_average=get_thermal_average(eigenvals,eigenvect,linear_op,T) Old line Op_T_average=get_thermal_average(eigenvals,eigenvect,linear_op,T,contributing) #At this point the prefactor due to the direction and the exponential factor must be multiply by the average factor previously found to have the total scattering function, the different type of cluster must be included aswell for sym in range(SYM.shape[0]): #Relative position vector and Z directions for both spin in the correlation factor r_ij=np.matmul(SYM[sym],Positions[s1]-Positions[s2]) z_1=np.matmul(SYM[sym],Z_DIR[ST[s1]])
def test_ops(): for L in range(1, 5): Jz = [[1.0, i, (i + 1)] for i in range(L - 1)] Jx = [[2.0, i, (i + 1)] for i in range(L - 1)] Jy = [[3.0, i, (i + 1)] for i in range(L - 1)] operator_list = [["zz", Jz], ["xx", Jx], ["yy", Jy]] basis = spin_basis_1d(L, kblock=1, pblock=1) if basis.Ns > 0: for dtype in dtypes: H = hamiltonian(operator_list, [], basis=basis, dtype=dtype, check_symm=False, check_herm=False, check_pcon=False) H_op = quantum_LinearOperator(operator_list, basis=basis, dtype=dtype, check_symm=False, check_herm=False, check_pcon=False) v = np.random.randint(3, size=(H.Ns, )).astype(dtype) yield check_dot, H, H_op, v yield check_dot, H.T, H_op.T, v yield check_dot, H.H, H_op.H, v yield check_dot, H.conj(), H_op.conj(), v yield check_rdot, H, H_op, v yield check_rdot, H.T, H_op.T, v yield check_rdot, H.H, H_op.H, v yield check_rdot, H.conj(), H_op.conj(), v v = np.random.randint(3, size=(H.Ns, 10)).astype(dtype) yield check_dot, H, H_op, v yield check_dot, H.T, H_op.T, v yield check_dot, H.H, H_op.H, v yield check_dot, H.conj(), H_op.conj(), v v = np.random.randint(3, size=(10, H.Ns)).astype(dtype) yield check_rdot, H, H_op, v yield check_rdot, H.T, H_op.T, v yield check_rdot, H.H, H_op.H, v yield check_rdot, H.conj(), H_op.conj(), v v = np.random.randint(3, size=(H.Ns, 1)).astype(dtype) v = sp.csr_matrix(v) yield check_dot, H, H_op, v yield check_dot, H.T, H_op.T, v yield check_dot, H.H, H_op.H, v yield check_dot, H.conj(), H_op.conj(), v yield check_rdot, H, H_op, v.T yield check_rdot, H.T, H_op.T, v.T yield check_rdot, H.H, H_op.H, v.T yield check_rdot, H.conj(), H_op.conj(), v.T v = np.random.randint(3, size=(H.Ns, 10)).astype(dtype) v = sp.csr_matrix(v) yield check_dot, H, H_op, v yield check_dot, H.T, H_op.T, v yield check_dot, H.H, H_op.H, v yield check_dot, H.conj(), H_op.conj(), v v = np.random.randint(3, size=(10, H.Ns)).astype(dtype) v = sp.csr_matrix(v) yield check_rdot, H, H_op, v yield check_rdot, H.T, H_op.T, v yield check_rdot, H.H, H_op.H, v yield check_rdot, H.conj(), H_op.conj(), v v = np.random.randint(3, size=(H.Ns, H.Ns)).astype(dtype) yield check_mul, H, H_op, v yield check_mul, H.T, H_op.T, v yield check_mul, H.H, H_op.H, v yield check_mul, H.conj(), H_op.conj(), v v = sp.random(H.Ns, H.Ns).astype(dtype) yield check_mul, H, H_op, v yield check_mul, H.T, H_op.T, v yield check_mul, H.H, H_op.H, v yield check_mul, H.conj(), H_op.conj(), v
z = -(1+i) basis_full = spin_basis_general(N,pauli=False) basis_pcon = spin_basis_general(N,pauli=False,m=0.0) basis_pcon_symm = spin_basis_general(N,pauli=False,m=0.0,tx=(tx,0),ty=(ty,0),px=(px,0),py=(py,0),z=(z,0)) Jzz_list = [[0.0,i,tx[i]] for i in range(N)]+[[0.0,i,ty[i]] for i in range(N)] Jxy_list = [[0.5,i,tx[i]] for i in range(N)]+[[0.5,i,ty[i]] for i in range(N)] static = [["+-",Jxy_list],["-+",Jxy_list],["zz",Jzz_list]] for b in [basis_full,basis_pcon,basis_pcon_symm]: for dtype1,dtype2 in product(dtypes,dtypes): H = hamiltonian(static,[],basis=b,dtype=dtype1) H_op = quantum_LinearOperator(static,basis=b,dtype=dtype1) for i in range(10): v = np.random.uniform(-1,1,size=(b.Ns,)) + 1j*np.random.uniform(-1,1,size=(b.Ns,)) v /= np.linalg.norm(v) v1 = H.dot(v) v2 = H_op.dot(v) atol = eps(dtype1,dtype2) np.testing.assert_allclose(v1,v2,atol=atol) v1 = H.T.dot(v) v2 = H_op.T.dot(v)
direc_perp[1][sp]=z_per[1] direc_perp[2][sp]=z_per[2] # if(c>1): # print(coef_perp) # print("Perp Sum is %f" %sum(projection_perp)) # print(coef_para) # print("Para Sum is %f" %sum(projection_para)) print("directions") print(direc_para) print(direc_para[0,:]) ### Getting the operator for the magnetization ### Sz_para=quantum_LinearOperator([['z',coef_para_z]], basis=basis, check_herm=False, check_symm=False) types_of_c.append(str(c)) Sz_average_para=thermal_average(eigenvals,eigenvect,Sz_para,T)# if(Sz_average_para.imag<1E-15): magnetization_cluster.append(Sz_average_para.real) else: print("Error due to imaginary values!") break if(c>1): Sz_perp=quantum_LinearOperator([['z',coef_perp_z]], basis=basis, check_herm=False, check_symm=False) types_of_c.append(str(c)+"p") Sz_average_perp=thermal_average(eigenvals,eigenvect,Sz_perp,T)
# translation transformation on the lattice sites [0,...,L-1] T = (np.arange(L)+1)%L # this example does not work under these conditions because ground-state sector is not q=0 if (L//2)%2 != 0: raise ValueError("Example requires modifications for Heisenberg chains with L=4*n+2.") if L%2 != 0: raise ValueError("Example requires modifications for Heisenberg chains with odd number of sites.") # construct basis basis0 = spin_basis_general(L,S=S,m=0,pauli=False,kblock=(T,0)) # construct static list for Heisenberg chain Jzz_list = [[1.0,i,(i+1)%L] for i in range(L)] Jxy_list = [[0.5,i,(i+1)%L] for i in range(L)] static = [["zz",Jzz_list],["+-",Jxy_list],["-+",Jxy_list]] # construct operator for Hamiltonian in the ground state sector if on_the_fly: H0 = quantum_LinearOperator(static,basis=basis0,dtype=np.float64) else: H0 = hamiltonian(static,[],basis=basis0,dtype=np.float64) # calculate ground state [E0],psi0 = H0.eigsh(k=1,which="SA") psi0 = psi0.ravel() # define all possible momentum sectors excluding q=L/2 (pi-momentum) where the peak is abnormally large qs = np.arange(-L//2+1,L//2,1) # define frequencies to calculate spectral function for omegas = np.arange(0,4,0.05) # spectral peaks broadening factor eta = 0.1 # allocate arrays to store data Gzz = np.zeros(omegas.shape+qs.shape,dtype=np.complex128) Gpm = np.zeros(omegas.shape+qs.shape,dtype=np.complex128) # loop over momentum sectors