def fsa_ops_from_root(ref, LR):
    bits = pxp.basis[pxp.keys[ref]]
    one_loc = []
    for m in range(0, np.size(bits, axis=0)):
        if bits[m] == 1:
            one_loc = np.append(one_loc, m)
    if LR == "Left":
        zero_loc = flippable_zeros[ref][1]
    elif LR == "Right":
        zero_loc = flippable_zeros[ref][0]
    print(bits, one_loc, zero_loc)

    Hp = np.zeros((pxp.dim, pxp.dim))
    for n in range(0, np.size(pxp.basis_refs, axis=0)):
        state_bits = pxp.basis[n]
        for m in range(0, np.size(state_bits, axis=0)):
            if m in one_loc:
                if state_bits[m] == 1:
                    new_bits = np.copy(state_bits)
                    new_bits[m] = 0
                    temp_ref = bin_to_int_base_m(new_bits, pxp.base)
                    if temp_ref in pxp.basis_refs:
                        temp_index = pxp.keys[temp_ref]
                        Hp[n, temp_index] = 1
            if m in zero_loc:
                if state_bits[m] == 0:
                    new_bits = np.copy(state_bits)
                    new_bits[m] = 1
                    temp_ref = bin_to_int_base_m(new_bits, pxp.base)
                    if temp_ref in pxp.basis_refs:
                        temp_index = pxp.keys[temp_ref]
                        Hp[n, temp_index] = 1
    Hm = np.conj(np.transpose(Hp))
    return Hp, Hm
Ejemplo n.º 2
0
def group_perm_refs(sector):
    refs = sector_refs[perm_key(sector)]
    sector_labels = []

    uniq_keys = []
    for m in range(0,np.size(refs,axis=0)):
        goes_to = to_sectors[refs[m]]
        #goes to key
        numbers = []
        for k in range(0,np.size(goes_to,axis=0)):
            numbers = np.append(numbers,bin_to_int_base_m(goes_to[k],int(pxp.N/2+1)))
        number_max = (pxp.N/2+1)*(pxp.N/2)+(pxp.N/2)
        key = bin_to_int_base_m(numbers,number_max+1)
        uniq_keys = np.unique(np.append(uniq_keys,key))

    uniq_refs = dict()
    for m in range(0,np.size(uniq_keys,axis=0)):
        uniq_refs[uniq_keys[m]] = []

    for m in range(0,np.size(refs,axis=0)):
        goes_to = to_sectors[refs[m]]
        #goes to key
        numbers = []
        for k in range(0,np.size(goes_to,axis=0)):
            numbers = np.append(numbers,bin_to_int_base_m(goes_to[k],int(pxp.N/2+1)))
        number_max = (pxp.N/2+1)*(pxp.N/2)+(pxp.N/2)
        key = bin_to_int_base_m(numbers,number_max+1)
        uniq_refs[key] = np.append(uniq_refs[key],refs[m])
    return uniq_refs
Ejemplo n.º 3
0
    def __init__(self, system, k_refs=None):
        self.system = system
        self.k_refs = k_refs

        #bipartite split computational basis,
        #to construct coefficient matrices for singular values (entanglement spectrum)
        self.N_A = int(np.floor(self.system.N / 2))
        self.N_B = int(self.system.N - np.floor(self.system.N / 2))
        #split basis
        self.basis_A = self.system.basis[:, :self.N_A]
        self.basis_B = self.system.basis[:, self.N_A:]

        self.basis_A_refs = np.zeros(np.size(self.system.basis, axis=0))
        self.basis_B_refs = np.zeros(np.size(self.system.basis, axis=0))
        for n in range(0, np.size(self.system.basis, axis=0)):
            self.basis_A_refs[n] = bin_to_int_base_m(self.basis_A[n],
                                                     self.system.base)
            self.basis_B_refs[n] = bin_to_int_base_m(self.basis_B[n],
                                                     self.system.base)

        self.basis_A_refs_unique = np.unique(self.basis_A_refs)
        self.basis_B_refs_unique = np.unique(self.basis_B_refs)

        self.basis_A_keys = dict()
        self.basis_B_keys = dict()
        for n in range(0, np.size(self.basis_A_refs_unique, axis=0)):
            self.basis_A_keys[self.basis_A_refs_unique[n]] = n
        for n in range(0, np.size(self.basis_B_refs_unique, axis=0)):
            self.basis_B_keys[self.basis_B_refs_unique[n]] = n
