Qubit spectroscopy: CZ Ramsey measurement example

Similar to a \(T_2^*\) Ramsey experiment, a CZ Ramsey experiment measures fringes resulting from induced Z rotations, which can result in non-unitary CZs. To rectify this non-unitarity, we determine the correction we need to apply to each qubit in the form of RZ rotations. If a CZ is perfectly unitary (or has been compensated for adequately with RZ pulses), a CZ Ramsey experiment should return 0 radians for each qubit. If, however, some correction is required, these angles will be non-zero.

A sample QUIL program at one data point (specified by the equatorial Z rotation which maximizes excited state visibility when equal to the required RZ correction) between qubits 0 and 1 would look like

DECLARE ro BIT[1]
DECLARE theta REAL[1]
RX(pi/2) 0
CZ 0 1
RZ(theta) 0
RX(pi/2) 0
MEASURE 0 ro[0]

Setup

[1]:
from typing import Tuple

from matplotlib import pyplot as plt
import numpy as np

from pyquil import Program
from pyquil.api import get_qc, QuantumComputer
from forest.benchmarking.qubit_spectroscopy import *
[2]:
#qc = get_qc('Aspen-1-15Q-A')
qc = get_qc('3q-noisy-qvm') # will run on a QVM, but not very meaningfully since there is no cross-talk.
graph = qc.qubit_topology()
edges = list(graph.edges())
edges
[2]:
[(0, 1), (0, 2), (1, 2)]
[3]:
# if you are on the QPU you can look at `qc.device.specs`
# qc.device.specs

Generate CZ Ramsey experiments

[4]:
import numpy as np
from numpy import pi
angles = np.linspace(0, 2*pi, 15)
edge = (0, 1)
# generate a set of len(angles) experiments for each measurement qubit on edge (0, 1).
edge_0_1_expts = [generate_cz_phase_ramsey_experiments(edge, measure_q, angles) for measure_q in edge]

Acquire data

Collect our Ramsey raw data using estimate_observables.

[5]:
from forest.benchmarking.observable_estimation import estimate_observables
# acquire results for each measurement qubit on each edge.
results = []
for angle_expts in zip(*edge_0_1_expts):
    angle_results = []
    for meas_q_expt in angle_expts:
        angle_results += estimate_observables(qc, meas_q_expt, num_shots=500)
    results.append(angle_results)

Analyze and plot

Use the results to produce estimates of Ramsey-acquired compensatory RZ phases for this edge

In the cell below we first extract the expectation and std_err for each measurement and store these results in lists separately for each qubit measured. For each qubit measured we then fit a sinusoid to the data from which we can determine the offset of the maximum excited state visibility, which tells us the effective imparted phase. Finally we plot the CZ Ramsey fringes for each qubit with respect to increasing applied contrast phase.

[6]:
from forest.benchmarking.plotting import plot_figure_for_fit

stats_by_qubit = get_stats_by_qubit(results)
for q, stats in stats_by_qubit.items():
    fit = fit_cz_phase_ramsey_results(angles, stats['expectation'], stats['std_err'])
    fig, axs = plot_figure_for_fit(fit, title=f'Q{q} Data and Fit', xlabel="RX angle [rad]",
                           ylabel=r"Pr($|1\rangle$)")
    frequency = fit.params['frequency'].value # ratio of actual angle over intended control angle
    amplitude = fit.params['amplitude'].value # (P(1 given 1) - P(1 given 0)) / 2
    baseline = fit.params['baseline'].value # amplitude + P(1 given 0)
    offset = fit.params['offset'].value # effective imparted phase on the qubit from the CZ, relative to the true qubit frequency
../_images/examples_qubit_spectroscopy_cz_ramsey_10_0.png
../_images/examples_qubit_spectroscopy_cz_ramsey_10_1.png
[ ]: