Esempio n. 1
0
 def generate_independent_sets(self):
     # Construct generator containing independent sets
     # Don't generate anything that depends on the entire Hilbert space as to save space
     # Generate complement graph
     complement = nx.complement(self.graph)
     # These are your independent sets of the original graphs, ordered by node and size
     independent_sets, backup = tee(
         nx.algorithms.clique.enumerate_all_cliques(complement))
     self.num_independent_sets = sum(
         1 for _ in backup) + 1  # We add one to include the empty set
     # Generate a list of integers corresponding to the independent sets in binary
     indices = np.zeros(self.num_independent_sets, dtype=int)
     indices[-1] = 2**self.n - 1
     k = self.num_independent_sets - 2
     self.mis_size = 0
     IS = dict.fromkeys(np.arange(self.num_independent_sets))
     # All spins down should be at the end
     IS[self.num_independent_sets - 1] = (2**self.n - 1, 0,
                                          np.ones(self.n, dtype=int))
     for i in independent_sets:
         indices[k] = 2**self.n - sum(2**j for j in i) - 1
         IS[k] = (indices[k], len(i),
                  tools.int_to_nary(indices[k], size=self.n))
         if len(i) > self.mis_size:
             self.mis_size = len(i)
         k -= 1
     binary_to_index = dict.fromkeys(indices)
     for j in range(self.num_independent_sets):
         binary_to_index[indices[j]] = j
     self.binary_to_index = binary_to_index
     self.independent_sets = IS
     return IS, binary_to_index, self.num_independent_sets
Esempio n. 2
0
def return_probability(graph, times, verbose=False, h=1, exact=True):
    # For random product states in the computational basis, time evolve then compute
    if verbose:
        print('beginning')
    czz_tot = np.zeros((len(times), graph.n))
    num = 0
    for _ in range(1):
        for k in range(2**graph.n):
            print(k)
            # Compute the total magnetization
            z_mags_init = 2 * (1 / 2 - tools.int_to_nary(k, size=graph.n))

            if np.sum(z_mags_init) == 0:
                num += 1
                if verbose:
                    print(z_mags_init)
                subspace = np.sum(z_mags_init)
                if path.exists('heisenberg_' + str(graph.n) + '_' +
                               str(subspace) + '.pickle'):
                    heisenberg = dill.load(
                        open(
                            'heisenberg_' + str(graph.n) + '_' +
                            str(subspace) + '.pickle', 'rb'))
                else:
                    heisenberg = qsim.evolution.hamiltonian.HamiltonianHeisenberg(
                        graph, subspace=subspace, energies=(1 / 4, 1 / 2))
                    dill.dump(
                        heisenberg,
                        open(
                            'heisenberg_' + str(graph.n) + '_' +
                            str(subspace) + '.pickle', 'wb'))
                    if verbose:
                        print('initialized Hamiltonian')

                # For every computational basis state,
                dim = int(comb(graph.n, int((graph.n + subspace) / 2)))
                print(dim, subspace)
                hamiltonian = heisenberg.hamiltonian + disorder_hamiltonian(
                    heisenberg.states, h=h)

                n_times = len(times)
                # hamiltonian_exp = expm(-1j *hamiltonian * (times[1] - times[0]))
                # print(2*(1-heisenberg.states-1/2),z_mags_init)
                ind = np.argwhere(
                    np.sum(np.abs(2 * (1 - heisenberg.states - 1 / 2) -
                                  z_mags_init),
                           axis=1) == 0)[0, 0]
                # print(ind)
                state = np.zeros((dim, 1))
                state[ind, 0] = 1
                states = np.zeros((dim, n_times), dtype=np.complex128)
                states[:, 0] = state.flatten()
                for i in range(n_times - 1):
                    if verbose:
                        print(i)
                    states[..., i + 1] = expm_multiply(
                        -1j * hamiltonian * (times[i + 1] - times[i]),
                        states[..., i])
                z_mags = (
                    (np.abs(states)**2).T @ (1 - heisenberg.states - 1 / 2) *
                    2).real
                # print(z_mags_init, z_mags, z_mags*z_mags_init/4)
                czz = z_mags * z_mags_init
                czz_tot = czz_tot + czz
    print(num)
    return czz_tot / num
Esempio n. 3
0
def index_to_state(i, size=None):
    """Given an index i, return the ket associated with that index"""
    return int_to_nary(i, base=d, size=size, pad_with=0)
Esempio n. 4
0
 def spin_hamiltonian():
     s = np.zeros((1, 2 ** n))
     for j in range(2**n):
         s[0,j] = n-np.sum(np.array([tools.int_to_nary(j)]))
     return s.T