forked from qiskit-community/qiskit-experiments
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add readout error mitigated state and process tomography experiments. These are implemented as a batch experiment of a local readout error characterization experiment, followed by the desired tomography experiment.
- Loading branch information
1 parent
867fb6c
commit 9df585a
Showing
11 changed files
with
366 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
qiskit_experiments/library/tomography/mit_qpt_experiment.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2023. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
""" | ||
Quantum Process Tomography experiment | ||
""" | ||
|
||
from typing import Union, Optional, Iterable, List, Tuple, Sequence | ||
from qiskit.providers.backend import Backend | ||
from qiskit.circuit import QuantumCircuit, Instruction | ||
from qiskit.quantum_info.operators.base_operator import BaseOperator | ||
from qiskit_experiments.framework import BatchExperiment, BaseAnalysis | ||
from qiskit_experiments.library.characterization.local_readout_error import LocalReadoutError | ||
from .qpt_experiment import ProcessTomography | ||
from .mit_tomography_analysis import MitigatedTomographyAnalysis | ||
from . import basis | ||
|
||
|
||
class MitigatedProcessTomography(BatchExperiment): | ||
"""Readout error mitigated quantum process tomography experiment. | ||
# section: overview | ||
Readout error mitigated Quantum process tomography is a batch | ||
experiment consisting of a :class:`~.LocalReadoutError` characterization | ||
experiments, followed by a :class:`~.ProcessTomography` experiment. | ||
During analysis the assignment matrix local readout error model is | ||
used to automatically construct a noisy Pauli measurement basis for | ||
performing readout error mitigated process tomography fitting. | ||
# section: note | ||
Performing readout error mitigation full process tomography on an | ||
`N`-qubit circuit requires running 2 readout error characterization | ||
circuits and :math:`4^N 3^N` measurement circuits using the Pauli | ||
preparation and measurement bases. | ||
# section: analysis_ref | ||
:py:class:`MitigatedTomographyAnalysis` | ||
# section: see_also | ||
qiskit_experiments.library.ProcessTomography | ||
qiskit_experiments.library.LocalReadoutError | ||
""" | ||
|
||
def __init__( | ||
self, | ||
circuit: Union[QuantumCircuit, Instruction, BaseOperator], | ||
backend: Optional[Backend] = None, | ||
physical_qubits: Optional[Sequence[int]] = None, | ||
measurement_indices: Optional[Sequence[int]] = None, | ||
preparation_indices: Optional[Sequence[int]] = None, | ||
basis_indices: Optional[Iterable[Tuple[List[int], List[int]]]] = None, | ||
analysis: Union[BaseAnalysis, None, str] = "default", | ||
): | ||
"""Initialize a quantum process tomography experiment. | ||
Args: | ||
circuit: the quantum process circuit. If not a quantum circuit | ||
it must be a class that can be appended to a quantum circuit. | ||
backend: The backend to run the experiment on. | ||
physical_qubits: Optional, the physical qubits for the initial state circuit. | ||
If None this will be qubits [0, N) for an N-qubit circuit. | ||
measurement_indices: Optional, the `physical_qubits` indices to be measured. | ||
If None all circuit physical qubits will be measured. | ||
preparation_indices: Optional, the `physical_qubits` indices to be prepared. | ||
If None all circuit physical qubits will be prepared. | ||
basis_indices: Optional, a list of basis indices for generating partial | ||
tomography measurement data. Each item should be given as a pair of | ||
lists of preparation and measurement basis configurations | ||
``([p[0], p[1], ..], m[0], m[1], ...])``, where ``p[i]`` is the | ||
preparation basis index, and ``m[i]`` is the measurement basis index | ||
for qubit-i. If not specified full tomography for all indices of the | ||
preparation and measurement bases will be performed. | ||
analysis: Optional, a custom tomography analysis instance to use. | ||
If ``"default"`` :class:`~.ProcessTomographyAnalysis` will be | ||
used. If None no analysis instance will be set. | ||
""" | ||
tomo_exp = ProcessTomography( | ||
circuit, | ||
backend=backend, | ||
physical_qubits=physical_qubits, | ||
measurement_basis=basis.PauliMeasurementBasis(), | ||
measurement_indices=measurement_indices, | ||
preparation_basis=basis.PauliPreparationBasis(), | ||
preparation_indices=preparation_indices, | ||
basis_indices=basis_indices, | ||
analysis=analysis, | ||
) | ||
|
||
roerror_exp = LocalReadoutError( | ||
tomo_exp.physical_qubits, | ||
backend=backend, | ||
) | ||
|
||
if analysis is None: | ||
mit_analysis = (None,) | ||
else: | ||
mit_analysis = MitigatedTomographyAnalysis(roerror_exp.analysis, tomo_exp.analysis) | ||
|
||
super().__init__( | ||
[roerror_exp, tomo_exp], backend=backend, flatten_results=True, analysis=mit_analysis | ||
) |
104 changes: 104 additions & 0 deletions
104
qiskit_experiments/library/tomography/mit_qst_experiment.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2023. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
""" | ||
Quantum State Tomography experiment | ||
""" | ||
|
||
from typing import Union, Optional, List, Sequence | ||
from qiskit.providers.backend import Backend | ||
from qiskit.circuit import QuantumCircuit, Instruction | ||
from qiskit.quantum_info.operators.base_operator import BaseOperator | ||
from qiskit_experiments.framework import BatchExperiment, BaseAnalysis | ||
from qiskit_experiments.library.characterization.local_readout_error import LocalReadoutError | ||
from .qst_experiment import StateTomography | ||
from .mit_tomography_analysis import MitigatedTomographyAnalysis | ||
from . import basis | ||
|
||
|
||
class MitigatedStateTomography(BatchExperiment): | ||
"""Readout error mitigated quantum state tomography experiment. | ||
# section: overview | ||
Readout error mitigated quantum state tomography is a batch | ||
experiment consisting of a :class:`~.LocalReadoutError` characterization | ||
experiments, followed by a :class:`~.StateTomography` experiment. | ||
During analysis the assignment matrix local readout error model is | ||
used to automatically construct a noisy Pauli measurement basis for | ||
performing readout error mitigated state tomography fitting. | ||
# section: note | ||
Performing readout error mitigation full state tomography on an | ||
`N`-qubit circuit requires running 2 readout error characterization | ||
circuits and :math:`3^N` measurement circuits using the Pauli | ||
measurement basis. | ||
# section: analysis_ref | ||
:py:class:`MitigatedTomographyAnalysis` | ||
# section: see_also | ||
qiskit_experiments.library.StateTomography | ||
qiskit_experiments.library.LocalReadoutError | ||
""" | ||
|
||
def __init__( | ||
self, | ||
circuit: Union[QuantumCircuit, Instruction, BaseOperator], | ||
backend: Optional[Backend] = None, | ||
physical_qubits: Optional[Sequence[int]] = None, | ||
measurement_indices: Optional[Sequence[int]] = None, | ||
basis_indices: Optional[Sequence[List[int]]] = None, | ||
analysis: Union[BaseAnalysis, None, str] = "default", | ||
): | ||
"""Initialize a quantum process tomography experiment. | ||
Args: | ||
circuit: the quantum process circuit. If not a quantum circuit | ||
it must be a class that can be appended to a quantum circuit. | ||
backend: The backend to run the experiment on. | ||
physical_qubits: Optional, the physical qubits for the initial state circuit. | ||
If None this will be qubits [0, N) for an N-qubit circuit. | ||
measurement_indices: Optional, the `physical_qubits` indices to be measured. | ||
If None all circuit physical qubits will be measured. | ||
basis_indices: Optional, a list of basis indices for generating partial | ||
tomography measurement data. Each item should be given as a list of | ||
measurement basis configurations ``[m[0], m[1], ...]`` where ``m[i]`` | ||
is the measurement basis index for qubit-i. If not specified full | ||
tomography for all indices of the measurement basis will be performed. | ||
analysis: Optional, a custom tomography analysis instance to use. | ||
If ``"default"`` :class:`~.ProcessTomographyAnalysis` will be | ||
used. If None no analysis instance will be set. | ||
""" | ||
tomo_exp = StateTomography( | ||
circuit, | ||
backend=backend, | ||
physical_qubits=physical_qubits, | ||
measurement_basis=basis.PauliMeasurementBasis(), | ||
measurement_indices=measurement_indices, | ||
basis_indices=basis_indices, | ||
analysis=analysis, | ||
) | ||
|
||
roerror_exp = LocalReadoutError( | ||
tomo_exp.physical_qubits, | ||
backend=backend, | ||
) | ||
|
||
if analysis is None: | ||
mit_analysis = (None,) | ||
else: | ||
mit_analysis = MitigatedTomographyAnalysis(roerror_exp.analysis, tomo_exp.analysis) | ||
|
||
super().__init__( | ||
[roerror_exp, tomo_exp], backend=backend, flatten_results=True, analysis=mit_analysis | ||
) |
108 changes: 108 additions & 0 deletions
108
qiskit_experiments/library/tomography/mit_tomography_analysis.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2023. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
""" | ||
Readout error mitigated tomography analysis | ||
""" | ||
|
||
from qiskit_experiments.framework import CompositeAnalysis | ||
from qiskit_experiments.library.characterization import LocalReadoutErrorAnalysis | ||
from .tomography_analysis import TomographyAnalysis | ||
from .basis.pauli_basis import PauliMeasurementBasis | ||
|
||
|
||
class MitigatedTomographyAnalysis(CompositeAnalysis): | ||
"""Analysis for readout error mitigated tomography experiments. | ||
Analysis is performed as a :class:`.CompositeAnalysis` consisting | ||
of :class:`.LocalReadoutErrorAnalysis` to determine the local | ||
assigment matrices describing single qubit Z-basis readout errors, | ||
and then these matrices are used to automatically construct a noisy | ||
:class:`~.PauliMeasurementBasis` for use during tomographic | ||
fitting with the tomography analysis. | ||
""" | ||
|
||
def __init__(self, roerror_analysis="default", tomography_analysis="default"): | ||
"""Initialize mitigated tomography analysis""" | ||
if roerror_analysis == "default": | ||
roerror_analysis = LocalReadoutErrorAnalysis() | ||
if tomography_analysis == "default": | ||
tomography_analysis = TomographyAnalysis() | ||
super().__init__([roerror_analysis, tomography_analysis], flatten_results=True) | ||
|
||
@classmethod | ||
def _default_options(cls): | ||
"""Default analysis options | ||
Analysis Options: | ||
fitter (str or Callable): The fitter function to use for reconstruction. | ||
This can be a string to select one of the built-in fitters, or a callable to | ||
supply a custom fitter function. See the `Fitter Functions` section for | ||
additional information. | ||
fitter_options (dict): Any addition kwarg options to be supplied to the fitter | ||
function. For documentation of available kwargs refer to the fitter function | ||
documentation. | ||
rescale_positive (bool): If True rescale the state returned by the fitter | ||
to be positive-semidefinite. See the `PSD Rescaling` section for | ||
additional information (Default: True). | ||
rescale_trace (bool): If True rescale the state returned by the fitter | ||
have either trace 1 for :class:`~qiskit.quantum_info.DensityMatrix`, | ||
or trace dim for :class:`~qiskit.quantum_info.Choi` matrices (Default: True). | ||
measurement_qubits (Sequence[int]): Optional, the physical qubits with tomographic | ||
measurements. If not specified will be set to ``[0, ..., N-1]`` for N-qubit | ||
tomographic measurements. | ||
preparation_qubits (Sequence[int]): Optional, the physical qubits with tomographic | ||
preparations. If not specified will be set to ``[0, ..., N-1]`` for N-qubit | ||
tomographic preparations. | ||
target (Any): Optional, target object for fidelity comparison of the fit | ||
(Default: None). | ||
""" | ||
# Override options to be tomography options minus bases | ||
options = super()._default_options() | ||
options.fitter = "linear_inversion" | ||
options.fitter_options = {} | ||
options.rescale_positive = True | ||
options.rescale_trace = True | ||
options.measurement_qubits = None | ||
options.preparation_qubits = None | ||
options.target = None | ||
return options | ||
|
||
def set_options(self, **fields): | ||
super().set_options(**fields) | ||
self._analyses[1].set_options(**fields) | ||
|
||
def _run_analysis(self, experiment_data): | ||
# Return list of experiment data containers for each component experiment | ||
# containing the marginalized data from the composite experiment | ||
roerror_analysis, tomo_analysis = self._analyses | ||
roerror_data, tomo_data = self._component_experiment_data(experiment_data) | ||
|
||
# Run readout error analysis | ||
roerror_analysis.run(roerror_data, replace_results=True).block_for_results() | ||
|
||
# Construct noisy measurement basis | ||
mitigator = roerror_data.analysis_results(0).value | ||
|
||
# Construct noisy measurement basis | ||
measurement_basis = PauliMeasurementBasis(mitigator=mitigator) | ||
tomo_analysis.set_options(measurement_basis=measurement_basis) | ||
|
||
# Run tomography analysis | ||
tomo_analysis.run(tomo_data, replace_results=True).block_for_results() | ||
|
||
# Optionally flatten results from all component experiments | ||
# for adding to the main experiment data container | ||
if self._flatten_results: | ||
# Combine results so that tomography results are ordered first | ||
return self._combine_results([tomo_data, roerror_data]) | ||
|
||
return [], [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.