Ejemplo n.º 4
0
def bipartite_basis_split(basis, base, N):
    N_A = int(np.floor(N / 2))
    N_B = int(N - np.floor(N / 2))
    #split basis
    basis_A = basis[:, :N_A]
    basis_B = basis[:, N_A:]
    basis_A_refs = np.zeros(np.size(basis, axis=0))
    basis_B_refs = np.zeros(np.size(basis, axis=0))
    for n in range(0, np.size(basis, axis=0)):
        basis_A_refs[n] = bin_to_int_base_m(basis_A[n], base)
        basis_B_refs[n] = bin_to_int_base_m(basis_B[n], base)
    return basis_A_refs, basis_B_refs
Ejemplo n.º 5
0
def energy_basis(state, H):
    #find sym blocks state has non zero overlap in
    state_ref = bin_to_int_base_m(state, H.system.base)
    state_index = find_index_bisection(state_ref, H.system.basis_refs)
    sym_ref = H.syms.sym_data[state_index, 0]
    k_refs = H.syms.find_k_ref(sym_ref)

    #dict to store state in sym sector basis
    z_sym = dict()
    eigenvalues = dict()
    for n in range(0, np.size(k_refs, axis=0)):
        psi = ref_state(state_ref, H.system)
        z_sym[n] = psi.sym_basis(k_refs[n], H.syms)
        eigenvalues[n] = H.sector.eigvalues(k_refs[n])

    #dict to store state from sym sector in energy eigenbasis
    z_energy = dict()
    for n in range(0, np.size(k_refs, axis=0)):
        z_energy[n] = np.zeros(np.size(H.sector.eigvalues(k_refs[n])),
                               dtype=complex)
        #find coefficients by taking overlaps
        for m in range(0, np.size(z_energy[n], axis=0)):
            z_energy[n][m] = np.vdot(
                H.sector.eigvectors(k_refs[n])[:, m], z_sym[n])

    #combine all sym sectors
    z_init = z_energy[0]
    eig_f = eigenvalues[0]
    for n in range(1, len(z_energy)):
        z_init = np.append(z_init, z_energy[n])
        eig_f = np.append(eig_f, eigenvalues[n])
    return z_init, eig_f
    def __init__(self,order,pol,system,shift=0):
        self.system = system
        self.order = order

        #sets the bit representation |1,0...>
        zm=np.zeros(self.system.N)
        zm[0] = pol
        count=1
        for n in range(1,np.size(zm,axis=0)):
            if count<order:
                zm[n] = 0
                count = count + 1
            else:
                zm[n] = pol
                count = 1
        #count zeros at end to check state is act z_n
        no_zeros=0
        for n in range(np.size(zm,axis=0)-1,-1,-1):
            if zm[n] == pol:
                break
            no_zeros = no_zeros + 1
        if no_zeros == order-1:
            self.bits = zm
        else: 
            print("ERROR Z_"+str(order)+" not at this chain length.")

        for n in range(0,shift):
            self.bits = cycle_bits_state(self.bits)
        self.ref = bin_to_int_base_m(self.bits,self.system.base)
        self.key = system.keys[self.ref]
Ejemplo n.º 7
0
 def sym_op(self,number,m):
     if m % 2 == 0:
         return int(number)
     else:
         state = self.system.basis[self.system.keys[number]]
         new_state = (-1)*(state-1/2*np.ones(np.size(state)))+1/2
         new_ref = bin_to_int_base_m(new_state,self.system.base)
         return new_ref
Ejemplo n.º 8
0
 def create_orbit(self,state):
     state_bin = self.system.basis[self.system.keys[state]]
     new_state = (-1)*(state_bin-1/2*np.ones(np.size(state_bin)))+1/2
     new_ref = bin_to_int_base_m(new_state,self.system.base)
     if new_ref == state:
         return np.array((state))
     else:
         return np.array((state,new_ref))
