def apply_H_cin(self, i):
     """
     @param i : unsigned integer, state in occupation representation.
     """
     targets = []
     # for each site
     for site in range(1, self.nb_sites + 1):
         # Perform the following tasks for both spins
         for spin in [site, site + self.nb_sites]:
             # if there is a current spin at site
             if (gmpy2.bit_test(i, spin - 1)):
                 # loop over each neighbors
                 for neighbor in self.get_neighbors(site):
                     # add element to the answer if site is vacant
                     if (not gmpy2.bit_test(
                             i, int(spin - site + neighbor - 1))):
                         # count the number of electrons between the creation and annihilation sites
                         create_at = int(spin - site + neighbor - 1)
                         destroy_at = int(spin - 1)
                         n_el = 0
                         for c in np.arange(
                                 min(create_at, destroy_at) + 1,
                                 max(create_at, destroy_at)):
                             if gmpy2.bit_test(i, int(c)):
                                 n_el += 1
                         targets.append([
                             ((-1)**(1 + n_el)) * self.t,
                             gmpy2.bit_flip(gmpy2.bit_flip(i, spin - 1),
                                            int(spin - site + neighbor - 1))
                         ])
     return targets
Exemplo n.º 2
0
    def get_rho_from_v(self,v,l):
        '''
        :param v: wave vector
        :param l: number of sites
        :return: <psi|cidci|psi>
        '''
        # initialize the density matrix
        rho = np.zeros([4*l,4*l],dtype=complex)

        # populate the matrix

        # iterate over all impurity+bath positions i
        for i in np.arange(4*l,dtype=int):
            # iterate over all impurity+bath positions j
            for j in np.arange(4*l,dtype=int):
                #iterate over all elements in the basis of the look-up table
                for run_k,k in enumerate(self.J):
                    #check if a+i aj|k> is not null
                    if(gmpy2.bit_test(int(k),int(j))):
                        if(gmpy2.bit_test(int(k),int(i))==0 or i==j):
                            new_state=gmpy2.bit_flip(int(k),int(j))
                            new_state=gmpy2.bit_flip(new_state,int(i))
                            run_new = self.state2index(new_state)
                            #and don't forget the sign !
                            occupancy_between=0
                            for l in np.arange(min(i,j)+1,max(i,j)):
                                occupancy_between+=gmpy2.bit_test(int(k),int(l))
                            rho[i,j]+=(-1)**occupancy_between*np.conjugate(v[run_new])*v[run_k]
        return rho
