Example #1
0
    def test_single_qubit_multiply_pauli(self):
        # Tests single qubit operation given a pauli index
        N = 6
        # Initialize in |000000>
        psi0 = State(np.zeros((2 ** N, 1)))
        psi0[0,0] = 1
        # Apply sigma_y on the second qubit to get 1j|010000>
        # Check Typing
        psi0 = qubit.multiply(psi0, 1, 'Y')
        self.assertTrue(psi0[2 ** (N - 2), 0] == 1j)

        # Apply sigma_z on the second qubit, codes is -1j|010000>
        psi0 = qubit.multiply(psi0, [1], 'Z')
        self.assertTrue(psi0[2 ** (N - 2), 0] == -1j)

        # Apply sigma_x on all qubits but 1
        psi0 = qubit.multiply(psi0, [0, 2, 3, 4, 5], ['X'] * (N - 1))

        # Vector is still normalized
        self.assertTrue(np.vdot(psi0, psi0) == 1)

        # Should be -1j|111111>
        self.assertTrue(psi0[-1, 0] == -1j)

        # Density matrix test
        psi1 = np.array([tools.tensor_product([np.array([1, 1]), np.array([1, 0])]) / 2 ** (1 / 2)]).T
        psi1 = State(tools.outer_product(psi1, psi1))

        # Apply sigma_Y to first qubit
        psi2 = np.array([np.kron([1j, -1j], [1, 0]) / 2 ** (1 / 2)]).T
        rho2 = tools.outer_product(psi2, psi2)

        psi1 = qubit.multiply(psi1, [0], 'Y')
        self.assertTrue(np.linalg.norm(psi1 - rho2) <= 1e-10)
Example #2
0
    def test_amplitude_damping_channel(self):
        psi0 = State(np.zeros((2, 2)))
        psi0[0, 0] = 1
        spontaneous_emission = quantum_channels.AmplitudeDampingChannel()
        for i in range(200):
            psi0 = spontaneous_emission.channel(psi0, .1)
        self.assertTrue(np.allclose(psi0, np.array([[0, 0], [0, 1]])))
        psi0 = State(np.zeros((2, 2)))
        psi0[0, 0] = 1
        psi0 = spontaneous_emission.evolve(psi0, 20)
        self.assertTrue(np.allclose(psi0, np.array([[0, 0], [0, 1]])))
        psi0 = State(np.zeros((2, 2)), IS_subspace=True, graph=line_graph(1))
        psi0[0, 0] = 1
        spontaneous_emission = quantum_channels.AmplitudeDampingChannel(
            IS_subspace=True, graph=line_graph(1), rates=(2, ))
        psi0 = spontaneous_emission.evolve(psi0, 20)
        self.assertTrue(np.allclose(psi0, np.array([[0, 0], [0, 1]])))

        psi0 = State(np.zeros((8, 8)),
                     IS_subspace=True,
                     code=rydberg,
                     graph=line_graph(2))
        psi0[3, 3] = 1
        spontaneous_emission = quantum_channels.AmplitudeDampingChannel(
            IS_subspace=True,
            graph=line_graph(2),
            rates=(2, ),
            code=rydberg,
            transition=(1, 2))
        psi0 = spontaneous_emission.evolve(psi0, 1)
        print(psi0)
Example #3
0
    def ground_state(self, which='S'):
        """Returns the ground state and ground state energy"""
        # Construct a LinearOperator for the Hamiltonians
        linear_operator = False
        ham = None
        for h in self.hamiltonians:
            if not hasattr(h, 'hamiltonian'):
                linear_operator = True
            else:
                if ham is None:
                    ham = h.hamiltonian
                else:
                    ham = ham + h.hamiltonian

        if not linear_operator:
            if which == 'S':
                w = 'SA'
            else:
                w = 'LA'
            eigvals, eigvecs = scipy.sparse.linalg.eigsh(ham, k=1, which=w)
            eigvecs = eigvecs.T
            # Reorder eigenvalues and eigenvectors
        else:
            # Construct a LinearOperator from the Hamiltonians
            raise NotImplementedError
        if which == 'S':
            return eigvals[0], State(eigvecs[0, np.newaxis].T, is_ket=True)
        elif which == 'L':
            return eigvals[-1], State(eigvecs[-1, np.newaxis].T, is_ket=True)
