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()
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
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
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)
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()
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
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
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()
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])
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()
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()
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
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()
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
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)
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()
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]
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
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
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))
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()
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)