def plot_result(result): # Get physical parameters for the simulation qubit_count = result["qubit_count"] segment_count = result["segment_count"] durations = get_durations(segment_count) local_shifts = get_local_shifts(qubit_count) omega_signal = result["omega_segments"] delta_signal = result["delta_segments"] omega_segments = np.array([sig["value"] for sig in omega_signal]) delta_segments = np.array([sig["value"] for sig in delta_signal]) fixed_segment = np.array([1]) krylov_subspace_dimension = result["krylov_subspace_dimension"] # Create initial and target states initial_state = create_initial_state(qubit_count) target_state = create_target_state(qubit_count) with qctrl.create_graph() as graph: # Calculate terms and put together the full Hamiltonian H_omega, H_delta, H_fixed = get_rydberg_hamiltonian_terms(qubit_count) hamiltonian = qctrl.operations.sparse_pwc_sum([ qctrl.operations.sparse_pwc_operator( signal=qctrl.operations.tensor_pwc(np.array(durations), omega_segments), operator=H_omega, ), qctrl.operations.sparse_pwc_operator( signal=qctrl.operations.tensor_pwc(np.array(durations), delta_segments), operator=H_delta, ), qctrl.operations.sparse_pwc_operator( signal=qctrl.operations.tensor_pwc(np.array([duration]), fixed_segment), operator=H_fixed, ), ]) sample_times = np.linspace(0, duration, 200) # Evolve the initial state evolved_states = qctrl.operations.state_evolution_pwc( initial_state=initial_state, hamiltonian=hamiltonian, krylov_subspace_dimension=krylov_subspace_dimension, sample_times=sample_times, name="evolved_states", ) states = qctrl.functions.calculate_graph( graph=graph, output_node_names=["evolved_states"], ) # Data to plot idx_even = sum([2**n for n in range(0, qubit_count, 2)]) idx_odd = sum([2**n for n in range(1, qubit_count, 2)]) densities_t = abs(np.squeeze(states.output["evolved_states"]["value"]))**2 initial_density_t = densities_t[:, 0] final_density_t = densities_t[:, idx_odd] + densities_t[:, idx_even] target_density = np.abs(target_state)**2 # Style and label definitions plt.style.use(get_qctrl_style()) bar_labels = [""] * 2**qubit_count bar_labels[idx_odd] = "|" + "10" * int(qubit_count / 2) + ">" bar_labels[idx_even] = "|" + "01" * int(qubit_count / 2) + ">" def bar_plot(ax, density, title): ax.bar( np.arange(2**qubit_count), density, edgecolor="#680CE9", color="#680CE94C", tick_label=bar_labels, linewidth=2, ) ax.set_title(title, fontsize=14) ax.set_ylabel("Population", fontsize=14) ax.tick_params(labelsize=14) gs = gridspec.GridSpec(2, 2, hspace=0.3) fig = plt.figure() fig.set_figheight(2 * 5) fig.set_figwidth(15) fig.suptitle("Optimized state preparation", fontsize=16, y=0.95) # Plot optimized final state and target state ax = fig.add_subplot(gs[0, 0]) bar_plot(ax, densities_t[-1], "Optimized final state") ax = fig.add_subplot(gs[0, 1]) bar_plot(ax, target_density, "Target GHZ state") # Plot time evolution of basis state population ax = fig.add_subplot(gs[1, :]) ax.plot( sample_times, densities_t, "#AAAAAA", linewidth=0.5, ) ax.plot( sample_times, initial_density_t, "#FB00A5", linewidth=1.5, ) ax.plot( sample_times, final_density_t, "#680CE9", linewidth=2, ) ax.set_xticks(np.linspace(0, 1e-6, 6)) ax.set_xticklabels(["0", "200 n", "400 n", "600 n", "800 n", "1 µ"]) ax.tick_params(labelsize=14) ax.set_xlabel("Time (s)", fontsize=14) ax.set_ylabel("Population", fontsize=14) ax.set_title( "Basis states (gray), ground state (pink), and target state (purple)", fontsize=14, )
from scipy import interpolate from scipy.optimize import curve_fit import os # Q-CTRL imports from qctrl import Qctrl # Starting a session with the API qctrl = Qctrl(email=os.getenv('EMAIL'), password=os.getenv('PASSWORD')) # Choose to run experiments or to use saved data use_saved_data = False # Plotting parameters plt.style.use(get_qctrl_style()) prop_cycle = plt.rcParams["axes.prop_cycle"] colors = prop_cycle.by_key()["color"] markers = {"x": "x", "y": "s", "z": "o"} lines = {"x": "--", "y": "-.", "z": "-"} # Definition of operators and functions sigma_z = np.array([[1.0, 0.0], [0.0, -1.0]], dtype=np.complex) sigma_x = np.array([[0.0, 1.0], [1.0, 0.0]], dtype=np.complex) sigma_y = np.array([[0.0, -1.0j], [1.0j, 0.0]], dtype=np.complex) X90_gate = np.array([[1.0, -1j], [-1j, 1.0]], dtype=np.complex) / np.sqrt(2) bloch_basis = ["x", "y", "z"] def save_var(file_name, var): # saves a single var to a file using jsonpickle
# In[2]: # Define standard matrices identity = np.array([[1.0, 0.0], [0.0, 1.0]], dtype=np.complex) sigma_x = np.array([[0.0, 1.0], [1.0, 0.0]], dtype=np.complex) sigma_y = np.array([[0.0, -1j], [1j, 0.0]], dtype=np.complex) sigma_z = np.array([[1.0, 0.0], [0.0, -1.0]], dtype=np.complex) sigma_m = np.array([[0.0, 1.0], [0.0, 0.0]], dtype=np.complex) sigmas = [sigma_x, sigma_y, sigma_z] sigma_names = ["X", "Y", "Z"] not_gate = np.array([[0.0, -1.0], [1.0, 0.0]]) # Plotting and formatting methods plt.style.use(qv.get_qctrl_style()) def plot_simulation_trajectories(figure, times, coherent_samples, noisy_trajectories): ideal_bloch_sphere_coords = np.array( [ [ np.real( np.dot( sample.state_vector.conj(), np.matmul(sigma, sample.state_vector), ) ) for sigma in sigmas ] for sample in coherent_samples