Example #4
0
    def test_single_qubit_rotation(self):
        # Initialize in |000000>
        N = 6
        psi0 = State(np.zeros((rydberg.d**N, 1)), code=rydberg)
        psi0[0, 0] = 1
        psi1 = State(psi0, code=rydberg)
        # Rotate by exp(-1i*pi/4*sigma_y) every qubit to get |++++++>
        for i in range(N):
            psi0 = rydberg.rotation(psi0, [i],
                                    np.pi / 4,
                                    rydberg.Y,
                                    is_involutary=True)
        # noinspection PyTypeChecker
        self.assertAlmostEqual(
            np.vdot(psi0,
                    np.ones((rydberg.d**N, 1)) / 2**(N / 2)), 1)

        # Apply exp(-1i*pi/4*sigma_x)*exp(-1i*pi/4*sigma_z) on every qubit to get exp(-1j*N*pi/4)*|000000>
        for i in range(N):
            psi0 = rydberg.rotation(psi0, [i],
                                    np.pi / 4, ['Z'],
                                    is_involutary=True)
            psi0 = rydberg.rotation(psi0, [i],
                                    np.pi / 4,
                                    rydberg.X,
                                    is_involutary=True)

        self.assertTrue(
            np.abs(np.vdot(psi1, psi0) * np.exp(1j * np.pi / 4 * N) -
                   1) <= 1e-10)
Example #5
0
def Q(eq: SchrodingerEquation, dissipation):
    # Diagonalize Hamiltonian
    # Compute Q matrix elements
    eigval, eigvec = eq.eig()
    q = np.zeros((len(eigval), len(eigval)))
    jump_operators = np.array(dissipation.jump_operators)
    # For each pair of eigenvectors
    for pair in itertools.product(range(eigvec.shape[0]), repeat=2):
        # Compute the rate
        if pair[0] != pair[1]:
            eigvec1 = State(tools.outer_product(eigvec[pair[0]].T,
                                                eigvec[pair[0]].T),
                            is_ket=False,
                            IS_subspace=True,
                            graph=graph)
            eigvec2 = State(tools.outer_product(eigvec[pair[1]].T,
                                                eigvec[pair[1]].T),
                            is_ket=False,
                            IS_subspace=True,
                            graph=graph)

            rates = np.sum([
                np.trace(eigvec2 @ jump_operators[i] @ eigvec1
                         @ jump_operators[i].conj().T)
                for i in range(len(jump_operators))
            ])
            q[pair[1], pair[0]] = rates.real**2
            q[pair[0], pair[0]] = q[pair[0], pair[0]] - rates.real**2
    return q
Example #6
0
 def run(self, param, initial_state=None):
     if self.code.logical_code and initial_state is None:
         initial_state = State(tensor_product([self.code.logical_basis[1]] *
                                              self.N),
                               code=self.code)
     elif initial_state is None:
         if isinstance(self.cost_hamiltonian, HamiltonianMIS):
             initial_state = State(np.zeros(
                 (self.cost_hamiltonian.hamiltonian.shape[0], 1)),
                                   code=self.code)
             initial_state[-1, -1] = 1
         else:
             initial_state = State(
                 np.ones((self.cost_hamiltonian.hamiltonian.shape[0], 1)) /
                 np.sqrt(self.cost_hamiltonian.hamiltonian.shape[0]),
                 code=self.code)
     if not (self.noise_model is None or self.noise_model == 'monte_carlo'):
         # Initial s should be a density matrix
         initial_state = State(outer_product(initial_state, initial_state),
                               code=self.code)
     s = initial_state
     for j in range(self.depth):
         s = self.hamiltonian[j].evolve(s, param[j])
         if self.noise_model is not None:
             if self.noise[j] is not None:
                 s = self.noise[j].evolve(s, param[j])
     # Return the expected value of the cost function
     # Note that the codes's defined expectation function won't work here due to the shape of C
     return self.cost_hamiltonian.cost_function(s)
Example #7
0
 def nh_evolve(self, state: State, time: float):
     """Non-hermitian time evolution."""
     if state.is_ket:
         return State(expm_multiply(-1j * time * self.nh_hamiltonian, state), is_ket=state.is_ket,
                      IS_subspace=state.IS_subspace, code=state.code, graph=self.graph)
     else:
         temp = expm(-1j * time * self.nh_hamiltonian)
         return State(temp @ state @ temp.conj().T, is_ket=state.is_ket, IS_subspace=state.IS_subspace,
                      code=state.code, graph=self.graph)
Example #8
0
    def evolve(self, state: State, time):
        if state.is_ket:
            return State(expm_multiply(-1j * time * self.hamiltonian, state),
                         is_ket=state.is_ket, IS_subspace=state.IS_subspace, code=state.code, graph=self.graph)

        else:
            exp_hamiltonian = expm(-1j * time * self.hamiltonian)
            return State(exp_hamiltonian @ state @ exp_hamiltonian.conj().T,
                         is_ket=state.is_ket, IS_subspace=state.IS_subspace, code=state.code, graph=self.graph)