Ejemplo n.º 9
0
 def gen_basis(self):
     self.basis = self.gen_P0K_basis()
     self.basis_refs = np.zeros(np.size(self.basis, axis=0))
     self.keys = dict()
     for n in range(0, np.size(self.basis, axis=0)):
         self.basis_refs[n] = bin_to_int_base_m(self.basis[n], self.base)
         self.keys[self.basis_refs[n]] = n
     self.dim = np.size(self.basis_refs)
Ejemplo n.º 10
0
 def sym_op(self,number,m):
     if m % 2 == 0:
         return int(number)
     else:
         state = self.system.basis[self.system.keys[number]]
         parity_state = np.flip(state,0)
         parity_ref = bin_to_int_base_m(parity_state,self.system.base)
         return parity_ref
Ejemplo n.º 11
0
 def create_orbit(self,state):
     state_bin = self.system.basis[self.system.keys[state]]
     state_pair = np.flip(state_bin,0)
     pair_ref = bin_to_int_base_m(state_pair,self.system.base)
     if pair_ref == state:
         return np.array((state))
     else:
         return np.array((state,pair_ref))
def m_pair_hash(m_pair,s1,s2):
    base = int(np.max(np.array((4*s1,4*s2))))
    temp = np.copy(m_pair)
    temp[0] = temp[0] + s1
    temp[1] = temp[1] + s2
    temp = 2*temp
    key = bin_to_int_base_m(temp,base)
    return key
def fsa_ops_root_to_target(root_ref, target_ref):
    root_bits = pxp.basis[pxp.keys[root_ref]]
    target_bits = pxp.basis[pxp.keys[target_ref]]
    sm_loc = []
    sp_loc = []
    for n in range(0, np.size(root_bits, axis=0)):
        if root_bits[n] == 1 and target_bits[n] == 0:
            sm_loc = np.append(sm_loc, n)
        if root_bits[n] == 0 and target_bits[n] == 1:
            sp_loc = np.append(sp_loc, n)

    #construct FSA op
    Hp = np.zeros((pxp.dim, pxp.dim))
    for n in range(0, np.size(pxp.basis_refs, axis=0)):
        state_bits = pxp.basis[n]
        for m in range(0, np.size(state_bits, axis=0)):
            if m == np.size(state_bits) - 1:
                mp1 = 0
            else:
                mp1 = m + 1
            if m == 0:
                mm1 = np.size(state_bits) - 1
            else:
                mm1 = m - 1

            if m in sm_loc:
                if state_bits[mm1] == 0 and state_bits[m] == 1 and state_bits[
                        mp1] == 0:
                    new_bits = np.copy(state_bits)
                    new_bits[m] = 0
                    new_ref = bin_to_int_base_m(new_bits, pxp.base)
                    if new_ref in pxp.basis_refs:
                        new_index = pxp.keys[new_ref]
                        Hp[n, new_index] = 1
            if m in sp_loc:
                if state_bits[mm1] == 0 and state_bits[m] == 0 and state_bits[
                        mp1] == 0:
                    new_bits = np.copy(state_bits)
                    new_bits[m] = 1
                    new_ref = bin_to_int_base_m(new_bits, pxp.base)
                    if new_ref in pxp.basis_refs:
                        new_index = pxp.keys[new_ref]
                        Hp[n, new_index] = 1
    Hm = np.conj(np.transpose(Hp))
    return Hp, Hm
Ejemplo n.º 14
0
 def sym_op(self,number,m):
     state = self.system.basis[self.system.keys[number]]
     d = np.size(state)
     state1 = state[:int(d/2)]
     state2 = state[int(d/2):]
     state1_new = np.flip(state1)
     state2_new = state2
     state = np.append(state1_new,state2_new)
     return bin_to_int_base_m(state,self.system.base)
