# HalfAngle¶

class HalfAngle(physical_qubits, backend=None)[source]

An experiment class to measure the amount by which sx and x are not parallel.

Overview

This experiment runs circuits that repeat blocks of sx - sx - y gates inserted in a Ramsey type experiment, i.e. the full gate sequence is thus Ry(π/2) - [sx - sx - y] ^ n - sx where n is varied.

        ┌─────────┐┌────┐┌────┐┌───┐   ┌────┐┌────┐┌───┐┌────┐ ░ ┌─┐
q_0: ┤ Ry(π/2) ├┤ sx ├┤ sx ├┤ y ├...┤ sx ├┤ sx ├┤ y ├┤ sx ├─░─┤M├
└─────────┘└────┘└────┘└───┘   └────┘└────┘└───┘└────┘ ░ └╥┘
meas: 1/════════════════════════════...═══════════════════════════╩═
0


This sequence measures angle errors where the axis of the sx and x rotation are not parallel. A similar experiment is described in Ref.~[1] where the gate sequence x - y is repeated to amplify errors caused by non-orthogonal x and y rotation axes.

One cause of such errors is non-linearity in the microwave mixer used to produce the pulses for the x and sx gates. Typically, these gates are calibrated to have the same duration and so have different pulse amplitudes. Non-linearities in the mixer’s skew can cause the angle to differ for these different pulse amplitudes.

The way the experiment works is that the initial Ry(π/2) puts the qubit close to the $$+X$$ state, with a deviation $$δθ$$, due to the misalignment between sx and x (Ry(π/2) is implemented with sx as described below). The first sx - sx do nothing as they should be rotations about the axis the qubit is pointing along. The first y then mirrors the qubit about the $$y$$ axis in the $$xy$$ plane of the Bloch sphere, so the $$δθ$$ deviation from $$+X$$ becomes a $$-δθ$$ from $$-X$$. The next sx - sx sequence rotates about the axis that is $$+δθ$$ rotated in the $$xy$$ plane from $$+X$$, which takes the deviation from $$-X$$ from $$-δθ$$ to $$+3 δθ$$. Then the next y mirrors this across the $$y$$ axis, taking the state to $$-3 δθ$$ from $$+X$$. This pattern continues with each iteration, with the angular deviation in units of $$δθ$$ following the sequence 1, 3, 5, 7, 9, etc. from $$+X$$ and $$-X$$. The final sx rotation serves mainly to rotate these deviations from $$+X$$ and $$-X$$ in the $$xy$$ plane into deviations out of the $$xy$$ plane, so that they appear as a signal in the $$Z$$ basis. Because sx has a $$δθ$$ deviation from x, the final sx adds an extra $$δθ$$ to the deviations, so the pattern ends up as 2, 4, 6, 8, etc., meaning that each iteration adds $$2 δθ$$ to the deviation from the equator of the Bloch sphere (with the sign alternating due to the y gates, so the deviations are really -2, 4, -6, 8, etc.).

For the implementation of the circuits, the experiment uses Rz(π/2) - sx - Rz(-π/2) to implement the Ry(π/2) and Rz(π/2) - x - Rz(-π/2) to implement the y. So the experiment makes use of only sx, x, Rz(π/2), and Rz(-π/2) gates. For the experiment’s analysis to be valid, it is important that the sx and x gates are not replaced (such as by a transpiler pass that replaces x with sx - sx), as it is the angle between them which is being inferred. It is assumed that the angle between x and Rz is exactly $$π/2$$.

References

[1] Sarah Sheldon, Lev S. Bishop, Easwar Magesan, Stefan Filipp, Jerry M. Chow, Jay M. Gambetta, Characterizing errors on qubit operations via iterative randomized benchmarking, Phys. Rev. A 93, 012301 (2016), doi: 10.1103/PhysRevA.93.012301 (open)

Analysis class reference

ErrorAmplificationAnalysis

Experiment options

These options can be set by the set_experiment_options() method.

Options
• Defined in the class HalfAngle:

• repetitions (List[int])

Default value: [0, 1, 2, 3, 4, …]
A list of the number of times that the gate sequence [sx sx y] is repeated.
• Defined in the class BaseExperiment:

• max_circuits (Optional[int])

Default value: None
The maximum number of circuits per job when running an experiment on a backend.

Example

from qiskit_experiments.library.characterization import HalfAngle

exp = HalfAngle((0,), backend=backend)

exp_data = exp.run().block_for_results()
display(exp_data.figure(0))
exp_data.analysis_results(dataframe=True)

name experiment components value quality backend run_time chisq unit
fda20505 @Parameters_ErrorAmplificationAnalysis HalfAngle [Q0] CurveFitResult:\n - fitting method: least_squa... bad PulseBackendV2 None None None

Initialization

Setup a half angle experiment on the given qubit.

Parameters:
• physical_qubits (Sequence[int]) – List containing the qubits on which to run the fine amplitude calibration experiment.

• backend (Backend | None) – Optional, the backend to run the experiment on.

Attributes

analysis

Return the analysis instance for the experiment

backend

Return the backend for the experiment

experiment_options

Return the options for the experiment.

experiment_type

Return experiment type.

num_qubits

Return the number of qubits for the experiment.

physical_qubits

Return the device qubits for the experiment.

run_options

Return options values for the experiment run() method.

transpile_options

Return the transpiler options for the run() method.

Methods

circuits()[source]

Create the circuits for the half angle calibration experiment.

Return type:

List[QuantumCircuit]

config()

Return the config dataclass for this experiment

Return type:

ExperimentConfig

copy()

Return a copy of the experiment

Return type:

BaseExperiment

classmethod from_config(config)

Initialize an experiment from experiment config

Return type:

BaseExperiment

job_info(backend=None)

Get information about job distribution for the experiment on a specific backend.

Parameters:

backend (Backend) – Optional, the backend for which to get job distribution information. If not specified, the experiment must already have a set backend.

Returns:

A dictionary containing information about job distribution.

• ”Total number of circuits in the experiment”: Total number of circuits in the experiment.

• ”Maximum number of circuits per job”: Maximum number of circuits in one job based on backend and experiment settings.

• ”Total number of jobs”: Number of jobs needed to run this experiment on the currently set backend.

Return type:

dict

Raises:

QiskitError – if backend is not specified.

run(backend=None, analysis='default', timeout=None, **run_options)

Run an experiment and perform analysis.

Parameters:
• backend (Backend | None) – Optional, the backend to run the experiment on. This will override any currently set backends for the single execution.

• analysis (BaseAnalysis | None) – Optional, a custom analysis instance to use for performing analysis. If None analysis will not be run. If "default" the experiments analysis() instance will be used if it contains one.

• timeout (float | None) – Time to wait for experiment jobs to finish running before cancelling.

• run_options – backend runtime options used for circuit execution.

Returns:

The experiment data object.

Raises:

QiskitError – If experiment is run with an incompatible existing ExperimentData container.

Return type:

ExperimentData

set_experiment_options(**fields)

Set the experiment options.

Parameters:

fields – The fields to update the options

Raises:

AttributeError – If the field passed in is not a supported options

set_run_options(**fields)

Set options values for the experiment run() method.

Parameters:

fields – The fields to update the options

The Setting options for your experiment guide for code example.

set_transpile_options(**fields)

Set the transpiler options for run() method.

Parameters:

fields – The fields to update the options

Raises:

QiskitError – If initial_layout is one of the fields.