Example #9
0
    def test_single_qubit_operation(self):
        N = 6
        # Test single qubit operation
        psi0 = State(np.zeros((rydberg.d**N, 1)), code=rydberg)
        psi0[0][0] = 1
        # Apply sigma_y on the second qubit to get 1j|020000>
        psi0 = rydberg.multiply(psi0, [1], rydberg.Y)
        self.assertTrue(psi0[(rydberg.d - 1) * rydberg.d**(N - 2), 0] == 1j)

        # Apply sigma_z on the second qubit, codes is -1j|010000>
        psi0 = rydberg.multiply(psi0, [1], rydberg.Z)
        self.assertTrue(psi0[(rydberg.d - 1) * rydberg.d**(N - 2), 0] == -1j)

        # Apply sigma_x on qubits
        psi0 = rydberg.multiply(psi0, [0, 2, 3, 4, 5],
                                tools.tensor_product([rydberg.X] * (N - 1)))

        # Vector is still normalized
        self.assertTrue(np.vdot(psi0, psi0) == 1)

        # Should be -1j|111111>
        self.assertTrue(psi0[-1, 0] == -1j)

        # Test rydberg operations with density matrices
        psi1 = np.array([
            tools.tensor_product([np.array([1, 0, 1]),
                                  np.array([1, 0, 0])]) / 2**(1 / 2)
        ]).T
        psi1 = State(tools.outer_product(psi1, psi1), code=rydberg)

        # Apply sigma_Y to first qubit
        psi2 = np.array([np.kron([1, 0, -1], [1, 0, 0]) * -1j / 2**(1 / 2)]).T
        rho2 = tools.outer_product(psi2, psi2)

        psi1 = rydberg.multiply(psi1, [0], ['Y'])
        self.assertTrue(np.linalg.norm(psi1 - rho2) <= 1e-10)

        psi0 = np.array([
            tools.tensor_product([np.array([1, 0, 1]),
                                  np.array([1, 0, 0])]) / 2**(1 / 2)
        ]).T
        psi0 = State(tools.outer_product(psi0, psi0), code=rydberg)
        psi1 = State(psi0.copy(), code=rydberg)

        # Apply sigma_Y to first qubit
        psi2 = np.array([np.kron([1, 0, -1], [1, 0, 0]) * -1j / 2**(1 / 2)]).T
        psi2 = tools.outer_product(psi2, psi2)

        # Apply single qubit operation to dmatrix
        psi0 = rydberg.multiply(psi0, [0], rydberg.Y)
        self.assertTrue(np.linalg.norm(psi0 - psi2) <= 1e-10)

        # Test on ket
        psi1 = rydberg.multiply(psi1, [0], rydberg.Y)
        self.assertTrue(np.linalg.norm(psi1 - psi2) <= 1e-10)
Example #10
0
    def test_hamiltonian_driver(self):
        N = 6

        hl_qubit = hamiltonian.HamiltonianDriver(graph=tools_test.sample_graph())

        psi0 = State(np.zeros((2 ** N, 1)))
        psi0[0, 0] = 1
        psi1 = State(tools.outer_product(psi0, psi0))

        # Evolve by e^{-i (\pi/2) \sum_i X_i}
        psi0 = hl_qubit.evolve(psi0, np.pi / 2)

        # Should get (-1j)^N |111111>
        self.assertTrue(np.vdot(psi0, psi0) == 1)
        self.assertTrue(psi0[-1, 0] == (-1j) ** N)

        # Evolve by e^{-i (\pi/2) \sum_i X_i}
        psi1 = hl_qubit.evolve(psi1, np.pi / 2)

        # Should get (-1j)^N |111111>
        self.assertTrue(tools.is_valid_state(psi1))
        self.assertAlmostEqual(psi1[-1, -1], 1)

        psi0 = State(np.zeros((2 ** N, 1)))
        psi0[0, 0] = 1
        psi0 = hl_qubit.left_multiply(psi0)
        psi1 = np.zeros((2 ** N, 1), dtype=np.complex128)
        for i in range(N):
            psi1[2 ** i, 0] = 1
        self.assertTrue(np.allclose(psi0, psi1))
        psi2 = State(np.zeros((2 ** N, 1)))
        psi2[0, 0] = 1
        psi2 = hl_qubit.hamiltonian @ psi2
        self.assertTrue(np.allclose(psi0, psi2))

        N = 3
        hl = hamiltonian.HamiltonianDriver(transition=(0, 1), code=rydberg)
        psi0 = State(np.zeros((rydberg.d ** N, 1)), code=rydberg)
        psi0[5, 0] = 1
        psi1 = State(tools.outer_product(psi0, psi0), code=rydberg)
        psi0 = hl.left_multiply(psi0)

        self.assertTrue(psi0[2, 0] == 1)
        self.assertTrue(psi0[14, 0] == 1)
        psi1 = hl.left_multiply(psi1)
        self.assertTrue(psi1[2, 5] == 1)
        self.assertTrue(psi1[14, 5] == 1)

        psi0 = State(np.zeros((rydberg.d ** N, 1)), code=rydberg)
        psi0[5, 0] = 1
        psi0 = hl.evolve(psi0, np.pi / 2)
        self.assertTrue(np.isclose(psi0[11, 0], -1))

        # IS subspace
        hl = hamiltonian.HamiltonianDriver(transition=(0, 2), code=rydberg, IS_subspace=True, graph=line_graph(2))
        psi0 = State(np.zeros((8, 1)), code=rydberg)
        psi0[-1,0] = 1
        psi0 = State(tools.outer_product(psi0, psi0), code=rydberg)
        self.assertTrue(tools.is_hermitian(hl.evolve(psi0, 1)))
