예제 #1
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()
예제 #2
0
def adiabatic_simulation(graph, show_graph=False, IS_subspace=True):
    if show_graph:
        nx.draw(graph)
        plt.show()
    # Generate the driving and Rydberg Hamiltonians
    laser = hamiltonian.HamiltonianDriver(IS_subspace=IS_subspace, graph=graph)
    detuning = hamiltonian.HamiltonianMIS(graph, IS_subspace=IS_subspace)
    rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=IS_subspace)
    graph.mis_size = int(np.max(rydberg_hamiltonian_cost.hamiltonian))
    print('Degeneracy',
          len(np.argwhere(rydberg_hamiltonian_cost.hamiltonian == np.max(rydberg_hamiltonian_cost.hamiltonian)).T[0]))
    # Initialize adiabatic algorithm
    simulation = SimulateAdiabatic(graph, hamiltonian=[laser, detuning], cost_hamiltonian=rydberg_hamiltonian_cost,
                                   IS_subspace=IS_subspace)
    return simulation
예제 #3
0
def find_fidelity(graph, critical_time):
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
    driver = hamiltonian.HamiltonianDriver(IS_subspace=True, graph=graph)

    def schedule(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (3 * 2 * (1 / 2 - x), )
        driver.energies = (amplitude, )

    ad = SimulateAdiabatic(graph=graph,
                           hamiltonian=[cost, driver],
                           cost_hamiltonian=cost,
                           IS_subspace=True)

    final_state = ad.run(critical_time, schedule, method='odeint')[0][-1]
    cost.energies = (1, )
    optimum_indices = np.argwhere(
        cost._diagonal_hamiltonian == cost.optimum).T[0]
    # Construct an operator that is zero everywhere except at the optimum
    optimum = np.zeros(cost._diagonal_hamiltonian.shape)
    optimum[optimum_indices] = 1
    optimum_overlap = cost.optimum_overlap(final_state)
    return final_state, optimum, optimum_overlap
예제 #4
0
def find_critical_time(graph, critical_optimum_overlap):
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
    driver = hamiltonian.HamiltonianDriver(IS_subspace=True, graph=graph)

    def schedule(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (3 * 2 * (1 / 2 - x), )
        driver.energies = (amplitude, )

    ad = SimulateAdiabatic(graph=graph,
                           hamiltonian=[cost, driver],
                           cost_hamiltonian=cost,
                           IS_subspace=True)

    def compute_final_state(T):
        final_state = ad.run(T, schedule, method='odeint')[0][-1]
        cost.energies = (1, )
        optimum_overlap = cost.optimum_overlap(final_state)
        return final_state, optimum_overlap

    def cost_function(T):
        final_state, optimum_overlap = compute_final_state(T)
        print(T, optimum_overlap)
        return optimum_overlap - critical_optimum_overlap

    #return basinhopping(cost_function, 35, niter=3, minimizer_kwargs={'bounds':[(20,50)]})['x']
    return brentq(cost_function, 20, 50, xtol=1e-5)
예제 #5
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()
예제 #6
0
def eit_simulation(graph, noise_model=None, show_graph=False, gamma=1, delta: float = 0):
    if show_graph:
        nx.draw(graph)
        plt.show()
    # Generate the driving and Rydberg Hamiltonians
    if noise_model == 'continuous':
        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)
        if delta != 0:
            detuning = hamiltonian.HamiltonianEnergyShift(code=rydberg, IS_subspace=True, graph=graph,
                                                          energies=[delta])
        spontaneous_emission = lindblad_operators.SpontaneousEmission(graph=graph, transition=(1, 2), rates=[gamma],
                                                                      IS_subspace=True, code=rydberg)

        # Initialize adiabatic algorithm
        if delta != 0:
            simulation = SimulateAdiabatic(graph, hamiltonian=[laser1, laser2, detuning],
                                           cost_hamiltonian=rydberg_hamiltonian_cost, IS_subspace=True,
                                           noise_model='continuous', code=rydberg, noise=[spontaneous_emission])
        else:
            simulation = SimulateAdiabatic(graph, hamiltonian=[laser1, laser2],
                                           cost_hamiltonian=rydberg_hamiltonian_cost, IS_subspace=True,
                                           noise_model='continuous', code=rydberg, noise=[spontaneous_emission])
        return simulation

    elif noise_model == 'monte_carlo':
        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
        if delta != 0:
            detuning = hamiltonian.HamiltonianEnergyShift(code=rydberg, IS_subspace=True, graph=graph, energies=[delta])
            simulation = SimulateAdiabatic(graph, hamiltonian=[laser1, laser2, detuning],
                                       cost_hamiltonian=rydberg_hamiltonian_cost, IS_subspace=True,
                                       noise_model='monte_carlo', code=rydberg, noise=[spontaneous_emission])
        else:
            simulation = SimulateAdiabatic(graph, hamiltonian=[laser1, laser2],
                                           cost_hamiltonian=rydberg_hamiltonian_cost, IS_subspace=True,
                                           noise_model='monte_carlo', code=rydberg, noise=[spontaneous_emission])
        return simulation
예제 #7
0
def adiabatic_simulation(graph,
                         show_graph=False,
                         IS_subspace=False,
                         noisy=False,
                         trotterize=True):
    if show_graph:
        nx.draw(graph)
        plt.show()
    # Generate the driving and Rydberg Hamiltonians
    if not noisy:
        laser = hamiltonian.HamiltonianDriver(IS_subspace=IS_subspace,
                                              graph=graph)
        detuning = hamiltonian.HamiltonianMIS(graph, IS_subspace=IS_subspace)
        rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(
            graph, IS_subspace=IS_subspace)
        # Initialize adiabatic algorithm
        simulation = SimulateAdiabatic(
            graph,
            hamiltonian=[laser, detuning],
            cost_hamiltonian=rydberg_hamiltonian_cost,
            IS_subspace=IS_subspace)
    else:
        laser = hamiltonian.HamiltonianDriver(IS_subspace=IS_subspace,
                                              graph=graph)
        detuning = hamiltonian.HamiltonianMIS(graph, IS_subspace=IS_subspace)
        rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(
            graph, IS_subspace=IS_subspace)
        if trotterize:
            spontaneous_emission = quantum_channels.AmplitudeDampingChannel(
                graph=graph, IS_subspace=IS_subspace, rates=(.1, ))
        else:
            spontaneous_emission = lindblad_operators.SpontaneousEmission(
                graph=graph, IS_subspace=IS_subspace, rates=(.1, ))

        # Initialize adiabatic algorithm
        simulation = SimulateAdiabatic(
            graph,
            hamiltonian=[laser, detuning],
            noise_model='continuous',
            noise=[spontaneous_emission],
            cost_hamiltonian=rydberg_hamiltonian_cost,
            IS_subspace=IS_subspace)
    return simulation
예제 #8
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()
예제 #9
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)
def find_ratio(tails_graph, graph, detuning_plateau, tf):
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
    print('Starting driver')
    driver = hamiltonian.HamiltonianDriver(IS_subspace=True, graph=graph)
    print('Starting rydberg')
    if tails_graph is not None:
        rydberg = hamiltonian.HamiltonianRydberg(tails_graph,
                                                 graph,
                                                 IS_subspace=True,
                                                 energies=(2 * np.pi, ))
        ad = SimulateAdiabatic(graph=graph,
                               hamiltonian=[cost, driver, rydberg],
                               cost_hamiltonian=cost,
                               IS_subspace=True)
    else:
        ad = SimulateAdiabatic(graph=graph,
                               hamiltonian=[cost, driver],
                               cost_hamiltonian=cost,
                               IS_subspace=True)

    def schedule_cubic(t, T):
        cubic_ys = 2 * np.pi * np.array([
            11.5, detuning_plateau + .5, detuning_plateau,
            detuning_plateau - .5, -11.5
        ])
        cubic_xs = np.array([
            .312, (T / 2 - .312) / 1.35 + .312, T / 2,
            T - .312 - (T / 2 - .312) / 1.35, T - .312
        ])
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 11.5, )
        elif .312 <= t <= T - .312:
            driver.energies = (2 * np.pi * 2, )
            cost.energies = (scipy.interpolate.interp1d(cubic_xs,
                                                        cubic_ys,
                                                        kind='cubic')(t), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * 11.5, )

    print('Starting evolution')
    states, data = ad.run(tf,
                          schedule_cubic,
                          num=int(400 * tf),
                          method='trotterize',
                          full_output=False)
    np.savez_compressed('{}x{}_{}_{}_{}_trotterize_highres.npz'.format(
        size, size, graph_index, np.round(np.abs(detuning_plateau), 2),
        np.round(np.abs(tf), 2)),
                        state=states[-1])
예제 #11
0
def jump_rate_scaling():
    graph = Graph(nx.star_graph(n=4))  # line_graph(n=3)
    energy = 1
    phis = np.arange(.001, .01, .001)
    rates = np.zeros(len(phis))
    rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph,
                                                          IS_subspace=True,
                                                          code=qubit)
    print(rydberg_hamiltonian_cost.hamiltonian)
    for d in range(len(phis)):
        print(d)
        laser = EffectiveOperatorHamiltonian(omega_g=np.cos(phis[d]),
                                             omega_r=np.sin(phis[d]),
                                             energies=(energy, ),
                                             graph=graph)
        dissipation = EffectiveOperatorDissipation(omega_g=np.cos(phis[d]),
                                                   omega_r=np.sin(phis[d]),
                                                   rates=(energy, ),
                                                   graph=graph)
        # Find the dressed states
        simulation = SchrodingerEquation(hamiltonians=[laser])
        eigval, eigvec = simulation.eig()
        eigval = [
            rydberg_hamiltonian_cost.approximation_ratio(
                State(eigvec[i].T, is_ket=True, graph=graph, IS_subspace=True))
            for i in range(eigval.shape[0])
        ]
        print(eigval)
        optimal_eigval_index = np.argmax(eigval)
        optimal_eigval = eigvec[optimal_eigval_index]
        rate = 0
        for i in range(graph.n):
            # Compute the decay rate of the MIS into other states
            for j in range(eigvec.shape[0]):
                if j != optimal_eigval_index:
                    rate += np.abs(eigvec[j] @ dissipation.jump_operators[i]
                                   @ optimal_eigval.T)**2
        rates[d] = rate
    fit = np.polyfit(np.log(phis), np.log(rates), deg=1)

    plt.scatter(np.log(phis), np.log(rates), color='teal')
    plt.plot(np.log(phis),
             fit[0] * np.log(phis) + fit[1],
             color='k',
             label=r'$y=$' + str(np.round(fit[0], decimals=2)) + r'$x+$' +
             str(np.round(fit[1], decimals=2)))
    plt.legend()
    plt.xlabel(r'$\log(\phi)$')
    plt.ylabel(r'$\log(\rm{rate})$')
    plt.show()
예제 #12
0
def find_ratio(tails_graph, graph, tf):
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
    driver = hamiltonian.HamiltonianDriver(IS_subspace=True, graph=graph)

    def schedule(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                            -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (11 * 2 * (1 / 2 - x), )
        driver.energies = (2 * amplitude, )

    # Uncomment this to print the schedule at t=0
    # schedule(0, 1)
    # print(cost.hamiltonian*2*np.pi)
    # print(driver.hamiltonian)
    if tails_graph is None:
        ad = SimulateAdiabatic(graph=graph,
                               hamiltonian=[cost, driver],
                               cost_hamiltonian=cost,
                               IS_subspace=True)
    else:
        rydberg = hamiltonian.HamiltonianRydberg(tails_graph,
                                                 graph,
                                                 IS_subspace=True,
                                                 energies=(1, ))
        ad = SimulateAdiabatic(graph=graph,
                               hamiltonian=[cost, driver, rydberg],
                               cost_hamiltonian=cost,
                               IS_subspace=True)
    print('running')
    states, data = ad.run(tf, schedule, method='odeint')
    print(data)
    times = data['t']
    is_overlaps = np.zeros((graph.mis_size + 1, len(states)))
    cost.energies = (1, )
    for j in range(graph.mis_size + 1):
        projector = (cost._diagonal_hamiltonian == j)
        for i in range(len(states)):
            is_overlaps[j, i] = np.sum(np.abs(states[i])**2 * projector)
    print(is_overlaps)
    for j in range(graph.mis_size + 1):
        plt.scatter(times, is_overlaps[j], label=str(j))
    plt.legend()
    plt.show()
예제 #13
0
def imperfect_blockade_performance():
    graph = line_graph(n=5, return_mis=False)
    phi = .02
    laser = hamiltonian.HamiltonianDriver(pauli='X', energies=(np.cos(phi) * np.sin(phi),), graph=graph)
    energy_shift_r = hamiltonian.HamiltonianEnergyShift(index=0, energies=(np.sin(phi) ** 2,), graph=graph)
    energy_shift_g = hamiltonian.HamiltonianEnergyShift(index=1, energies=(np.cos(phi) ** 2,), graph=graph)
    dissipation = EffectiveOperatorDissipation(omega_g=np.cos(phi), omega_r=np.sin(phi), rates=(1,), graph=graph,
                                               IS_subspace=False)

    rydberg_hamiltonian = hamiltonian.HamiltonianMIS(graph, IS_subspace=False, code=qubit, energies=(0, 4,))
    rydberg_hamiltonian_cost_IS = hamiltonian.HamiltonianMIS(graph, IS_subspace=True, code=qubit)
    rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=False, code=qubit, energies=(1, -4,))


    eq = LindbladMasterEquation(hamiltonians=[laser, energy_shift_g, energy_shift_r, rydberg_hamiltonian], jump_operators=[dissipation])
    state = np.zeros(rydberg_hamiltonian_cost.hamiltonian.shape)
    state[graph.independent_sets[np.argmax(rydberg_hamiltonian_cost_IS.hamiltonian)][0], graph.independent_sets[np.argmax(rydberg_hamiltonian_cost_IS.hamiltonian)][0]] = 1
    state = State(state, is_ket=False, graph=graph, IS_subspace=False)
    ss = eq.steady_state(state, k=80, use_initial_guess=True)
    print(ss[1].shape)
    ss = ss[1][0]
    print(np.diagonal(ss), rydberg_hamiltonian_cost.hamiltonian)
    state = State(ss, is_ket=False, graph=graph, IS_subspace=False)
    print(np.around(ss, decimals=3), rydberg_hamiltonian_cost.optimum_overlap(state))
    layout = np.zeros((2, 2))
    layout[0, 0] = 1
    layout[1, 1] = 1
    layout[0, 1] = 1
    adjacent_energy = 4
    diag_energy = adjacent_energy/8
    second_nearest_energy = adjacent_energy/64
    for i in range(layout.shape[0] - 1):
        for j in range(layout.shape[1] - 1):
            if layout[i, j] == 1:
                # There is a spin here
                pass
예제 #14
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()
예제 #15
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
예제 #16
0
 def adiabatic_hamiltonian(t, tf):
     graph, mis = line_graph(n=n)
     ham = np.zeros((2**n, 2**n))
     coefficients = adiabatic_schedule(t, tf)
     rydberg_energy = 50
     rydberg_hamiltonian = hamiltonian.HamiltonianMIS(graph,
                                                      energy=rydberg_energy,
                                                      code=qubit)
     # TODO: generalize this!
     if n == 3:
         ham = ham + coefficients[1] * tools.tensor_product(
             [qubit.Z, np.identity(2),
              np.identity(2)])
         ham = ham + coefficients[1] * tools.tensor_product(
             [np.identity(2), qubit.Z,
              np.identity(2)])
         ham = ham + coefficients[1] * tools.tensor_product(
             [np.identity(2), np.identity(2), qubit.Z])
         ham = ham + coefficients[0] * tools.tensor_product(
             [qubit.X, np.identity(2),
              np.identity(2)])
         ham = ham + coefficients[0] * tools.tensor_product(
             [np.identity(2), qubit.X,
              np.identity(2)])
         ham = ham + coefficients[0] * tools.tensor_product(
             [np.identity(2), np.identity(2), qubit.X])
         ham = ham + np.diag(rydberg_hamiltonian.hamiltonian.T[0])
     elif n == 2:
         ham = ham + coefficients[1] * tools.tensor_product(
             [qubit.Z, np.identity(2)])
         ham = ham + coefficients[1] * tools.tensor_product(
             [np.identity(2), qubit.Z])
         ham = ham + coefficients[0] * tools.tensor_product(
             [qubit.X, np.identity(2)])
         ham = ham + coefficients[0] * tools.tensor_product(
             [np.identity(2), qubit.X])
         ham = ham + np.diag(rydberg_hamiltonian.hamiltonian.T[0])
     return np.linalg.eig(ham)
예제 #17
0
def simple_greedy_heisenberg(dt=0.001):
    g = nx.Graph()
    g.add_nodes_from([0, 1, 2, 3, 4], weight = 1)
    g.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 4)], weight = -1)
    graph = Graph(g)
    tf = 3
    times = np.arange(0, tf, dt)
    psi0 = np.zeros((2**graph.n, 1))
    psi0[-1] = 1
    s = State(psi0, graph.n, is_ket=True)
    greedy = GreedyNoise(graph, rate = 10)
    heisenberg = HamiltonianHeisenberg(graph, k=100)
    mis_hamiltonian = hamiltonian.HamiltonianMIS(g)
    sw = StochasticWavefunction(hamiltonians=[heisenberg, greedy], jumps=[greedy])
    output = sw.run(s.state, 0, tf, dt)
    mis = np.zeros((2**graph.n, 1))
    mis[10] = 1
    overlap_mis = np.abs(np.squeeze(output, axis=-1)@mis)
    spin = np.abs(np.squeeze(output, axis=-1))**2 @ mis_hamiltonian.hamiltonian_diag
    plt.plot(times, overlap_mis, label = 'mis')
    plt.plot(times, spin, label='spin')
    plt.legend(loc='upper left')
    plt.show()
예제 #18
0
def performance_vs_alpha():
    # alpha = gamma * omega^2/(delta^2 T)
    graph = line_graph(n=3)
    gammas = np.array([1, 5, 10])
    times = np.array([1, 5, 10])
    deltas = np.array([20, 30])
    omegas = np.array([1, 5, 10])
    for (g, d, o) in zip(gammas, deltas, omegas):
        # Find the performance vs alpha
        laser = EffectiveOperatorHamiltonian(graph=graph)
        dissipation = EffectiveOperatorDissipation(graph=graph)
        rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True, code=qubit)
        adiabatic = SimulateAdiabatic(hamiltonian=[laser], noise = [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)
        performance = adiabatic.performance_vs_total_time(times, schedule=schedule, verbose=True, method='odeint')[0]
        alphas = g * o**2/(d**2 * times)
        plt.scatter(alphas, performance)
    plt.show()
                                   (0, 3, 1)])
    return graph, 2