Exemplo n.º 3
0
    def get_rho_impurity(self, impurity_index, verbose=False):
        '''
        :param impurity_index: index of the impurity
        :return: single particle density matrix in the impurity basis
        '''
        # Get ground state (updates the chemical potential)
        vs = self.get_ground_state(impurity_index, verbose)
        v = np.zeros(np.shape(vs[0]), dtype=complex)
        if verbose:
            print(np.around(vs, 2))
        # initialize the density matrix
        rho = np.zeros([4 * len(impurity_index), 4 * len(impurity_index)],
                       dtype=complex)

        # the coefs part ensures that the ground state has a defined spin on the impurity if it is degenerated
        coefs = np.zeros(len(vs), dtype=complex)
        for k, psi in enumerate(vs):
            for i in np.arange(len(psi)):
                impurity_down = 0
                for j in np.arange(len(impurity_index)):
                    if (gmpy2.bit_test(int(i), int(j + len(impurity_index)))
                            and not gmpy2.bit_test(int(i), int(j))):
                        impurity_down += 1
                coefs[k] += impurity_down * psi[i]
        if len(coefs) == 2:
            if (np.abs(coefs[0]) > 0.0001):
                c = coefs[1] / coefs[0]
                beta = 1 / np.sqrt(1 + c**2)
                alpha = -beta * c
                v = alpha * vs[0] + beta * vs[1]
            else:
                v = vs[0]
        else:
            v = vs[0]
        v = v / np.linalg.norm(v)
        if verbose:
            print("new ground state")
            print(v)
        # populate the matrix
        # iterate over all impurity+bath positions i
        for i in np.arange(4 * len(impurity_index), dtype=int):
            # iterate over all impurity+bath positions j
            for j in np.arange(4 * len(impurity_index), dtype=int):
                #iterate over all elements in the basis of the Fock space
                for k in np.arange(2**(4 * len(impurity_index)), dtype=int):
                    #check if a+i aj|k> is not null
                    if (gmpy2.bit_test(int(k), int(j))):
                        if (gmpy2.bit_test(int(k), int(i)) == 0 or i == j):
                            new_state = gmpy2.bit_flip(int(k), int(j))
                            new_state = gmpy2.bit_flip(new_state, int(i))
                            #and don't forget the sign !
                            occupancy_between = 0
                            for l in np.arange(min(i, j) + 1, max(i, j)):
                                occupancy_between += gmpy2.bit_test(
                                    int(k), int(l))
                            rho[i,
                                j] += (-1)**occupancy_between * np.conjugate(
                                    v[new_state]) * v[k]
        return rho
 def apply_H_pot(self, i):
     """
     @param i : unsigned integer, state in occupation representation.
     """
     potential_energy = 0
     ## loop over the sites
     for site in range(0, self.nb_sites):
         if (gmpy2.bit_test(i, site)
                 and gmpy2.bit_test(i, site + self.nb_sites)):
             potential_energy += self.U
     return [[potential_energy, i]]
Exemplo n.º 5
0
    def h_2_cdef(self,state_i,state_j):
        '''
        :param state_j: (int) state where the destruction happened
        :param state_i: (int) state where the creation happened
        :return: The "2 particles" energy for 2 jump from site d towards site c
        '''
        jumps = state_i^state_j
        # get the position of the 2 destruction and creation sites
        d_sites = int(state_j & jumps)
        c_sites = int((state_i & jumps))
        found_c1 = False
        found_d1 = False
        c1=0
        c2=0
        d1=0
        d2=0
        for i in np.arange(self.imp_bath_size):
            i=int(i)
            if(gmpy2.bit_test(d_sites,i)):
                if found_d1:
                    d2=i
                else:
                    found_d1=True
                    d1=i
            elif(gmpy2.bit_test(c_sites,i)):
                if found_c1:
                    c2=i
                else:
                    found_c1=True
                    c1=i

        # compute the term
        h=self.get_U_tilda(c1,d1,c2,d2)-self.get_U_tilda(c1,d2,c2,d1)-self.get_U_tilda(c2,d1,c1,d2)+self.get_U_tilda(c2,d2,c1,d1)

        # get the occupation between c2 d2
        occupied = 0
        for k in np.arange((min(c2, d2) + 1), max(c2, d2)):
            occupied += gmpy2.bit_test(state_j, int(k))

        s1 = (-1) ** (occupied)

        # compute the intermediary state
        tmp_state = gmpy2.bit_flip(state_j,c2)
        tmp_state = gmpy2.bit_flip(tmp_state,d2)
        # get the occupation berween c1 d1
        occupied = 0
        for k in np.arange((min(c1, d1) + 1), max(c1, d1)):
            occupied += gmpy2.bit_test(tmp_state, int(k))

        s2 = (-1) ** (occupied)

        return s1*s2*h
Exemplo n.º 6
0
def generateKeyPairsBulk(pvk_list):
    count = len(pvk_list)

    table = []  # generate a table of points G, 2G, 4G, 8G...(2^255)G
    table.append(G)
    for i in range(1, 256):
        table.append(Point_Doubling(table[i - 1]))

    pub_list = [Point.IDENTITY_ELEMENT for i in range(count)]

    for i in range(256):
        runList = []
        #        // calculate (Px - Qx)
        for j in range(count):
            k = pvk_list[j]
            if gmpy2.bit_test(k, i):
                if pub_list[j] == Point.IDENTITY_ELEMENT:
                    run = 2
                else:
                    run = (pub_list[j].x - table[i].x) % modulo
            else:
                run = 2

            runList.append(run)