Example #11
0
 def test_multi_qubit_multiply(self):
     N = 6
     psi0 = np.zeros((2 ** N, 1), dtype=np.complex128)
     psi0[0, 0] = 1
     psi1 = State(psi0)
     psi0 = State(psi0)
     op = tools.tensor_product([qubit.X, qubit.Y, qubit.Z])
     psi0 = qubit.multiply(psi0, [1, 3, 4], op)
     psi1 = qubit.multiply(psi1, [1], 'X')
     psi1 = qubit.multiply(psi1, [3], 'Y')
     psi1 = qubit.multiply(psi1, [4], 'Z')
     self.assertTrue(np.allclose(psi0, psi1))
Example #12
0
    def test_trotterize_noiseless(self):
        # Noiseless simulations
        # Compare that the integrator adiabatic results match the trotterized results
        # First, compare the non-IS subspace results
        simulation = adiabatic_simulation(sample_graph(), IS_subspace=False)
        res_trotterize = simulation.performance_vs_total_time(
            np.arange(1, 5, 1),
            metric='optimum_overlap',
            initial_state=State(equal_superposition(6)),
            schedule=lambda t, tf: simulation.linear_schedule(
                t, tf, coefficients=[10, 10]),
            plot=False,
            verbose=True,
            method='trotterize')
        res_RK45 = simulation.performance_vs_total_time(
            np.arange(1, 5, 1),
            metric='optimum_overlap',
            initial_state=State(equal_superposition(6)),
            schedule=lambda t, tf: simulation.linear_schedule(
                t, tf, coefficients=[10, 10]),
            plot=False,
            verbose=True,
            method='RK45')
        # Now test in the IS subspace
        self.assertTrue(
            np.allclose(res_trotterize[0]['trotterize']['optimum_overlap'],
                        res_RK45[0]['RK45']['optimum_overlap'],
                        atol=1e-2))

        simulation = adiabatic_simulation(sample_graph(), IS_subspace=True)
        res_trotterize = simulation.performance_vs_total_time(
            np.arange(1, 4, 1),
            metric='optimum_overlap',
            schedule=lambda t, tf: simulation.linear_schedule(
                t, tf, coefficients=[10, 10]),
            plot=False,
            verbose=True,
            method='trotterize')
        res_RK45 = simulation.performance_vs_total_time(
            np.arange(1, 4, 1),
            metric='optimum_overlap',
            schedule=lambda t, tf: simulation.linear_schedule(
                t, tf, coefficients=[10, 10]),
            plot=False,
            verbose=True,
            method='RK45')
        self.assertTrue(
            np.allclose(res_trotterize[0]['trotterize']['optimum_overlap'],
                        res_RK45[0]['RK45']['optimum_overlap'],
                        atol=1e-2))
Example #13
0
    def jump_rate(self, state: State, apply_to=None):
        assert state.is_ket
        if apply_to is None:
            apply_to = list(range(state.number_physical_qudits))
        if isinstance(apply_to, int):
            apply_to = [apply_to]
        jump_rates = []
        jumped_states = []
        if not self.IS_subspace:
            for j in range(len(self.jump_operators)):
                for i in apply_to:
                    out = self.code.left_multiply(state, i,
                                                  self.jump_operators[j])
                    jump_rates.append(np.vdot(out, out).real)
                    # IMPORTANT: add in a factor of sqrt(rates) for normalization purposes later
                    jumped_states.append(out)
        else:
            for j in range(len(self.jump_operators)):
                out = self.jump_operators[j] @ state
                jump_rates.append(np.vdot(out, out).real)
                # IMPORTANT: add in a factor of sqrt(rates) for normalization purposes later
                jumped_states.append(
                    State(out,
                          is_ket=state.is_ket,
                          code=state.code,
                          IS_subspace=state.IS_subspace,
                          graph=state.graph))

        return np.asarray(jumped_states), np.asarray(jump_rates)
