Esempio n. 1
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()
Esempio n. 2
0
def fidelity_vs_alpha():
    graph = line_graph(5)
    omega = 100
    T = 100
    delta_e = 1000
    beta = delta_e / (omega**2 * T)
    print('beta = ' + str(beta))
    gammas = 10**np.linspace(1.75, 3.25, 3)
    print(gammas * omega**2 * T / delta_e**2)
    dissipation = EffectiveOperatorDissipation(0,
                                               0,
                                               graph=graph,
                                               IS_subspace=True,
                                               rates=(1 / delta_e**2, ))
    laser = EffectiveOperatorHamiltonian(0,
                                         0,
                                         energies=(1 / delta_e, ),
                                         graph=graph,
                                         IS_subspace=True)
    energy_shift = hamiltonian.HamiltonianEnergyShift(graph=graph,
                                                      IS_subspace=True)

    def schedule_exp_fixed(t, tf=T):
        x = t / tf * np.pi / 2
        amplitude = np.abs(np.cos(x) * np.sin(x))
        # Now we need to figure out what the driver strengths should be for STIRAP
        omega_g = np.sin(x) * omega
        omega_r = np.cos(x) * omega
        offset = omega_r**2 - omega_g**2
        # Now, choose the opposite of the STIRAP sequence
        energy_shift.energies = (offset / 1000, )
        laser.omega_g = np.sqrt(amplitude) * omega
        laser.omega_r = np.sqrt(amplitude) * omega
        dissipation.omega_g = np.sqrt(amplitude) * omega
        dissipation.omega_r = np.sqrt(amplitude) * omega

    def schedule_reit(t, tf=T):
        x = t / tf * np.pi / 2
        omega_g = np.sin(x) * omega
        omega_r = np.cos(x) * omega
        energy_shift.energies = (0, )
        laser.omega_g = omega_g
        laser.omega_r = omega_r
        dissipation.omega_g = omega_g
        dissipation.omega_r = omega_r

    eq = LindbladMasterEquation(hamiltonians=[laser, energy_shift],
                                jump_operators=[dissipation])
    nonoise_eq = SchrodingerEquation(hamiltonians=[laser, energy_shift])
    state = State(np.array([[0, 0], [0, 1]], dtype=np.complex128),
                  IS_subspace=True,
                  graph=graph,
                  is_ket=False)
    state = State(np.array([[0, 0, 0], [0, 0, 0], [0, 0, 1]],
                           dtype=np.complex128),
                  IS_subspace=True,
                  graph=graph,
                  is_ket=False)
    state = State(np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0],
                            [0, 0, 0, 0, 0], [0, 0, 0, 0, 1]],
                           dtype=np.complex128),
                  IS_subspace=True,
                  graph=graph,
                  is_ket=False)
    state = State(np.zeros((13, 13), dtype=np.complex128),
                  IS_subspace=True,
                  graph=graph,
                  is_ket=False)
    state[-1, -1] = 1
    # nonoise_state = State(np.array([[0], [0], [1]], dtype=np.complex128), IS_subspace=True, graph=graph, is_ket=True)
    # print(np.abs(nonoise_eq.run_ode_solver(nonoise_state, 0, T, num=500, schedule=schedule_exp_fixed, method='odeint')[0][-1])**2)
    for a in [1]:
        delta_e = a * 1000
        laser.energies = (1 / delta_e, )
        fidelities = []
        ars = []
        for i in range(len(gammas)):
            dissipation.rates = (gammas[i] / delta_e**2, )
            states = eq.run_ode_solver(state,
                                       0,
                                       T,
                                       num=50,
                                       schedule=schedule_reit,
                                       make_valid_state=False,
                                       method='odeint')
            times = states[1]['t']
            states = states[0]
            """print(gammas[i], i)
            for j in range(len(times)):
                for op in dissipation.jump_operators:
                    print(np.trace(op.conj().T@op@states[j])-np.abs(np.trace(op@states[j]))**2)"""
            """print(times[25])
            schedule_exp_fixed(times[25], tf=T)
            eigvals, eigvecs = nonoise_eq.eig(k='all')
            print(eigvals)
            print(eigvecs.conj()@states[25]@eigvecs.T)"""
            final_state = states[-1]
            #print(final_state)
            #print(final_state[0, 0], np.trace(final_state))
            ar = (final_state[0, 0] + 2 / 3 *
                  (final_state[1, 1] + final_state[2, 2] + final_state[3, 3] +
                   final_state[6, 6] + final_state[5, 5] + final_state[8, 8]) +
                  1 / 2 *
                  (final_state[7, 7] + final_state[4, 4] + final_state[9, 9] +
                   final_state[10, 10] + final_state[11, 11]))
            print(ar)
            print(final_state[0, 0])
            print(final_state.diagonal())
            ars.append(ar)
            fidelities.append(final_state[0, 0])
        fidelities = np.array(fidelities)
        ars = np.array(ars)
        plt.loglog()
        plt.ylabel(r'$1-$ fidelity')
        plt.xlabel(r'$\frac{\gamma \Omega^2 T}{\delta_e^2}$')
        plt.plot(gammas * omega**2 * T / delta_e**2,
                 1 - fidelities,
                 label='fidelity')
        plt.plot(gammas * omega**2 * T / delta_e**2, 1 - ars, label='ar')
        res = np.polyfit(np.log(gammas * omega**2 * T / delta_e**2),
                         np.log(1 - fidelities), 1)
        print(res)
        #plt.plot(gammas * omega ** 2 * T / delta_e ** 2,
        #         1 - np.e ** (-gammas * omega ** 2 * T / delta_e ** 2 * 0.033875094811638556),
        #         label='bound')
        """if a == -1:

            plt.plot(gammas * omega ** 2 * T / delta_e ** 2,
                     0.28187096704733217 * gammas * omega ** 2 * T / delta_e ** 2,
                     label='first order correction')
        else:
            plt.plot(gammas * omega ** 2 * T / delta_e ** 2,
                     0.033875094811638556 * gammas * omega ** 2 * T / delta_e ** 2,
                     label='first order correction')"""

    plt.legend()
    plt.tight_layout()
    plt.show()
