def simple_graph(dt = .001): graph = nx.Graph() graph.add_nodes_from([0, 1, 2]) graph.add_edges_from([(0, 1), (1, 2)]) psi0 = np.array([[0,0,1,0,0,0,0,0]]).T s = State(psi0, 3, is_ket=True) times = np.arange(0, 3, dt) hamiltonian = HamiltonianHeisenberg(graph) se = schrodinger_equation.SchrodingerEquation(hamiltonians=[hamiltonian], is_ket=True) output = np.squeeze(se.run_ode_solver(s.state, 0, 3, dt), axis=-1) overlap = np.abs([email protected]()) plt.plot(times, overlap) plt.show()
def run(self, s, t0, tf, dt): # Compute probability that we have a jump times = np.arange(t0, tf, dt) outputs = np.zeros((times.shape[0], s.shape[0], s.shape[1]), dtype=np.complex128) se = schrodinger_equation.SchrodingerEquation(hamiltonians=self.hamiltonians, is_ket=True) for (j, time) in zip(range(times.shape[0]), times): output = se.run_ode_solver(s, time, time+2*dt, dt)[-1] jump = self.jumps[0] jump_probability = jump.jump_rate(s)*dt if np.random.uniform() < jump_probability: print('jumping up') s = jump.random_jump(s) # Renormalize codes s = s / np.linalg.norm(s) else: jump_probability_integrated = 1 - np.linalg.norm(np.squeeze(output.T)) ** 2 s = output/(1-jump_probability_integrated)**.5 outputs[j,...] = s return outputs
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_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 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 visualize_low_energy_subspace(graph, tails_graph, k=5): 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] 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)) max_detuning = np.max(pulse[:, 2]) 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 * 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, ) # 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) 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) if tails_graph is None: eq = schrodinger_equation.SchrodingerEquation( hamiltonians=[cost, driver]) else: eq = schrodinger_equation.SchrodingerEquation( hamiltonians=[cost, driver, rydberg]) fig, ax = plt.subplots(1, 1) num = 100 print('beginning computation') for (i, t) in enumerate(np.linspace(.5, .97, num) * t_max): print(i) g, eigvec = gap(t) schedule_exp_linear(t, t_max) detuning = cost.energies[0] / (2 * np.pi) g = g / (2 * np.pi) ax.scatter(-np.ones(len(g)) * detuning, g, s=3, color='navy') ax.set_xlabel(r'Detuning (MHz)') ax.set_ylabel(r'Eigenenergy (MHz))') plt.show()