graph, mis = two_triangle()
"""nx.draw(graph)
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))
def track_eigenstate_populations(graph, tails_graph, grid, k=2):
    n_points = 7
    times_exp = 2**np.linspace(-2.5, 4.5 / 6 *
                               (n_points - 1) - 2.5, n_points) + .312 * 2
    t_max = times_exp[6]
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
    # print('Starting driver')
    driver = hamiltonian.HamiltonianDriver(IS_subspace=True, graph=graph)
    # print('Starting rydberg')
    if tails_graph is not None:
        rydberg = hamiltonian.HamiltonianRydberg(tails_graph,
                                                 graph,
                                                 IS_subspace=True,
                                                 energies=(2 * np.pi, ))
    pulse = np.loadtxt('for_AWG_{}.000000.txt'.format(6))
    t_pulse_max = np.max(pulse[:, 0]) - 2 * 0.312
    max_detuning = np.max(pulse[:, 2])

    def schedule_old(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                            -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (-2 * np.pi * 11 * 2 * (1 / 2 - t / T),
                         )  # (2 * np.pi * (-(11 + 15) / T * t + 15),)
        driver.energies = (2 * np.pi * 2 * amplitude,
                           )  # (2 * np.pi * 2 * amplitude,)

    def schedule_exp_optimized(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 15, )
        elif .312 <= t <= T - .312:
            t_pulse = (t - 0.312) / (T - 2 * 0.312) * t_pulse_max + 0.312
            driver.energies = (
                2 * np.pi * np.interp(t_pulse, pulse[:, 0], pulse[:, 1] / 2), )
            cost.energies = (2 * np.pi *
                             np.interp(t_pulse, pulse[:, 0], -pulse[:, 2]), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * max_detuning, )
        # print(t, cost.energies)

    def schedule_exp_linear(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 15, )
        elif .312 <= t <= T - .312:
            driver.energies = (2 * np.pi * 2, )
            cost.energies = (2 * np.pi * (-(11 + 15) / (T - 2 * .312) *
                                          (t - .312) + 15), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * 11, )

    def eigs(t):
        schedule_exp_linear(t, t_max)
        eigval, eigvec = eq.eig(which='S', k=k)
        return eigval - eigval[0], eigvec

    if tails_graph is not None:
        eq = schrodinger_equation.SchrodingerEquation(
            hamiltonians=[cost, driver, rydberg])

        ad = SimulateAdiabatic(graph=graph,
                               hamiltonian=[cost, driver, rydberg],
                               cost_hamiltonian=cost,
                               IS_subspace=True)
    else:
        eq = schrodinger_equation.SchrodingerEquation(
            hamiltonians=[cost, driver])

        ad = SimulateAdiabatic(graph=graph,
                               hamiltonian=[cost, driver],
                               cost_hamiltonian=cost,
                               IS_subspace=True)
    print('starting evolution')

    states, data = ad.run(t_max,
                          schedule_exp_linear,
                          num=int(60 * t_max),
                          method='odeint',
                          full_output=True)
    print('finished evolution')
    times = data['t']
    start_index = len(times) // 2
    times = times[start_index:]
    states = states[start_index:]
    populations = np.zeros((len(times), k))
    energies = np.zeros((len(times), k))
    for (i, time) in enumerate(times):
        print(i)
        eigval, eigvecs = eigs(time)
        populations[i] = (np.abs(eigvecs @ states[i])**2).flatten()
        energies[i] = eigval / (2 * np.pi)
    populations = np.log10(populations)
    from matplotlib.collections import LineCollection
    fig, ax = plt.subplots()
    norm = plt.Normalize(-5, np.max(populations))
    for i in range(energies.shape[1]):
        points = np.array([times, energies[:, i]]).T.reshape(-1, 1, 2)
        segments = np.concatenate([points[:-1], points[1:]], axis=1)
        lc = LineCollection(segments, cmap='coolwarm', norm=norm)
        # Set the values used for colormapping
        lc.set_array(populations[:-1, i])
        lc.set_linewidth(1)
        line = ax.add_collection(lc)
    cbar = fig.colorbar(line, ax=ax)
    cbar.ax.set_ylabel(r'$\log_{10}(\rm{population})$')
    ax.set_xlim(np.min(times), np.max(times))
    ax.set_xlabel(r'Time ($\mu$s)')
    ax.set_ylabel(r'Eigenenergy (MHz)')
    ax.set_ylim(np.min(energies) - .3, np.max(energies))
    # ax.annotate(r'$r_{0\rightarrow j} = \sum_\mu |\langle j |c_\mu |0\rangle |^2$', xy=(0.4, 0.1), xycoords='data')
    plt.show()

    fig, ax = plt.subplots()
    deltas = np.zeros(len(times))
    print(times)
    for (i, time) in enumerate(times):
        schedule_exp_linear(time, t_max)
        deltas[i] = cost.energies[0] / (2 * np.pi)
    print(deltas)
    norm = plt.Normalize(-5, np.max(populations))
    for i in range(energies.shape[1]):
        points = np.array([deltas, energies[:, i]]).T.reshape(-1, 1, 2)
        segments = np.concatenate([points[:-1], points[1:]], axis=1)
        lc = LineCollection(segments, cmap='coolwarm', norm=norm)
        # Set the values used for colormapping
        lc.set_array(populations[:-1, i])
        lc.set_linewidth(1)
        line = ax.add_collection(lc)
    cbar = fig.colorbar(line, ax=ax)
    cbar.ax.set_ylabel(r'$\log_{10}(\rm{population})$')
    ax.set_xlim(np.max(deltas), np.min(deltas))
    ax.set_xlabel(r'$\Delta$ (MHz)')
    ax.set_ylabel(r'Eigenenergy (MHz)')
    ax.set_ylim(np.min(energies) - .3, np.max(energies))
    # ax.annotate(r'$r_{0\rightarrow j} = \sum_\mu |\langle j |c_\mu |0\rangle |^2$', xy=(0.4, 0.1), xycoords='data')
    plt.show()

    fig, ax = plt.subplots(3, 5)

    probs = np.abs(eigvecs)**2
    print(probs[:, :10])
    for l in range(k):
        i = l // 5
        j = l % 5
        layout = grid.copy().flatten().astype(float)
        layout[layout == 0] = -5
        layout[layout == 1] = 0
        layout_temp = layout.copy()
        for m in range(probs.shape[1]):
            layout_temp[layout == 0] = layout_temp[
                layout == 0] + (1 - graph.independent_sets[m]) * probs[l, m]
        ax[i][j].imshow(layout_temp.reshape(grid.shape))
        ax[i][j].set_axis_off()
        ax[i][j].text(-0.1,
                      1.05,
                      '$\lambda${}'.format(str(l)),
                      transform=ax[i][j].transAxes,
                      size=10,
                      weight='bold')

    plt.show()
def visualize_low_energy_subspace(graph, tails_graph, k=5):
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
    # print('Starting driver')
    n_points = 7
    times_exp = 2**np.linspace(-2.5, 4.5 / 6 *
                               (n_points - 1) - 2.5, n_points) + .312 * 2
    t_max = times_exp[4]
    driver = hamiltonian.HamiltonianDriver(IS_subspace=True, graph=graph)
    # print('Starting rydberg')
    rydberg = hamiltonian.HamiltonianRydberg(tails_graph,
                                             graph,
                                             IS_subspace=True,
                                             energies=(2 * np.pi, ))
    pulse = np.loadtxt('for_AWG_{}.000000.txt'.format(6))
    t_pulse_max = np.max(pulse[:, 0]) - 2 * 0.312

    def schedule(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                            -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (2 * np.pi * (-(11 + 15) / T * t + 15), )
        driver.energies = (2 * np.pi * 2 * amplitude, )

    def schedule_old(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                            -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (-2 * np.pi * 11 * 2 * (1 / 2 - t / T),
                         )  # (2 * np.pi * (-(11 + 15) / T * t + 15),)
        driver.energies = (2 * np.pi * 2 * amplitude,
                           )  # (2 * np.pi * 2 * amplitude,)

    def schedule_exp_optimized(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 15, )
        elif .312 <= t <= T - .312:
            t_pulse = (t - 0.312) / (T - 2 * 0.312) * t_pulse_max + 0.312
            driver.energies = (
                2 * np.pi * np.interp(t_pulse, pulse[:, 0], pulse[:, 1] / 2), )
            cost.energies = (2 * np.pi *
                             np.interp(t_pulse, pulse[:, 0], -pulse[:, 2]), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * 11, )
        # print(t, cost.energies)

    def schedule_exp_linear(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 15, )
        elif .312 <= t <= T - .312:
            driver.energies = (2 * np.pi * 2, )
            cost.energies = (2 * np.pi * (-(11 + 15) / (T - 2 * .312) *
                                          (t - .312) + 15), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * 11, )

    # print(t, cost.energies)
    # Uncomment this to print the schedule at t=0
    # schedule(0, 1)
    # print(cost.hamiltonian*2*np.pi)

    def gap(t):
        schedule_exp_linear(t * t_max, t_max)
        eigval, eigvec = eq.eig(which='S', k=k)
        return np.abs(eigval - eigval[0]), eigvec

    # Uncomment this to print the schedule at t=0
    # schedule(0, 1)
    # print(cost.hamiltonian*2*np.pi)
    # print(driver.hamiltonian)
    eq = schrodinger_equation.SchrodingerEquation(
        hamiltonians=[cost, driver, rydberg])

    fig = plt.figure(tight_layout=True)
    k_cutoff = 5
    gs = gridspec.GridSpec(k_cutoff, k_cutoff)
    ax = fig.add_subplot(gs[:, 0:k_cutoff - 1])
    num = 50
    print('beginning computation')
    for (i, t) in enumerate(np.linspace(.5, .98, num)):
        print(i)
        g, eigvec = gap(t)
        print(g)
        if i == num - 1:
            probs = np.abs(eigvec)**2
            for l in range(k_cutoff):
                layout = grid.copy().flatten().astype(float)
                layout[layout == 0] = -5
                layout[layout == 1] = 0
                layout_temp = layout.copy()
                ax_im = fig.add_subplot(gs[k_cutoff - l - 1, -1])
                for j in range(probs.shape[1]):
                    layout_temp[layout == 0] = layout_temp[layout == 0] + (
                        1 - graph.independent_sets[j]) * probs[l, j]
                ax_im.imshow(layout_temp.reshape(grid.shape))
                ax_im.set_axis_off()
        ax.scatter(np.ones(len(g)) * t, g, s=5, color='navy')
        ax.set_xlabel(r'$t/T$')
        ax.set_ylabel(r'Eigenenergy ($\Omega_{\max} = 1$)')
    plt.show()
def find_ratio(tails_graph, graph, tf, graph_index=None, size=None):
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
    # print('Starting driver')
    driver = hamiltonian.HamiltonianDriver(IS_subspace=True, graph=graph)
    # print('Starting rydberg')
    if tails_graph is not None:
        rydberg = hamiltonian.HamiltonianRydberg(tails_graph,
                                                 graph,
                                                 IS_subspace=True,
                                                 energies=(2 * np.pi, ))
    pulse = np.loadtxt('for_AWG_{}.000000.txt'.format(6))
    t_pulse_max = np.max(pulse[:, 0]) - 2 * 0.312

    def schedule(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                            -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (2 * np.pi * (-(11 + 15) / T * t + 15), )
        driver.energies = (2 * np.pi * 2 * amplitude, )

    def schedule_old(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                            -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (-2 * np.pi * 11 * 2 * (1 / 2 - t / T),
                         )  # (2 * np.pi * (-(11 + 15) / T * t + 15),)
        driver.energies = (2 * np.pi * 2 * amplitude,
                           )  # (2 * np.pi * 2 * amplitude,)

    def schedule_exp_optimized(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 15, )
        elif .312 <= t <= T - .312:
            t_pulse = (t - 0.312) / (T - 2 * 0.312) * t_pulse_max + 0.312
            driver.energies = (
                2 * np.pi * np.interp(t_pulse, pulse[:, 0], pulse[:, 1] / 2), )
            cost.energies = (2 * np.pi *
                             np.interp(t_pulse, pulse[:, 0], -pulse[:, 2]), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * 11, )
        # print(t, cost.energies)

    def schedule_exp_linear(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 15, )
        elif .312 <= t <= T - .312:
            driver.energies = (2 * np.pi * 2, )
            cost.energies = (2 * np.pi * (-(11 + 15) / (T - 2 * .312) *
                                          (t - .312) + 15), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * 11, )

    # print(t, cost.energies)
    # Uncomment this to print the schedule at t=0
    # schedule(0, 1)
    # print(cost.hamiltonian*2*np.pi)
    # print(driver.hamiltonian)
    if tails_graph is None:
        ad = SimulateAdiabatic(graph=graph,
                               hamiltonian=[cost, driver],
                               cost_hamiltonian=cost,
                               IS_subspace=True)
    else:
        ad = SimulateAdiabatic(graph=graph,
                               hamiltonian=[cost, driver, rydberg],
                               cost_hamiltonian=cost,
                               IS_subspace=True)
    # print('Starting evolution')
    ars = []
    probs = []
    for i in range(len(tf)):
        states, data = ad.run(tf[i],
                              schedule_exp_linear,
                              num=int(20 * tf[i]),
                              method='odeint',
                              full_output=False)
        cost.energies = (1, )
        ar = cost.approximation_ratio(states[-1])
        prob = cost.optimum_overlap(states[-1])
        # np.savez_compressed('{}x{}_{}_{}.npz'.format(size, size, graph_index, i), state=states[-1])
        print(tf[i], ar, prob)
        ars.append(ar)
        probs.append(prob)
    return ars, probs
def find_ground_first_excited(graph, tails_graph, t, k=2):
    n_points = 7
    times_exp = 2**np.linspace(-2.5, 4.5 / 6 *
                               (n_points - 1) - 2.5, n_points) + .312 * 2
    t_max = times_exp[4]
    print('Starting cost')
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
    print('Starting driver')
    driver = hamiltonian.HamiltonianDriver(IS_subspace=True, graph=graph)
    if tails_graph is not None:
        print('Starting rydberg')
        rydberg = hamiltonian.HamiltonianRydberg(tails_graph,
                                                 graph,
                                                 IS_subspace=True,
                                                 energies=(2 * np.pi, ))
    pulse = np.loadtxt('for_AWG_{}.000000.txt'.format(6))
    t_pulse_max = np.max(pulse[:, 0]) - 2 * 0.312
    max_detuning = np.max(pulse[:, 2])

    def schedule_old(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                            -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (-2 * np.pi * 11 * 2 * (1 / 2 - t / T),
                         )  # (2 * np.pi * (-(11 + 15) / T * t + 15),)
        driver.energies = (2 * np.pi * 2 * amplitude,
                           )  # (2 * np.pi * 2 * amplitude,)

    def schedule_exp_optimized(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 15, )
        elif .312 <= t <= T - .312:
            t_pulse = (t - 0.312) / (T - 2 * 0.312) * t_pulse_max + 0.312
            driver.energies = (
                2 * np.pi * np.interp(t_pulse, pulse[:, 0], pulse[:, 1] / 2), )
            cost.energies = (2 * np.pi *
                             np.interp(t_pulse, pulse[:, 0], -pulse[:, 2]), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * max_detuning, )
        # print(t, cost.energies)

    def schedule_exp_linear(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 15, )
        elif .312 <= t <= T - .312:
            driver.energies = (2 * np.pi * 2, )
            cost.energies = (2 * np.pi * (-(11 + 15) / (T - 2 * .312) *
                                          (t - .312) + 15), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * 11, )

    if tails_graph is None:
        eq = schrodinger_equation.SchrodingerEquation(
            hamiltonians=[cost, driver])
    else:
        eq = schrodinger_equation.SchrodingerEquation(
            hamiltonians=[cost, driver, rydberg])

    # Do minimization
    schedule = schedule_exp_linear
    t = t * t_max
    schedule(t, t_max)
    eigval, eigvec = eq.eig(which='S', k=k)
    print(eigval[0], eigval[1])
    return eigval, eigvec
def find_gap(graph, tails_graph, k=2, verbose=False):
    n_points = 7
    times_exp = 2**np.linspace(-2.5, 4.5 / 6 *
                               (n_points - 1) - 2.5, n_points) + .312 * 2
    t_max = times_exp[4]
    print('Starting cost')
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
    print('Starting driver')
    driver = hamiltonian.HamiltonianDriver(IS_subspace=True, graph=graph)
    if tails_graph is not None:
        print('Starting rydberg')
        rydberg = hamiltonian.HamiltonianRydberg(tails_graph,
                                                 graph,
                                                 IS_subspace=True,
                                                 energies=(2 * np.pi, ))
    pulse = np.loadtxt('for_AWG_{}.000000.txt'.format(6))
    t_pulse_max = np.max(pulse[:, 0]) - 2 * 0.312
    max_detuning = np.max(pulse[:, 2])

    def schedule_old(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                            -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (-2 * np.pi * 11 * 2 * (1 / 2 - t / T),
                         )  # (2 * np.pi * (-(11 + 15) / T * t + 15),)
        driver.energies = (2 * np.pi * 2 * amplitude,
                           )  # (2 * np.pi * 2 * amplitude,)

    def schedule_exp_optimized(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 15, )
        elif .312 <= t <= T - .312:
            t_pulse = (t - 0.312) / (T - 2 * 0.312) * t_pulse_max + 0.312
            driver.energies = (
                2 * np.pi * np.interp(t_pulse, pulse[:, 0], pulse[:, 1] / 2), )
            cost.energies = (2 * np.pi *
                             np.interp(t_pulse, pulse[:, 0], -pulse[:, 2]), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * max_detuning, )
        # print(t, cost.energies)

    def schedule_exp_linear(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312, )
            cost.energies = (2 * np.pi * 15, )
        elif .312 <= t <= T - .312:
            driver.energies = (2 * np.pi * 2, )
            cost.energies = (2 * np.pi * (-(11 + 15) / (T - 2 * .312) *
                                          (t - .312) + 15), )
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312, )
            cost.energies = (-2 * np.pi * 11, )

    def gap(t):
        t = t[0]
        t = t * t_max
        schedule(t, t_max)
        eigval, eigvec = eq.eig(which='S', k=k)
        if verbose:
            print(np.abs(eigval[1] - eigval[0]), t / t_max)
        # print(t/t_max, np.abs(eigval[1] - eigval[0]))
        return np.abs(eigval[1] - eigval[0])

    if tails_graph is None:
        eq = schrodinger_equation.SchrodingerEquation(
            hamiltonians=[cost, driver])
    else:
        eq = schrodinger_equation.SchrodingerEquation(
            hamiltonians=[cost, driver, rydberg])

    # Do minimization
    schedule = schedule_exp_linear
    if tails_graph is None:
        # Previously .67
        upper = 0.8
        # Previously .55
        lower = .55
        init = np.array([.7])
    else:
        # Default: .77
        upper = 0.7860824  # 0.77
        lower = 0.7856305  # 0.8161#.77#.6
        # Default: .71
        init = np.array([0.7860309])  # 0.74
    print('Starting gap')
    res_linear = scipy.optimize.minimize(gap,
                                         init,
                                         bounds=[(lower, upper)],
                                         method='L-BFGS-B')
    terminate = False
    while res_linear.x[0] == upper and not terminate:
        upper -= .01
        if upper <= lower:
            upper = .95
        res_linear = scipy.optimize.minimize(gap,
                                             init,
                                             bounds=[(lower, upper)],
                                             tol=1e-2)

    return res_linear.fun, res_linear.x[0]
예제 #25
0
def eit_simulation(graph,
                   noise_model=None,
                   show_graph=False,
                   gamma=3.8,
                   delta=0,
                   approximate=False,
                   Omega_g=1,
                   Omega_r=1):
    if show_graph:
        nx.draw(graph)
        plt.show()
    # Generate the driving and Rydberg Hamiltonians
    if noise_model == 'continuous':
        if not approximate:
            laser1 = hamiltonian.HamiltonianDriver(transition=(1, 2),
                                                   IS_subspace=True,
                                                   graph=graph,
                                                   code=rydberg,
                                                   energies=[Omega_g])
            laser2 = hamiltonian.HamiltonianDriver(transition=(0, 1),
                                                   IS_subspace=True,
                                                   graph=graph,
                                                   code=rydberg,
                                                   energies=[Omega_r])
            rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(
                graph, IS_subspace=True, code=rydberg)
            detuning = hamiltonian.HamiltonianEnergyShift(code=rydberg,
                                                          IS_subspace=True,
                                                          graph=graph,
                                                          energies=[delta])
            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, detuning],
                cost_hamiltonian=rydberg_hamiltonian_cost,
                IS_subspace=True,
                noise_model='continuous',
                code=rydberg,
                noise=[spontaneous_emission])
            return simulation
        else:
            laser = hamiltonian.HamiltonianDriver(
                transition=(0, 1),
                IS_subspace=True,
                graph=graph,
                energies=[Omega_g * Omega_r / delta])
            detuning = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
            spontaneous_emission1 = lindblad_operators.SpontaneousEmission(
                graph=graph,
                transition=(1, 1),
                rates=[(Omega_g / delta)**2 * gamma],
                IS_subspace=True)
            spontaneous_emission2 = lindblad_operators.SpontaneousEmission(
                graph=graph,
                transition=(0, 1),
                rates=[(Omega_r / delta)**2 * gamma],
                IS_subspace=True)
            rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(
                graph, IS_subspace=True)

            simulation = SimulateAdiabatic(
                graph,
                hamiltonian=[laser, detuning],
                cost_hamiltonian=rydberg_hamiltonian_cost,
                IS_subspace=True,
                noise_model='continuous',
                noise=[spontaneous_emission1, spontaneous_emission2])
            return simulation

    elif noise_model == 'monte_carlo':
        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)
        detuning = hamiltonian.HamiltonianEnergyShift(code=rydberg,
                                                      IS_subspace=True,
                                                      graph=graph,
                                                      energies=[delta])

        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, detuning],
            cost_hamiltonian=rydberg_hamiltonian_cost,
            IS_subspace=True,
            noise_model='monte_carlo',
            code=rydberg,
            noise=[spontaneous_emission])
        return simulation
예제 #26
0
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)
s = zero
costs = np.zeros((spacing, spacing))
probabilities = np.zeros((spacing**p, 2**N))
m = 0
for i in np.linspace(0, 2 * np.pi / np.sqrt(3), spacing):
    n = 0
    for l in np.linspace(0, 2 * np.pi / np.sqrt(3), spacing):
        print(m, n, i, l)
        s = zero
        me = lindblad_master_equation.MasterEquation(
            hamiltonians=[hb_x, hb_y], jump_operators=[rydberg_noise])
def adiabatic_simulation(graph, show_graph=False, approximate=False):
    if show_graph:
        nx.draw(graph)
        plt.show()
    if approximate:
        laser = hamiltonian.HamiltonianDriver(transition=(0, 1),
                                              IS_subspace=True,
                                              graph=graph,
                                              energies=(Omega_g * Omega_r /
                                                        delta, ))
        detuning = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
        spontaneous_emission1 = lindblad_operators.SpontaneousEmission(
            graph=graph,
            transition=(1, 1),
            rates=[(Omega_g / delta)**2 * Gamma],
            IS_subspace=True)
        spontaneous_emission2 = lindblad_operators.SpontaneousEmission(
            graph=graph,
            transition=(0, 1),
            rates=[(Omega_r / delta)**2 * Gamma],
            IS_subspace=True)
        rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph,
                                                              IS_subspace=True)

        simulation = SimulateAdiabatic(
            graph,
            hamiltonian=[laser, detuning],
            cost_hamiltonian=rydberg_hamiltonian_cost,
            IS_subspace=True,
            noise_model='continuous',
            noise=[spontaneous_emission1, spontaneous_emission2])
        return simulation
    else:
        # 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)
        laser_detuning = hamiltonian.HamiltonianEnergyShift(index=1,
                                                            IS_subspace=True,
                                                            energies=[delta],
                                                            graph=graph,
                                                            code=rydberg)
        detuning = hamiltonian.HamiltonianMIS(graph,
                                              IS_subspace=True,
                                              code=rydberg)
        rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph,
                                                              IS_subspace=True,
                                                              code=rydberg)
        spontaneous_emission = lindblad_operators.SpontaneousEmission(
            graph=graph,
            transition=(1, 2),
            IS_subspace=True,
            code=rydberg,
            rates=[Gamma])

        # Initialize adiabatic algorithm
        simulation = SimulateAdiabatic(
            graph,
            hamiltonian=[laser1, laser2, laser_detuning, detuning],
            cost_hamiltonian=rydberg_hamiltonian_cost,
            IS_subspace=True,
            noise_model='continuous',
            code=rydberg,
            noise=[spontaneous_emission])
        return simulation
예제 #28
0
def expansion(mode='reit'):
    # Find the performance vs alpha
    graph = line_graph(n=2)
    num = 100
    times = np.linspace(0, 1, 100)
    if mode == 'reit':
        laser = EffectiveOperatorHamiltonian(graph=graph,
                                             omega_r=1,
                                             omega_g=1,
                                             energies=(1, ))
        dissipation = EffectiveOperatorDissipation(graph=graph,
                                                   omega_r=1,
                                                   omega_g=1,
                                                   rates=(1, ))
        rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph,
                                                              IS_subspace=True,
                                                              code=qubit)

        def schedule_EIT(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)

        """def compute_eigenenergies(t, y):
            schedule_EIT(t, 1)
            # Compute the Hamiltonian basis vectors
            eq = SchrodingerEquation(hamiltonians=[laser])
            eigval, eigvec = eq.eig()
            return eigval
        """
        #theta = \
        #    scipy.integrate.solve_ivp(compute_eigenenergies, (0, 1), np.zeros(eigval.shape), atol=1e-8, rtol=1e-6,
        #                              method='DOP853', t_eval=times)['y'].T
        schedule = schedule_EIT
        eq = LindbladMasterEquation(hamiltonians=[laser],
                                    jump_operators=[dissipation])

    if mode == 'adiabatic':

        def schedule_adiabatic(t, tf):
            energy_shift.energies = (-5 * (t / tf - 1 / 2), )
            laser.energies = (np.sin(t / tf * np.pi)**2, )
            dissipation.rates = (np.sin(t / tf * np.pi)**2, )
            # Now run the standard adiabatic algorithm

        laser = EffectiveOperatorHamiltonian(graph=graph,
                                             IS_subspace=True,
                                             energies=(1, ),
                                             omega_g=np.cos(np.pi / 4),
                                             omega_r=np.sin(np.pi / 4))
        energy_shift = hamiltonian.HamiltonianEnergyShift(IS_subspace=True,
                                                          graph=graph,
                                                          energies=(2.5, ),
                                                          index=0)
        dissipation = EffectiveOperatorDissipation(graph=graph,
                                                   omega_r=1,
                                                   omega_g=1,
                                                   rates=(1, ))
        schedule = schedule_adiabatic
        eq = LindbladMasterEquation(hamiltonians=[laser, energy_shift],
                                    jump_operators=[dissipation])

    #rho = np.zeros((5, num, graph.num_independent_sets, graph.num_independent_sets), dtype=np.complex128)
    # Allow the integrator to allocate space. First get the zeroth order solution
    #psi0 = np.zeros((graph.num_independent_sets, graph.num_independent_sets))
    #psi0[0, 0] = 1
    # Convert results to density matrices
    #for i in range(num):
    #    rho[0, i, :] = psi0
    # Compute orders in alpha
    #rho[o,:] = compute_alpha_order(rho[o-1,:], eq, schedule)
    #print(rho[o,-1,0,0])
    #print(compute_first_alpha_order(eq, schedule))
    print(compute_first_beta_order(eq, schedule))
예제 #29
0
def track_eigenstate_composition(graph, tails_graph, num=1):
    cost = hamiltonian.HamiltonianMIS(graph, IS_subspace=True)
    # print('Starting driver')
    n_points = 7
    times_exp = 2 ** np.linspace(-2.5, 4.5 / 6 * (n_points - 1) - 2.5, n_points) + .312 * 2
    t_max = times_exp[4]
    driver = hamiltonian.HamiltonianDriver(IS_subspace=True, graph=graph)
    # print('Starting rydberg')
    if tails_graph is not None:
        rydberg = hamiltonian.HamiltonianRydberg(tails_graph, graph, IS_subspace=True, energies=(2 * np.pi,))
    pulse = np.loadtxt('for_AWG_{}.000000.txt'.format(6))
    t_pulse_max = np.max(pulse[:, 0]) - 2 * 0.312

    def schedule(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                            -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (2 * np.pi * (-(11 + 15) / T * t + 15),)
        driver.energies = (2 * np.pi * 2 * amplitude,)

    def schedule_old(t, T):
        # Linear ramp on the detuning, experiment-like ramp on the driver
        k = 50
        a = .95
        b = 3.1
        x = t / T
        amplitude = (
                            -1 / (1 + np.e ** (k * (x - a))) ** b - 1 / (1 + np.e ** (-k * (x - (1 - a)))) ** b + 1) / \
                    (-1 / ((1 + np.e ** (k * (1 / 2 - a))) ** b) - 1 / (
                            (1 + np.e ** (-k * (1 / 2 - (1 - a)))) ** b) + 1)
        cost.energies = (-2 * np.pi * 11 * 2 * (1 / 2 - t / T),)  # (2 * np.pi * (-(11 + 15) / T * t + 15),)
        driver.energies = (2 * np.pi * 2 * amplitude,)  # (2 * np.pi * 2 * amplitude,)

    def schedule_exp_optimized(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312,)
            cost.energies = (2 * np.pi * 15,)
        elif .312 <= t <= T - .312:
            t_pulse = (t - 0.312) / (T - 2 * 0.312) * t_pulse_max + 0.312
            driver.energies = (2 * np.pi * np.interp(t_pulse, pulse[:, 0], pulse[:, 1] / 2),)
            cost.energies = (2 * np.pi * np.interp(t_pulse, pulse[:, 0], -pulse[:, 2]),)
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312,)
            cost.energies = (-2 * np.pi * 11,)
        # print(t, cost.energies)

    def schedule_exp_linear(t, T):
        if t < .312:
            driver.energies = (2 * np.pi * 2 * t / .312,)
            cost.energies = (2 * np.pi * 15,)
        elif .312 <= t <= T - .312:
            driver.energies = (2 * np.pi * 2,)
            cost.energies = (2 * np.pi * (-(11 + 15) / (T - 2 * .312) * (t - .312) + 15),)
        else:
            driver.energies = (2 * np.pi * 2 * (T - t) / .312,)
            cost.energies = (-2 * np.pi * 11,)

    # print(t, cost.energies)
    # Uncomment this to print the schedule at t=0
    # schedule(0, 1)
    # print(cost.hamiltonian*2*np.pi)

    def eigs(t):
        schedule_exp_linear(t * t_max, t_max)
        if num == 0:
            eigval, eigvec = eq.eig(which='S', k=num+2)
        else:
            eigval, eigvec = eq.eig(which='S', k=num+1)

        return eigval, eigvec

    # Uncomment this to print the schedule at t=0
    # schedule(0, 1)
    # print(cost.hamiltonian*2*np.pi)
    # print(driver.hamiltonian)
    if tails_graph is not None:
        eq = schrodinger_equation.SchrodingerEquation(hamiltonians=[cost, driver, rydberg])
    else:
        eq = schrodinger_equation.SchrodingerEquation(hamiltonians=[cost, driver])
    #gap, loc = find_gap(graph, tails_graph)
    loc = 0.6403615396636326
    fig, ax = plt.subplots(1, num+2, sharex=True)

    print('Beginning computation')
    print(graph.mis_size)
    colors = ['blue', 'green', 'navy', 'orange', 'firebrick', 'purple', 'magenta', 'cornflowerblue', 'teal',
              'grey', 'cyan', 'limegreen', 'red', 'yellow', 'pink', 'orangered', 'salmon', 'violet']
    for (i, t) in enumerate(np.linspace(.6, .7, 50)):
        print(i)
        eigval, eigvec = eigs(t)
        ax[0].scatter(t, np.abs(eigval[0] - eigval[1]), color='k')
        for n in range(num + 1):
            if i == 0:
                ax[n+1].vlines(loc, 0, 1)
            vec = np.abs(eigvec[n])**2
            for j in range(graph.mis_size+1):
                population = np.sum(vec*(np.isclose(np.sum(1-graph.independent_sets, axis=1),j)))
                ax[n+1].scatter(t, population, color=colors[j])
    ax[0].set_xlabel(r'$t/T$')
    ax[1].set_xlabel(r'$t/T$')
    ax[1].set_ylabel(r'Gap')

    ax[0].set_ylabel(r'Population')
    for j in range(graph.mis_size):
        ax[0].scatter([],[],color=colors[j], label='IS size '+str(j))
    ax[0].legend()
    plt.show()
예제 #30
0
def expansion(graph=line_graph(n=3),
              mode='reit',
              full_output=False,
              alpha_order=1,
              beta_order=1):
    # Find the performance vs alpha
    ground_energy = graph.independent_sets[0][1]
    degeneracy = 0
    for IS in graph.independent_sets:
        if graph.independent_sets[IS][1] == ground_energy:
            degeneracy += 1
    num = 100
    if mode == 'reit':
        laser = EffectiveOperatorHamiltonian(graph=graph,
                                             omega_r=1,
                                             omega_g=1,
                                             energies=(1, ))
        dissipation = EffectiveOperatorDissipation(graph=graph,
                                                   omega_r=1,
                                                   omega_g=1,
                                                   rates=(1, ))
        rydberg_hamiltonian_cost = hamiltonian.HamiltonianMIS(graph,
                                                              IS_subspace=True,
                                                              code=qubit)

        def schedule_EIT(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)

        schedule = schedule_EIT
        eq = LindbladMasterEquation(hamiltonians=[laser],
                                    jump_operators=[dissipation])

    if mode == 'adiabatic':

        def schedule_adiabatic(t, tf):
            phi = (tf - t) / tf * np.pi / 2
            energy_shift.energies = (4 * np.sin(phi)**2 - np.cos(phi)**2, )
            laser.energies = (np.cos(phi) * np.sin(phi), )
            dissipation.rates = (np.cos(phi) * np.sin(phi), )
            # Now run the standard adiabatic algorithm

        """laser = EffectiveOperatorHamiltonian(graph=graph, IS_subspace=True,
                                             energies=(1,),
                                             omega_g=np.cos(np.pi / 4),
                                             omega_r=np.sin(np.pi / 4))"""
        laser = hamiltonian.HamiltonianDriver(graph=graph,
                                              IS_subspace=True,
                                              energies=(1, ))
        energy_shift = hamiltonian.HamiltonianEnergyShift(IS_subspace=True,
                                                          graph=graph,
                                                          energies=(1, ),
                                                          index=0)
        dissipation = EffectiveOperatorDissipation(graph=graph,
                                                   omega_r=1,
                                                   omega_g=1,
                                                   rates=(1, ))
        schedule = schedule_adiabatic
        eq = LindbladMasterEquation(hamiltonians=[laser, energy_shift],
                                    jump_operators=[dissipation])

    if mode == 'hybrid':

        def schedule_hybrid(t, tf):
            phi = (tf - t) / tf * np.pi / 2
            energy_shift.energies = (np.sin(phi)**2,
                                     )  # (- 1.35 * (t / tf - 1 / 2),)
            laser.omega_r = np.sin(phi)
            laser.omega_g = np.cos(phi)
            dissipation.omega_r = np.sin(phi)
            dissipation.omega_g = np.cos(phi)

        laser = EffectiveOperatorHamiltonian(graph=graph,
                                             IS_subspace=True,
                                             energies=(1, ),
                                             omega_g=np.cos(np.pi / 4),
                                             omega_r=np.sin(np.pi / 4))
        energy_shift = hamiltonian.HamiltonianEnergyShift(IS_subspace=True,
                                                          graph=graph,
                                                          energies=(2.5, ),
                                                          index=0)
        dissipation = EffectiveOperatorDissipation(graph=graph,
                                                   omega_r=1,
                                                   omega_g=1,
                                                   rates=(1, ))
        schedule = schedule_hybrid
        eq = LindbladMasterEquation(hamiltonians=[laser, energy_shift],
                                    jump_operators=[dissipation])
    # Compute orders in alpha
    # rho[o,:] = compute_alpha_order(rho[o-1,:], eq, schedule)
    # print(rho[o,-1,0,0])
    if alpha_order == 1:
        rates = compute_first_alpha_order(eq,
                                          schedule,
                                          degeneracy,
                                          full_output=full_output)
        return rates
        rates = rates[:, 0]
        print(np.sum(rates[1:]))
        if degeneracy > 1:
            return -np.sum(rates)
        else:
            return rates
    if beta_order == 1:
        print('rate', compute_first_beta_order(eq, schedule).real)