Пример #1
0
 def test_fidelity(self):
     a = np.ones((2,1))/2**.5
     a[0] = -1 * a[0]
     b = a * 1j
     a = tools.outer_product(a, a)
     b = tools.outer_product(b, b)
     assert tools.fidelity(a, b) == 1
Пример #2
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)
Пример #3
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)))
Пример #4
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)
Пример #5
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]
                ])))
Пример #6
0
def ARvstime_EIT(tf=10, graph=None, mis=None, show_graph=False, n=3):
    schedule = lambda t, tf: [[t / tf, (tf - t) / tf, 1], [1]]
    if graph is None:
        graph, mis = line_graph(n=n)
    graph = Graph(graph)
    if show_graph:
        nx.draw(graph)
        plt.show()
    rabi1 = 3
    rabi2 = 3
    # Generate the driving
    laser1 = hamiltonian.HamiltonianDriver(transition=(0, 1),
                                           energy=rabi1,
                                           code=rydberg,
                                           IS_subspace=True,
                                           graph=graph)
    laser2 = hamiltonian.HamiltonianDriver(transition=(1, 2),
                                           energy=rabi2,
                                           code=rydberg,
                                           IS_subspace=True,
                                           graph=graph)
    rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph,
                                                          code=rydberg,
                                                          detuning=1,
                                                          energy=0,
                                                          IS_subspace=True)
    # Initialize spontaneous emission
    spontaneous_emission_rate = 1
    spontaneous_emission = lindblad_operators.SpontaneousEmission(
        transition=(1, 2),
        rate=spontaneous_emission_rate,
        code=rydberg,
        IS_subspace=True,
        graph=graph)

    # Initialize master equation
    master_equation = LindbladMasterEquation(
        hamiltonians=[laser2, laser1], jump_operators=[spontaneous_emission])
    # Begin with all qubits in the ground codes
    psi = np.zeros((rydberg_hamiltonian_cost.hamiltonian.shape[0], 1),
                   dtype=np.complex128)
    psi[-1, -1] = 1
    psi = tools.outer_product(psi, psi)
    # Generate annealing schedule
    results = master_equation.run_ode_solver(
        psi, 0, tf, num_from_time(tf), schedule=lambda t: schedule(t, tf))
    cost_function = [
        rydberg_hamiltonian_cost.cost_function(results[i], is_ket=False) / mis
        for i in range(results.shape[0])
    ]
    print(cost_function[-1])
    plt.scatter(np.linspace(0, tf, num_from_time(tf)),
                cost_function,
                c='teal',
                label='approximation ratio')
    plt.legend()
    plt.xlabel(r'Approximation ratio')
    plt.ylabel(r'Time $t$')
    plt.show()
Пример #7
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)
Пример #8
0
def eit_steady_state(graph, show_graph=False, gamma=1):
    if show_graph:
        nx.draw(graph)
        plt.show()
    # Generate the driving and Rydberg Hamiltonians
    laser1 = hamiltonian.HamiltonianDriver(transition=(1, 2),
                                           IS_subspace=True,
                                           graph=graph,
                                           code=rydberg)
    laser2 = hamiltonian.HamiltonianDriver(transition=(0, 1),
                                           IS_subspace=True,
                                           graph=graph,
                                           code=rydberg)
    rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph,
                                                          IS_subspace=True,
                                                          code=rydberg)
    spontaneous_emission = lindblad_operators.SpontaneousEmission(
        graph=graph,
        transition=(1, 2),
        rates=[gamma],
        IS_subspace=True,
        code=rydberg)

    # Initialize adiabatic algorithm
    simulation = SimulateAdiabatic(graph,
                                   hamiltonian=[laser1, laser2],
                                   cost_hamiltonian=rydberg_hamiltonian_cost,
                                   IS_subspace=True,
                                   noise_model='continuous',
                                   code=rydberg,
                                   noise=[spontaneous_emission])

    master_equation = LindbladMasterEquation(
        hamiltonians=[laser1, laser2], jump_operators=[spontaneous_emission])
    initial_state = State(tools.outer_product(
        np.array([[0, 0, 0, 0, 0, 0, 0, 1]]).T,
        np.array([[0, 0, 0, 0, 0, 0, 0, 1]]).T),
                          code=rydberg,
                          IS_subspace=True,
                          is_ket=False)

    print(master_equation.steady_state(initial_state))

    return simulation
