From 92f8571f8716ae249f14027707e12469ec23d424 Mon Sep 17 00:00:00 2001 From: Naohito Nakazawa <117684192+Naohnakazawa@users.noreply.github.com> Date: Wed, 18 Dec 2024 23:44:21 +0900 Subject: [PATCH] Add minimal working code examples in Experiment API docs (#1494) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Summary This change adds minimal working code examples to the API pages for Experiments, EFSpectroscopy, EFRabi, StarkRamseyXYAmpScan, FineAmplitudeCal, FineXAmplitudeCal, FineSXAmplitudeCal, FineDragCal, FineXDragCal, FineSXDragCal, FineFrequencyCal, FrequencyCal, HalfAngleCal, RoughAmplitudeCal, RoughXSXAmplitudeCal, EFRoughXSXAmplitudeCal, RoughDragCal, RoughFrequencyCal, QuantumVolume, InterleavedRB, LayerFidelity, StandardRB, MitigatedProcessTomography, MitigatedStateTomography, ProcessTomography, StateTomography and TomographyExperiment. ### Details and comments - This PR covers many remaining experiments in `issue#1238` and `issue#1221`. - In the API pages, the documentation for each experiment has been updated with its code example. Users are required to specify a backend in the code example. By default, backends used in the code examples, are simulators such as, SingleTransmonTestBackend() and AerSimulator(FakePerth()). --------- Co-authored-by: 中澤 直仁 (cherry picked from commit cc258d76d22711bd826afc1482a2f3b11e879805) --- qiskit_experiments/library/__init__.py | 1 + .../library/calibration/fine_amplitude.py | 111 +++++++++++++- .../library/calibration/fine_drag_cal.py | 106 ++++++++++++- .../library/calibration/fine_frequency_cal.py | 30 +++- .../library/calibration/frequency_cal.py | 30 +++- .../library/calibration/half_angle_cal.py | 44 +++++- .../calibration/rough_amplitude_cal.py | 145 +++++++++++++++++- .../library/calibration/rough_drag_cal.py | 29 +++- .../library/calibration/rough_frequency.py | 36 ++++- .../characterization/ef_spectroscopy.py | 15 +- .../library/characterization/rabi.py | 12 +- .../library/driven_freq_tuning/p1_spect.py | 1 - .../driven_freq_tuning/ramsey_amp_scan.py | 1 - .../library/quantum_volume/qv_experiment.py | 24 +++ .../interleaved_rb_experiment.py | 31 ++++ .../randomized_benchmarking/layer_fidelity.py | 41 +++++ .../randomized_benchmarking/standard_rb.py | 46 ++++++ .../library/tomography/mit_qpt_experiment.py | 45 ++++++ .../library/tomography/mit_qst_experiment.py | 37 +++++ .../library/tomography/qpt_experiment.py | 45 ++++++ .../library/tomography/qst_experiment.py | 30 ++++ .../tomography/tomography_experiment.py | 1 + ...experiments-api-docs-31f3e3c3369a6f3d.yaml | 31 ++++ 23 files changed, 867 insertions(+), 25 deletions(-) create mode 100644 releasenotes/notes/add-examples-to-experiments-api-docs-31f3e3c3369a6f3d.yaml diff --git a/qiskit_experiments/library/__init__.py b/qiskit_experiments/library/__init__.py index 29770ed7b3..2e47b281e8 100644 --- a/qiskit_experiments/library/__init__.py +++ b/qiskit_experiments/library/__init__.py @@ -36,6 +36,7 @@ ~randomized_benchmarking.StandardRB ~randomized_benchmarking.InterleavedRB + ~randomized_benchmarking.LayerFidelity ~tomography.TomographyExperiment ~tomography.StateTomography ~tomography.ProcessTomography diff --git a/qiskit_experiments/library/calibration/fine_amplitude.py b/qiskit_experiments/library/calibration/fine_amplitude.py index 8e3ff17972..3055d6fedb 100644 --- a/qiskit_experiments/library/calibration/fine_amplitude.py +++ b/qiskit_experiments/library/calibration/fine_amplitude.py @@ -36,6 +36,43 @@ class FineAmplitudeCal(BaseCalibrationExperiment, FineAmplitude): experiment the circuits that are run have a custom gate with the pulse schedule attached to it through the calibrations. + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + # backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=True, seed=101) + + .. jupyter-execute:: + + import numpy as np + from qiskit.circuit.library import SXGate + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library import FineAmplitudeCal + + library = FixedFrequencyTransmon(default_values={"duration": 320, "amp": 0.030}) + cals = Calibrations.from_backend(backend=backend, libraries=[library]) + exp_cal = FineAmplitudeCal(physical_qubits=(0,), + calibrations=cals, + schedule_name="sx", + backend=backend, + cal_parameter_name="amp", + auto_update=True, + gate=SXGate(), + measurement_qubits=(0,)) + # This option is necessary! + exp_cal.analysis.set_options(fixed_parameters={"angle_per_gate" : np.pi / 2, + "phase_offset" : np.pi}) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) """ def __init__( @@ -156,7 +193,42 @@ def update_calibrations(self, experiment_data: ExperimentData): class FineXAmplitudeCal(FineAmplitudeCal): - """A calibration experiment to calibrate the amplitude of the X schedule.""" + """A calibration experiment to calibrate the amplitude of the X schedule. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + # backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=True, seed=111) + + .. jupyter-execute:: + + import numpy as np + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library import FineXAmplitudeCal + + library = FixedFrequencyTransmon(default_values={"duration": 320, "amp": 0.030}) + cals = Calibrations.from_backend(backend, libraries=[library]) + + exp_cal = FineXAmplitudeCal((0,), + cals, + schedule_name="x", + backend=backend, + cal_parameter_name="amp", + auto_update=True, + ) + + exp_data = exp_cal.run().block_for_results() + display(exp_data.figure(0)) + exp_data.analysis_results(dataframe=True) + """ def __init__( self, @@ -204,7 +276,42 @@ def _pre_circuit(self, num_clbits: int) -> QuantumCircuit: class FineSXAmplitudeCal(FineAmplitudeCal): - """A calibration experiment to calibrate the amplitude of the SX schedule.""" + """A calibration experiment to calibrate the amplitude of the SX schedule. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + # backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=True, seed=105) + + .. jupyter-execute:: + + import numpy as np + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library import FineSXAmplitudeCal + + library = FixedFrequencyTransmon(default_values={"duration": 320, "amp": 0.015}) + cals = Calibrations.from_backend(backend, libraries=[library]) + + exp_cal = FineSXAmplitudeCal((0,), + cals, + schedule_name="sx", + backend=backend, + cal_parameter_name="amp", + auto_update=True, + ) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + """ def __init__( self, diff --git a/qiskit_experiments/library/calibration/fine_drag_cal.py b/qiskit_experiments/library/calibration/fine_drag_cal.py index 74ff341657..883a69fd66 100644 --- a/qiskit_experiments/library/calibration/fine_drag_cal.py +++ b/qiskit_experiments/library/calibration/fine_drag_cal.py @@ -30,7 +30,41 @@ class FineDragCal(BaseCalibrationExperiment, FineDrag): - """A calibration version of the fine DRAG experiment.""" + """A calibration version of the fine DRAG experiment. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + #backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=False, seed=108) + + .. jupyter-execute:: + + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library import FineDragCal + + library = FixedFrequencyTransmon(default_values={"duration": 320, "amp": 0.030, "beta": 0.0}) + cals = Calibrations.from_backend(backend, libraries=[library]) + + exp_cal = FineDragCal((0,), + calibrations=cals, + backend=backend, + schedule_name="sx", + cal_parameter_name="β", + auto_update=True, + ) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + """ def __init__( self, @@ -146,7 +180,40 @@ def update_calibrations(self, experiment_data: ExperimentData): class FineXDragCal(FineDragCal): - """Fine DRAG calibration of X gate.""" + """Fine DRAG calibration of X gate. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + #backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=False, seed=118) + + .. jupyter-execute:: + + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library import FineXDragCal + + library = FixedFrequencyTransmon(default_values={"duration": 320, "amp": 0.030, "beta": 0.0}) + cals = Calibrations.from_backend(backend, libraries=[library]) + + exp_cal = FineXDragCal((0,), + calibrations=cals, + backend=backend, + cal_parameter_name="β", + auto_update=True, + ) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + """ def __init__( self, @@ -178,7 +245,40 @@ def __init__( class FineSXDragCal(FineDragCal): - """Fine DRAG calibration of X gate.""" + """Fine DRAG calibration of X gate. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + #backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=False, seed=118) + + .. jupyter-execute:: + + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library import FineSXDragCal + + library = FixedFrequencyTransmon(default_values={"duration": 320, "amp": 0.030, "beta": 0.0}) + cals = Calibrations.from_backend(backend=backend, libraries=[library]) + + exp_cal = FineSXDragCal((0,), + calibrations=cals, + backend=backend, + cal_parameter_name="β", + auto_update=True, + ) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + """ def __init__( self, diff --git a/qiskit_experiments/library/calibration/fine_frequency_cal.py b/qiskit_experiments/library/calibration/fine_frequency_cal.py index 13b1c64b62..ed9652af86 100644 --- a/qiskit_experiments/library/calibration/fine_frequency_cal.py +++ b/qiskit_experiments/library/calibration/fine_frequency_cal.py @@ -28,7 +28,35 @@ class FineFrequencyCal(BaseCalibrationExperiment, FineFrequency): - """A calibration version of the fine frequency experiment.""" + """A calibration version of the fine frequency experiment. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + # backend + from qiskit_ibm_runtime.fake_provider import FakePerth + from qiskit_aer import AerSimulator + + backend = AerSimulator.from_backend(FakePerth()) + + .. jupyter-execute:: + + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library.calibration.fine_frequency_cal import FineFrequencyCal + + cals = Calibrations.from_backend(backend=backend, libraries=[FixedFrequencyTransmon()]) + exp_cal = FineFrequencyCal((0,), cals, backend=backend, auto_update=False, gate_name="sx") + + cal_data=exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + """ def __init__( self, diff --git a/qiskit_experiments/library/calibration/frequency_cal.py b/qiskit_experiments/library/calibration/frequency_cal.py index 5f683b217d..8f8bd48848 100644 --- a/qiskit_experiments/library/calibration/frequency_cal.py +++ b/qiskit_experiments/library/calibration/frequency_cal.py @@ -27,7 +27,35 @@ class FrequencyCal(BaseCalibrationExperiment, RamseyXY): - """A qubit frequency calibration experiment based on the Ramsey XY experiment.""" + """A qubit frequency calibration experiment based on the Ramsey XY experiment. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + # backend + from qiskit_ibm_runtime.fake_provider import FakePerth + from qiskit_aer import AerSimulator + + backend = AerSimulator.from_backend(FakePerth()) + + .. jupyter-execute:: + + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library.calibration.frequency_cal import FrequencyCal + + cals = Calibrations.from_backend(backend=backend, libraries=[FixedFrequencyTransmon()]) + exp_cal = FrequencyCal((0,), cals, backend=backend, auto_update=False) + + cal_data=exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + """ def __init__( self, diff --git a/qiskit_experiments/library/calibration/half_angle_cal.py b/qiskit_experiments/library/calibration/half_angle_cal.py index e3c3784ba3..b298cb552e 100644 --- a/qiskit_experiments/library/calibration/half_angle_cal.py +++ b/qiskit_experiments/library/calibration/half_angle_cal.py @@ -28,7 +28,49 @@ class HalfAngleCal(BaseCalibrationExperiment, HalfAngle): - """Calibration version of the :class:`.HalfAngle` experiment.""" + """Calibration version of the :class:`.HalfAngle` experiment. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + warnings.filterwarnings("ignore", + message=".*entire Qiskit Pulse package is being deprecated.*", + category=DeprecationWarning, + ) + + # backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=False, seed=199) + + .. jupyter-execute:: + + from qiskit import pulse + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library.calibration.half_angle_cal import HalfAngleCal + + library = FixedFrequencyTransmon(default_values={"duration": 640}) + cals = Calibrations.from_backend(backend=backend, libraries=[library]) + exp_cal = HalfAngleCal((0,), cals, backend=backend) + + inst_map = backend.defaults().instruction_schedule_map + with pulse.build(backend=backend, name="y") as sched_build: + pulse.play(pulse.Drag(duration=160, + sigma=40, + beta=5, + amp=0.05821399464431249, + angle=0.0,), pulse.DriveChannel(0),) + inst_map.add("y", (0,), sched_build) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + """ def __init__( self, diff --git a/qiskit_experiments/library/calibration/rough_amplitude_cal.py b/qiskit_experiments/library/calibration/rough_amplitude_cal.py index c6bea05d53..65251c912a 100644 --- a/qiskit_experiments/library/calibration/rough_amplitude_cal.py +++ b/qiskit_experiments/library/calibration/rough_amplitude_cal.py @@ -31,7 +31,44 @@ class RoughAmplitudeCal(BaseCalibrationExperiment, Rabi): - """A calibration version of the Rabi experiment.""" + """A calibration version of the Rabi experiment. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + # backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=True, seed=106) + + .. jupyter-execute:: + + import numpy as np + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library.calibration import RoughAmplitudeCal + + library = FixedFrequencyTransmon() + cals = Calibrations.from_backend(backend=backend, libraries=[library]) + + exp_cal = RoughAmplitudeCal(physical_qubits=(0,), + calibrations=cals, + schedule_name="x", + amplitudes=np.linspace(-0.1, 0.1, 51), + cal_parameter_name="amp", + target_angle=np.pi, + auto_update=True, + group="default", + backend=backend) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + """ def __init__( self, @@ -189,7 +226,39 @@ def update_calibrations(self, experiment_data: ExperimentData): class RoughXSXAmplitudeCal(RoughAmplitudeCal): - """A rough amplitude calibration of x and sx gates.""" + """A rough amplitude calibration of x and sx gates. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + # backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=True, seed=180) + + .. jupyter-execute:: + + import numpy as np + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library.calibration import RoughXSXAmplitudeCal + + library = FixedFrequencyTransmon() + cals = Calibrations.from_backend(backend, libraries=[library]) + exp_cal = RoughXSXAmplitudeCal((0,), + cals, + backend=backend, + amplitudes=np.linspace(-0.1, 0.1, 51) + ) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + """ def __init__( self, @@ -220,6 +289,78 @@ def __init__( class EFRoughXSXAmplitudeCal(RoughAmplitudeCal): r"""A rough amplitude calibration of :math:`X` and :math:`SX` gates on the :math:`|1\rangle` <-> :math:`|2\rangle` transition. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + warnings.filterwarnings("ignore", + message=".*entire Qiskit Pulse package is being deprecated.*", + category=DeprecationWarning, + ) + + # backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=True, seed=180) + + .. jupyter-execute:: + + import numpy as np + import qiskit.pulse as pulse + from qiskit.circuit import Parameter + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library.calibration import EFRoughXSXAmplitudeCal + + library = FixedFrequencyTransmon() + cals = Calibrations.from_backend( + backend=backend, + libraries=[library] + ) + + amp = Parameter("amp") + + with pulse.build(name="x12") as build_x12: + with pulse.align_left(): + pulse.shift_frequency(-.25e9, pulse.DriveChannel(0)) + pulse.play(pulse.Drag(160, + amp, + 40, + 0., + 0., + ), pulse.DriveChannel(0)) + + with pulse.build(name="sx12") as build_sx12: + with pulse.align_left(): + pulse.shift_frequency(-.25e9, pulse.DriveChannel(0)) + pulse.play(pulse.Drag(160, + amp / 2, + 40, + 0., + 0., + ), pulse.DriveChannel(0)) + + cals.add_schedule(build_x12, qubits=(0,), num_qubits=1) + cals.add_schedule(build_sx12, qubits=(0,), num_qubits=1) + for sched in ["x", "x12"]: + cals.add_parameter_value(0.5, "amp", (0,), schedule=sched) + + for sched in ["sx", "sx12"]: + cals.add_parameter_value(0.25, "amp", (0,), schedule=sched) + + exp_cal = EFRoughXSXAmplitudeCal(physical_qubits=(0,), + calibrations=cals, + amplitudes=np.linspace(-0.1, 0.1, 51), + backend=backend, + ef_pulse_label="12",) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) """ __outcome__ = "rabi_rate_12" diff --git a/qiskit_experiments/library/calibration/rough_drag_cal.py b/qiskit_experiments/library/calibration/rough_drag_cal.py index 21e055f8c4..4628472223 100644 --- a/qiskit_experiments/library/calibration/rough_drag_cal.py +++ b/qiskit_experiments/library/calibration/rough_drag_cal.py @@ -29,9 +29,36 @@ class RoughDragCal(BaseCalibrationExperiment, RoughDrag): """A calibration version of the :class:`.RoughDrag` experiment. + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + #backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=False, seed=161) + + .. jupyter-execute:: + + import numpy as np + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library import RoughDragCal + + library = FixedFrequencyTransmon(default_values={"duration": 320, "amp": 0.03}) + cals = Calibrations.from_backend(backend=backend, libraries=[library]) + exp_cal = RoughDragCal((0,), cals, backend=backend, betas=np.linspace(-20, 20, 25)) + exp_cal.set_experiment_options(reps=[3, 5, 7]) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + # section: manual :ref:`DRAG Calibration` - """ def __init__( diff --git a/qiskit_experiments/library/calibration/rough_frequency.py b/qiskit_experiments/library/calibration/rough_frequency.py index a40f7dcb80..da675df742 100644 --- a/qiskit_experiments/library/calibration/rough_frequency.py +++ b/qiskit_experiments/library/calibration/rough_frequency.py @@ -28,7 +28,40 @@ class RoughFrequencyCal(BaseCalibrationExperiment, QubitSpectroscopy): """A calibration experiment that runs :class:`.QubitSpectroscopy` to calibrate the qubit - transition frequency.""" + transition frequency. + + # section: example + .. jupyter-execute:: + :hide-code: + + import warnings + warnings.filterwarnings("ignore", ".*Could not determine job completion time.*", UserWarning) + + # backend + from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5.2e9,-.25e9, 1e9, 0.8e9, 1e4, noise=True, seed=100) + + .. jupyter-execute:: + + import numpy as np + from qiskit_experiments.calibration_management.calibrations import Calibrations + from qiskit_experiments.calibration_management.basis_gate_library \ + import FixedFrequencyTransmon + from qiskit_experiments.library.calibration.rough_frequency import RoughFrequencyCal + + qubit=0 + library = FixedFrequencyTransmon() + cals = Calibrations.from_backend(backend=backend, libraries=[library]) + + freq_est = backend.defaults().qubit_freq_est[qubit] + frequencies = np.linspace(freq_est-15e6, freq_est+15e6, 51) + exp_cal = RoughFrequencyCal((qubit,), cals, frequencies, backend=backend) + exp_cal.set_experiment_options(amp=0.005) + + cal_data = exp_cal.run().block_for_results() + display(cal_data.figure(0)) + cal_data.analysis_results(dataframe=True) + """ def __init__( self, @@ -78,6 +111,7 @@ def _attach_calibrations(self, circuit: QuantumCircuit): class RoughEFFrequencyCal(BaseCalibrationExperiment, EFSpectroscopy): r"""A calibration experiment that runs :class:`.QubitSpectroscopy` for the :math:`|1\rangle` <-> :math:`|2\rangle` transition. + """ __updater__ = Frequency diff --git a/qiskit_experiments/library/characterization/ef_spectroscopy.py b/qiskit_experiments/library/characterization/ef_spectroscopy.py index 0b28c6636f..400927a0d5 100644 --- a/qiskit_experiments/library/characterization/ef_spectroscopy.py +++ b/qiskit_experiments/library/characterization/ef_spectroscopy.py @@ -49,12 +49,15 @@ class EFSpectroscopy(QubitSpectroscopy): qubit = 0 freq01_estimate = backend.defaults().qubit_freq_est[qubit] - frequencies = np.linspace(freq01_estimate-15e6, freq01_estimate+15e6, 51) - - exp = EFSpectroscopy(physical_qubits = (0,), - frequencies = frequencies, - backend = backend, - ) + freq12_estimate = freq01_estimate + (-.25e9) + frequencies = np.linspace(freq12_estimate-15e6, freq12_estimate+15e6, 51) + + exp = EFSpectroscopy( + physical_qubits = (0,), + frequencies = frequencies, + backend = backend, + absolute = True, + ) exp.set_experiment_options(amp=0.005) exp_data = exp.run().block_for_results() diff --git a/qiskit_experiments/library/characterization/rabi.py b/qiskit_experiments/library/characterization/rabi.py index fd16a7c05b..2c547ba7fa 100644 --- a/qiskit_experiments/library/characterization/rabi.py +++ b/qiskit_experiments/library/characterization/rabi.py @@ -266,8 +266,8 @@ class EFRabi(Rabi): ) # backend - from qiskit_experiments.test.pulse_backend import SingleTransmonTestBackend - backend = SingleTransmonTestBackend(5.2e9, -0.25e9, 1e9, 0.8e9, 1e4, noise=True, seed=198) + from qiskit_experiments.test import SingleTransmonTestBackend + backend = SingleTransmonTestBackend(5e9, -0.25e9, 1e9, 0.8e9, 1e4, noise=True) .. jupyter-execute:: @@ -277,12 +277,14 @@ class EFRabi(Rabi): from qiskit_experiments.library import EFRabi with pulse.build() as build_sched: - pulse.play(pulse.Gaussian(160, Parameter("amp"), sigma=40), pulse.DriveChannel(0)) + with pulse.align_left(): + pulse.shift_frequency(-0.25e9, pulse.DriveChannel(0)) + pulse.play(pulse.Gaussian(160, Parameter("amp"), 40), pulse.DriveChannel(0)) exp = EFRabi(physical_qubits=(0,), - backend=backend, schedule=build_sched, - amplitudes=np.linspace(-0.1, 0.1, 21),) + amplitudes=np.linspace(-0.1, 0.1, 21), + backend=backend,) exp_data = exp.run().block_for_results() display(exp_data.figure(0)) diff --git a/qiskit_experiments/library/driven_freq_tuning/p1_spect.py b/qiskit_experiments/library/driven_freq_tuning/p1_spect.py index 7c81611419..5a2e867e54 100644 --- a/qiskit_experiments/library/driven_freq_tuning/p1_spect.py +++ b/qiskit_experiments/library/driven_freq_tuning/p1_spect.py @@ -71,7 +71,6 @@ class StarkP1Spectroscopy(BaseExperiment): # section: manual :doc:`/manuals/characterization/stark_experiment` - """ @deprecate_func( diff --git a/qiskit_experiments/library/driven_freq_tuning/ramsey_amp_scan.py b/qiskit_experiments/library/driven_freq_tuning/ramsey_amp_scan.py index e82d5d7910..494718e08d 100644 --- a/qiskit_experiments/library/driven_freq_tuning/ramsey_amp_scan.py +++ b/qiskit_experiments/library/driven_freq_tuning/ramsey_amp_scan.py @@ -92,7 +92,6 @@ class StarkRamseyXYAmpScan(BaseExperiment): # section: manual :doc:`/manuals/characterization/stark_experiment` - """ @deprecate_func( diff --git a/qiskit_experiments/library/quantum_volume/qv_experiment.py b/qiskit_experiments/library/quantum_volume/qv_experiment.py index 5d64b37377..ae8406c928 100644 --- a/qiskit_experiments/library/quantum_volume/qv_experiment.py +++ b/qiskit_experiments/library/quantum_volume/qv_experiment.py @@ -66,6 +66,30 @@ class QuantumVolume(BaseExperiment): .. ref_arxiv:: 1 1811.12926 .. ref_arxiv:: 2 2008.08571 + # section: example + .. jupyter-execute:: + :hide-code: + + # backend + from qiskit_aer import AerSimulator + from qiskit_ibm_runtime.fake_provider import FakeSydneyV2 + backend = AerSimulator.from_backend(FakeSydneyV2()) + + .. jupyter-execute:: + + from qiskit_experiments.framework import BatchExperiment + from qiskit_experiments.library import QuantumVolume + + qubits = tuple(range(4)) # Can use specific qubits. for example [2, 4, 7, 10] + qv_exp = QuantumVolume(qubits, seed=42) + qv_exp.set_transpile_options(optimization_level=3) + qv_exp.set_run_options(shots=1000) + + expdata = qv_exp.run(backend=backend).block_for_results() + display(expdata.figure(0)) + + for result in expdata.analysis_results(): + print(result) """ def __init__( diff --git a/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py b/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py index 114f23b8a5..5da2024973 100644 --- a/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py +++ b/qiskit_experiments/library/randomized_benchmarking/interleaved_rb_experiment.py @@ -53,6 +53,37 @@ class InterleavedRB(StandardRB): # section: reference .. ref_arxiv:: 1 1203.4550 + # section: example + .. jupyter-execute:: + :hide-code: + + # backend + from qiskit_aer import AerSimulator + from qiskit_ibm_runtime.fake_provider import FakePerth + + backend = AerSimulator.from_backend(FakePerth()) + + .. jupyter-execute:: + + import numpy as np + from qiskit_experiments.library import StandardRB, InterleavedRB + from qiskit_experiments.framework import ParallelExperiment, BatchExperiment + import qiskit.circuit.library as circuits + + lengths = np.arange(1, 200, 30) + num_samples = 10 + seed = 1010 + qubits = (1, 2) + + int_exp2 = InterleavedRB( + circuits.CXGate(), qubits, lengths, num_samples=num_samples, seed=seed) + + int_expdata2 = int_exp2.run(backend=backend).block_for_results() + int_results2 = int_expdata2.analysis_results() + display(int_expdata2.figure(0)) + + names = {result.name for result in int_results2} + print(f"Available results: {names}") """ def __init__( diff --git a/qiskit_experiments/library/randomized_benchmarking/layer_fidelity.py b/qiskit_experiments/library/randomized_benchmarking/layer_fidelity.py index 40c5247f87..1d274ca550 100644 --- a/qiskit_experiments/library/randomized_benchmarking/layer_fidelity.py +++ b/qiskit_experiments/library/randomized_benchmarking/layer_fidelity.py @@ -76,6 +76,47 @@ class LayerFidelity(BaseExperiment, RestlessMixin): # section: reference .. ref_arxiv:: 1 2311.05933 + + # section: example + .. jupyter-execute:: + :hide-code: + + # backend + from qiskit_aer import AerSimulator + from qiskit_ibm_runtime.fake_provider import FakePerth + backend = AerSimulator.from_backend(FakePerth()) + + .. jupyter-execute:: + + import numpy as np + from qiskit_experiments.library import StandardRB + from qiskit_experiments.library.randomized_benchmarking import LayerFidelity + + lengths = np.arange(1, 800, 200) + two_qubit_layers=[[(0, 1), (3, 5)], [(1, 3), (5, 6)]] + + num_samples = 6 + seed = 106 + + exp = LayerFidelity( + physical_qubits=[0, 1, 3, 5, 6], + two_qubit_layers=two_qubit_layers, + lengths=lengths, + backend=backend, + num_samples=num_samples, + seed=seed, + two_qubit_gate=None, + one_qubit_basis_gates=None, + ) + + exp_data = exp.run().block_for_results() + results = exp_data.analysis_results() + + display(exp_data.figure(0)) # one of 6 figures + display(exp_data.analysis_results("EPLG", dataframe=True)) + + names={result.name for result in results} + print(f"Available results: {names}") """ def __init__( diff --git a/qiskit_experiments/library/randomized_benchmarking/standard_rb.py b/qiskit_experiments/library/randomized_benchmarking/standard_rb.py index 43c77bb8c1..7c29059960 100644 --- a/qiskit_experiments/library/randomized_benchmarking/standard_rb.py +++ b/qiskit_experiments/library/randomized_benchmarking/standard_rb.py @@ -84,6 +84,52 @@ class StandardRB(BaseExperiment, RestlessMixin): # section: reference .. ref_arxiv:: 1 1009.3639 .. ref_arxiv:: 2 1109.6887 + + # section: example + .. jupyter-execute:: + :hide-code: + + # backend + from qiskit_aer import AerSimulator + from qiskit_ibm_runtime.fake_provider import FakePerth + + backend = AerSimulator.from_backend(FakePerth()) + + .. jupyter-execute:: + + import numpy as np + from qiskit_experiments.library import StandardRB, InterleavedRB + from qiskit_experiments.framework import ParallelExperiment, BatchExperiment + import qiskit.circuit.library as circuits + + lengths_2_qubit = np.arange(1, 200, 30) + lengths_1_qubit = np.arange(1, 800, 200) + num_samples = 10 + seed = 1010 + qubits = (1, 2) + + # Run a 1-qubit RB experiment on qubits 1, 2 to determine the error-per-gate of 1-qubit gates + single_exps = BatchExperiment( + [ + StandardRB((qubit,), lengths_1_qubit, num_samples=num_samples, seed=seed) + for qubit in qubits + ] + ) + expdata_1q = single_exps.run(backend=backend).block_for_results() + + exp_2q = StandardRB(qubits, lengths_2_qubit, num_samples=num_samples, seed=seed) + + # Use the EPG data of the 1-qubit runs to ensure correct 2-qubit EPG computation + exp_2q.analysis.set_options(epg_1_qubit=expdata_1q.analysis_results()) + + expdata_2q = exp_2q.run(backend=backend).block_for_results() + results_2q = expdata_2q.analysis_results() + + print("Gate error ratio: %s" % expdata_2q.experiment.analysis.options.gate_error_ratio) + display(expdata_2q.figure(0)) + + names = {result.name for result in results_2q} + print(f"Available results: {names}") """ def __init__( diff --git a/qiskit_experiments/library/tomography/mit_qpt_experiment.py b/qiskit_experiments/library/tomography/mit_qpt_experiment.py index bdebf34bd0..8a9a000302 100644 --- a/qiskit_experiments/library/tomography/mit_qpt_experiment.py +++ b/qiskit_experiments/library/tomography/mit_qpt_experiment.py @@ -50,6 +50,51 @@ class MitigatedProcessTomography(BatchExperiment): * :py:class:`qiskit_experiments.library.tomography.ProcessTomography` * :py:class:`qiskit_experiments.library.characterization.LocalReadoutError` + # section: example + .. jupyter-execute:: + :hide-code: + + # backend + from qiskit_aer import AerSimulator + from qiskit_ibm_runtime.fake_provider import FakePerth + + backend = AerSimulator.from_backend(FakePerth()) + + .. jupyter-execute:: + + import numpy as np + from qiskit import QuantumCircuit + from qiskit_experiments.library import MitigatedProcessTomography + + num_qubits = 2 + qc_ghz = QuantumCircuit(num_qubits) + qc_ghz.h(0) + qc_ghz.s(0) + + for i in range(1, num_qubits): + qc_ghz.cx(0, i) + + mitqptexp = MitigatedProcessTomography(qc_ghz) + mitqptexp.set_run_options(shots=1000) + mitqptdata = mitqptexp.run(backend=backend, + seed_simulator=100,).block_for_results() + mitigated_choi_out = mitqptdata.analysis_results("state").value + + # extracting a densitymatrix from mitigated_choi_out + from qiskit.visualization import plot_state_city + import qiskit.quantum_info as qinfo + + _rho_exp_00 = np.array([[None, None, None, None], + [None, None, None, None], + [None, None, None, None], + [None, None, None, None]]) + + for i in range(4): + for j in range(4): + _rho_exp_00[i][j] = mitigated_choi_out.data[i][j] + + mitigated_rho_exp_00 = qinfo.DensityMatrix(_rho_exp_00) + display(plot_state_city(mitigated_rho_exp_00, title="mitigated Density Matrix")) """ def __init__( diff --git a/qiskit_experiments/library/tomography/mit_qst_experiment.py b/qiskit_experiments/library/tomography/mit_qst_experiment.py index 98bec48fe2..7256f90f5e 100644 --- a/qiskit_experiments/library/tomography/mit_qst_experiment.py +++ b/qiskit_experiments/library/tomography/mit_qst_experiment.py @@ -50,6 +50,43 @@ class MitigatedStateTomography(BatchExperiment): * :py:class:`qiskit_experiments.library.tomography.StateTomography` * :py:class:`qiskit_experiments.library.characterization.LocalReadoutError` + # section: example + .. jupyter-execute:: + :hide-code: + + # backend + from qiskit_aer import AerSimulator + from qiskit_ibm_runtime.fake_provider import FakePerth + from qiskit_aer.noise import NoiseModel + + noise_model = NoiseModel.from_backend(FakePerth(), + thermal_relaxation=False, + gate_error=False, + readout_error=True, + ) + + backend = AerSimulator.from_backend(FakePerth(), noise_model=noise_model) + + .. jupyter-execute:: + + from qiskit import QuantumCircuit + from qiskit_experiments.library import MitigatedStateTomography + from qiskit.visualization import plot_state_city + + nq = 2 + qc_ghz = QuantumCircuit(nq) + qc_ghz.h(0) + qc_ghz.s(0) + + for i in range(1, nq): + qc_ghz.cx(0, i) + + mitqstexp = MitigatedStateTomography(qc_ghz) + mitqstexp.set_run_options(shots=1000) + mitqstdata = mitqstexp.run(backend=backend, + seed_simulator=100,).block_for_results() + state_result = mitqstdata.analysis_results("state") + plot_state_city(state_result.value, title="mitigated Density Matrix") """ def __init__( diff --git a/qiskit_experiments/library/tomography/qpt_experiment.py b/qiskit_experiments/library/tomography/qpt_experiment.py index 17d7d7347b..72faf2a2ca 100644 --- a/qiskit_experiments/library/tomography/qpt_experiment.py +++ b/qiskit_experiments/library/tomography/qpt_experiment.py @@ -46,6 +46,51 @@ class ProcessTomography(TomographyExperiment): # section: analysis_ref :class:`ProcessTomographyAnalysis` + # section: example + .. jupyter-execute:: + :hide-code: + + # backend + from qiskit_aer import AerSimulator + from qiskit_ibm_runtime.fake_provider import FakePerth + + backend = AerSimulator.from_backend(FakePerth()) + + .. jupyter-execute:: + + import numpy as np + from qiskit import QuantumCircuit + from qiskit_experiments.library import ProcessTomography + + num_qubits = 2 + qc_ghz = QuantumCircuit(num_qubits) + qc_ghz.h(0) + qc_ghz.s(0) + + for i in range(1, num_qubits): + qc_ghz.cx(0, i) + + qptexp = ProcessTomography(qc_ghz) + qptdata = qptexp.run(backend=backend, + shots=1000, + seed_simulator=100,).block_for_results() + choi_out = qptdata.analysis_results("state").value + + # extracting a densitymatrix from choi_out + from qiskit.visualization import plot_state_city + import qiskit.quantum_info as qinfo + + _rho_exp_00 = np.array([[None, None, None, None], + [None, None, None, None], + [None, None, None, None], + [None, None, None, None]]) + + for i in range(4): + for j in range(4): + _rho_exp_00[i][j] = choi_out.data[i][j] + + rho_exp_00 = qinfo.DensityMatrix(_rho_exp_00) + display(plot_state_city(rho_exp_00, title="Density Matrix")) """ def __init__( diff --git a/qiskit_experiments/library/tomography/qst_experiment.py b/qiskit_experiments/library/tomography/qst_experiment.py index 39c17a11d6..4d63ba071e 100644 --- a/qiskit_experiments/library/tomography/qst_experiment.py +++ b/qiskit_experiments/library/tomography/qst_experiment.py @@ -47,6 +47,36 @@ class StateTomography(TomographyExperiment): # section: manual :doc:`/manuals/verification/state_tomography` + # section: example + .. jupyter-execute:: + :hide-code: + + # backend + from qiskit_aer import AerSimulator + from qiskit_ibm_runtime.fake_provider import FakePerth + + backend = AerSimulator.from_backend(FakePerth()) + + .. jupyter-execute:: + + from qiskit import QuantumCircuit + from qiskit_experiments.library import StateTomography + from qiskit.visualization import plot_state_city + + nq = 2 + qc_ghz = QuantumCircuit(nq) + qc_ghz.h(0) + qc_ghz.s(0) + + for i in range(1, nq): + qc_ghz.cx(0, i) + + qstexp = StateTomography(qc_ghz) + qstdata = qstexp.run(backend=backend, + shots=1000, + seed_simulator=100,).block_for_results() + state_result = qstdata.analysis_results("state") + plot_state_city(state_result.value, title="Density Matrix") """ def __init__( diff --git a/qiskit_experiments/library/tomography/tomography_experiment.py b/qiskit_experiments/library/tomography/tomography_experiment.py index 3af65abe02..200ca6992f 100644 --- a/qiskit_experiments/library/tomography/tomography_experiment.py +++ b/qiskit_experiments/library/tomography/tomography_experiment.py @@ -31,6 +31,7 @@ class TomographyExperiment(BaseExperiment): # section: analysis_ref :class:`TomographyAnalysis` + """ @classmethod diff --git a/releasenotes/notes/add-examples-to-experiments-api-docs-31f3e3c3369a6f3d.yaml b/releasenotes/notes/add-examples-to-experiments-api-docs-31f3e3c3369a6f3d.yaml new file mode 100644 index 0000000000..4cc833152f --- /dev/null +++ b/releasenotes/notes/add-examples-to-experiments-api-docs-31f3e3c3369a6f3d.yaml @@ -0,0 +1,31 @@ +--- +other: + - | + Added minimal working code examples to the API pages for the experiments, + :class:`~.EFSpectroscopy`, + :class:`~.EFRabi`, + :class:`~.FineAmplitudeCal`, + :class:`~.FineXAmplitudeCal`, + :class:`~.FineSXAmplitudeCal`, + :class:`~.FineDragCal`, + :class:`~.FineXDragCal`, + :class:`~.FineSXDragCal`, + :class:`~.FineFrequencyCal`, + :class:`~.FrequencyCal`, + :class:`~.HalfAngleCal`, + :class:`~.RoughAmplitudeCal`, + :class:`~.RoughXSXAmplitudeCal`, + :class:`~.EFRoughXSXAmplitudeCal`, + :class:`~.RoughDragCal`, + :class:`~.RoughFrequencyCal`, + :class:`~.QuantumVolume`, + :class:`~.InterleavedRB`, + :class:`~.LayerFidelity`, + :class:`~.StandardRB`, + :class:`~.MitigatedProcessTomography`, + :class:`~.MitigatedStateTomography`, + :class:`~.ProcessTomography` and + :class:`~.StateTomography`. + The backends used in the code examples are simulators + such as, ``SingleTransmonTestBackend()`` and + ``AerSimulator(FakePerth())``.