Esempio n. 3
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()
Esempio n. 4
0
    def run(self, time, schedule, num=None, initial_state=None, full_output=True, method='RK45', verbose=False,
            iterations=None):
        if method == 'odeint' or method == 'trotterize' and num is None:
            num = self._num_from_time(time, method=method)

        if initial_state is None:
            # Begin with all qudits in the ground s
            initial_state = State(np.zeros((self.cost_hamiltonian.hamiltonian.shape[0], 1)), code=self.code,
                                  IS_subspace=self.IS_subspace, graph=self.graph)
            initial_state[-1, -1] = 1

        if self.noise_model is not None and self.noise_model != 'monte_carlo':
            initial_state = State(outer_product(initial_state, initial_state), IS_subspace=self.IS_subspace,
                                  code=self.code, graph=self.graph)

        if self.noise_model == 'continuous':
            # Initialize master equation
            if method == 'trotterize':
                master_equation = LindbladMasterEquation(hamiltonians=self.hamiltonian, jump_operators=self.noise)
                results, info = master_equation.run_trotterized_solver(initial_state, 0, time, num=num,
                                                                       schedule=lambda t: schedule(t, time),
                                                                       full_output=full_output, verbose=verbose)
            else:
                master_equation = LindbladMasterEquation(hamiltonians=self.hamiltonian, jump_operators=self.noise)
                results, info = master_equation.run_ode_solver(initial_state, 0, time, num=num,
                                                               schedule=lambda t: schedule(t, time), method=method,
                                                               full_output=full_output, verbose=verbose)
        elif self.noise_model is None:
            # Noise model is None
            # Initialize Schrodinger equation
            schrodinger_equation = SchrodingerEquation(hamiltonians=self.hamiltonian)
            if method == 'trotterize':
                results, info = schrodinger_equation.run_trotterized_solver(initial_state, 0, time, num=num,
                                                                            verbose=verbose, full_output=full_output,
                                                                            schedule=lambda t: schedule(t, time))
            else:
                results, info = schrodinger_equation.run_ode_solver(initial_state, 0, time, num=num, verbose=verbose,
                                                                    schedule=lambda t: schedule(t, time), method=method,
                                                                    full_output=full_output)

        else:
            assert self.noise_model == 'monte_carlo'
            # Initialize master equation
            master_equation = LindbladMasterEquation(hamiltonians=self.hamiltonian, jump_operators=self.noise)
            results, info = master_equation.run_stochastic_wavefunction_solver(initial_state, 0, time, num=num,
                                                                               full_output=full_output,
                                                                               schedule=lambda t: schedule(t, time),
                                                                               method=method, verbose=verbose,
                                                                               iterations=iterations)

        if len(results.shape) == 2:
            # The algorithm has output a single state
            out = [State(results, IS_subspace=self.IS_subspace, code=self.code, graph=self.graph)]
        elif len(results.shape) == 3:
            # The algorithm has output an array of states
            out = [State(res, IS_subspace=self.IS_subspace, code=self.code, graph=self.graph) for res in results]
        else:
            assert len(results.shape) == 4
            if self.noise_model != 'monte_carlo':
                raise Exception('Run output has more dimensions than expected')
            out = []
            for i in range(results.shape[0]):
                # For all iterations
                res = []
                for j in range(results.shape[1]):
                    # For all times
                    res.append(
                        State(results[i, j, ...], IS_subspace=self.IS_subspace, code=self.code, graph=self.graph))
                out.append(res)
        return out, info