Download

Download this file as Jupyter notebook: error_amplification.ipynb.

Error Amplification

The Rabi experiment (RabiExperiment) is performed in order to tune the amplitude of our pulses to perform rotation gates. This step is crucial in our calibration workflow as imprecisions in its value lead to rotation angles that do not match our expectations, resulting in errors that propagate throughout our computations.

The Error Amplification experiment (also referred to as ping-pong in the literature) is a simple protocol to determine the accuracy of the rotation pulse amplitude. It relies on a simple concept: any given number of \(\pi\) pulse pairs should get the system back to its initial state. If the effective rotation angle is not exactly \(\pi\), increasing the number of \(\pi\) pulse pairs accumulates the errors and increases the deviation.

[2]:
import numpy as np

import keysight.qcs as qcs
from keysight.qcs.experiments import ErrorAmplification, make_calibration_set

We start by initializing a qubit and defining an empty channel mapper to create a new instance of the ErrorAmplification class. We use the make_calibration_set() function that creates a calibration set for the given amount of qubit containing the linkers for the

RX, Z and measurement gates.

[3]:
# set the following to True when connected to hardware
run_on_hw = False

n_qubits = 1
qubits = qcs.Qudits(range(n_qubits))
calibration_set = make_calibration_set(n_qubits)

# generate an empty channel mapper
mapper = qcs.ChannelMapper("ip_addr")

# create Error Amplification experiment
error_amp_exp = ErrorAmplification(
    backend=mapper, calibration_set=calibration_set, n_amplifications=3, qubits=qubits
)

n_amplifications is an integer that determines the maximal number of \(\pi\) pulse pairs sent to the driven system. For instance, n_amplifications = 3, 4 different pulse sequences are prepared (0, 2, 4 and 6 \(\pi\) pulses). We can view the operations in the program with the following command:

[4]:
error_amp_exp.draw()
keysight-logo-svg
Program
Program
Duration undefined
Layers 1
Targets 1
Repetitions
Layer #0
Layer #0
Duration undefined
qudits 0
RX
ParameterizedGate RX on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
RX
ParameterizedGate RX on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
RX
ParameterizedGate RX on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
RX
ParameterizedGate RX on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
RX
ParameterizedGate RX on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
RX
ParameterizedGate RX on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
Measure on ('qudits', 0)

Parameters
Dim 2

We then configure the repetitions for this experiment and the pulse amplitudes to sweep over by passing n_shots and amplitudes array as arguments of configure_repetitions(). We need to provide the name of the amplitude variable in the calibration set that we are tuning, as we did in RabiExperiment. Note that the amplitude values swept over can be different qubits but the number of values should be the same.

[5]:
array = np.transpose([np.linspace(0.1, 1, 5)] * n_qubits)
amplitudes = qcs.Array(
    "amplitudes",
    value=array,
    dtype=float,
)

error_amp_exp.configure_repetitions(
    amplitudes=amplitudes, amplitude_name="x180_pulse_amplitudes", n_shots=1
)

Compiling this program to the waveform level using the ParameterizedLinkers in the calibration set results in the following program:

[6]:
error_amp_exp.compiled_program.draw()
keysight-logo-svg
Program
Program
Duration 280 ns
Layers 1
Targets 3
Repetitions Sweep with 4 repetitions
Associations
pulse_pair_sequence Array(name=pairs, shape=(4, 6), dtype=float, unit=none, value=[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1], [0, 0, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]])
Repeat with 1 repetitions
Sweep with 5 repetitions
Associations
angle Array(name=angles, shape=(5, 1), dtype=float, unit=none, value=[[0.6283], [2.04204], [3.45575], [4.86947], [6.28319]])
Layer #0
Layer #0
Duration 280 ns
xy_pulse 0
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
Delay on ('xy_pulse', 0)

Parameters
Duration Max(ScalarRef(name=readout_pulse_duration, value=100 ns, dtype=float, unit=s), ScalarRef(name=acquisition_duration, value=100 ns, dtype=float, unit=s))
readout_pulse 0
Delay on ('readout_pulse', 0)