#       // calculate 1/(Px - Qx)
        runList = bulkInversionModP(runList)
        #       // complete the addition
        for j in range(count):
            k = pvk_list[j]
            if gmpy2.bit_test(k, i):
                if pub_list[j] == Point.IDENTITY_ELEMENT:
                    pub_list[j] = table[i]
                else:
                    rise = (pub_list[j].y - table[i].y) % modulo
                    #                   // s = (Py - Qy)/(Px - Qx)
                    s = rise * runList[j]
                    #                   //rx = (s*s - px - qx) % _p;
                    rx = (s * s - pub_list[j].x - table[i].x) % modulo
                    #                   //ry = (s * (px - rx) - py) % _p;
                    ry = ((s * (pub_list[j].x - rx)) % modulo -
                          pub_list[j].y) % modulo

                    pub_list[j] = Point(rx, ry)

    return pub_list
Exemplo n.º 7
0
def check_top_row(mask: Bitmap, col: PlayerAction, board_shp: Tuple) -> bool:
    """ Checks whether the top row of the given column is full

    :param mask: bitmap representing positions of both players
    :param col: the column to be checked
    :param board_shp: the shape of the game board

    :return: True if the top row is full, False if it is empty
    """

    bit_pos = col * board_shp[1] + board_shp[0] - 1
    return bit_test(mask, bit_pos)
Exemplo n.º 8
0
    def h_2_cd(self,state_i,state_j):
        '''
        :param state_j: (int) state where the destruction happened
        :param state_i: (int) state where the creation happened
        :return: The "2 particles" energy for a jump from site d towards site c
        '''
        jump = state_i^state_j
        d = int(math.log2(state_j & jump))
        c = int(math.log2(state_i & jump))
        h=0
        state_i=int(state_i)
        state_j=int(state_j)
        for k in np.arange(self.imp_bath_size):
            k=int(k)
            occ_k_1=gmpy2.bit_test(state_i,k)
            occ_k_2=gmpy2.bit_test(state_j,k)
            occ_k_3=gmpy2.bit_test(state_i,k)*(k!=c)
            occ_k_4=gmpy2.bit_test(state_j,k)*(k!=d)
            if(occ_k_1==1):
                h+=self.get_U_tilda(k,k,c,d)
            if(k!=c and k!=d and occ_k_1==1):
                h+=-self.get_U_tilda(k,d,c,k)+self.get_U_tilda(c,k,k,d)
            h-=self.get_U_tilda(c,k,k,d)
            if(occ_k_2==1):
                h+=self.get_U_tilda(c,d,k,k)
            #if(occ_k_2==1):
            #    h+=self.get_U_tilda(c,d,k,k)
            #if(occ_k_3==1):
            #    h-=self.get_U_tilda(k,d,k,c)
            #if(occ_k_4==1):
            #    h-=self.get_U_tilda(c,k,d,k)
            #h+=self.get_U_tilda(c,k,d,k)
        #Check for the sign coming from c+i cj
        occupied = 0
        for k in np.arange((min(c, d) + 1), max(c, d)):
            occupied += gmpy2.bit_test(state_j, int(k))

        sign = (-1) ** (occupied)
        return sign*h
Exemplo n.º 9
0
 def h_2_ii(self,state,verbose=False):
     '''
     :param state: (int) binary occupation number
     :return: The "on site" energy (site correspond to impurity or bath) of state i
     '''
     h=0
     state=int(state)
     if verbose:
         print("considering state "+str(state))
     for m in np.arange(self.imp_bath_size):
         for n in np.arange(self.imp_bath_size):
             m = int(m)
             n = int(n)
             occ_m = gmpy2.bit_test(state, m)
             occ_n = gmpy2.bit_test(state, n)
             if m!=n:
                 #direct term
                 h+=self.get_U_tilda(m,m,n,n)*occ_n*occ_m
                 # cross term
                 h+=self.get_U_tilda(m,n,n,m)*occ_m*(1-occ_n)
             else:
                 h+=self.get_U_tilda(m,m,m,m)*occ_m
     return h