Example #14
0
    def liouvillian(self, state: State, apply_to=None):
        if apply_to is None:
            apply_to = list(range(state.number_physical_qudits))
        out = np.zeros(state.shape)
        if self.IS_subspace:
            for i in range(len(self.jump_operators)):
                out = out + self.jump_operators[i] @ state @ self.jump_operators[i].T - 1 / 2 * self.jump_operators[
                    i].T @ self.jump_operators[i] @ state - 1 / 2 * state @ self.jump_operators[i].T @ \
                      self.jump_operators[i]

        else:
            for i in range(len(apply_to)):
                for j in range(len(self.jump_operators)):
                    out = out + self.code.multiply(state, [apply_to[i]],
                                                   self.jump_operators[j]) - 1 / 2 * \
                          self.code.left_multiply(state, [apply_to[i]], self.jump_operators[j].T @ self.jump_operators[
                              j]) - 1 / 2 * self.code.right_multiply(
                        state, [apply_to[i]],
                        self.jump_operators[j].T @
                        self.jump_operators[j])
        return State(out,
                     is_ket=state.is_ket,
                     code=state.code,
                     IS_subspace=state.IS_subspace,
                     graph=self.graph)
Example #15
0
    def test_single_qubit(self):
        psi0 = State(
            tools.tensor_product([
                three_qubit_code.logical_basis[0],
                three_qubit_code.logical_basis[0]
            ]))
        psi1 = psi0.copy()
        # Density matrix test
        psi2 = State(tools.outer_product(psi1, psi1))
        psi0 = three_qubit_code.multiply(psi0, [1], ['Y'])
        # Test non-pauli operation
        psi1 = three_qubit_code.multiply(psi1, [1], three_qubit_code.Y)
        psi2 = three_qubit_code.multiply(psi2, [1], three_qubit_code.Y)
        res = 1j * tools.tensor_product([
            three_qubit_code.logical_basis[0],
            three_qubit_code.logical_basis[1]
        ])
        # Should get out 1j|0L>|1L>
        self.assertTrue(np.allclose(psi0, res))
        self.assertTrue(np.allclose(psi1, res))
        self.assertTrue(np.allclose(psi2, tools.outer_product(res, res)))

        self.assertTrue(
            np.allclose(
                three_qubit_code.multiply(psi0, [1], ['Z']),
                -1j * tools.tensor_product([
                    three_qubit_code.logical_basis[0],
                    three_qubit_code.logical_basis[1]
                ])))
        psi0 = three_qubit_code.multiply(psi0, [0], ['X'])
        # Should get out -1j|1L>|1L>
        self.assertTrue(
            np.allclose(
                psi0, 1j * tools.tensor_product([
                    three_qubit_code.logical_basis[1],
                    three_qubit_code.logical_basis[1]
                ])))
        # Rotate all qubits
        for i in range(2):
            psi0 = three_qubit_code.rotation(psi0, [i], np.pi / 2,
                                             three_qubit_code.X)
        self.assertTrue(
            np.allclose(
                psi0, -1j * tools.tensor_product([
                    three_qubit_code.logical_basis[0],
                    three_qubit_code.logical_basis[0]
                ])))
Example #16
0
 def test_state(self):
     # This method just tests if State initializes property
     state = np.zeros((16, 1))
     state[-1, -1] = 1
     state = State(state, code=jordan_farhi_shor)
     self.assertTrue(state.code == jordan_farhi_shor)
     self.assertTrue(state.number_physical_qudits == 4)
     self.assertTrue(state.number_logical_qudits == 1)
Example #17
0
 def f(t, s):
     global state
     if method == 'odeint':
         t, s = s, t
     if method != 'odeint':
         s = np.reshape(np.expand_dims(s, axis=0), state_shape)
     schedule(t)
     s = State(s, is_ket=is_ket, code=code, IS_subspace=IS_subspace, graph=graph)
     return np.asarray(self.evolution_generator(s)).flatten()