Пример #9
0
    def test_depolarize(self):
        # First test single qubit channel
        psi0 = State(np.zeros((4, 1)))
        psi0[0] = 1
        psi0 = State(tools.outer_product(psi0, psi0))
        psi1 = psi0.copy()
        psi2 = psi0.copy()
        psi3 = psi0.copy()
        psi4 = psi0.copy()
        p = 0.093
        op0 = quantum_channels.DepolarizingChannel()
        psi0 = op0.channel(psi0, p, apply_to=1)
        op1 = quantum_channels.DepolarizingChannel()
        psi1 = op1.channel(psi1, 2 * p, apply_to=0)
        self.assertTrue(psi1[2, 2] == 0.124)
        self.assertTrue(psi0[1, 1] == 0.062)

        # Now test multi qubit channel
        psi2 = op0.channel(psi2, p, apply_to=[0, 1])
        psi3 = op0.channel(psi3, p, apply_to=0)
        psi3 = op0.channel(psi3, p, apply_to=1)
        psi4 = op0.channel(psi4, p)
        self.assertTrue(np.allclose(psi2, psi3))
        self.assertTrue(np.allclose(psi2, psi4))

        expected = np.zeros((4, 4))
        expected[0, 0] = 0.46827
        expected[1, 1] = 0.03173
        expected[2, 2] = 0.46827
        expected[3, 3] = 0.03173
        psi0 = op0.evolve(psi0, 20)
        self.assertTrue(np.allclose(expected, psi0))

        psi0 = State(np.array([[1, 0], [0, 0]]))
        psi0 = op0.evolve(psi0, 20)
        self.assertTrue(np.allclose(psi0, .5 * np.identity(2)))
plt.show()"""
# Generate the driving and Rydberg Hamiltonians

# Initialize spontaneous emission
IS_penalty = 20
mis_dissipation = lindblad_operators.MISDissipation(graph,
                                                    IS_penalty=IS_penalty,
                                                    code=qubit)
hadamard_dissipation = Hadamard_Dissipation(code=qubit)
rydberg = hamiltonian.HamiltonianMIS(graph, energies=[IS_penalty], code=qubit)
# Initialize master equation
master_equation = LindbladMasterEquation(jump_operators=[mis_dissipation])

# Begin with all qubits in the ground codes
psi = tools.equal_superposition(graph.number_of_nodes())
psi = State(tools.outer_product(psi, psi))

dt = 0.1


def ARvstime(tf=10, schedule=lambda t, tf: [[], [t / tf, (tf - t) / tf]]):
    def ground_overlap(state):
        g = np.array([[0, 0], [0, 1]])
        op = tools.tensor_product([g] * graph.number_of_nodes())
        return np.real(np.trace(op @ state))

    t_cutoff = 5

    def step_schedule(t, tf):
        if t < t_cutoff:
            return [[], [t / tf, (tf - t) / tf]]
Пример #11
0
__all__ = ['multiply', 'right_multiply', 'left_multiply', 'rotation']

logical_code = True

X = tools.tensor_product([tools.X(), tools.identity()])
Y = tools.tensor_product([tools.Y(), tools.Z()])
Z = tools.tensor_product([tools.Z(), tools.Z()])
n = 2
d = 2
logical_basis = np.array([[[1], [0], [0], [1]], [[0], [1], [1], [0]]]).astype(
    np.complex128) / np.sqrt(2)
Q = 1 / 2 * (np.identity(d**n) + Z)
P = 1 / 2 * (np.identity(d**n) - Z)

code_space_projector = tools.outer_product(
    logical_basis[0], logical_basis[0]) + tools.outer_product(
        logical_basis[1], logical_basis[1])


def rotation(state: State,
             apply_to: Union[int, list],
             angle: float,
             op,
             is_involutary=False,
             is_idempotent=False):
    """
    Apply a single qubit rotation :math:`e^{-i \\alpha A}` to the input ``codes``.

    :param apply_to:
    :param is_idempotent:
    :param is_involutary:
