def check_m(Lmax): for dtype in dtypes: for L in range(2, Lmax + 1): h = [[2.0 * random() - 1.0, i] for i in range(L)] J1 = [[2.0 * random() - 1.0, i, (i + 1) % L] for i in range(L)] J2_p = [[2.0 * random() - 1.0, i, (i + 1) % L] for i in range(L)] J2_m = [[-J2_p[i][0], i, (i + 1) % L] for i in range(L)] static = [["zz", J1], ["+-", J2_p], ["-+", J2_m], ["z", h]] basis = spinless_fermion_basis_1d(L=L) H = hamiltonian(static, [], dtype=dtype, basis=basis) Ns = H.Ns E = H.eigvalsh() Em = [] for Nf in range(L + 1): basis = spinless_fermion_basis_1d(L=L, Nf=Nf) H = hamiltonian(static, [], dtype=dtype, basis=basis) Etemp = H.eigvalsh() Em.append(Etemp) Em = np.concatenate(Em) Em.sort() if norm(Em - E) > Ns * eps(dtype): raise Exception( "test failed m symmetry at L={0:3d} with dtype {1} {2}". format(L, dtype, norm(Em - E)))
def getvec_spinless_fermion(L, H1, static, Nf=None, kblock=None, pblock=None, a=1, sparse=True): jb = [[i, 1.0] for i in range(L)] jbhc = [[i, -1.0] for i in range(L)] dtype = np.complex128 b = spinless_fermion_basis_1d(L, Nf=Nf, kblock=kblock, pblock=pblock, a=a) Ns = b.Ns if Ns == 0: return H2 = hamiltonian(static, [], basis=b, dtype=dtype) E, v0 = H2.eigh() v = b.get_vec(v0, sparse=sparse) P = b.get_proj(dtype=np.complex128) if sp.issparse(v): v = v.todense() H2 = H2.todense() H2 = np.asarray(v0.T.conj().dot(H2.dot(v0))) H1 = np.asarray(v.T.conj().dot(H1.dot(v))) err_msg = "get_vec() symmetries failed for L={0} {1}".format(b.N, b.blocks) np.testing.assert_allclose(H1, H2, atol=1e-10, err_msg=err_msg)
def ham( L, J, t1, t2 ): #define the 1-D dimerized random hopping model with n-flavors of Majorana fermions sigmaj = J / (n**(1.5)) # variance of interaction sigmat1 = t1 / (n**(0.5)) # variance of odd bond hopping sigmat2 = t2 / (n**(0.5)) # variance of even bond hopping hop1 = 0.5 * np.random.normal( 0, sigmat1, (L, n, n) ) # the factor 0.5 and 0.25 is in accordance with the definition in MMA code hop2 = 0.5 * np.random.normal(0, sigmat2, (L, n, n)) intj = 0.25 * np.random.normal(0, sigmaj, L) t1_pp = [[ 1j * hop1[i, 0, 0] - 1j * hop1[i, 1, 1] + 2 * hop1[i, 0, 1], i, (i + 1) % L ] for i in range(0, L, 2)] t1_mm = [[ 1j * hop1[i, 0, 0] - 1j * hop1[i, 1, 1] - 2 * hop1[i, 0, 1], i, (i + 1) % L ] for i in range(0, L, 2)] t1_mp = [[1j * hop1[i, 0, 0] + 1j * hop1[i, 1, 1], i, (i + 1) % L] for i in range(0, L, 2)] t1_pm = [[1j * hop1[i, 0, 0] + 1j * hop1[i, 1, 1], i, (i + 1) % L] for i in range(0, L, 2)] t2_pp = [[ 1j * hop2[i, 0, 0] - 1j * hop2[i, 1, 1] + 2 * hop2[i, 0, 1], i, (i + 1) % L ] for i in range(1, L, 2)] t2_mm = [[ 1j * hop2[i, 0, 0] - 1j * hop2[i, 1, 1] - 2 * hop2[i, 0, 1], i, (i + 1) % L ] for i in range(1, L, 2)] t2_mp = [[1j * hop2[i, 0, 0] + 1j * hop2[i, 1, 1], i, (i + 1) % L] for i in range(1, L, 2)] t2_pm = [[1j * hop2[i, 0, 0] + 1j * hop2[i, 1, 1], i, (i + 1) % L] for i in range(1, L, 2)] J_int = [[-4 * intj[i], i, (i + 1) % L] for i in range(L)] basis = spinless_fermion_basis_1d(L=L, Nf=range(0, L + 1, 2)) #even number sector static = [["+-", t1_pm], ["-+", t1_mp], ["++", t1_pp], ["--", t1_mm], ["+-", t2_pm], ["-+", t2_mp], ["++", t2_pp], ["--", t2_mm], ["zz", J_int]] dynamic = [] # time-dependent part of H no_checks = {"check_herm": False, "check_pcon": False, "check_symm": False} H = hamiltonian(static, dynamic, dtype=np.complex128, basis=basis, **no_checks) return H
def check_p(L, dtype, Nf=None): L_2 = int(L / 2) hr = [2.0 * random() - 1.0 for i in range(L_2)] hi = [hr[i] for i in range(L_2)] hi.reverse() hi.extend(hr) h = [[hi[i], i] for i in range(L)] J = [[1.0, i, (i + 1) % L] for i in range(L - 1)] J_p = [[1.0, i, (i + 1) % L] for i in range(L - 1)] J_m = [[-1.0, i, (i + 1) % L] for i in range(L - 1)] J_pp = [[np.sqrt(2), i, (i + 1) % L] for i in range(L - 1)] # OBC J_mm = [[-np.sqrt(2), i, (i + 1) % L] for i in range(L - 1)] # OBC static = [["+-", J_p], ["-+", J_m], ["n", h], ["nn", J]] basis = spinless_fermion_basis_1d(L=L, Nf=Nf) H = hamiltonian(static, [], dtype=dtype, basis=basis) Ns = H.Ns E = H.eigvalsh() basis1 = spinless_fermion_basis_1d(L=L, Nf=Nf, pblock=1) H1 = hamiltonian(static, [], dtype=dtype, basis=basis1) basis2 = spinless_fermion_basis_1d(L=L, Nf=Nf, pblock=-1) H2 = hamiltonian(static, [], dtype=dtype, basis=basis2) E1 = H1.eigvalsh() E2 = H2.eigvalsh() Ep = np.concatenate((E1, E2)) Ep.sort() if norm(Ep - E) > Ns * eps(dtype): raise Exception( "test failed p symmetry at L={0:3d} with dtype {1} and Nf={2} {3}". format(L, np.dtype(dtype), Nf, norm(Ep - E)))
def check_t(L, dtype, Nf=None): hx = random() J = random() Delta = random() h = [[hx, i] for i in range(L)] J1 = [[+J, i, (i + 1) % L] for i in range(L)] J1_p = [[+J, i, (i + 1) % L] for i in range(L)] J1_m = [[-J, i, (i + 1) % L] for i in range(L)] J_pp = [[+Delta, i, (i + 1) % L] for i in range(L)] # PBC J_mm = [[-Delta, i, (i + 1) % L] for i in range(L)] # PBC if type(Nf) is int: static = [["+-", J1_p], ["-+", J1_m], ["zz", J1], ["z", h]] else: static = [["zz", J1], ["++", J_pp], ["--", J_mm], ["z", h]] basis = spinless_fermion_basis_1d(L=L, Nf=Nf) H = hamiltonian(static, [], dtype=dtype, basis=basis) Ns = H.Ns E = H.eigvalsh() Et = np.array([]) for kblock in range(0, L): basisk = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=kblock) Hk = hamiltonian(static, [], dtype=dtype, basis=basisk) Et = np.append(Et, Hk.eigvalsh()) Et.sort() if norm(Et - E) > Ns * eps(dtype): raise Exception( "test failed t symmetry at L={0:3d} with dtype {1} and Nf={2} {3}". format(L, np.dtype(dtype), Nf, norm(Et - E)))
def ssh_model_real_space(t, tp, Delta, L, bc = 'pbc'): stagg_pot = [[Delta*(-1)**i, i] for i in range(L)] if bc == 'pbc': hop_intracell_pm = [[t, i, (i+1)%L] for i in range(0, L, 2)] hop_intracell_mp = [[-t, i, (i+1)%L] for i in range(0, L, 2)] hop_intercell_pm = [[tp, i, (i+1)%L] for i in range(1, L, 2)] hop_intercell_mp = [[-tp, i, (i+1)%L] for i in range(1, L, 2)] elif bc == 'obc': hop_intracell_pm = [[t, i, (i+1)] for i in range(0, L-1, 2)] hop_intracell_mp = [[-t, i, (i+1)] for i in range(0, L-1, 2)] hop_intercell_pm = [[tp, i, (i+1)] for i in range(1, L-1, 2)] hop_intercell_mp = [[-tp, i, (i+1)] for i in range(1, L-1, 2)] basis = spinless_fermion_basis_1d(L, Nf = 1) # single-body if Nf = 1 static = [["+-", hop_intracell_pm], ["-+", hop_intracell_mp], ["+-", hop_intercell_pm], ["-+", hop_intercell_mp], ["n", stagg_pot]] checks = dict(check_pcon = True, check_symm = True, check_herm = True) H = hamiltonian(static, [], basis = basis, dtype = np.complex_, **checks) E, V = H.eigh() return E, V
def ev(h): h_dense = h.todense( ) #convert h into dense matrix for fully diagonalization en, wave = eigh(h_dense) p = int(0.1 * 2**(L - 1)) wav = wave[ p: -p] #discard the largest and smallest 10% eigenstates to improve accuray, see RPB 95, 245134 for details es = np.zeros((len(wav), int(2**(L // 2 + 1))), dtype='float64') basis = spinless_fermion_basis_1d(L=L, Nf=range(0, L + 1, 2)) #even number sector #calculate the half-chain entanglement spectrum for all selected eigenstates for i in range(len(wav)): ps = wav[i, :] S = basis.ent_entropy(ps, sub_sys_A=tuple(range(L // 2 + 1)), density=False, return_rdm="A") rdm_A = S["rdm_A"] es[i] = -eigh(np.log(rdm_A), eigvals_only=True) #entanglement spectrum ind = len(wave) // 2 stat = level(en) # calculate the energy level statistics #only the 200 middle states will be kept return es, en, stat, wave[ind - 100:ind + 100, :]
sys.path.insert(0,qspin_path) # from quspin.operators import hamiltonian # Hamiltonians and operators from quspin.basis import spinless_fermion_basis_1d # Hilbert space fermion basis from quspin.tools.block_tools import block_diag_hamiltonian # block diagonalisation import numpy as np # generic math functions # ##### define model parameters ##### L=6 # system size J=1.0 # uniform hopping contribution deltaJ=0.1 # bond dimerisation Delta=0.5 # staggered potential # ##### construct single-particle Hamiltonian ##### # define basis basis=spinless_fermion_basis_1d(L,Nf=1) print(basis) # define site-coupling lists hop_pm=[[-J-deltaJ*(-1)**i,i,(i+1)%L] for i in range(L)] # PBC hop_mp=[[+J+deltaJ*(-1)**i,i,(i+1)%L] for i in range(L)] # PBC stagg_pot=[[Delta*(-1)**i,i] for i in range(L)] # define static and dynamic lists static=[["+-",hop_pm],["-+",hop_mp],['n',stagg_pot]] dynamic=[] # build real-space Hamiltonian H=hamiltonian(static,dynamic,basis=basis,dtype=np.float64) print(H.toarray()) # diagonalise real-space Hamiltonian E,V=H.eigh() # ##### compute Fourier transform and momentum-space Hamiltonian #####
lat = hhg(nup=N_up, ndown=N_down, nx=L, ny=0, U=U, t=t0, pbc=pbc, gamma=gamma, mu=mu) outfile = './Data/Approx/expectations:{}sites-{}up-{}down-{}t0-{}U-{}t_max-{}steps-{}gamma-{}mu-{}rank-{}pbc.npz'.format( L, N_up, N_down, t0, U, t_max, n_steps, gamma, mu, rank, pbc) lat.gamma = lat.gamma """create basis""" # build spinful fermions basis. Note that the basis _cannot_ have number conservation as the leads inject and absorb # fermions. This is frankly a massive pain, and the only gain we get basis = spinless_fermion_basis_1d(L) #no symmetries # basis = spinful_fermion_basis_1d(L, sblock=1) # spin inversion symmetry # basis = spinful_fermion_basis_1d(L,Nf=(N_up, N_down)) #number symmetry # basis = spinful_fermion_basis_1d(L, Nf=(N_up, N_down),sblock=1) #parity and spin inversion symmetry # basis = spinful_fermion_basis_1d(L, Nf=(N_up, N_down),a=1,kblock=1) #translation symmetry print('Hilbert space size: {0:d}.\n'.format(basis.Ns)) """building model""" # define site-coupling lists # create static lists # Note that the pipe determines the spinfulness of the operator. | on the left corresponds to down spin, | on the right # is for up spin. For the onsite interaction here, we have: # add dynamic lists hop_left = [[-lat.t, i, i + 1] for i in range(L - 1)] # hopping to the left OBC
def check_t_p(L, dtype, Nf=None): hx = random() Jnn = random() h = [[hx, i] for i in range(L)] J = [[Jnn, i, (i + 1) % L] for i in range(L)] J1_p = [[Jnn, i, (i + 1) % L] for i in range(L)] J1_n = [[-Jnn, i, (i + 1) % L] for i in range(L)] Delta = random() J_pp = [[+Delta, i, (i + 1) % L] for i in range(L)] # PBC J_mm = [[-Delta, i, (i + 1) % L] for i in range(L)] # PBC if type(Nf) is int: static = [["+-", J1_p], ["-+", J1_n], ["z", h], ["zz", J]] else: static = [["zz", J], ["+-", J1_p], ["-+", J1_n], ["+", h], ["-", h]] L_2 = int(L / 2) if dtype is np.float32: kdtype = np.complex64 elif dtype is np.float64: kdtype = np.complex128 else: kdtype = dtype for kblock in range(-L_2 + 1, 0): basisk = spinless_fermion_basis_1d(L=L, kblock=kblock) Hk = hamiltonian(static, [], dtype=kdtype, basis=basisk) Ns = Hk.Ns Ek = Hk.eigvalsh() basisk1 = spinless_fermion_basis_1d(L=L, kblock=kblock, pblock=+1) Hk1 = hamiltonian(static, [], dtype=dtype, basis=basisk1) basisk2 = spinless_fermion_basis_1d(L=L, kblock=kblock, pblock=-1) Hk2 = hamiltonian(static, [], dtype=dtype, basis=basisk2) Ek1 = Hk1.eigvalsh() Ek2 = Hk2.eigvalsh() if norm(Ek - Ek1) > Ns * eps(dtype): raise Exception( "test failed t p+ symmetry at L={0:3d} kblock={1:3d} with dtype {2} and Nf={3} {4}" .format(L, kblock, np.dtype(dtype), Nf, norm(Ek - Ek1))) if norm(Ek - Ek2) > Ns * eps(dtype): raise Exception( "test failed t p- symmetry at L={0:3d} kblock={1:3d} with dtype {2} and Nf={3} {4}" .format(L, kblock, np.dtype(dtype), Nf, norm(Ek - Ek2))) basisk = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=0) Hk = hamiltonian(static, [], dtype=kdtype, basis=basisk) Ns = Hk.Ns Ek = Hk.eigvalsh() basisk1 = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=0, pblock=+1) Hk1 = hamiltonian(static, [], dtype=dtype, basis=basisk1) basisk2 = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=0, pblock=-1) Hk2 = hamiltonian(static, [], dtype=dtype, basis=basisk2) Ek1 = Hk1.eigvalsh() Ek2 = Hk2.eigvalsh() Ekp = np.append(Ek1, Ek2) Ekp.sort() if norm(Ek - Ekp) > Ns * eps(dtype): raise Exception( "test failed t p symmetry at L={0:3d} kblock={1:3d} with dtype {2} and Nf={3} {4}" .format(L, 0, np.dtype(dtype), Nf, norm(Ek - Ekp))) if L % 2 == 0: for kblock in range(1, L_2): basisk = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=kblock) Hk = hamiltonian(static, [], dtype=kdtype, basis=basisk) Ns = Hk.Ns Ek = Hk.eigvalsh() basisk1 = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=kblock, pblock=+1) Hk1 = hamiltonian(static, [], dtype=dtype, basis=basisk1) basisk2 = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=kblock, pblock=-1) Hk2 = hamiltonian(static, [], dtype=dtype, basis=basisk2) Ek1 = Hk1.eigvalsh() Ek2 = Hk2.eigvalsh() if norm(Ek - Ek1) > Ns * eps(dtype): raise Exception( "test failed t p+ symmetry at L={0:3d} kblock={1:3d} with dtype {2} and Nf={3} {4}" .format(L, kblock, np.dtype(dtype), Nf, norm(Ek - Ek1))) if norm(Ek - Ek2) > Ns * eps(dtype): raise Exception( "test failed t p- symmetry at L={0:3d} kblock={1:3d} with dtype {2} and Nf={3} {4}" .format(L, kblock, np.dtype(dtype), Nf, norm(Ek - Ek1))) basisk = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=L_2) Hk = hamiltonian(static, [], dtype=kdtype, basis=basisk) Ns = Hk.Ns Ek = Hk.eigvalsh() basisk1 = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=L_2, pblock=+1) Hk1 = hamiltonian(static, [], dtype=dtype, basis=basisk1) basisk2 = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=L_2, pblock=-1) Hk2 = hamiltonian(static, [], dtype=dtype, basis=basisk2) Ek1 = Hk1.eigvalsh() Ek2 = Hk2.eigvalsh() Ekp = np.append(Ek1, Ek2) Ekp.sort() if norm(Ek - Ekp) > Ns * eps(dtype): raise Exception( "test failed t pc symmetry at L={0:3d} kblock={1:3d} with dtype {2} and Nf={3} {4}" .format(L, int(L / 2), np.dtype(dtype), Nf, norm(Ek - Ekp))) else: for kblock in range(1, L_2 + 1): basisk = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=kblock) Hk = hamiltonian(static, [], dtype=kdtype, basis=basisk) Ns = Hk.Ns Ek = Hk.eigvalsh() basisk1 = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=kblock, pblock=+1) Hk1 = hamiltonian(static, [], dtype=dtype, basis=basisk1) basisk2 = spinless_fermion_basis_1d(L=L, Nf=Nf, kblock=kblock, pblock=-1) Hk2 = hamiltonian(static, [], dtype=dtype, basis=basisk2) Ek1 = Hk1.eigvalsh() Ek2 = Hk2.eigvalsh() if norm(Ek - Ek1) > Ns * eps(dtype): raise Exception( "test failed t p+ symmetry at L={0:3d} kblock={1:3d} with dtype {2} and Nf={3} {4}" .format(L, kblock, np.dtype(dtype), Nf, norm(Ek - Ek1))) if norm(Ek - Ek2) > Ns * eps(dtype): raise Exception( "test failed t p- symmetry at L={0:3d} kblock={1:3d} with dtype {2} and Nf={3} {4}" .format(L, kblock, np.dtype(dtype), Nf, norm(Ek - Ek2)))
J=1.0 # spin interaction h=0.8592 # spin magnetic field for PBC in [-1,1]: # periodic or antiperiodic BC # defien site-coupling lists for external field x_field=[[2.0*h,i] for i in range(L)] if PBC==1: J_pm=[[-J,i,(i+1)%L] for i in range(L)] # PBC J_mp=[[+J,i,(i+1)%L] for i in range(L)] # PBC J_pp=[[-J,i,(i+1)%L] for i in range(L)] # PBC J_mm=[[+J,i,(i+1)%L] for i in range(L)] # PBC basis_fermion = spinless_fermion_basis_1d(L=L,Nf=range(1,L+1,2)) elif PBC==-1: J_pm=[[-J,i,(i+1)%L] for i in range(L-1)] # APBC J_mp=[[+J,i,(i+1)%L] for i in range(L-1)] # APBC J_pp=[[-J,i,(i+1)%L] for i in range(L-1)] # APBC J_mm=[[+J,i,(i+1)%L] for i in range(L-1)] # APBC J_pm.append([+J,L-1,0]) J_mp.append([-J,L-1,0]) J_pp.append([+J,L-1,0]) J_mm.append([-J,L-1,0]) basis_fermion = spinless_fermion_basis_1d(L=L,Nf=range(0,L+1,2))
count_particles_args=count_particles_args, n_sectors=n_sectors) op_dict = dict(op=op, op_args=op_args) # create user basiss basis = user_basis(np.uint32, N, op_dict, allowed_ops=set("+-nI"), sps=2, pcon_dict=pcon_dict, **maps) # # # ############ create same spinless fermion basis_1d object ############# basis_1d = spinless_fermion_basis_1d(N, Nf=Np, kblock=0, pblock=1) # # # print(basis) print(basis_1d) # ############ create Hamiltonians ############# # J = -1.0 U = +1.0 # hopping_pm = [[+J, j, (j + 1) % N] for j in range(N)] hopping_mp = [[-J, j, (j + 1) % N] for j in range(N)] nn_int = [[U, j, (j + 1) % N] for j in range(N)] # static = [["+-", hopping_pm], ["-+", hopping_mp], ["nn", nn_int]]
from quspin.basis import spinless_fermion_basis_1d # Hilbert space spinless fermion basis import numpy as np # generic math functions # ##### define model parameters ##### L = 10 # system size J = 1.0 # hopping strength mu = 0.9045 # chemical potential U = 1.5 # nn interaction strength ##### define periodic drive ##### Omega = 4.5 # drive frequency def drive(t, Omega): return np.cos(Omega * t) drive_args = [Omega] # ##### construct basis in the 0-total momentum and +1-parity sector basis = spinless_fermion_basis_1d(L=L, Nf=L // 2, a=1, kblock=0, pblock=1) print(basis) # define PBC site-coupling lists for operators n_pot = [[-mu, i] for i in range(L)] J_nn_right = [[-J, i, (i + 1) % L] for i in range(L)] # PBC J_nn_left = [[+J, i, (i + 1) % L] for i in range(L)] # PBC U_nn_int = [[U, i, (i + 1) % L] for i in range(L)] # PBC # static and dynamic lists static = [["+-", J_nn_left], ["-+", J_nn_right], ["n", n_pot]] dynamic = [["nn", U_nn_int, drive, drive_args]] ###### construct Hamiltonian H = hamiltonian(static, dynamic, dtype=np.float64, basis=basis)
def check_getvec_spinless_fermion(L, a=1, sparse=True): dtype = np.complex128 jb = [[i, 1.0] for i in range(L)] jbhc = [[i, -1.0] for i in range(L)] static = [ ['nn', J(L, jb, 2)], ['+-', J(L, jb, 2)], ['-+', J(L, jbhc, 2)], ['nnnn', J(L, jb, 4)], ['+nn-', J(L, jb, 4)], ['-nn+', J(L, jbhc, 4)], ['++--', J(L, jb, 4)], ['--++', J(L, jb, 4)], ['+-+-', J(L, jb, 4)], ['-+-+', J(L, jb, 4)], ] b_full = spinless_fermion_basis_1d(L) H1 = hamiltonian(static, [], basis=b_full, dtype=dtype) H1 = H1.todense() for k in range(-L // a, L // a): getvec_spinless_fermion(L, H1, static, kblock=k, a=a, sparse=sparse) for j in range(-1, 2, 2): getvec_spinless_fermion(L, H1, static, pblock=j, a=a, sparse=sparse) for k in range(-L // a, L // a): getvec_spinless_fermion(L, H1, static, kblock=k, pblock=j, a=a, sparse=sparse) for Nf in range(L + 1): for k in range(-L // a, L // a): getvec_spinless_fermion(L, H1, static, Nf=Nf, kblock=k, a=a, sparse=sparse) for Nf in range(0, L + 1): for j in range(-1, 2, 2): getvec_spinless_fermion(L, H1, static, Nf=Nf, pblock=j, a=a, sparse=sparse) for k in range(-L // a, L // a): getvec_spinless_fermion(L, H1, static, kblock=k, Nf=Nf, pblock=j, a=a, sparse=sparse)
Uff, Ubb, Ubf = -2.0, 0.5, 5.0 # bb, ff, bf interaction # define time-dependent perturbation A = 2.0 Omega = 1.0 def drive(t, Omega): return np.sin(Omega * t) drive_args = [Omega] # ###### create the basis # build the two bases to tensor together to a bose-fermi mixture basis_b = boson_basis_1d(L, Nb=Nb, sps=3) # boson basis basis_f = spinless_fermion_basis_1d(L, Nf=Nf) # fermion basis basis = tensor_basis(basis_b, basis_f) # BFM # ##### create model # define site-coupling lists hop_b = [[-Jb, i, (i + 1) % L] for i in range(L)] # b hopping int_list_bb = [[Ubb / 2.0, i, i] for i in range(L)] # bb onsite interaction int_list_bb_lin = [[-Ubb / 2.0, i] for i in range(L)] # bb interaction, linear term # hop_f_right = [[-Jf, i, (i + 1) % L] for i in range(L)] # f hopping right hop_f_left = [[Jf, i, (i + 1) % L] for i in range(L)] # f hopping left int_list_ff = [[Uff, i, (i + 1) % L] for i in range(L)] # ff nearest-neighbour interaction drive_f = [[A * (-1.0)**i, i] for i in range(L)] # density staggered drive #
# drive protocol parameters drive_args = [J, dJ] ##### construct single-particle Hamiltonian ##### mu_array = np.load("Master_%g_mu.npy" % (mu0)) # define site-coupling lists hopping = [[-1, i, (i + 1) % L] for i in range(L)] hopping_hc = [[-1, (i + 1) % L, i] for i in range(L)] chem = [[mu_array[i], i, i] for i in range(L)] # define static and dynamic lists dynamic = [["+-", hopping, drive, drive_args], ["+-", hopping_hc, drive, drive_args]] static = [["+-", chem]] # define basis basis = spinless_fermion_basis_1d(L=L, Nf=L // 2) basis_dim = int((fact(L)) / (fact(L // 2))**2) # build Hamiltonian H = hamiltonian(static, dynamic, basis=basis, dtype=np.float64) ''' ################ Initial state ####################### ''' psi0 = np.zeros(basis_dim) psi0[0] = 1.0 #Initial state hopping_im = [[-(J + dJ), i, (i + 1) % L] for i in range(L)] hopping_hc_im = [[-(J + dJ), (i + 1) % L, i] for i in range(L)] chem_im = [[mu_array[i], i, i] for i in range(L)] # define static and dynamic lists static_im = [["+-", hopping_im], ["+-", hopping_hc_im], ["+-", chem_im]] H_im = hamiltonian(static_im, [], basis=basis, dtype=np.float64) tau = np.linspace(0.0, 70.0, 100)
["|+-", hop_left], # down hop left ["|-+", hop_right], # down hop right ["n|n", int_list], # onsite interaction ] no_checks = dict(check_pcon=False, check_symm=False, check_herm=False, dtype=np.float64) for N_up, N_down in product(range(L + 1), range(L + 1)): print("L=%s, Nup=%s, Ndown=%s" % (L, N_up, N_down)) ###### create the basis # build the two bases to tensor together to spinful fermions basis_up = spinless_fermion_basis_1d(L, Nf=N_up) # up basis basis_down = spinless_fermion_basis_1d(L, Nf=N_down) # down basis basis_tensor = tensor_basis(basis_up, basis_down) # spinful fermions basis_spinful = spinful_fermion_basis_1d(L, Nf=(N_up, N_down)) H_tensor = hamiltonian(static, [], basis=basis_tensor, **no_checks) H_spinful = hamiltonian(static, [], basis=basis_spinful, **no_checks) E_tensor, V_tensor = H_tensor.eigh() E_spinful, V_spinful = H_spinful.eigh() np.testing.assert_allclose( E_tensor - E_spinful, 0.0, atol=1E-5,
tr = square_lattice_trans(Lx, Ly) Jp = [[1.0, i, tr.T_x[i]] for i in range(N)] Jp.extend([[1.0, i, tr.T_y[i]] for i in range(N)]) Jm = [[-1.0, i, tr.T_x[i]] for i in range(N)] Jm.extend([[-1.0, i, tr.T_y[i]] for i in range(N)]) U_onsite = [[1.0, i, i] for i in range(N)] operator_list_0 = [["+-|", Jp], ["-+|", Jm], ["|+-", Jp], ["|-+", Jm]] operator_list_1 = [["n|n", U_onsite]] operator_dict = dict(H0=operator_list_0, H1=operator_list_1) basis_f = spinless_fermion_basis_1d(L=N, Nf=2) basis_1 = tensor_basis(basis_f, basis_f) basis_f = spinless_fermion_basis_general(N, Nf=2) basis_2 = tensor_basis(basis_f, basis_f) basis_3 = spinful_fermion_basis_1d(L=N, Nf=(2, 2)) basis_4 = spinful_fermion_basis_general(N, Nf=(2, 2)) basis_dict = dict(tensored_spinless_fermion_basis_1d=basis_1, spinful_fermion_basis_1d=basis_3, tensored_spinless_fermion_basis_general=basis_2, spinful_fermion_basis_general=basis_4) for basis_name, basis in basis_dict.items(): H_U = quantum_operator(operator_dict,
J_nn_p_full = [[+1.0] + subsysA_mod] J_nn_n_full = [[-1.0] + subsysA_mod] if np.min(subsysA) <= L - 1 and np.max(subsysA) > L - 1: basis_red = spinful_fermion_basis_1d(1, ) J_nn_p_red = [[+1.0, 0, 0]] J_nn_n_red = [[-1.0, 0, 0]] static_full = [['+|+', J_nn_p_full], ['-|-', J_nn_n_full]] static_red = [['+|+', J_nn_p_red], ['-|-', J_nn_n_red]] elif np.max(subsysA) <= L - 1: basis_red = spinless_fermion_basis_1d(2, ) J_nn_p_red = [[+1.0, 0, 1]] J_nn_n_red = [[-1.0, 0, 1]] static_full = [['++|', J_nn_p_full], ['--|', J_nn_n_full]] static_red = [['++', J_nn_p_red], ['--', J_nn_n_red]] elif np.min(subsysA) > L - 1: basis_red = spinless_fermion_basis_general(2, ) J_nn_p_red = [[+1.0, 0, 1]] J_nn_n_red = [[-1.0, 0, 1]] static_full = [['|++', J_nn_p_full], ['|--', J_nn_n_full]] static_red = [['++', J_nn_p_red], ['--', J_nn_n_red]]
from quspin.basis import spin_basis_1d, boson_basis_1d, spinless_fermion_basis_1d, spinful_fermion_basis_1d from quspin.basis import spin_basis_general, boson_basis_general, spinless_fermion_basis_general, spinful_fermion_basis_general from itertools import product import numpy as np for L in [6, 7]: # symmetry-free basis_1 = spin_basis_1d(L=L, Nup=range(0, L, 2)) basis_1g = spin_basis_general(N=L, Nup=range(0, L, 2)) basis_2 = boson_basis_1d(L=L, Nb=range(0, L, 2)) basis_2g = boson_basis_general(N=L, Nb=range(0, L, 2)) basis_3 = spinless_fermion_basis_1d(L=L, Nf=range(0, L, 2)) basis_3g = spinless_fermion_basis_general(N=L, Nf=range(0, L, 2)) basis_4 = spinful_fermion_basis_1d(L=L, Nf=product(range(0, L, 2), range(0, L, 2))) basis_4g = spinful_fermion_basis_general(N=L, Nf=product( range(0, L, 2), range(0, L, 2))) # symmetry-ful t = (np.arange(L) + 1) % L basis_1 = spin_basis_1d(L=L, Nup=range(0, L, 2), kblock=0)
qspin_path = os.path.join(os.getcwd(), "../../") sys.path.insert(0, qspin_path) # from quspin.operators import hamiltonian # Hamiltonians and operators from quspin.basis import spinless_fermion_basis_1d, tensor_basis # Hilbert space fermion and tensor bases import numpy as np # generic math functions ##### define model parameters ##### L = 4 # system size J = 1.0 # hopping U = np.sqrt(2.0) # interaction mu = 0.0 # chemical potential ##### construct Fermi-Hubbard Hamiltonian ##### # define boson basis with 3 states per site L bosons in the lattice N_up = L // 2 + L % 2 # number of fermions with spin up N_down = L // 2 # number of fermions with spin down basis_up = spinless_fermion_basis_1d(L, Nf=N_up) basis_down = spinless_fermion_basis_1d(L, Nf=N_down) basis = tensor_basis(basis_up, basis_down) # spinful fermions print(basis) # define site-coupling lists hop_right = [[-J, i, (i + 1) % L] for i in range(L)] #PBC hop_left = [[+J, i, (i + 1) % L] for i in range(L)] #PBC pot = [[-mu, i] for i in range(L)] # -\mu \sum_j n_{j \sigma} interact = [[U, i, i] for i in range(L)] # U/2 \sum_j n_{j,up} n_{j,down} # define static and dynamic lists static = [ ['+-|', hop_left], # up hops left ['-+|', hop_right], # up hops right ['|+-', hop_left], # down hops left ['|-+', hop_right], # down hops right ['n|', pot], # up on-site potention
def test_gen_basis_spinless_fermion(l_max, N=4): L = 6 kblocks = [None] kblocks.extend(range(L)) pblocks = [None, 0, 1] ops = ["n", "z", "+", "-", "I"] Nfs = [None, N] t = np.array([(i + 1) % L for i in range(L)]) p = np.array([L - i - 1 for i in range(L)]) for Nf, kblock, pblock in product(Nfs, kblocks, pblocks): gen_blocks = {} basis_blocks = {} if kblock == 0 or kblock == L // 2: if pblock is not None: basis_blocks["pblock"] = (-1)**pblock gen_blocks["pblock"] = (p, pblock) else: basis_blocks["pblock"] = None gen_blocks["pblock"] = None else: basis_blocks["pblock"] = None gen_blocks["pblock"] = None if kblock is not None: basis_blocks["kblock"] = kblock gen_blocks["kblock"] = (t, kblock) else: basis_blocks["kblock"] = None gen_blocks["kblock"] = None basis_1d = spinless_fermion_basis_1d(L, Nf=Nf, **basis_blocks) gen_basis = spinless_fermion_basis_general(L, Nf=Nf, **gen_blocks) n = basis_1d._get_norms(np.float64)**2 n_gen = (gen_basis._n.astype(np.float64)) * gen_basis._pers.prod() if basis_1d.Ns != gen_basis.Ns: print(L, basis_blocks) print(basis_1d) print(gen_basis) raise ValueError("basis size mismatch") np.testing.assert_allclose(basis_1d._basis - gen_basis._basis, 0, atol=1e-6) np.testing.assert_allclose(n - n_gen, 0, atol=1e-6) for l in range(1, l_max + 1): for i0 in range(0, L - l + 1, 1): indx = range(i0, i0 + l, 1) for opstr in product(*[ops for i in range(l)]): opstr = "".join(list(opstr)) printing = dict(basis_blocks) printing["opstr"] = opstr printing["indx"] = indx printing["Nf"] = Nf err_msg = "testing: {opstr:} {indx:} Nf={Nf:} kblock={kblock:} pblock={pblock:}".format( **printing) check_ME(basis_1d, gen_basis, opstr, indx, np.complex128, err_msg)