Example #18
0
def dephasing_performance():
    # adiabatic = SimulateAdiabatic(hamiltonian=[laser], noise = [dephasing, dissipation], noise_model='continuous',
    #                              graph=graph, IS_subspace=True, cost_hamiltonian=rydberg_hamiltonian_cost)
    # def schedule(t, tf):
    #    phi = (tf-t)/tf*np.pi/2
    #    laser.omega_g = np.cos(phi)
    #    laser.omega_r = np.sin(phi)
    #    dissipation.omega_g = np.cos(phi)
    #    dissipation.omega_r = np.sin(phi)
    # adiabatic.performance_vs_total_time(np.arange(5, 100, 5), schedule=schedule, verbose=True, plot=True, method='odeint')
    dephasing_rates = 10. ** (np.arange(-3, 0, .2))
    performance_3 = []
    performance_5 = []
    for j in [3, 5]:
        graph = line_graph(n=j)
        phi = .02
        laser = EffectiveOperatorHamiltonian(omega_g=np.cos(phi), omega_r=np.sin(phi), energies=(1,), graph=graph)
        dissipation = EffectiveOperatorDissipation(omega_g=np.cos(phi), omega_r=np.sin(phi), rates=(1,), graph=graph)
        dephasing = lindblad_operators.LindbladPauliOperator(pauli='Z', IS_subspace=True, graph=graph, rates=(.1,))
        rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True, code=qubit)
        eq = LindbladMasterEquation(hamiltonians=[laser], jump_operators=[dissipation, dephasing])

        for i in range(len(dephasing_rates)):
            dissipation.rates = (1,)
            laser.energies = (1,)
            dephasing.rates = (dephasing_rates[i],)
            state = np.zeros(dissipation.nh_hamiltonian.shape)
            state[-1, -1] = 1
            state = State(state, is_ket=False, graph=graph, IS_subspace=True)
            ss = eq.steady_state(state)
            ss = ss[1][0]
            state = State(ss, is_ket=False, graph=graph, IS_subspace=True)
            print(rydberg_hamiltonian_cost.optimum_overlap(state))
            if j == 3:
                performance_3.append(rydberg_hamiltonian_cost.optimum_overlap(state))
            else:
                performance_5.append(rydberg_hamiltonian_cost.optimum_overlap(state))

    plt.scatter(dephasing_rates, performance_3, color='teal', label=r'$n=3$ line graph')
    plt.scatter(dephasing_rates, performance_5, color='purple', label=r'$n=5$ line graph')
    plt.ylabel(r'log(-log(optimum overlap))')
    plt.xlabel(r'$\log(\gamma\Omega^2/(\delta^2\Gamma_{\rm{dephasing}}))$')
    plt.legend()
    plt.show()
Example #19
0
def plot_6():
    size = 6
    critical_detuning = -9.604213726908476  #-6.019449429835163
    critical_detunings = np.concatenate(
        [-np.linspace(2, 10, 10), [critical_detuning]])
    graph_index = 807
    graph_data = loadfile(graph_index, size)
    grid = graph_data['graph_mask']
    print('Initializing graph')
    graph = unit_disk_grid_graph(grid, periodic=False, radius=1.6)
    graph_finite = unit_disk_grid_graph(grid, periodic=False, radius=1.1)

    graph_finite.generate_independent_sets()

    n_points = 7
    times = 2**np.linspace(-2.5, 4.5 / 6 * (n_points - 1) - 2.5, n_points)
    times = np.concatenate([times, [2.5]])  # np.array([2.5])#
    times = times + .312 * 2
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)

    performances = np.zeros((len(critical_detunings), len(times))) * np.nan
    for (d, detuning) in enumerate(critical_detunings):
        for (t, tf) in enumerate(times):
            try:
                cost.energies = (1, )
                state = State(np.load('{}x{}_{}_{}_{}_trotterize.npz'.format(
                    size, size, graph_index, np.round(np.abs(detuning), 2),
                    np.round(np.abs(tf), 2)))['state'],
                              is_ket=True,
                              IS_subspace=True,
                              graph=graph)
                performances[d, t] = MIS_probability_finite(
                    state, graph, graph_finite)
                print(tf, detuning, performances[d, t])
            except:
                pass

    colors = [
        'blue', 'green', 'navy', 'orange', 'firebrick', 'purple', 'magenta',
        'cornflowerblue', 'teal', 'grey', 'cyan', 'limegreen', 'red', 'yellow',
        'pink', 'orangered', 'salmon', 'violet'
    ]

    for (d, detuning) in enumerate(critical_detunings):
        plt.scatter(times - 2 * .312,
                    performances[d],
                    color=colors[d],
                    label='Detuning $={}$'.format(np.round(detuning, 2)))
        plt.plot(times - 2 * .312, performances[d], color=colors[d])
    print(repr(performances))
    plt.xlabel('Total time ($\mu s$)')
    plt.ylabel('MIS probability')
    plt.semilogx()
    plt.legend()
    plt.show()
Example #20
0
 def test_multi_qubit_operation(self):
     N = 6
     psi0 = State(np.zeros((rydberg.d**N, 1)), code=rydberg)
     psi0[0, 0] = 1
     psi1 = psi0.copy()
     op = tools.tensor_product([rydberg.X, rydberg.Y, rydberg.Z])
     psi0 = rydberg.multiply(psi0, [1, 3, 4], op)
     psi1 = rydberg.multiply(psi1, [1], 'X')
     psi1 = rydberg.multiply(psi1, [3], 'Y')
     psi1 = rydberg.multiply(psi1, [4], 'Z')
     self.assertTrue(np.allclose(psi0, psi1))