Ejemplo n.º 15
0
 def sym_op(self,number,m):
     state = self.system.basis[self.system.keys[number]]
     L=np.size(state)
     for k in range(0,m):
         trans_state=np.zeros(np.size(state))
         trans_state[0:L-1] = state[1:L]
         trans_state[L-1] = state[0]
         state = trans_state
         state = np.flip(state)
     return bin_to_int_base_m(state,self.system.base)
 def find_eig(self, index=None, k0=None, verbose=False):
     if index is None:
         self.table["no_sym"].e, self.table["no_sym"].u = np.linalg.eigh(
             self.table["no_sym"].H)
     else:
         key = bin_to_int_base_m(index, self.system.N)
         self.table[key].e, self.table[key].u = np.linalg.eigh(
             self.table[key].H)
     if verbose is True:
         print("Found Eigenvalues")
Ejemplo n.º 17
0
    def bulk_eval(state, H, k_vec=None):
        if k_vec is None:  #no symmetry, use full basis
            z_ref = bin_to_int_base_m(state, H.system.base)
            z_index = find_index_bisection(z_ref, H.system.basis_refs)
            z_energy = H.sector.eigvectors()[z_index, :]
            eigenvalues = H.sector.eigvalues()
        else:  #symmetry used, just plot the given sym_block
            z_ref = bin_to_int_base_m(state, H.system.base)
            psi = ref_state(z_ref, H.system)
            z_mom = psi.sym_basis(k_vec, H.syms)
            # z_mom = z_mom * np.power(np.vdot(z_mom,z_mom),-0.5)
            z_energy = np.zeros(np.size(H.sector.eigvalues(k_vec)),
                                dtype=complex)
            for n in range(0, np.size(z_energy, axis=0)):
                z_energy[n] = np.vdot(z_mom, H.sector.eigvectors(k_vec)[:, n])
            eigenvalues = H.sector.eigvalues(k_vec)

        overlap = np.log10(np.abs(z_energy)**2)
        return overlap
Ejemplo n.º 18
0
 def create_orbit(self,state_ref):
     if state_ref == 0:
         return np.array((state_ref))
     else:
         conjugated_state = np.copy(self.system.basis[self.system.keys[state_ref]])
         for m in range(0,np.size(conjugated_state,axis=0)):
             if conjugated_state[m] != 0:
                 conjugated_state[m] = (self.system.base-conjugated_state[m]) % self.system.base
         conjugated_ref = bin_to_int_base_m(conjugated_state,self.system.base)
         return np.array((state_ref,conjugated_ref))
Ejemplo n.º 19
0
 def sym_op(self,state_ref,m):
     if m % 2 == 0:
         return int(state_ref)
     else:
         conjugated_state = np.copy(self.system.basis[self.system.keys[state_ref]])
         for m in range(0,np.size(conjugated_state,axis=0)):
             if conjugated_state[m] != 0:
                 conjugated_state[m] = (self.system.base-conjugated_state[m]) % self.system.base
         conjugated_ref = bin_to_int_base_m(conjugated_state,self.system.base)
         return conjugated_ref
