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,
    )
Example #2
0
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