Example #21
0
    def test_multi_qubit(self):
        n = 5
        psi0 = State(
            tools.tensor_product([jordan_farhi_shor.logical_basis[0]] * n))
        psi1 = psi0.copy()
        op = tools.tensor_product(
            [jordan_farhi_shor.X, jordan_farhi_shor.Y, jordan_farhi_shor.Z])
        psi0 = jordan_farhi_shor.multiply(psi0, [1, 3, 4], op)
        psi1 = jordan_farhi_shor.multiply(psi1, [1, 3, 4], ['X', 'Y', 'Z'])

        self.assertTrue(np.allclose(psi0, psi1))
Example #22
0
    def test_multi_qubit(self):
        N = 5
        psi0 = State(
            tools.tensor_product([two_qubit_code.logical_basis[0]] * N))
        psi1 = psi0.copy()
        op = tools.tensor_product(
            [two_qubit_code.X, two_qubit_code.Y, two_qubit_code.Z])
        psi0 = two_qubit_code.multiply(psi0, [1, 3, 4], op)
        psi1 = two_qubit_code.multiply(psi1, [1, 3, 4], ['X', 'Y', 'Z'])

        self.assertTrue(np.allclose(psi0, psi1))
Example #23
0
 def test_multi_qubit_pauli(self):
     N = 6
     psi0 = np.zeros((2 ** N, 1), dtype=np.complex128)
     psi0[0, 0] = 1
     psi1 = State(psi0)
     psi2 = State(psi0)
     psi3 = State(psi0)
     psi4 = State(psi0)
     psi0 = State(psi0)
     psi0 = qubit.multiply(psi0, [1, 3, 4], ['X', 'Y', 'Z'])
     psi2 = qubit.multiply(psi2, [4, 1, 3], ['Z', 'X', 'Y'])
     psi3 = qubit.multiply(psi3, [1, 3, 4], tools.tensor_product([qubit.X, qubit.Y, qubit.Z]))
     psi4 = qubit.multiply(psi4, [4, 1, 3], tools.tensor_product([qubit.Z, qubit.X, qubit.Y]))
     psi1 = qubit.multiply(psi1, [1], 'X')
     psi1 = qubit.multiply(psi1, [3], 'Y')
     psi1 = qubit.multiply(psi1, [4], 'Z')
     self.assertTrue(np.allclose(psi0, psi1))
     self.assertTrue(np.allclose(psi1, psi2))
     self.assertTrue(np.allclose(psi2, psi3))
     self.assertTrue(np.allclose(psi3, psi4))
Example #24
0
def mis_qaoa(n, method='minimize', show=True, analytic_gradient=True):
    penalty = 1
    psi0 = tools.equal_superposition(n)
    psi0 = State(psi0)
    G = make_ring_graph_multiring(n)
    if show:
        nx.draw_networkx(G)
        plt.show()

    depths = [2 * i for i in range(1, 2 * n + 1)]
    mis = []
    # Find MIS optimum
    # Uncomment to visualize graph
    hc_qubit = hamiltonian.HamiltonianMIS(G, energies=[1, penalty])
    cost = hamiltonian.HamiltonianMIS(G, energies=[1, penalty])
    # Set the default variational operators
    hb_qubit = hamiltonian.HamiltonianDriver()
    # Create Hamiltonian list
    sim = qaoa.SimulateQAOA(G, cost_hamiltonian=cost, hamiltonian=[], noise_model=None)
    sim.hamiltonian = []
    for p in depths:
        sim.hamiltonian.append(hc_qubit)
        sim.hamiltonian.append(hb_qubit)
        sim.depth = p
        # You should get the same thing
        print(p)
        if method == 'minimize':
            results = sim.find_parameters_minimize(verbose=True, initial_state=psi0,
                                                   analytic_gradient=analytic_gradient)

            approximation_ratio = np.real(results['approximation_ratio'])
            mis.append(approximation_ratio)
        if method == 'brute':
            results = sim.find_parameters_brute(n=15, verbose=True, initial_state=psi0)
            approximation_ratio = np.real(results['approximation_ratio'])
            mis.append(approximation_ratio)
        if method == 'basinhopping':
            if p >= 10:
                results = sim.find_parameters_basinhopping(verbose=True, initial_state=psi0, n=250,
                                                           analytic_gradient=analytic_gradient)
                print(results)
                approximation_ratio = np.real(results['approximation_ratio'])
                mis.append(approximation_ratio)

    # plt.plot(list(range(n)), maxcut, c='y', label='maxcut')
    print(mis)
    plt.plot(depths, [(i + 1) / (i + 2) for i in depths])
    plt.scatter(depths, [i / (i + 1) for i in depths], label='maxcut')
    plt.scatter(depths, mis, label='mis with $n=$' + str(n))
    plt.plot(depths, mis)

    plt.legend()
    if show:
        plt.show()
Example #25
0
 def f(t, state):
     if method == 'odeint':
         t, state = state, t
     if method != 'odeint':
         state = np.reshape(np.expand_dims(state, axis=0), state_shape)
     state = State(state,
                   is_ket=is_ket,
                   code=code,
                   IS_subspace=IS_subspace)
     return np.asarray(
         schrodinger_equation.evolution_generator(state)).flatten()