Parameters
Duration Scalar(name=_implicit, value=180 ns, dtype=float, unit=s)
RFWaveform on ('readout_pulse', 0)

Parameters
Duration ScalarRef(name=readout_pulse_duration, value=100 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=readout_pulse_amplitudes, value=0.1, dtype=float, unit=none)
Frequency ScalarRef(name=readout_frequencies, value=5.15 GHz, dtype=float, unit=Hz)
Envelope SineEnvelope()
Instantaneous Phase ScalarRef(name=measurement_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=measurement_post_phase, value=0 rad, dtype=float, unit=rad)
Delay on ('readout_pulse', 0)

Parameters
Duration Scalar(name=_implicit, value=0 s, dtype=float, unit=s)
readout_acquisition 0
Delay on ('readout_acquisition', 0)

Parameters
Duration Scalar(name=_implicit, value=180 ns, dtype=float, unit=s)
Acquisition on ('readout_acquisition', 0)

Parameters
Duration ScalarRef(name=acquisition_duration, value=100 ns, dtype=float, unit=s)
Integration Filter
RFWaveform

Parameters
Duration ScalarRef(name=acquisition_duration, value=100 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=measurement_integrator_amplitude, value=1, dtype=float, unit=none)
Frequency ScalarRef(name=readout_frequencies, value=5.15 GHz, dtype=float, unit=Hz)
Envelope ConstantEnvelope()
Instantaneous Phase ScalarRef(name=measurement_integrator_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=measurement_integrator_post_phase, value=0 rad, dtype=float, unit=rad)
Classifier Classifier(Array(name=references, shape=(1, 2), dtype=complex, unit=none))
Delay on ('readout_acquisition', 0)

Parameters
Duration Scalar(name=_implicit, value=0 s, dtype=float, unit=s)

We use the render() method to visualize this with the ChannelMapper. The first index controls the number of \(\pi\) pulse pairs displayed (up to n_amplifications) whereas the second one relates to the amplitude array provided when configuring the repetitions.

[7]:
error_amp_exp.compiled_program.render(
    channel_subplots=False, sweep_index=(3, 1), lo_frequency=4.9e9, sample_rate=5.0e9
)

The first index control the number of pi pulse pairs and the second one controls the amplitude.

[8]:
error_amp_exp.compiled_program.render(
    channel_subplots=False, sweep_index=(2, 4), lo_frequency=4.9e9, sample_rate=5.0e9
)

To execute this experiment, we can simply run

[9]:
if run_on_hw:
    error_amp_exp.execute()
else:
    # load in a previously executed version of this experiment
    error_amp_exp = qcs.load("ErrorAmplification.qcs")
..note::

For the purposes of this demonstration, we added a second “ancilla” qubit to the ErrorAmplification program and connected the physical output channels for our qubit to the digizer associated with the ancilla to allow us to capture the full pulse sequence.

[10]:
error_amp_exp.draw()
keysight-logo-svg
Program
Program
Duration undefined
Layers 1
Targets 2
Repetitions Sweep with 5 repetitions
Associations
pulse_pair Array(name=pairs, shape=(5, 8), dtype=float, unit=none, value=[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]])
Sweep with 5 repetitions
Associations
amplitude Array(name=scan_values, shape=(5, 1), dtype=float, unit=none)
Repeat with 1 repetitions
Layer #0
Layer #0
Duration undefined
qudits 0
RX
ParameterizedGate RX on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
PGATE
ParameterizedGate on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
PGATE
ParameterizedGate on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
PGATE
ParameterizedGate on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
PGATE
ParameterizedGate on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
PGATE
ParameterizedGate on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
PGATE
ParameterizedGate on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
PGATE
ParameterizedGate on ('qudits', 0)

Parameters phi_x
Values Array(name=_implicit, shape=(1,), dtype=float, unit=none)

Matrices
0 1
1 0
Measure on ('qudits', 0)

Parameters
Dim 2
ancilla 1
Measure on ('ancilla', 1)

Parameters
Dim 2

The compiled program in the waveform level is as follows:

