Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
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
Example #6
0
    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
Example #7
0
    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
Example #8
0
    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
Example #9
0
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
Example #10
0
    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
Example #11
0
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
Example #12
0
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
Example #13
0
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