Example #26
0
    def test_rydberg_hamiltonian(self):
        # Test normal MIS Hamiltonian
        # Graph has six nodes and nine edges
        hc = hamiltonian.HamiltonianMIS(g)
        self.assertTrue(hc.hamiltonian[0, 0] == -3)
        self.assertTrue(hc.hamiltonian[-1, -1] == 0)
        self.assertTrue(hc.hamiltonian[-2, -2] == 1)
        self.assertTrue(hc.hamiltonian[2, 2] == -1)

        # Test for qubits
        hq = hamiltonian.HamiltonianMIS(g, energies=(1, 100))
        self.assertTrue(hq.hamiltonian[0, 0] == -894)
        self.assertTrue(hq.hamiltonian[-1, -1] == 0)
        self.assertTrue(hq.hamiltonian[2, 2] == -595)

        psi0 = State(np.zeros((2**g.n, 1)))
        psi0[-1, -1] = 1
        psi1 = State(tools.outer_product(psi0, psi0))
        self.assertTrue(hq.cost_function(psi1) == 0)
        self.assertTrue(hq.cost_function(psi0) == 0)
        self.assertTrue(hq.optimum_overlap(psi0) == 0)
        psi2 = State(np.zeros((2**g.n, 1)))
        psi2[27, -1] = 1
        self.assertTrue(hq.optimum_overlap(psi2) == 1)
        self.assertTrue(hq.cost_function(psi2) == 2)
        psi2[30, -1] = 1
        psi2 = psi2 / np.sqrt(2)
        self.assertTrue(np.isclose(hq.optimum_overlap(psi2), 1))
        self.assertTrue(np.isclose(hq.cost_function(psi2), 2))

        # Test for rydberg EIT
        hr = hamiltonian.HamiltonianMIS(g, energies=(1, 100), code=rydberg)
        self.assertTrue(hr.hamiltonian[0, 0] == -894)
        self.assertTrue(hr.hamiltonian[-1, -1] == 0)
        self.assertTrue(hr.hamiltonian[6, 6] == -595)

        psi0 = State(np.zeros((rydberg.d**g.n, 1)))
        psi0[-1, -1] = 1
        psi1 = State(tools.outer_product(psi0, psi0))
        self.assertTrue(hr.cost_function(psi1) == 0)
        self.assertTrue(hr.cost_function(psi0) == 0)
Example #27
0
def simple_stochastic(dt=0.001):
    """Simple stochastic integrator with no Hamiltonian evolution"""
    graph = nx.Graph()
    graph.add_nodes_from([0, 1, 2])
    graph.add_edges_from([(0, 1), (1, 2)])
    graph = Graph(graph)
    psi0 = np.array([[0, 1, 0, 0, 0, 0, 0, 0]]).T
    s = State(psi0, 3, is_ket=True)
    hamiltonian = GreedyNoiseTwoLocal(graph, rate = 1)
    sw = StochasticWavefunction(hamiltonians=[hamiltonian], jumps=[hamiltonian])
    output = sw.run(s.state, 0, 3, dt)
    print(output)
Example #28
0
def generate_inital_state_cf(graph, diff=2, verbose=False):
    cost = hamiltonian.HamiltonianMaxCut(graph, cost_function=True)
    maxcut = np.max(cost.hamiltonian)
    target = maxcut - diff
    where_target = sparse.find(cost.hamiltonian.real == target)[0]
    state = np.zeros(2**graph.n)
    state[where_target] = 1
    if verbose:
        print('num nonzero', len(np.argwhere(state != 0)))
    return State(state[:, np.newaxis] / np.linalg.norm(state),
                 is_ket=True,
                 graph=graph)
Example #29
0
 def compute_rate():
     # Construct the first order transition matrix
     energies, states = eq.eig(k='all')
     rates = np.zeros(len(bad))
     for j in range(graph.n):
         for i in range(len(bad)):
             rates[i] = rates[i] + (np.abs(
                 states[i].conj() @ qubit.left_multiply(
                     State(states[index].T), [j], qubit.Z))**2)[0, 0]
     # Select the relevant rates from 'good' to 'bad'
     print(rates)
     return rates
Example #30
0
 def evolution_generator(self, s: State):
     res = State(np.zeros(s.shape),
                 is_ket=s.is_ket,
                 code=s.code,
                 IS_subspace=s.IS_subspace,
                 graph=s.graph)
     for i in range(len(self.hamiltonians)):
         res = res - 1j * (self.hamiltonians[i].left_multiply(s) -
                           self.hamiltonians[i].right_multiply(s))
     for i in range(len(self.jump_operators)):
         res = res + self.jump_operators[i].liouvillian(s)
     return res