Пример #12
0
def effective_operator_comparison(graph=None,
                                  mis=None,
                                  tf=10,
                                  show_graph=False,
                                  n=3,
                                  gamma=500):
    # Generate annealing schedule
    def schedule1(t, tf):
        return [[t / tf, (tf - t) / tf, 1], [1]]

    if graph is None:
        graph, mis = line_graph(n=n)
    graph = Graph(graph)
    if show_graph:
        nx.draw(graph)
        plt.show()
    # Generate the driving and Rydberg Hamiltonians
    rabi1 = 1
    laser1 = hamiltonian.HamiltonianDriver(transition=(0, 1),
                                           energies=[rabi1],
                                           code=rydberg,
                                           IS_subspace=True,
                                           graph=graph)
    rabi2 = 1
    laser2 = hamiltonian.HamiltonianDriver(transition=(1, 2),
                                           energies=[rabi2],
                                           code=rydberg,
                                           IS_subspace=True,
                                           graph=graph)
    rydberg_hamiltonian_cost = hamiltonian.HamiltonianRydberg(graph,
                                                              code=rydberg,
                                                              detuning=1,
                                                              energy=0,
                                                              IS_subspace=True)
    # Initialize spontaneous emission
    spontaneous_emission_rate = gamma
    spontaneous_emission = lindblad_operators.SpontaneousEmission(
        transition=(1, 2),
        rate=spontaneous_emission_rate,
        code=rydberg,
        IS_subspace=True,
        graph=graph)
    strong_spontaneous_emission_rate = (1, 1)
    strong_spontaneous_emission = lindblad_operators.StrongSpontaneousEmission(
        transition=(0, 2),
        rates=strong_spontaneous_emission_rate,
        code=rydberg,
        IS_subspace=True,
        graph=graph)

    def schedule2(t, tf):
        return [[],
                [(2 * t / tf / np.sqrt(spontaneous_emission_rate),
                  2 * (tf - t) / tf / np.sqrt(spontaneous_emission_rate))]]

    # Initialize master equation
    master_equation = LindbladMasterEquation(
        hamiltonians=[laser2, laser1], jump_operators=[spontaneous_emission])
    # Begin with all qubits in the ground codes
    psi = np.zeros((rydberg_hamiltonian_cost.hamiltonian.shape[0], 1),
                   dtype=np.complex128)
    psi[-1, -1] = 1
    psi = tools.outer_product(psi, psi)

    # Integrate the master equation
    results1 = master_equation.run_ode_solver(
        psi, 0, tf, num_from_time(tf), schedule=lambda t: schedule1(t, tf))
    cost_function = [
        rydberg_hamiltonian_cost.cost_function(results1[i], is_ket=False) / mis
        for i in range(results1.shape[0])
    ]
    # Initialize master equation
    master_equation = LindbladMasterEquation(
        hamiltonians=[], jump_operators=[strong_spontaneous_emission])

    # Integrate the master equation
    results2 = master_equation.run_ode_solver(
        psi, 0, tf, num_from_time(tf), schedule=lambda t: schedule2(t, tf))
    cost_function_strong = [
        rydberg_hamiltonian_cost.cost_function(results2[i], is_ket=False) / mis
        for i in range(results2.shape[0])
    ]
    print(results2[-1])
    times = np.linspace(0, tf, num_from_time(tf))
    # Compute the fidelity of the results
    fidelities = [
        tools.fidelity(results1[i], results2[i])
        for i in range(results1.shape[0])
    ]
    plt.plot(times, fidelities, color='r', label='Fidelity')
    plt.plot(times,
             cost_function,
             color='teal',
             label='Rydberg EIT approximation ratio')
    plt.plot(times,
             cost_function_strong,
             color='y',
             linestyle=':',
             label='Effective operator approximation ratio')

    plt.hlines(1, 0, max(times), linestyles=':', colors='k')
    plt.legend(loc='lower right')
    plt.ylim(0, 1.03)
    plt.xlabel(r'Annealing time $t$')
    plt.ylabel(r'Approximation ratio')
    plt.show()
p_len = 10
# Hamiltonian strength
kappa = 1  # np.linspace(0, 10, 10)
# Bit flip rate
p_error = 1 * dt
bit_flip = lindblad_operators.PauliNoise((p_error, 0, 0))
# Dissipative evolution rate
rate = np.linspace(0, n, p_len)
corrective = lindblad_operators.AmplitudeDampingNoise(1)

noisy_results = np.zeros((p_len, n))
ec_results = np.zeros((p_len, n))
for j in range(p_len):
    ideal = ThreeQubitCodeTwoAncillas.basis[0]
    # Noise with no error correction
    noisy = ThreeQubitCodeTwoAncillas(tools.outer_product(ideal, ideal),
                                      N,
                                      is_ket=False)
    # Dissipative error correction
    ec = ThreeQubitCodeTwoAncillas(tools.outer_product(ideal, ideal),
                                   N,
                                   is_ket=False)
    # Ideal codes for fidelity calculations
    ideal = ThreeQubitCodeTwoAncillas(tools.outer_product(ideal, ideal),
                                      N,
                                      is_ket=False)
    corrective.p = rate[j] * dt
    for i in range(n):
        # Evolve density matrix
        # Apply bit flip evolution
        hamiltonian.evolve(ec, dt * kappa)
Пример #14
0
    for c in G.nodes:
        C = C + tools.tensor_product([myeye(c), sigma_plus, myeye(N - c - 1)])
    return C


rydberg_noise_rate = 10
G = nx.Graph()

G.add_edge(0, 1, weight=rydberg_noise_rate)
#G.add_edge(2, 3, weight=rydberg_noise_rate)
G.add_edge(0, 2, weight=rydberg_noise_rate)
G.add_edge(1, 2, weight=rydberg_noise_rate)
zero = np.zeros([1, 2**N], dtype=np.complex128)
zero[-1, -1] = 1
zero = zero.T
zero = tools.outer_product(zero, zero)
#plot.draw_graph(G)
# Goal: numerically integrate master equation with (1) spontaneous emission and (2) IS constraint evolution
# with Hb hamiltonian
p = 2
spacing = 10
#se_noise_rate = 0.01
#se_noise = jump_operators.SpontaneousEmission(se_noise_rate)
rydberg_noise = MISLoweringJumpOperator(G, rydberg_noise_rate)
hb_x = hamiltonian.HamiltonianDriver(pauli='X')
hb_y = hamiltonian.HamiltonianDriver(pauli='Y')
hb_z = hamiltonian.HamiltonianDriver(pauli='Z')
hMIS = hamiltonian.HamiltonianMIS(G, blockade_energy=rydberg_noise_rate)
C = cost_function(G, rydberg_noise_rate)
C = C / np.max(C)
is_proj = IS_projector(G)