Exemplo n.º 10
0
def valid_actions(mask: Bitmap, board_shp: Tuple) -> list:
    """ Determines which actions are valid for the current game state

    :param mask: bitmap representing positions of both players
    :param board_shp: the shape of the game board

    :return: array of valid actions
    """

    # actions = np.ndarray(0)
    actions = []
    for col in range(board_shp[1]):
        bit_pos = col * board_shp[1] + board_shp[0] - 1
        if not bit_test(mask, bit_pos):
            # actions = np.append(actions, col)
            actions.append(col)

    return actions
Exemplo n.º 11
0
 def apply_c(self, a, i, dagger=False):
     '''
     compute C(?dagger)(a)|i>
     :param i: (int) binary representation of state i in occupation state
     :param a: (int) number of the site(+spin) on which we want to apply cdagger
     :param dagger: (bool) if True, return cdagger|i>, othervise c|i>
     :return: (int,int) 1 or -1, binary representation of state cd|i> in occupation state
     '''
     #Get the ath state
     ath_state = gmpy2.bit_test(i, a)
     #if the site is empty and we want to destroy of occupied and we want to create
     if (ath_state == dagger):
         return [0, 0]
     # Othervise
     else:
         # count the number of occupied states before a to get the phase
         nb_bits_on_before_a = gmpy2.popcount(i % (1 << a))
         # flip the ath bit
         new_state = gmpy2.bit_flip(i, a)
         # return the phase and the new state
         return [(-1)**nb_bits_on_before_a, new_state]
Exemplo n.º 12
0
    def occupation_between(self,state,a,b):
        '''
        Return the number of occupied sites between a and b
        :param state: integer representation of a quantum state
        :param a: "min" site
        :param b: "max" site
        :return: number of occupied states between min and max
        '''
        # cast the state
        state = int(state)
        # make sure that a is the min and b the max
        a,b=np.sort([a,b])

        nb_el=0 # numer of electrons between the two sites
        # loop over all sites between a and b
        for runner in np.arange(a+1,b,dtype="int"):
            runner = int(runner)
            # add an electron if present at site runner
            nb_el+=gmpy2.bit_test(state,runner)

        return nb_el
Exemplo n.º 13
0
    def get_random_adjacent_state(self, i):
        '''
        :param i: (integer) state which is in the binary representation state
        :return: state j which is obtained by permuting one electron and one hole from state i
        '''
        pos_e = random.randint(
            1, self.nb_electrons)  # we will move the pos_e.th. electron
        pos_h = random.randint(
            1, self.nb_sites * self.nb_flavors - self.nb_electrons
        )  # we will permute the electron with the pos_h th. hole

        count_e = 0
        count_h = 0  #count the number of visited bit with electrons and holes

        has_flipped = False  # if we have already made a move

        for site in range(0, self.nb_flavors *
                          self.nb_sites):  #we loop over each bit of i.
            #update the number of visited bits with electrons and holes
            if (gmpy2.bit_test(i, site)):
                count_e += 1
            else:
                count_h += 1
            #Flip the bit if it's the correct position
            if (count_e == pos_e):
                i = gmpy2.bit_flip(i, site)
                count_e += 1  #update count_e to not enter the condition on the next loop
                if not has_flipped:  #if it's the first flip
                    has_flipped = True
                else:  #if we already made a move, then we can exist the loop
                    break
            elif (count_h == pos_h):
                i = gmpy2.bit_flip(i, site)
                count_h += 1
                if not has_flipped:  #if it's the first flip
                    has_flipped = True
                else:  #if we already made a move, then we can exist the loop
                    break
        return i
Exemplo n.º 14
0
    def apply_c_dagger(self,state,a):
        '''
        Compute c_a+|state>
        :param state: integer representation of quantum state
        :param a: spin-site where we will apply c
        :return: sign (+-1) and new state
        '''
        # Make sure that state and the site are casted correctly
        state = int(state)
        a = int(a)
        # check the occupation until a
        sgn = (-1)**self.occupation_between(state,-1,a) # -1 because we count the first state at 0

        # check that there is an electron at a
        if gmpy2.bit_test(state, a):
            # if there is already an electron, set the sgn to 0 (and state to 0 as a convention)
            sgn=0
            state=0
        else :
            # otherwise we flip the bit
            state = gmpy2.bit_flip(state,a)

        return sgn,state
Exemplo n.º 15
0
 def int2representation(self, i):
     representation = np.zeros([self.nb_sites * self.nb_flavors])
     for r in np.arange(0, np.size(representation)):
         if (gmpy2.bit_test(int(i), int(r))):
             representation[r] = 1
     return representation
Exemplo n.º 16
0
    def H_ij(self,i,j,verbose=False):
        '''
        Compute <i|H|j>
        :param i: int, binary representation of state |i>
        :param j: int, binary representation of state |j>
        :return: <i|H|j>
        '''
        i+=gmpy2.mpz(0)
        j+=gmpy2.mpz(0)

        L=int(len(self.impurity_index)*2) # L is the total number of site (bath + impurity)
        impurity_site=[x-1 for x in self.impurity_index]
        bath_site=[]
        #build the bath site
        for n in np.arange(L):
            if n not in impurity_site:
                bath_site.append(int(n))

        # if there is a different number of electron, return 0
        if(gmpy2.popcount(i)!=gmpy2.popcount(j)):
            if verbose:
                print("Not the same number of electron")
            return 0

        # otherwise prepare to sum
        hij=0

        # H(2) contribution, we need to distinguish between 3 cases, i.e. 0 jump, 1 jump and 2 jumps
        # jump has bit on on the sites that differs
        jump = i ^ j
        # first case 0 differences
        if(gmpy2.popcount(jump)==0):
            if(verbose):
                print("0 dif contr "+str(self.h_2_ii(i)))
            hij += self.h_2_ii(i)
            hij -= self.mu*gmpy2.popcount(i)
        #second case 2 differences (one jump)
        elif(gmpy2.popcount(jump)==2):
            if(verbose):
                print("2 dif contr "+str(self.h_2_cd(state_i=i,state_j=j)))
            hij+= self.h_2_cd(state_i=i,state_j=j)
        # last possibility : 2 jumps
        elif(gmpy2.popcount(jump)==4):
            if(verbose):
                print("4 dif contr "+str(self.h_2_cdef(i,j)))
            hij+=self.h_2_cdef(i,j)

        # H(1) contribution
        if (gmpy2.popcount((i^j))==2):
            if verbose:
                print("One jump")

            # jump has bit on on the 2 sites that differs
            jump=i^j
            # we now look for the index of the sites that were destroyed and created
            destruction_site = int(math.log2(j&jump) )
            creation_site = int(math.log2(i&jump))
            if verbose:
                print("Site of interest : cration at "+str(creation_site)+" and destruction at "+str(destruction_site))
            occupied=0
            for k in np.arange((min(creation_site,destruction_site)+1),max(creation_site,destruction_site)):
                occupied+=gmpy2.bit_test(j,int(k))

            sign = (-1)**(occupied)

            # we finally look at the element
            t = self.T_tilda[creation_site,destruction_site]
            if verbose:
                print("t between "+str(creation_site)+" and "+str(destruction_site)+" = "+str(t))
                print("occupation = "+str(occupied))
            hij+= sign*(t)
        # Kinetic diagonal elements may have appeared during the transformation
        elif i==j:
            for runner in np.arange(2*self.imp_bath_size):
                if(gmpy2.bit_test(int(i),int(runner))):
                    hij+=self.T_tilda[runner,runner]

        return hij