Ejemplo n.º 20
0
def find_subcube_basis(root_ref, bits_to_add, LR):
    root_bits = pxp.basis[pxp.keys[root_ref]]
    one_loc = []
    for m in range(0, np.size(root_bits, axis=0)):
        if np.abs(root_bits[m]) > 1e-5:
            one_loc = np.append(one_loc, m)
    poss_zero_loc = []
    for m in range(0, np.size(root_bits, axis=0)):
        if m == 0:
            mm1 = pxp.N - 1
        else:
            mm1 = m - 1

        if m == pxp.N - 1:
            mp1 = 0
        else:
            mp1 = m + 1

        if LR == "Right":
            if m % 2 != 0:
                if root_bits[mm1] == 0 and root_bits[mp1] == 0 and root_bits[
                        m] == 0:
                    poss_zero_loc = np.append(poss_zero_loc, m)

        if LR == "Left":
            if m % 2 == 0:
                if root_bits[mm1] == 0 and root_bits[mp1] == 0 and root_bits[
                        m] == 0:
                    poss_zero_loc = np.append(poss_zero_loc, m)

    bit_loc = np.append(one_loc, poss_zero_loc)
    dim = np.sum(from_sector[root_ref]) + bits_to_add
    subcube_system = unlocking_System([0, 1], "open", 2, dim)
    subcube_system.gen_basis()
    init_bits = np.append(np.ones(np.size(one_loc)),
                          np.zeros(np.size(poss_zero_loc)))
    subcube_hamming = find_hamming_sectors(init_bits, subcube_system)
    basis = np.zeros((pxp.dim, len(subcube_hamming)))
    if np.size(poss_zero_loc) == bits_to_add:
        for m in range(0, len(subcube_hamming)):
            temp_state = np.zeros(pxp.dim)
            refs = subcube_hamming[m]
            for u in range(0, np.size(refs, axis=0)):
                sub_bits = subcube_system.basis[subcube_system.keys[refs[u]]]
                temp_bits = np.zeros(pxp.N)
                for k in range(0, np.size(sub_bits, axis=0)):
                    temp_bits[int(bit_loc[k])] = sub_bits[k]
                temp_ref = bin_to_int_base_m(temp_bits, pxp.base)
                temp_state[pxp.keys[temp_ref]] = 1
            temp_state = temp_state / np.power(np.vdot(temp_state, temp_state),
                                               0.5)
            basis[:, m] = temp_state
        return basis
    else:
        return basis
 def update_H_entry(self, i, j, val, k_vec=None, dim=None):
     if k_vec is None:
         #init hamiltonian matrix as emtpy
         if "no_sym" not in list(self.table.keys()):
             self.table["no_sym"] = H_entry(
                 np.zeros((dim, dim), dtype=complex))
         self.table["no_sym"].H[i, j] = self.table["no_sym"].H[i, j] + val
     else:
         key = bin_to_int_base_m(k_vec, self.system.N)  #hash function
         if key not in list(self.table.keys()):
             self.table[key] = H_entry(np.zeros((dim, dim), dtype=complex))
         self.table[key].H[i, j] = self.table[key].H[i, j] + val
Ejemplo n.º 22
0
    def __init__(self, name, bc, N):
        self.base = 3  #3level system
        self.name = name
        self.bc = bc
        self.N = N

        self.basis = self.gen_basis()

        self.basis_refs = np.zeros(np.size(self.basis, axis=0), dtype=int)
        self.keys = dict()
        for n in range(0, np.size(self.basis, axis=0)):
            self.basis_refs[n] = bin_to_int_base_m(self.basis[n], self.base)
            self.keys[self.basis_refs[n]] = n
Ejemplo n.º 23
0
def perm_matrix(N, perm):
    P = np.zeros((pxp.dim, pxp.dim))
    for n in range(0, np.size(pxp.basis, axis=0)):
        bits = np.copy(pxp.basis[n])
        new_bits = np.copy(pxp.basis[n])
        for m in range(0, np.size(perm, axis=0)):
            loc = int(2 * m)
            new_bits[loc] = bits[2 * perm[m]]
            new_bits[loc + 1] = bits[2 * perm[m] + 1]
        new_ref = bin_to_int_base_m(new_bits, pxp.base)
        if new_ref in pxp.basis_refs:
            new_index = pxp.keys[new_ref]
            P[new_index, n] += 1
    return P
Ejemplo n.º 24
0
 def create_orbit(self,state):
     state_bin = self.system.basis[self.system.keys[state]]
     state_pair = np.flip(state_bin,0)
     new_state = np.copy(state_pair)
     for m in range(0,np.size(state_pair,axis=0)):
         if state_pair[m] == 0:
             new_state[m] = 2
         elif state_pair[m] == 2:
             new_state[m] = 0
     pair_ref = bin_to_int_base_m(new_state,self.system.base)
     if pair_ref == state:
         return np.array((state))
     else:
         return np.array((state,pair_ref))