[11]:
error_amp_exp.compiled_program.draw()
keysight-logo-svg
Program
Program
Duration 590 ns
Layers 1
Targets 4
Repetitions Sweep with 5 repetitions
Associations
pulse_pair Array(name=pairs, shape=(5, 8), dtype=float, unit=none, value=[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]])
Sweep with 5 repetitions
Associations
amplitude Array(name=scan_values, shape=(5, 1), dtype=float, unit=none)
Repeat with 1 repetitions
Layer #0
Layer #0
Duration 590 ns
xy_pulse 0
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
RFWaveform on ('xy_pulse', 0)

Parameters
Duration ScalarRef(name=xy_pulse_durations, value=30 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=_implicit, value=None, dtype=float, unit=none)
Frequency ScalarRef(name=xy_pulse_frequencies, value=5.1 GHz, dtype=float, unit=Hz)
Envelope GaussianEnvelope(2.0)
Instantaneous Phase ScalarRef(name=rx_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=rx_post_phase, value=0 rad, dtype=float, unit=rad)
Delay on ('xy_pulse', 0)

Parameters
Duration Max(ScalarRef(name=readout_pulse_duration, value=350 ns, dtype=float, unit=s), ScalarRef(name=acquisition_duration, value=350 ns, dtype=float, unit=s))
readout_pulse 0
Delay on ('readout_pulse', 0)

Parameters
Duration Scalar(name=_implicit, value=240 ns, dtype=float, unit=s)
RFWaveform on ('readout_pulse', 0)

Parameters
Duration ScalarRef(name=readout_pulse_duration, value=100 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=readout_pulse_amplitudes, value=0.1, dtype=float, unit=none)
Frequency ScalarRef(name=readout_frequencies, value=5.15 GHz, dtype=float, unit=Hz)
Envelope SineEnvelope()
Instantaneous Phase ScalarRef(name=measurement_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=measurement_post_phase, value=0 rad, dtype=float, unit=rad)
Delay on ('readout_pulse', 0)

Parameters
Duration Scalar(name=_implicit, value=250 ns, dtype=float, unit=s)
readout_acquisition 0
Delay on ('readout_acquisition', 0)

Parameters
Duration Scalar(name=_implicit, value=240 ns, dtype=float, unit=s)
Acquisition on ('readout_acquisition', 0)

Parameters
Duration ScalarRef(name=acquisition_duration, value=350 ns, dtype=float, unit=s)
Integration Filter
RFWaveform

Parameters
Duration ScalarRef(name=acquisition_duration, value=350 ns, dtype=float, unit=s)
Amplitude ScalarRef(name=measurement_integrator_amplitude, value=1, dtype=float, unit=none)
Frequency ScalarRef(name=readout_frequencies, value=5.15 GHz, dtype=float, unit=Hz)
Envelope ConstantEnvelope()
Instantaneous Phase ScalarRef(name=measurement_integrator_phase, value=0 rad, dtype=float, unit=rad)
Post-phase ScalarRef(name=measurement_integrator_post_phase, value=0 rad, dtype=float, unit=rad)
Classifier Classifier(Array(name=references, shape=(1, 2), dtype=complex, unit=none))
Delay on ('readout_acquisition', 0)

Parameters
Duration Scalar(name=_implicit, value=0 s, dtype=float, unit=s)
1
Acquisition on ('readout_acquisition', 1)

Parameters
Duration Scalar(name=_implicit, value=350 ns, dtype=float, unit=s)
Integration Filter
DCWaveform

Parameters
Duration Scalar(name=_implicit, value=350 ns, dtype=float, unit=s)
Amplitude 1
Frequency 0 Hz
Envelope ConstantEnvelope()
Instantaneous Phase 0
Post-phase 0

We can visualize the generated pulses directly with the following command:

[12]:
error_amp_exp.plot_trace(channels=qcs.Qudits(1, "ancilla"))

This concludes the tutorial for running an error amplification experiment, using the Keysight QCS System. For detailed information on all available arguments and functionalities, please refer to the API documentation for ErrorAmplification.


Download

Download this file as Jupyter notebook: error_amplification.ipynb.

On this page