def create_state(spin1, orb1, x1, y1, spin2, orb2, x2, y2): ''' Creates a dictionary representing a state Parameters ---------- spin1, spin2 : string of spin orb_up, orb_dn : string of orb x_up, y_up: integer coordinates of hole1 Must be (1,0), (0,1), (0,0) x_dn, y_dn: integer coordinates of hole2 Note ---- It is possible to return a state that is not in the variational space because the hole-hole Manhattan distance exceeds Mc. ''' assert (check_in_vs_condition(x1, y1, x2, y2)) assert not (((x1, y1)) == (x2, y2) and spin1 == spin2 and orb1 == orb2) assert (x1, y1) in [(0, 0), (1, 0), (0, 1)] orb, _, _ = lat.get_unit_cell_rep(x1, y1) assert orb1 in orb orb, _, _ = lat.get_unit_cell_rep(x2, y2) assert orb2 in orb state = {'hole1_spin' :spin1,\ 'hole1_orb' :orb1,\ 'hole1_coord':(x1,y1),\ 'hole2_spin' :spin2,\ 'hole2_orb' :orb2,\ 'hole2_coord':(x2,y2)} return state
def create_tpp_nn_matrix(VS, tpp_nn_hop_fac): ''' similar to comments in create_tpd_nn_matrix ''' print "start create_tpp_nn_matrix" print "==========================" dim = VS.dim data = [] row = [] col = [] for i in xrange(0, dim): start_state = VS.get_state(VS.lookup_tbl[i]) # only hole hops with tpd if start_state['type'] == 'no_eh': continue if start_state['type'] == 'one_eh': s1 = start_state['e_spin'] orb1 = start_state['e_orb'] orb2 = start_state['h_orb'] x1, y1, z1 = start_state['e_coord'] x2, y2, z2 = start_state['h_coord'] # hole hops, only p-orbitals has t_pp if orb2 in pam.O_orbs and orb2 not in pam.ap_orbs and orb2 != 'pz1' and orb2 != 'pz2': for dir_ in tpp_nn_hop_dir: vx, vy, vz = directions_to_vecs[dir_] orbs2 = lat.get_unit_cell_rep(x2 + vx, y2 + vy, z2 + vz) if orbs2 != pam.O1_orbs and orbs2 != pam.O2_orbs: continue if not vs.check_in_vs_condition(x1, y1, x2 + vx, y2 + vy): continue for o2 in orbs2: if o2 == 'pz1' or o2 == 'pz2': continue new_state = vs.create_state(s1, orb1, x1, y1, z1, o2, x2 + vx, y2 + vy, z2 + vz) o12 = sorted([orb2, dir_, o2]) o12 = tuple(o12) set_matrix_element(row, col, data, new_state, i, VS, tpp_nn_hop_fac[o12]) row = np.array(row) col = np.array(col) data = np.array(data) # check if hoppings occur within groups of (up,up), (dn,dn), and (up,dn) #assert(check_spin_group(row,col,data,VS)==True) out = sps.coo_matrix((data, (row, col)), shape=(dim, dim)) return out
def create_tNdNd_nn_matrix(VS, tNdNd): ''' similar to comments in create_tNdNd_nn_matrix ''' print "start create_tNdNd_nn_matrix" print "============================" dim = VS.dim data = [] row = [] col = [] for i in xrange(0, dim): start_state = VS.get_state(VS.lookup_tbl[i]) if start_state['type'] == 'one_eh': se = start_state['e_spin'] orbe = start_state['e_orb'] orbh = start_state['h_orb'] xe, ye, ze = start_state['e_coord'] xh, yh, zh = start_state['h_coord'] # Nd electron hops for dir_ in tNdNd_nn_hop_dir: vx, vy, vz = directions_to_vecs[dir_] orbse = lat.get_unit_cell_rep(xe + vx, ye + vy, ze + vz) if orbse != pam.Nd_orbs: continue if not vs.check_in_vs_condition(xe + vx, ye + vy, xh, yh): continue for oe in orbse: new_state = vs.create_one_eh_state(se, oe, xe + vx, ye + vy, ze + vz, orbh, xh, yh, zh) set_matrix_element(row, col, data, new_state, i, VS, tNdNd) row = np.array(row) col = np.array(col) data = np.array(data) # check if hoppings occur within groups of (up,up), (dn,dn), and (up,dn) #assert(check_spin_group(row,col,data,VS)==True) out = sps.coo_matrix((data, (row, col)), shape=(dim, dim)) return out
def create_tpp_nn_matrix(phase, VS, tpp_nn_hop_fac): ''' similar to comments in create_tpd_nn_matrix ''' print "start create_tpp_nn_matrix" print "==========================" dim = VS.dim data = [] row = [] col = [] for i in xrange(0, dim): start_state = VS.get_state(VS.lookup_tbl[i]) # below check has been done in create_tpd_nn_matrix so here not necessary #assert VS.get_uid(start_state) == VS.lookup_tbl[i] s1 = start_state['hole1_spin'] s2 = start_state['hole2_spin'] orb1 = start_state['hole1_orb'] orb2 = start_state['hole2_orb'] x1, y1 = start_state['hole1_coord'] x2, y2 = start_state['hole2_coord'] # only p-orbitals has t_pp if orb1 in pam.O_orbs: # hole 1 hops (coordninates need to be shifted -> phase change) for dir_ in tpp_nn_hop_dir: vx, vy = directions_to_vecs[dir_] x1_new, y1_new = x1 + vx, y1 + vy # get the position of reference site(Cu) in the same unit cell orbs1_new, Rx_new, Ry_new = lat.get_unit_cell_rep( x1_new, y1_new) if orbs1_new == ['NotOnSublattice' ] or orbs1_new == pam.Cu_orbs: continue x1_shift = x1_new - Rx_new y1_shift = y1_new - Ry_new x2_shift = x2 - Rx_new y2_shift = y2 - Ry_new # consider t_pp for all cases for o1 in orbs1_new: if s1 == s2 and o1 == orb2 and x1_shift == x2_shift and y1_shift == y2_shift: continue #if pam.if_project_out_two_holes_on_different_Cu == 1: # if (o1 in pam.Cu_orbs and orb2 in pam.Cu_orbs and (x1_shift,y1_shift)!=(x2_shift,y2_shift)): # continue if vs.check_in_vs_condition(x1_shift, y1_shift, x2_shift, y2_shift): tmp_state = vs.create_state(s1,o1, x1_shift,y1_shift,\ s2,orb2,x2_shift,y2_shift) new_state, ph = vs.make_state_canonical(tmp_state) o12 = sorted([orb1, dir_, o1]) o12 = tuple(o12) set_matrix_element(row,col,data,new_state,i,VS,\ tpp_nn_hop_fac[o12]*phase[(Rx_new,Ry_new)]*ph) # hole 2 hops, only p-orbitals has t_pp if orb2 in pam.O_orbs: for dir_ in tpp_nn_hop_dir: vx, vy = directions_to_vecs[dir_] x2_new, y2_new = x2 + vx, y2 + vy orbs2_new, _, _ = lat.get_unit_cell_rep(x2_new, y2_new) if orbs2_new == ['NotOnSublattice' ] or orbs2_new == pam.Cu_orbs: continue for o2 in orbs2_new: # consider Pauli principle if s1 == s2 and orb1 == o2 and x1 == x2_new and y1 == y2_new: continue #if pam.if_project_out_two_holes_on_different_Cu == 1: # if (orb1 in pam.Cu_orbs and o2 in pam.Cu_orbs and (x1,y1)!=(x2_new,y2_new)): # continue if vs.check_in_vs_condition(x1, y1, x2_new, y2_new): tmp_state = vs.create_state(s1, orb1, x1, y1, s2, o2, x2_new, y2_new) new_state, ph = vs.make_state_canonical(tmp_state) o12 = sorted([orb2, dir_, o2]) o12 = tuple(o12) set_matrix_element(row, col, data, new_state, i, VS, tpp_nn_hop_fac[o12] * ph) row = np.array(row) col = np.array(col) data = np.array(data) # check if hoppings occur within groups of (up,up), (dn,dn), and (up,dn) assert (check_spin_group(row, col, data, VS) == True) out = sps.coo_matrix((data, (row, col)), shape=(dim, dim)) return out
def create_tpd_nn_matrix(phase, VS, tpd_nn_hop_dir, if_tpd_nn_hop, tpd_nn_hop_fac): ''' Create nearest neighbor (NN) pd hopping part of the Hamiltonian Parameters ---------- phase: dictionary containing the phase values exp(-kx*Rx*1j/2.0-ky*Ry*1j/2.0). Created with create_phase_dict. VS: VariationalSpace class from the module variationalSpace Returns ------- matrix: (sps coo format) t_pd hopping part of the Hamiltonian without the prefactor t_pd. Note from the sps documentation ------------------------------- By default when converting to CSR or CSC format, duplicate (i,j) entries will be summed together IMPORTANT ------------------------------- See note_on_set_hopping_term.jpg for how to set up the hopping elements The convention is to assign the phase to hole1 hopping When hole1 hops, there is an additional phase It seems hole2 can hop to another orb, but actually not, j'+n-1=j-n only change hole2's coordinate, not the orb For multiorbital cases, should make sure that hole2 does not change orb ''' print "start create_tpd_nn_matrix" print "==========================" dim = VS.dim tpd_orbs = tpd_nn_hop_fac.keys() data = [] row = [] col = [] for i in xrange(0, dim): start_state = VS.get_state(VS.lookup_tbl[i]) # double check which cost some time, might not necessary assert VS.get_uid(start_state) == VS.lookup_tbl[i] s1 = start_state['hole1_spin'] s2 = start_state['hole2_spin'] orb1 = start_state['hole1_orb'] orb2 = start_state['hole2_orb'] x1, y1 = start_state['hole1_coord'] x2, y2 = start_state['hole2_coord'] #print s1,s2,orb1,orb2,x1, y1,x2, y2 # some d-orbitals might have no tpd if if_tpd_nn_hop[orb1] == 1: # hole 1 hops (coordninates need to be shifted -> phase change) for dir_ in tpd_nn_hop_dir[orb1]: vx, vy = directions_to_vecs[dir_] # recall that x1, y1 are kept in (1,0), (0,1), (0,0) x1_new, y1_new = x1 + vx, y1 + vy # it is possible that up hole hops to neighboring unit cell # so need to get the position of reference site(Cu) after hopping orb, Rx_new, Ry_new = lat.get_unit_cell_rep(x1_new, y1_new) if orb == ['NotOnSublattice']: continue # get the coordinates relative to the new unit cell origin x1_shift = x1_new - Rx_new y1_shift = y1_new - Ry_new # dn hole needs change coor corresponding to the new unit cell of up hole # but not change orb. see above and note_on_set_hopping_term.jpg x2_shift = x2 - Rx_new y2_shift = y2 - Ry_new orbs1_new, _, _ = lat.get_unit_cell_rep(x1_shift, y1_shift) orbs2_new, _, _ = lat.get_unit_cell_rep(x2_shift, y2_shift) if orbs1_new == ['NotOnSublattice' ] or orbs2_new == ['NotOnSublattice']: continue # consider t_pd for all cases # recall that when up hole hops, dn hole should not change orb for o1 in orbs1_new: if if_tpd_nn_hop[o1] == 0: continue # consider Pauli principle if s1 == s2 and o1 == orb2 and x1_shift == x2_shift and y1_shift == y2_shift: continue #if pam.if_project_out_two_holes_on_different_Cu == 1: # if (o1 in pam.Cu_orbs and orb2 in pam.Cu_orbs and (x1_shift,y1_shift)!=(x2_shift,y2_shift)): # continue if vs.check_in_vs_condition(x1_shift, y1_shift, x2_shift, y2_shift): tmp_state = vs.create_state(s1,o1, x1_shift,y1_shift,\ s2,orb2,x2_shift,y2_shift) new_state, ph = vs.make_state_canonical(tmp_state) o12 = tuple([orb1, dir_, o1]) if o12 in tpd_orbs: set_matrix_element(row,col,data,new_state,i,VS,\ tpd_nn_hop_fac[o12]*phase[(Rx_new,Ry_new)]*ph) # hole 2 hops; some d-orbitals might have no tpd if if_tpd_nn_hop[orb2] == 1: for dir_ in tpd_nn_hop_dir[orb2]: vx, vy = directions_to_vecs[dir_] x2_new, y2_new = x2 + vx, y2 + vy orbs2_new, _, _ = lat.get_unit_cell_rep(x2_new, y2_new) if orbs2_new == ['NotOnSublattice']: continue for o2 in orbs2_new: if if_tpd_nn_hop[o2] == 0: continue # consider Pauli principle if s1 == s2 and orb1 == o2 and x1 == x2_new and y1 == y2_new: continue #if pam.if_project_out_two_holes_on_different_Cu == 1: # if (orb1 in pam.Cu_orbs and o2 in pam.Cu_orbs and (x1,y1)!=(x2_new,y2_new)): # continue if vs.check_in_vs_condition(x1, y1, x2_new, y2_new): tmp_state = vs.create_state(s1, orb1, x1, y1, s2, o2, x2_new, y2_new) new_state, ph = vs.make_state_canonical(tmp_state) o12 = tuple([orb2, dir_, o2]) if o12 in tpd_orbs: set_matrix_element(row, col, data, new_state, i, VS, tpd_nn_hop_fac[o12] * ph) row = np.array(row) col = np.array(col) data = np.array(data) # check if hoppings occur within groups of (up,up), (dn,dn), and (up,dn) assert (check_spin_group(row, col, data, VS) == True) out = sps.coo_matrix((data, (row, col)), shape=(dim, dim)) return out
def create_lookup_tbl(self): ''' Create a sorted lookup table containing the unique identifiers (uid) of all the states in the variational space. Manhattan distance between a hole and the Cu-site (0,0) does not exceed Mc Then the hole-hole distance cannot be larger than 2*Mc Returns ------- lookup_tbl: sorted python list ''' Mc = self.Mc lookup_tbl = [] # one_hole no e-h pairs: hole can only be on Ni or O for ux in range(-Mc,Mc+1): Bu = Mc - abs(ux) for uy in range(-Bu,Bu+1): for uz in [0]: orb1s = lat.get_unit_cell_rep(ux,uy,uz) if orb1s==['NotOnSublattice'] or orb1s==pam.Nd_orbs: continue for orb1 in orb1s: # see H_matrix_reducing_VS.pdf if pam.reduce_VS==1: for s1 in ['up']:#,'dn']: if check_in_vs_condition(ux,uy,0,0): state = create_one_hole_no_eh_state(s1,orb1,ux,uy,uz) canonical_state,_ = make_state_canonical(state) if self.filter_func(canonical_state): uid = self.get_uid(canonical_state) lookup_tbl.append(uid) # one e-h pair # electron: for ux in range(-Mc,Mc+1): Bu = Mc - abs(ux) for uy in range(-Bu,Bu+1): for uz in [0]: orbes = lat.get_unit_cell_rep(ux,uy,uz) # e must be on Nd if orbes!=pam.Nd_orbs: continue # hole1: for vx in range(-Mc,Mc+1): Bv = Mc - abs(vx) for vy in range(-Bv,Bv+1): for vz in [0]: orb1s = lat.get_unit_cell_rep(vx,vy,vz) if orb1s==['NotOnSublattice'] or orb1s==pam.Nd_orbs: continue # hole2: for wx in range(-Mc,Mc+1): Bw = Mc - abs(wx) for wy in range(-Bw,Bw+1): for wz in [0]: orb2s = lat.get_unit_cell_rep(wx,wy,wz) if orb2s==['NotOnSublattice'] or orb2s==pam.Nd_orbs: continue if not (check_in_vs_condition(ux,uy,vx,vy) and \ check_in_vs_condition(ux,uy,wx,wy) and \ check_in_vs_condition(vx,vy,wx,wy)): continue for orbe in orbes: for orb1 in orb1s: for orb2 in orb2s: for se in ['up','dn']: for s1 in ['up','dn']: for s2 in ['up','dn']: # s2!=se because of eh pair if s2==se and s1==se: continue if pam.reduce_VS==1: # complicated way: #if s1==s2=='dn': # continue #s12 = sorted([s1,s2]) #if se=='up': # if s12!=['dn','up']: # continue #elif se=='dn': # if s12!=['up','up']: # continue # simple way: total spin should be up s12e = sorted([se,s1,s2]) if s12e!=['dn','up','up']: continue # consider Pauli principle if s1==s2 and orb1==orb2 \ and vx==wx and vy==wy and vz==wz: continue if se==s1 and orbe==orb1 \ and ux==vx and uy==vy and uz==vz: continue if se==s2 and orbe==orb2 \ and ux==wx and uy==wy and uz==wz: continue state = create_one_hole_one_eh_state(se,orbe,ux,uy,uz,\ s1,orb1,vx,vy,vz,s2,orb2,wx,wy,wz) canonical_state,_ = make_state_canonical(state) if self.filter_func(canonical_state): uid = self.get_uid(canonical_state) lookup_tbl.append(uid) lookup_tbl = list(set(lookup_tbl)) # remove duplicates lookup_tbl.sort() #print "\n lookup_tbl:\n", lookup_tbl return lookup_tbl
def create_lookup_tbl(self): ''' Create a sorted lookup table containing the unique identifiers (uid) of all the states in the variational space. Manhattan distance between a hole and the Cu-site (0,0) does not exceed Mc Then the hole-hole distance cannot be larger than 2*Mc Returns ------- lookup_tbl: sorted python list. ''' Mc = self.Mc lookup_tbl = [] for ux in range(-Mc, Mc + 1): Bu = Mc - abs(ux) for uy in range(-Bu, Bu + 1): orb1s = lat.get_unit_cell_rep(ux, uy) if orb1s == ['NotOnSublattice']: continue for vx in range(-Mc, Mc + 1): Bv = Mc - abs(vx) for vy in range(-Bv, Bv + 1): orb2s = lat.get_unit_cell_rep(vx, vy) if orb2s == ['NotOnSublattice']: continue if calc_manhattan_dist(ux, uy, vx, vy) > 2 * Mc: continue for orb1 in orb1s: for orb2 in orb2s: for s1 in ['up', 'dn']: for s2 in ['up', 'dn']: # try screen out same spin states if pam.VS_only_up_dn == 1: if s1 == s2: continue # try only keep Sz=1 triplet states if pam.VS_only_up_up == 1: if not s1 == s2 == 'up': continue # consider Pauli principle if s1 == s2 and orb1 == orb2 and ux == vx and uy == vy: continue #if s1=='dn' and s2=='dn': # print "candiate state: ", s1,orb1,ux,uy,s2,orb2,vx,vy if check_in_vs_condition( ux, uy, vx, vy): state = create_state( s1, orb1, ux, uy, s2, orb2, vx, vy) canonical_state, _ = make_state_canonical( state) if self.filter_func(canonical_state): uid = self.get_uid(canonical_state) lookup_tbl.append(uid) lookup_tbl = list(set(lookup_tbl)) # remove duplicates lookup_tbl.sort() #print "\n lookup_tbl:\n", lookup_tbl return lookup_tbl
def create_lookup_tbl(self): ''' Create a sorted lookup table containing the unique identifiers (uid) of all the states in the variational space. Manhattan distance between a hole and the Cu-site (0,0) does not exceed Mc Then the hole-hole distance cannot be larger than 2*Mc Returns ------- lookup_tbl: sorted python list. ''' Mc = self.Mc lookup_tbl = [] # vacuum undoped state (no e-h pairs) state = create_no_eh_state() if self.filter_func(state): uid = self.get_uid(state) lookup_tbl.append(uid) # one e-h pair # electron: for ux in range(-Mc, Mc + 1): Bu = Mc - abs(ux) for uy in range(-Bu, Bu + 1): for uz in [0]: orb1s = lat.get_unit_cell_rep(ux, uy, uz) # el must be on Nd if orb1s != pam.Nd_orbs: continue # hole: for vx in range(-Mc, Mc + 1): Bv = Mc - abs(vx) for vy in range(-Bv, Bv + 1): for vz in [0]: orb2s = lat.get_unit_cell_rep(vx, vy, vz) if orb2s == ['NotOnSublattice' ] or orb2s == pam.Nd_orbs: continue if not check_in_vs_condition(ux, uy, vx, vy): continue for orb1 in orb1s: for orb2 in orb2s: # only need to consider one spin case, see top for s in ['up', 'dn']: # reduce VS size if pam.VS_only_up_Nd == 1: if s == 'dn': continue state = create_one_eh_state( s, orb1, ux, uy, uz, orb2, vx, vy, vz) if self.filter_func(state): uid = self.get_uid(state) lookup_tbl.append(uid) lookup_tbl = list(set(lookup_tbl)) # remove duplicates lookup_tbl.sort() #print "\n lookup_tbl:\n", lookup_tbl return lookup_tbl
def make_state_canonical(state): ''' 1. There are a few cases to avoid having duplicate states where the holes are indistinguishable. The sign change due to anticommuting creation operators should be taken into account so that phase below has a negative sign see Mirko's notes VS_state.pdf for the real meaning of states! ============================================================= Case 1: when hole2 is on left of hole 1, need to shift hole2's coordinates to origin unit cell so that all states' first hole locates in origin Orders the hole coordinates in such a way that the coordinates of the left creation operator are lexicographically smaller than those of the right. ======================================================= Case 2: If two holes locate on the same sites a) same spin state: up, dxy, (0,0), up, dx2-y2, (0,0) = up, dx2-y2, (0,0), up, dxy, (0,0) need sort orbital order b) opposite spin state: only keep spin1 up state For phase, see note_on_two_holes_same_spin.jpg Note the /2.0, same as create_phase_dict in hamiltonian.py 2. Besides, see emails with Mirko on Mar.1, 2018: Suppose Tpd|state_i> = |state_j> = phase*|tmp_state_j> = phase*ph*|canonical_state_j>, then tpd = <state_j | Tpd | state_i> = conj(phase*ph)* <canonical_state_j | Tpp | state_i> so <canonical_state_j | Tpp | state_i> = tpd/conj(phase*ph) = tpd*phase*ph Because conj(phase) = 1/phase, *phase and /phase in setting tpd and tpp seem to give same results But need to change * or / in both tpd and tpp functions Similar for tpp ''' s1 = state['hole1_spin'] s2 = state['hole2_spin'] orb1 = state['hole1_orb'] orb2 = state['hole2_orb'] x1, y1 = state['hole1_coord'] x2, y2 = state['hole2_coord'] canonical_state = state phase = 1.0 # see Mirko's notes VS_state.pdf; note that phase depends on Dx,Dy instead of dx,dy if (x2, y2) < (x1, y1): dx = x2 - x1 dy = y2 - y1 (ux, uy) = lat.orb_pos[orb2] canonical_state = create_state(s2, orb2, ux, uy, s1, orb1, ux - dx, uy - dy) kx = pam.kx ky = pam.ky _, Rx2, Ry2 = lat.get_unit_cell_rep(x2, y2) _, Rx1, Ry1 = lat.get_unit_cell_rep(x1, y1) Dx = Rx2 - Rx1 Dy = Ry2 - Ry1 phase = -np.exp(-(kx * Dx + ky * Dy) * 1j / 2.0) elif (x1, y1) == (x2, y2): if s1 == s2: o12 = list(sorted([orb1, orb2])) if o12[0] == orb2: canonical_state = create_state(s2, orb2, x1, y1, s1, orb1, x1, y1) phase = -1.0 elif s1 == 'dn' and s2 == 'up': canonical_state = create_state('up', orb2, x1, y1, 'dn', orb1, x1, y1) phase = -1.0 return canonical_state, phase
def create_lookup_tbl(self): ''' Create a sorted lookup table containing the unique identifiers (uid) of all the states in the variational space. Returns ------- lookup_tbl: sorted python list. ''' Mc = self.Mc # Loops are over all states for which the Manhattan distance # between any two particles does not exceed Mc. lookup_tbl = [] for s1 in ['up', 'dn']: for orb1 in pam.orbs: ux, uy = lat.orb_pos[orb1] # Manhattan distance between any two holes does not exceed Mc for vx in range(-Mc + ux, Mc + ux + 1): B = Mc - abs(vx - ux) for vy in range(-B + uy, B + uy + 1): orb2s, _, _ = lat.get_unit_cell_rep(vx, vy) if orb2s == ['NotOnSublattice']: continue for orb2 in orb2s: for s2 in ['up', 'dn']: # try screen out same spin states #if s1==s2: # continue # consider Pauli principle if s1 == s2 and orb1 == orb2 and ux == vx and uy == vy: continue #if pam.if_project_out_two_holes_on_different_Cu == 1: # if (orb1 in pam.Cu_orbs and orb2 in pam.Cu_orbs and (ux,uy)!=(vx,vy)): # continue #if s1=='dn' and s2=='dn': # print "candiate state: ", s1,orb1,ux,uy,s2,orb2,vx,vy if check_in_vs_condition(ux, uy, vx, vy): state = create_state( s1, orb1, ux, uy, s2, orb2, vx, vy) canonical_state, _ = make_state_canonical( state) #if pam.if_project_out_two_holes_on_different_Cu == 1: # if torb1 in pam.Cu_orbs and torb2 in pam.Cu_orbs and (tx1, ty1)!=(tx2, ty2): # continue if self.filter_func(canonical_state): uid = self.get_uid(canonical_state) lookup_tbl.append(uid) lookup_tbl = list(set(lookup_tbl)) # remove duplicates lookup_tbl.sort() #print "\n lookup_tbl:\n", lookup_tbl return lookup_tbl
def create_tpp_nn_matrix(VS, tpp_nn_hop_fac): ''' similar to comments in create_tpd_nn_matrix ''' print "start create_tpp_nn_matrix" print "==========================" dim = VS.dim data = [] row = [] col = [] for i in xrange(0, dim): start_state = VS.get_state(VS.lookup_tbl[i]) # below check has been done in create_tpd_nn_matrix so here not necessary #assert VS.get_uid(start_state) == VS.lookup_tbl[i] s1 = start_state['hole1_spin'] s2 = start_state['hole2_spin'] orb1 = start_state['hole1_orb'] orb2 = start_state['hole2_orb'] x1, y1 = start_state['hole1_coord'] x2, y2 = start_state['hole2_coord'] # hole1 hops: only p-orbitals has t_pp if orb1 in pam.O_orbs: for dir_ in tpp_nn_hop_dir: vx, vy = directions_to_vecs[dir_] orbs1 = lat.get_unit_cell_rep(x1 + vx, y1 + vy) if orbs1 == ['NotOnSublattice'] or orbs1 == pam.Cu_orbs: continue # consider t_pd for all cases; when up hole hops, dn hole should not change orb for o1 in orbs1: # consider Pauli principle if s1 == s2 and o1 == orb2 and (x1 + vx, y1 + vy) == (x2, y2): continue if vs.check_in_vs_condition(x1 + vx, y1 + vy, x2, y2): tmp_state = vs.create_state(s1, o1, x1 + vx, y1 + vy, s2, orb2, x2, y2) new_state, ph = vs.make_state_canonical(tmp_state) s1n = new_state['hole1_spin'] s2n = new_state['hole2_spin'] orb1n = new_state['hole1_orb'] orb2n = new_state['hole2_orb'] x1n, y1n = new_state['hole1_coord'] x2n, y2n = new_state['hole2_coord'] #print x1,y1,orb1,s1,x2,y2,orb2,s2,'tpp hops to',x1n, y1n,orb1n,s1n,x2n, y2n,orb2n,s2n o12 = sorted([orb1, dir_, o1]) o12 = tuple(o12) set_matrix_element(row, col, data, new_state, i, VS, tpp_nn_hop_fac[o12] * ph) # hole 2 hops, only p-orbitals has t_pp if orb2 in pam.O_orbs: for dir_ in tpp_nn_hop_dir: vx, vy = directions_to_vecs[dir_] orbs2 = lat.get_unit_cell_rep(x2 + vx, y2 + vy) if orbs2 == ['NotOnSublattice'] or orbs2 == pam.Cu_orbs: continue for o2 in orbs2: # consider Pauli principle if s1 == s2 and orb1 == o2 and (x1, y1) == (x2 + vx, y2 + vy): continue if vs.check_in_vs_condition(x1, y1, x2 + vx, y2 + vy): tmp_state = vs.create_state(s1, orb1, x1, y1, s2, o2, x2 + vx, y2 + vy) new_state, ph = vs.make_state_canonical(tmp_state) s1n = new_state['hole1_spin'] s2n = new_state['hole2_spin'] orb1n = new_state['hole1_orb'] orb2n = new_state['hole2_orb'] x1n, y1n = new_state['hole1_coord'] x2n, y2n = new_state['hole2_coord'] #print x1,y1,orb1,s1,x2,y2,orb2,s2,'tpp hops to',x1n, y1n,orb1n,s1n,x2n, y2n,orb2n,s2n o12 = sorted([orb2, dir_, o2]) o12 = tuple(o12) set_matrix_element(row, col, data, new_state, i, VS, tpp_nn_hop_fac[o12] * ph) row = np.array(row) col = np.array(col) data = np.array(data) # check if hoppings occur within groups of (up,up), (dn,dn), and (up,dn) assert (check_spin_group(row, col, data, VS) == True) out = sps.coo_matrix((data, (row, col)), shape=(dim, dim)) return out
def create_tpd_nn_matrix(VS, tpd_nn_hop_dir, if_tpd_nn_hop, tpd_nn_hop_fac): ''' Create nearest neighbor (NN) pd hopping part of the Hamiltonian Parameters ---------- VS: VariationalSpace class from the module variationalSpace Returns ------- matrix: (sps coo format) t_pd hopping part of the Hamiltonian without the prefactor t_pd. Note from the sps documentation ------------------------------- By default when converting to CSR or CSC format, duplicate (i,j) entries will be summed together ''' print "start create_tpd_nn_matrix" print "==========================" dim = VS.dim tpd_orbs = tpd_nn_hop_fac.keys() data = [] row = [] col = [] for i in xrange(0, dim): start_state = VS.get_state(VS.lookup_tbl[i]) # double check which cost some time, might not necessary assert VS.get_uid(start_state) == VS.lookup_tbl[i] s1 = start_state['hole1_spin'] s2 = start_state['hole2_spin'] orb1 = start_state['hole1_orb'] orb2 = start_state['hole2_orb'] x1, y1 = start_state['hole1_coord'] x2, y2 = start_state['hole2_coord'] # hole 1 hops: some d-orbitals might have no tpd if if_tpd_nn_hop[orb1] == 1: for dir_ in tpd_nn_hop_dir[orb1]: vx, vy = directions_to_vecs[dir_] orbs1 = lat.get_unit_cell_rep(x1 + vx, y1 + vy) if orbs1 == ['NotOnSublattice']: continue # consider t_pd for all cases; when up hole hops, dn hole should not change orb for o1 in orbs1: if if_tpd_nn_hop[o1] == 0: continue # consider Pauli principle if s1 == s2 and o1 == orb2 and (x1 + vx, y1 + vy) == (x2, y2): continue if vs.check_in_vs_condition(x1 + vx, y1 + vy, x2, y2): tmp_state = vs.create_state(s1, o1, x1 + vx, y1 + vy, s2, orb2, x2, y2) new_state, ph = vs.make_state_canonical(tmp_state) s1n = new_state['hole1_spin'] s2n = new_state['hole2_spin'] orb1n = new_state['hole1_orb'] orb2n = new_state['hole2_orb'] x1n, y1n = new_state['hole1_coord'] x2n, y2n = new_state['hole2_coord'] # print x1,y1,orb1,s1,x2,y2,orb2,s2,'tpd hops to',x1n, y1n,orb1n,s1n,x2n, y2n,orb2n,s2n o12 = tuple([orb1, dir_, o1]) if o12 in tpd_orbs: set_matrix_element(row, col, data, new_state, i, VS, tpd_nn_hop_fac[o12] * ph) # hole 2 hops; some d-orbitals might have no tpd if if_tpd_nn_hop[orb2] == 1: for dir_ in tpd_nn_hop_dir[orb2]: vx, vy = directions_to_vecs[dir_] orbs2 = lat.get_unit_cell_rep(x2 + vx, y2 + vy) if orbs2 == ['NotOnSublattice']: continue for o2 in orbs2: if if_tpd_nn_hop[o2] == 0: continue # consider Pauli principle if s1 == s2 and orb1 == o2 and (x1, y1) == (x2 + vx, y2 + vy): continue if vs.check_in_vs_condition(x1, y1, x2 + vx, y2 + vy): tmp_state = vs.create_state(s1, orb1, x1, y1, s2, o2, x2 + vx, y2 + vy) new_state, ph = vs.make_state_canonical(tmp_state) s1n = new_state['hole1_spin'] s2n = new_state['hole2_spin'] orb1n = new_state['hole1_orb'] orb2n = new_state['hole2_orb'] x1n, y1n = new_state['hole1_coord'] x2n, y2n = new_state['hole2_coord'] #print x1,y1,orb1,s1,x2,y2,orb2,s2,'tpd hops to',x1n, y1n,orb1n,s1n,x2n, y2n,orb2n,s2n o12 = tuple([orb2, dir_, o2]) if o12 in tpd_orbs: set_matrix_element(row, col, data, new_state, i, VS, tpd_nn_hop_fac[o12] * ph) row = np.array(row) col = np.array(col) data = np.array(data) # check if hoppings occur within groups of (up,up), (dn,dn), and (up,dn) assert (check_spin_group(row, col, data, VS) == True) out = sps.coo_matrix((data, (row, col)), shape=(dim, dim)) return out
def create_tpd_nn_matrix(VS, tpd_nn_hop_dir, if_tpd_nn_hop, tpd_nn_hop_fac): ''' Create nearest neighbor (NN) pd hopping part of the Hamiltonian Only hole can hop with tpd Parameters ---------- VS: VariationalSpace class from the module variationalSpace Returns ------- matrix: (sps coo format) t_pd hopping part of the Hamiltonian without the prefactor t_pd. Note from the sps documentation ------------------------------- By default when converting to CSR or CSC format, duplicate (i,j) entries will be summed together ''' print "start create_tpd_nn_matrix" print "==========================" dim = VS.dim tpd_orbs = tpd_nn_hop_fac.keys() data = [] row = [] col = [] for i in xrange(0, dim): start_state = VS.get_state(VS.lookup_tbl[i]) # double check which cost some time, might not necessary assert VS.get_uid(start_state) == VS.lookup_tbl[i] # only hole hops with tpd if start_state['type'] == 'no_eh': continue if start_state['type'] == 'one_eh': s1 = start_state['e_spin'] orb1 = start_state['e_orb'] orb2 = start_state['h_orb'] x1, y1, z1 = start_state['e_coord'] x2, y2, z2 = start_state['h_coord'] # hole hops; some d-orbitals might have no tpd if if_tpd_nn_hop[orb2] == 1: for dir_ in tpd_nn_hop_dir[orb2]: vx, vy, vz = directions_to_vecs[dir_] orbs2 = lat.get_unit_cell_rep(x2 + vx, y2 + vy, z2 + vz) if orbs2 == ['NotOnSublattice'] or orbs2 == pam.Nd_orbs: continue if not vs.check_in_vs_condition(x1, y1, x2 + vx, y2 + vy): continue for o2 in orbs2: if if_tpd_nn_hop[o2] == 0: continue new_state = vs.create_one_eh_state( s1, orb1, x1, y1, z1, o2, x2 + vx, y2 + vy, z2 + vz) o12 = tuple([orb2, dir_, o2]) if o12 in tpd_orbs: set_matrix_element(row, col, data, new_state, i, VS, tpd_nn_hop_fac[o12]) row = np.array(row) col = np.array(col) data = np.array(data) # check if hoppings occur within groups of (up,up), (dn,dn), and (up,dn) #assert(check_spin_group(row,col,data,VS)==True) out = sps.coo_matrix((data, (row, col)), shape=(dim, dim)) return out