Ejemplo n.º 25
0
    def bulk_eval(state, t, H, use_syms=None):
        if use_syms == None:
            z_ref = bin_to_int_base_m(state, H.system.base)
            z_index = find_index_bisection(z_ref, H.system.basis_refs)
            z_init = H.sector.eigvectors()[z_index, :]
            eig_f = H.sector.eigvalues()
        else:
            z_init, eig_f = energy_basis(state, H)

        fidelity_y = np.zeros(np.size(t))
        for n in range(0, np.size(t, axis=0)):
            evolved_state = time_evolve_state(z_init, eig_f, t[n])
            fidelity_y[n] = np.abs(np.vdot(evolved_state, z_init))**2
        return fidelity_y
Ejemplo n.º 26
0
    def eval(state, t, H, use_syms=None):
        if use_syms == None:
            z_ref = bin_to_int_base_m(state, H.system.base)
            z_index = find_index_bisection(z_ref, H.system.basis_refs)
            z_init = H.sector.eigvectors()[z_index, :]
            eig_f = H.sector.eigvalues()
        else:
            z_init, eig_f = energy_basis(state, H)

        evolved_state = time_evolve_state(z_init, eig_f, t)
        print(np.abs(np.vdot(z_init, evolved_state))**2)
        # if t<0.5:
        # return -100
        # else:
        return np.abs(np.vdot(z_init, evolved_state))**2
Ejemplo n.º 27
0
 def sym_op(self,number,m):
     if m % 2 == 0:
         return int(number)
     else:
         state = self.system.basis[self.system.keys[number]]
         parity_state = np.flip(state,0)
         new_state = np.copy(parity_state)
         #now invert
         for m in range(0,np.size(parity_state,axis=0)):
             if parity_state[m] == 0:
                 new_state[m] = 2
             elif parity_state[m] == 2:
                 new_state[m] = 0
         parity_ref = bin_to_int_base_m(new_state,self.system.base)
         return parity_ref
Ejemplo n.º 28
0
    def U1_sector(self, n_up):
        from sympy.utilities.iterables import multiset_permutations
        root = np.append(np.ones(n_up), np.zeros(self.N - n_up)).astype(int)
        basis = np.array(list(multiset_permutations(root)))

        new_basis = deepcopy(self)
        new_basis.basis = basis
        new_basis.basis_refs = np.zeros(np.size(new_basis.basis, axis=0))
        new_basis.keys = dict()
        for n in range(0, np.size(new_basis.basis_refs)):
            new_basis.basis_refs[n] = bin_to_int_base_m(
                new_basis.basis[n], new_basis.base)
            new_basis.keys[new_basis.basis_refs[n]] = n
        new_basis.dim = np.size(new_basis.basis_refs)
        return new_basis
def Hm_from_ref(ref):
    bits = pxp.basis[pxp.keys[ref]]
    one_loc = []
    for m in range(0, np.size(bits, axis=0)):
        if bits[m] == 1:
            one_loc = np.append(one_loc, m)

    Hm = np.zeros((pxp.dim, pxp.dim))
    for n in range(0, np.size(pxp.basis_refs, axis=0)):
        state_bits = pxp.basis[n]
        for m in range(0, np.size(one_loc, axis=0)):
            if state_bits[int(one_loc[m])] == 1:
                new_bits = np.copy(state_bits)
                new_bits[int(one_loc[m])] = 0
                temp_ref = bin_to_int_base_m(new_bits, pxp.base)
                Hm[n, pxp.keys[temp_ref]] = 1
    return Hm
Ejemplo n.º 30
0
def join_basis_states(n, m, system, double_system):
    even_state_bits = system.basis[n]
    odd_state_bits = system.basis[m]
    full_bits = np.zeros(2 * np.size(even_state_bits))
    c_even = 0
    c_odd = 0
    for n in range(0, np.size(full_bits, axis=0)):
        if n % 2 == 0:
            full_bits[n] = even_state_bits[c_even]
            c_even = c_even + 1
        else:
            full_bits[n] = odd_state_bits[c_odd]
            c_odd = c_odd + 1
    full_bits_ref = bin_to_int_base_m(full_bits, double_system.base)
    if full_bits_ref in double_system.basis_refs:
        return full_bits_ref
    else:
        return None