From 5a349a2f479d96bf9932f40ddcd66f2057b60d61 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Sun, 16 Jan 2022 17:14:20 +0200 Subject: [PATCH 01/32] Mitigation class documentation --- .../mitigation/mitigation_experiment.py | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/qiskit_experiments/library/mitigation/mitigation_experiment.py b/qiskit_experiments/library/mitigation/mitigation_experiment.py index a5febc3372..c18366acf2 100644 --- a/qiskit_experiments/library/mitigation/mitigation_experiment.py +++ b/qiskit_experiments/library/mitigation/mitigation_experiment.py @@ -21,7 +21,54 @@ class ReadoutMitigationExperiment(BaseExperiment): - """Class for readout mitigation experiments""" + """Class for readout mitigation experiments + # section: overview + Readout mitigation aims to reduce the effect of errors during the measurement + of the qubits in a quantum device. It is used both to obtain a more accurate + distribution of the outputs, and more accurate measurements of expectation + value for measurables. + + The readout mitigator is generated from an *assignment matrix*: + a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the probability + to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used + to compute the *mitigation matrix* used in the mitigation process itself. + + + A readout mitigation experiment aims to determine the assignment matrix + for the readout error in a given device, and generate a corresponding mitigator + based on the `qiskit-terra` classes of `Correlated readout mitigator + _` + and `Local readout mitigator + _` + + A *Correlated readout mitigator* uses the full :math:`2^n\times 2^n` assignment matrix, meaning + it can only be used for small values of :math:`n`. + + A *Local readout mitigator* works under the assumption the readout errors are mostly *local*, meaning + readout errors for different qubits are independent of each other. In this case, the assignment matrix + is the tensor product of :math:`n` :math:`2\times 2` matrices, one for each qubit, making it practical + to store the assignment matrix in implicit form, by storing the individual :math:`2\times 2` assignment matrices. + + The readout mitigation experiment can be passed a `method` parameter to determine + which method will be used (and which mitigator will be returned): The default `local` method + or the `correlated` method. + + In the `local` method, the experiment generates 2 circuits, corresponding to the states + :math:`|0^n>` and :math:`|1^n>`, measuring the error in all the qubits at once. + + In the `correlated` method, the experiment generates :math:`2^n` circuits, for every possible + :math:`n`-qubit quantum state. + + See :class:`LocalMitigationAnalysis` and :class:`CorrelatedMitigationAnalysis` + documentation for additional information on readout mitigation experiment analysis. + + # section: analysis_ref + :py:class:`LocalMitigationAnalysis` + :py:class:`CorrelatedMitigationAnalysis` + + # section: reference + .. ref_arxiv:: 1 2006.14044 + """ METHOD_LOCAL = "local" METHOD_CORRELATED = "correlated" From 0cac1464edddddbba92c4b3418bd92ea75ed76c1 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Mon, 17 Jan 2022 09:39:41 +0200 Subject: [PATCH 02/32] Splitting the mitigation experiments to two classes --- .../library/mitigation/__init__.py | 6 +- .../correlated_mitigation_analysis.py | 84 +++++++++++++++++ ...py => correlated_mitigation_experiment.py} | 91 ++----------------- ...alysis.py => local_mitigation_analysis.py} | 67 +------------- .../mitigation/local_mitigation_experiment.py | 83 +++++++++++++++++ .../library/mitigation/utils.py | 17 ++++ 6 files changed, 198 insertions(+), 150 deletions(-) create mode 100644 qiskit_experiments/library/mitigation/correlated_mitigation_analysis.py rename qiskit_experiments/library/mitigation/{mitigation_experiment.py => correlated_mitigation_experiment.py} (57%) rename qiskit_experiments/library/mitigation/{mitigation_analysis.py => local_mitigation_analysis.py} (59%) create mode 100644 qiskit_experiments/library/mitigation/local_mitigation_experiment.py create mode 100644 qiskit_experiments/library/mitigation/utils.py diff --git a/qiskit_experiments/library/mitigation/__init__.py b/qiskit_experiments/library/mitigation/__init__.py index 25d6a23a35..1ea97873f8 100644 --- a/qiskit_experiments/library/mitigation/__init__.py +++ b/qiskit_experiments/library/mitigation/__init__.py @@ -36,6 +36,6 @@ CorrelatedMitigationAnalysis LocalMitigationAnalysis """ -from .mitigation_experiment import ReadoutMitigationExperiment -from .mitigation_analysis import CorrelatedMitigationAnalysis -from .mitigation_analysis import LocalMitigationAnalysis +from .correlated_mitigation_experiment import ReadoutMitigationExperiment +from .correlated_mitigation_analysis import CorrelatedMitigationAnalysis +from .correlated_mitigation_analysis import LocalMitigationAnalysis diff --git a/qiskit_experiments/library/mitigation/correlated_mitigation_analysis.py b/qiskit_experiments/library/mitigation/correlated_mitigation_analysis.py new file mode 100644 index 0000000000..3a8694559c --- /dev/null +++ b/qiskit_experiments/library/mitigation/correlated_mitigation_analysis.py @@ -0,0 +1,84 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2021. +# +# 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. +""" +Correlated readout mitigation calibration analysis classes +""" +from typing import List, Tuple +import numpy as np +import matplotlib.pyplot as plt +from qiskit.result import CorrelatedReadoutMitigator +from qiskit_experiments.framework import ExperimentData +from qiskit_experiments.framework.matplotlib import get_non_gui_ax +from qiskit_experiments.framework import BaseAnalysis, AnalysisResultData, Options + + +class CorrelatedMitigationAnalysis(BaseAnalysis): + """ + Measurement correction analysis for a full calibration + """ + + def _run_analysis( + self, experiment_data: ExperimentData, **options + ) -> Tuple[List[AnalysisResultData], List["matplotlib.figure.Figure"]]: + data = experiment_data.data() + qubits = experiment_data.metadata["physical_qubits"] + labels = [datum["metadata"]["label"] for datum in data] + matrix = self._generate_matrix(data, labels) + result_mitigator = CorrelatedReadoutMitigator(matrix, qubits=qubits) + analysis_results = [AnalysisResultData("Correlated Readout Mitigator", result_mitigator)] + ax = options.get("ax", None) + figures = [self._plot_calibration(matrix, labels, ax)] + return analysis_results, figures + + def _generate_matrix(self, data, labels) -> np.array: + list_size = len(labels) + matrix = np.zeros([list_size, list_size], dtype=float) + # matrix[i][j] is the probability of counting i for expected j + for datum in data: + expected_outcome = datum["metadata"]["label"] + j = labels.index(expected_outcome) + total_counts = sum(datum["counts"].values()) + for measured_outcome, count in datum["counts"].items(): + i = labels.index(measured_outcome) + matrix[i][j] = count / total_counts + return matrix + + def _plot_calibration(self, matrix, labels, ax=None) -> "matplotlib.figure.Figure": + """ + Plot the calibration matrix (2D color grid plot). + + Args: + matrix: calibration matrix to plot + ax (matplotlib.axes): settings for the graph + + Returns: + The generated plot of the calibration matrix + + Raises: + QiskitError: if _cal_matrices was not set. + + ImportError: if matplotlib was not installed. + + """ + + if ax is None: + ax = get_non_gui_ax() + figure = ax.get_figure() + ax.matshow(matrix, cmap=plt.cm.binary, clim=[0, 1]) + ax.set_xlabel("Prepared State") + ax.xaxis.set_label_position("top") + ax.set_ylabel("Measured State") + ax.set_xticks(np.arange(len(labels))) + ax.set_yticks(np.arange(len(labels))) + ax.set_xticklabels(labels) + ax.set_yticklabels(labels) + return figure \ No newline at end of file diff --git a/qiskit_experiments/library/mitigation/mitigation_experiment.py b/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py similarity index 57% rename from qiskit_experiments/library/mitigation/mitigation_experiment.py rename to qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py index c18366acf2..5b8f475d52 100644 --- a/qiskit_experiments/library/mitigation/mitigation_experiment.py +++ b/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py @@ -10,18 +10,16 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """ -Measurement calibration experiment classes. +Correlated readout mitigation calibration experiment class. """ from typing import Iterable, List - from qiskit import QuantumCircuit -from qiskit.exceptions import QiskitError from qiskit_experiments.framework import BaseExperiment -from .mitigation_analysis import CorrelatedMitigationAnalysis, LocalMitigationAnalysis - +from .correlated_mitigation_analysis import CorrelatedMitigationAnalysis +from .utils import calibration_circuit -class ReadoutMitigationExperiment(BaseExperiment): - """Class for readout mitigation experiments +class CorrelatedReadoutMitigationExperiment(BaseExperiment): + """Class for correlated readout mitigation experiment # section: overview Readout mitigation aims to reduce the effect of errors during the measurement of the qubits in a quantum device. It is used both to obtain a more accurate @@ -69,20 +67,11 @@ class ReadoutMitigationExperiment(BaseExperiment): # section: reference .. ref_arxiv:: 1 2006.14044 """ - - METHOD_LOCAL = "local" - METHOD_CORRELATED = "correlated" - ALL_METHODS = [METHOD_LOCAL, METHOD_CORRELATED] - - def __init__(self, qubits: Iterable[int], method=METHOD_LOCAL): - """Initialize a mitigation experiment. + def __init__(self, qubits: Iterable[int]): + """Initialize a correlated readout mitigation calibration experiment. Args: qubits: The qubits being mitigated - method: A string denoting mitigation method - - Raises: - QiskitError: if the given mitigation method is not recoginzed Additional info: The currently supported mitigation methods are: @@ -93,69 +82,9 @@ def __init__(self, qubits: Iterable[int], method=METHOD_LOCAL): but might be more accurate than local mitigation. """ super().__init__(qubits) - if method not in self.ALL_METHODS: - raise QiskitError("Method {} not recognized".format(method)) - if method == self.METHOD_LOCAL: - self.helper = LocalMitigationHelper(self.num_qubits) - if method == self.METHOD_CORRELATED: - self.helper = CorrelatedMitigationHelper(self.num_qubits) - - self.analysis = self.helper.analysis() + self.analysis = CorrelatedMitigationAnalysis() def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" - return [self._calibration_circuit(self.num_qubits, label) for label in self.helper.labels()] - - @staticmethod - def _calibration_circuit(num_qubits: int, label: str) -> QuantumCircuit: - """Return a calibration circuit. - - This is an N-qubit circuit where N is the length of the label. - The circuit consists of X-gates on qubits with label bits equal to 1, - and measurements of all qubits. - """ - circ = QuantumCircuit(num_qubits, name="meas_mit_cal_" + label) - for i, val in enumerate(reversed(label)): - if val == "1": - circ.x(i) - circ.measure_all() - circ.metadata = {"label": label} - return circ - - -class CorrelatedMitigationHelper: - """Helper class for correlated mitigation experiment data""" - - def __init__(self, num_qubits: int): - """Creates the helper class - Args: - num_qubits: The number of qubits being mitigated - """ - self.num_qubits = num_qubits - - def analysis(self): - """Returns the analysis class for the mitigation""" - return CorrelatedMitigationAnalysis() - - def labels(self) -> List[str]: - """Returns the labels dictating the generation of the mitigation circuits""" - return [bin(j)[2:].zfill(self.num_qubits) for j in range(2 ** self.num_qubits)] - - -class LocalMitigationHelper: - """Helper class for local mitigation experiment data""" - - def __init__(self, num_qubits: int): - """Creates the helper class - Args: - num_qubits: The number of qubits being mitigated - """ - self.num_qubits = num_qubits - - def analysis(self): - """Returns the analysis class for the mitigation""" - return LocalMitigationAnalysis() - - def labels(self) -> List[str]: - """Returns the labels dictating the generation of the mitigation circuits""" - return ["0" * self.num_qubits, "1" * self.num_qubits] + labels = [bin(j)[2:].zfill(self.num_qubits) for j in range(2 ** self.num_qubits)] + return [calibration_circuit(self.num_qubits, label) for label in self.helper.labels()] \ No newline at end of file diff --git a/qiskit_experiments/library/mitigation/mitigation_analysis.py b/qiskit_experiments/library/mitigation/local_mitigation_analysis.py similarity index 59% rename from qiskit_experiments/library/mitigation/mitigation_analysis.py rename to qiskit_experiments/library/mitigation/local_mitigation_analysis.py index 8ec1049044..6aa9240404 100644 --- a/qiskit_experiments/library/mitigation/mitigation_analysis.py +++ b/qiskit_experiments/library/mitigation/local_mitigation_analysis.py @@ -10,82 +10,17 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """ -Measurement calibration analysis classes +Local readout mitigation calibration analysis class """ from typing import List, Tuple import numpy as np import matplotlib.pyplot as plt -from qiskit.result import CorrelatedReadoutMitigator from qiskit.result import LocalReadoutMitigator from qiskit.result import marginal_counts from qiskit_experiments.framework import ExperimentData from qiskit_experiments.framework.matplotlib import get_non_gui_ax from qiskit_experiments.framework import BaseAnalysis, AnalysisResultData, Options - -class CorrelatedMitigationAnalysis(BaseAnalysis): - """ - Measurement correction analysis for a full calibration - """ - - def _run_analysis( - self, experiment_data: ExperimentData, **options - ) -> Tuple[List[AnalysisResultData], List["matplotlib.figure.Figure"]]: - data = experiment_data.data() - qubits = experiment_data.metadata["physical_qubits"] - labels = [datum["metadata"]["label"] for datum in data] - matrix = self._generate_matrix(data, labels) - result_mitigator = CorrelatedReadoutMitigator(matrix, qubits=qubits) - analysis_results = [AnalysisResultData("Correlated Readout Mitigator", result_mitigator)] - ax = options.get("ax", None) - figures = [self._plot_calibration(matrix, labels, ax)] - return analysis_results, figures - - def _generate_matrix(self, data, labels) -> np.array: - list_size = len(labels) - matrix = np.zeros([list_size, list_size], dtype=float) - # matrix[i][j] is the probability of counting i for expected j - for datum in data: - expected_outcome = datum["metadata"]["label"] - j = labels.index(expected_outcome) - total_counts = sum(datum["counts"].values()) - for measured_outcome, count in datum["counts"].items(): - i = labels.index(measured_outcome) - matrix[i][j] = count / total_counts - return matrix - - def _plot_calibration(self, matrix, labels, ax=None) -> "matplotlib.figure.Figure": - """ - Plot the calibration matrix (2D color grid plot). - - Args: - matrix: calibration matrix to plot - ax (matplotlib.axes): settings for the graph - - Returns: - The generated plot of the calibration matrix - - Raises: - QiskitError: if _cal_matrices was not set. - - ImportError: if matplotlib was not installed. - - """ - - if ax is None: - ax = get_non_gui_ax() - figure = ax.get_figure() - ax.matshow(matrix, cmap=plt.cm.binary, clim=[0, 1]) - ax.set_xlabel("Prepared State") - ax.xaxis.set_label_position("top") - ax.set_ylabel("Measured State") - ax.set_xticks(np.arange(len(labels))) - ax.set_yticks(np.arange(len(labels))) - ax.set_xticklabels(labels) - ax.set_yticklabels(labels) - return figure - - class LocalMitigationAnalysis(BaseAnalysis): """ Measurement correction analysis for a full calibration diff --git a/qiskit_experiments/library/mitigation/local_mitigation_experiment.py b/qiskit_experiments/library/mitigation/local_mitigation_experiment.py new file mode 100644 index 0000000000..ce5c2094cb --- /dev/null +++ b/qiskit_experiments/library/mitigation/local_mitigation_experiment.py @@ -0,0 +1,83 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2021. +# +# 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. +""" +Local readout mitigation calibration experiment class. +""" +from typing import Iterable, List + +from qiskit import QuantumCircuit +from qiskit_experiments.framework import BaseExperiment +from .local_mitigation_analysis import LocalMitigationAnalysis +from .utils import calibration_circuit + +class LocalReadoutMitigationExperiment(BaseExperiment): + """Class for local readout mitigation experiments + # section: overview + Readout mitigation aims to reduce the effect of errors during the measurement + of the qubits in a quantum device. It is used both to obtain a more accurate + distribution of the outputs, and more accurate measurements of expectation + value for measurables. + + The readout mitigator is generated from an *assignment matrix*: + a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the probability + to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used + to compute the *mitigation matrix* used in the mitigation process itself. + + A readout mitigation experiment aims to determine the assignment matrix + for the readout error in a given device, and generate a corresponding mitigator + based on the `qiskit-terra` classes of `Correlated readout mitigator + _` + and `Local readout mitigator + _` + + A *Correlated readout mitigator* uses the full :math:`2^n\times 2^n` assignment matrix, meaning + it can only be used for small values of :math:`n`. + + A *Local readout mitigator* works under the assumption the readout errors are mostly *local*, meaning + readout errors for different qubits are independent of each other. In this case, the assignment matrix + is the tensor product of :math:`n` :math:`2\times 2` matrices, one for each qubit, making it practical + to store the assignment matrix in implicit form, by storing the individual :math:`2\times 2` assignment matrices. + + The readout mitigation experiment can be passed a `method` parameter to determine + which method will be used (and which mitigator will be returned): The default `local` method + or the `correlated` method. + + In the `local` method, the experiment generates 2 circuits, corresponding to the states + :math:`|0^n>` and :math:`|1^n>`, measuring the error in all the qubits at once. + + In the `correlated` method, the experiment generates :math:`2^n` circuits, for every possible + :math:`n`-qubit quantum state. + + See :class:`LocalMitigationAnalysis` and :class:`CorrelatedMitigationAnalysis` + documentation for additional information on readout mitigation experiment analysis. + + # section: analysis_ref + :py:class:`LocalMitigationAnalysis` + :py:class:`CorrelatedMitigationAnalysis` + + # section: reference + .. ref_arxiv:: 1 2006.14044 + """ + + def __init__(self, qubits: Iterable[int]): + """Initialize a local readout mitigation calibration experiment. + + Args: + qubits: The qubits being mitigated + """ + super().__init__(qubits) + self.analysis = LocalMitigationAnalysis() + + def circuits(self) -> List[QuantumCircuit]: + """Returns the experiment's circuits""" + labels = ["0" * self.num_qubits, "1" * self.num_qubits] + return [calibration_circuit(self.num_qubits, label) for label in labels()] \ No newline at end of file diff --git a/qiskit_experiments/library/mitigation/utils.py b/qiskit_experiments/library/mitigation/utils.py new file mode 100644 index 0000000000..76821c1c79 --- /dev/null +++ b/qiskit_experiments/library/mitigation/utils.py @@ -0,0 +1,17 @@ +from qiskit import QuantumCircuit + + +def calibration_circuit(num_qubits: int, label: str) -> QuantumCircuit: + """Return a calibration circuit. + + This is an N-qubit circuit where N is the length of the label. + The circuit consists of X-gates on qubits with label bits equal to 1, + and measurements of all qubits. + """ + circ = QuantumCircuit(num_qubits, name="meas_mit_cal_" + label) + for i, val in enumerate(reversed(label)): + if val == "1": + circ.x(i) + circ.measure_all() + circ.metadata = {"label": label} + return circ \ No newline at end of file From f927dea87834c2180952490ab24ec5ddf3f7f8a6 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Mon, 17 Jan 2022 09:40:58 +0200 Subject: [PATCH 03/32] Splitting the mitigation experiments to two classes --- qiskit_experiments/library/mitigation/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/qiskit_experiments/library/mitigation/__init__.py b/qiskit_experiments/library/mitigation/__init__.py index 1ea97873f8..6761f1c6fb 100644 --- a/qiskit_experiments/library/mitigation/__init__.py +++ b/qiskit_experiments/library/mitigation/__init__.py @@ -23,7 +23,8 @@ :toctree: ../stubs/ :template: autosummary/experiment.rst - ReadoutMitigationExperiment + CorrelatedReadoutMitigationExperiment + LocalReadoutMitigationExperiment Analysis @@ -36,6 +37,7 @@ CorrelatedMitigationAnalysis LocalMitigationAnalysis """ -from .correlated_mitigation_experiment import ReadoutMitigationExperiment +from .correlated_mitigation_experiment import CorrelatedReadoutMitigationExperiment +from .local_mitigation_experiment import LocalReadoutMitigationExperiment from .correlated_mitigation_analysis import CorrelatedMitigationAnalysis -from .correlated_mitigation_analysis import LocalMitigationAnalysis +from .local_mitigation_analysis import LocalMitigationAnalysis From aee85caf88e7fc942b4779e26bd5ccd56cfa1b59 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Mon, 17 Jan 2022 09:45:48 +0200 Subject: [PATCH 04/32] Changing the test file to accomodate experiments split --- test/test_mitigation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_mitigation.py b/test/test_mitigation.py index 92acaa5a7b..b0714091d0 100644 --- a/test/test_mitigation.py +++ b/test/test_mitigation.py @@ -19,7 +19,7 @@ from test.base import QiskitExperimentsTestCase import numpy as np from qiskit.quantum_info.operators.predicates import matrix_equal -from qiskit_experiments.library import ReadoutMitigationExperiment +from qiskit_experiments.library import LocalReadoutMitigationExperiment, CorrelatedReadoutMitigationExperiment from qiskit_experiments.framework import ExperimentData @@ -50,7 +50,7 @@ def test_local_analysis(self): expdata = ExperimentData() expdata.add_data(run_data) expdata._metadata = run_meta - exp = ReadoutMitigationExperiment(qubits) + exp = LocalReadoutMitigationExperiment(qubits) result = exp.analysis.run(expdata) mitigator = result.analysis_results(0).value @@ -120,7 +120,7 @@ def test_correlated_analysis(self): expdata = ExperimentData() expdata.add_data(run_data) expdata._metadata = run_meta - exp = ReadoutMitigationExperiment(qubits, method="correlated") + exp = CorrelatedReadoutMitigationExperiment(qubits) result = exp.analysis.run(expdata) mitigator = result.analysis_results(0).value From 410774cecc4c7dde3ac5b5cbe31fe2500ab0d834 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Mon, 17 Jan 2022 13:47:53 +0200 Subject: [PATCH 05/32] Splitting the existing documentation --- qiskit_experiments/library/__init__.py | 2 +- .../correlated_mitigation_experiment.py | 33 +++++-------------- .../mitigation/local_mitigation_experiment.py | 31 +++++------------ 3 files changed, 17 insertions(+), 49 deletions(-) diff --git a/qiskit_experiments/library/__init__.py b/qiskit_experiments/library/__init__.py index 08dd8b22dc..6ec674e65c 100644 --- a/qiskit_experiments/library/__init__.py +++ b/qiskit_experiments/library/__init__.py @@ -142,7 +142,7 @@ class instance to manage parameters and pulse schedules. from .randomized_benchmarking import StandardRB, InterleavedRB from .tomography import StateTomography, ProcessTomography from .quantum_volume import QuantumVolume -from .mitigation import ReadoutMitigationExperiment +from .mitigation import LocalReadoutMitigationExperiment, CorrelatedReadoutMitigationExperiment # Experiment Sub-modules from . import calibration diff --git a/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py b/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py index 5b8f475d52..5b6fec0d3a 100644 --- a/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py +++ b/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py @@ -31,37 +31,20 @@ class CorrelatedReadoutMitigationExperiment(BaseExperiment): to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used to compute the *mitigation matrix* used in the mitigation process itself. - - A readout mitigation experiment aims to determine the assignment matrix - for the readout error in a given device, and generate a corresponding mitigator - based on the `qiskit-terra` classes of `Correlated readout mitigator - _` - and `Local readout mitigator - _` - A *Correlated readout mitigator* uses the full :math:`2^n\times 2^n` assignment matrix, meaning it can only be used for small values of :math:`n`. + The corresponding class in Qiskit is the `Correlated readout mitigator + _` + in `qiskit-terra`. - A *Local readout mitigator* works under the assumption the readout errors are mostly *local*, meaning - readout errors for different qubits are independent of each other. In this case, the assignment matrix - is the tensor product of :math:`n` :math:`2\times 2` matrices, one for each qubit, making it practical - to store the assignment matrix in implicit form, by storing the individual :math:`2\times 2` assignment matrices. - - The readout mitigation experiment can be passed a `method` parameter to determine - which method will be used (and which mitigator will be returned): The default `local` method - or the `correlated` method. - - In the `local` method, the experiment generates 2 circuits, corresponding to the states - :math:`|0^n>` and :math:`|1^n>`, measuring the error in all the qubits at once. - - In the `correlated` method, the experiment generates :math:`2^n` circuits, for every possible - :math:`n`-qubit quantum state. + The experiment generates :math:`2^n` circuits, for every possible + :math:`n`-qubit quantum state and constructs + the assignment matrix and correlated mitigator from the results. - See :class:`LocalMitigationAnalysis` and :class:`CorrelatedMitigationAnalysis` - documentation for additional information on readout mitigation experiment analysis. + See :class:`CorrelatedMitigationAnalysis` + documentation for additional information on correlated readout mitigation experiment analysis. # section: analysis_ref - :py:class:`LocalMitigationAnalysis` :py:class:`CorrelatedMitigationAnalysis` # section: reference diff --git a/qiskit_experiments/library/mitigation/local_mitigation_experiment.py b/qiskit_experiments/library/mitigation/local_mitigation_experiment.py index ce5c2094cb..f042735eb7 100644 --- a/qiskit_experiments/library/mitigation/local_mitigation_experiment.py +++ b/qiskit_experiments/library/mitigation/local_mitigation_experiment.py @@ -13,7 +13,6 @@ Local readout mitigation calibration experiment class. """ from typing import Iterable, List - from qiskit import QuantumCircuit from qiskit_experiments.framework import BaseExperiment from .local_mitigation_analysis import LocalMitigationAnalysis @@ -32,37 +31,23 @@ class LocalReadoutMitigationExperiment(BaseExperiment): to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used to compute the *mitigation matrix* used in the mitigation process itself. - A readout mitigation experiment aims to determine the assignment matrix - for the readout error in a given device, and generate a corresponding mitigator - based on the `qiskit-terra` classes of `Correlated readout mitigator - _` - and `Local readout mitigator - _` - - A *Correlated readout mitigator* uses the full :math:`2^n\times 2^n` assignment matrix, meaning - it can only be used for small values of :math:`n`. - A *Local readout mitigator* works under the assumption the readout errors are mostly *local*, meaning readout errors for different qubits are independent of each other. In this case, the assignment matrix is the tensor product of :math:`n` :math:`2\times 2` matrices, one for each qubit, making it practical to store the assignment matrix in implicit form, by storing the individual :math:`2\times 2` assignment matrices. + The corresponding class in Qiskit is the `Local readout mitigator + _` + in `qiskit-terra`. - The readout mitigation experiment can be passed a `method` parameter to determine - which method will be used (and which mitigator will be returned): The default `local` method - or the `correlated` method. - - In the `local` method, the experiment generates 2 circuits, corresponding to the states - :math:`|0^n>` and :math:`|1^n>`, measuring the error in all the qubits at once. - - In the `correlated` method, the experiment generates :math:`2^n` circuits, for every possible - :math:`n`-qubit quantum state. + The experiment generates 2 circuits, corresponding to the states + :math:`|0^n>` and :math:`|1^n>`, measuring the error in all the qubits at once, and constructs + the assignment matrix and local mitigator from the results. - See :class:`LocalMitigationAnalysis` and :class:`CorrelatedMitigationAnalysis` - documentation for additional information on readout mitigation experiment analysis. + See :class:`LocalMitigationAnalysis` + documentation for additional information on local readout mitigation experiment analysis. # section: analysis_ref :py:class:`LocalMitigationAnalysis` - :py:class:`CorrelatedMitigationAnalysis` # section: reference .. ref_arxiv:: 1 2006.14044 From 20bd3edfada7e7d10756c36ef7785ead5e3da8c3 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Mon, 17 Jan 2022 13:52:54 +0200 Subject: [PATCH 06/32] Small documentation fixes --- .../correlated_mitigation_experiment.py | 8 -------- qiskit_experiments/library/mitigation/utils.py | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py b/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py index 5b6fec0d3a..03f7e4d913 100644 --- a/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py +++ b/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py @@ -55,14 +55,6 @@ def __init__(self, qubits: Iterable[int]): Args: qubits: The qubits being mitigated - - Additional info: - The currently supported mitigation methods are: - * "local": each qubit is mitigated by itself; this is the default method, - and assumes readout errors are independent for each qubits - * "correlated": All the qubits are mitigated together; this results in an exponentially - large mitigation matrix and so is useable only for a small number of qubits, - but might be more accurate than local mitigation. """ super().__init__(qubits) self.analysis = CorrelatedMitigationAnalysis() diff --git a/qiskit_experiments/library/mitigation/utils.py b/qiskit_experiments/library/mitigation/utils.py index 76821c1c79..6e93cf17b6 100644 --- a/qiskit_experiments/library/mitigation/utils.py +++ b/qiskit_experiments/library/mitigation/utils.py @@ -1,6 +1,19 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2022. +# +# 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. +""" +Utility functions for readout mitigation experiments +""" from qiskit import QuantumCircuit - def calibration_circuit(num_qubits: int, label: str) -> QuantumCircuit: """Return a calibration circuit. From f745194bd0ca1be4e4cbd96cc148f5583152633f Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Mon, 17 Jan 2022 13:59:44 +0200 Subject: [PATCH 07/32] Class renaming "readout mitigation" => "readout error" --- qiskit_experiments/library/__init__.py | 2 +- .../library/mitigation/__init__.py | 16 ++++++++-------- ...s.py => correlated_readout_error_analysis.py} | 2 +- ...py => correlated_readout_error_experiment.py} | 8 ++++---- ...alysis.py => local_readout_error_analysis.py} | 2 +- ...ment.py => local_readout_error_experiment.py} | 8 ++++---- test/test_mitigation.py | 6 +++--- 7 files changed, 22 insertions(+), 22 deletions(-) rename qiskit_experiments/library/mitigation/{correlated_mitigation_analysis.py => correlated_readout_error_analysis.py} (98%) rename qiskit_experiments/library/mitigation/{correlated_mitigation_experiment.py => correlated_readout_error_experiment.py} (91%) rename qiskit_experiments/library/mitigation/{local_mitigation_analysis.py => local_readout_error_analysis.py} (98%) rename qiskit_experiments/library/mitigation/{local_mitigation_experiment.py => local_readout_error_experiment.py} (92%) diff --git a/qiskit_experiments/library/__init__.py b/qiskit_experiments/library/__init__.py index 6ec674e65c..8c81fb268d 100644 --- a/qiskit_experiments/library/__init__.py +++ b/qiskit_experiments/library/__init__.py @@ -142,7 +142,7 @@ class instance to manage parameters and pulse schedules. from .randomized_benchmarking import StandardRB, InterleavedRB from .tomography import StateTomography, ProcessTomography from .quantum_volume import QuantumVolume -from .mitigation import LocalReadoutMitigationExperiment, CorrelatedReadoutMitigationExperiment +from .mitigation import LocalReadoutErrorExperiment, CorrelatedReadoutErrorExperiment # Experiment Sub-modules from . import calibration diff --git a/qiskit_experiments/library/mitigation/__init__.py b/qiskit_experiments/library/mitigation/__init__.py index 6761f1c6fb..f7ea5bb4ed 100644 --- a/qiskit_experiments/library/mitigation/__init__.py +++ b/qiskit_experiments/library/mitigation/__init__.py @@ -23,8 +23,8 @@ :toctree: ../stubs/ :template: autosummary/experiment.rst - CorrelatedReadoutMitigationExperiment - LocalReadoutMitigationExperiment + CorrelatedReadoutErrorExperiment + LocalReadoutErrorExperiment Analysis @@ -34,10 +34,10 @@ :toctree: ../stubs/ :template: autosummary/analysis.rst - CorrelatedMitigationAnalysis - LocalMitigationAnalysis + CorrelatedReadoutErrorAnalysis + LocalReadoutErrorAnalysis """ -from .correlated_mitigation_experiment import CorrelatedReadoutMitigationExperiment -from .local_mitigation_experiment import LocalReadoutMitigationExperiment -from .correlated_mitigation_analysis import CorrelatedMitigationAnalysis -from .local_mitigation_analysis import LocalMitigationAnalysis +from .correlated_readout_error_experiment import CorrelatedReadoutErrorExperiment +from .local_readout_error_experiment import LocalReadoutErrorExperiment +from .correlated_readout_error_analysis import CorrelatedReadoutErrorAnalysis +from .local_readout_error_analysis import LocalReadoutErrorAnalysis diff --git a/qiskit_experiments/library/mitigation/correlated_mitigation_analysis.py b/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py similarity index 98% rename from qiskit_experiments/library/mitigation/correlated_mitigation_analysis.py rename to qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py index 3a8694559c..fa09e443e3 100644 --- a/qiskit_experiments/library/mitigation/correlated_mitigation_analysis.py +++ b/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py @@ -21,7 +21,7 @@ from qiskit_experiments.framework import BaseAnalysis, AnalysisResultData, Options -class CorrelatedMitigationAnalysis(BaseAnalysis): +class CorrelatedReadoutErrorAnalysis(BaseAnalysis): """ Measurement correction analysis for a full calibration """ diff --git a/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py b/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py similarity index 91% rename from qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py rename to qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py index 03f7e4d913..1ae202ae70 100644 --- a/qiskit_experiments/library/mitigation/correlated_mitigation_experiment.py +++ b/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py @@ -15,11 +15,11 @@ from typing import Iterable, List from qiskit import QuantumCircuit from qiskit_experiments.framework import BaseExperiment -from .correlated_mitigation_analysis import CorrelatedMitigationAnalysis +from .correlated_readout_error_analysis import CorrelatedReadoutErrorAnalysis from .utils import calibration_circuit -class CorrelatedReadoutMitigationExperiment(BaseExperiment): - """Class for correlated readout mitigation experiment +class CorrelatedReadoutErrorExperiment(BaseExperiment): + """Class for correlated readout error characterization experiment # section: overview Readout mitigation aims to reduce the effect of errors during the measurement of the qubits in a quantum device. It is used both to obtain a more accurate @@ -57,7 +57,7 @@ def __init__(self, qubits: Iterable[int]): qubits: The qubits being mitigated """ super().__init__(qubits) - self.analysis = CorrelatedMitigationAnalysis() + self.analysis = CorrelatedReadoutErrorAnalysis() def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" diff --git a/qiskit_experiments/library/mitigation/local_mitigation_analysis.py b/qiskit_experiments/library/mitigation/local_readout_error_analysis.py similarity index 98% rename from qiskit_experiments/library/mitigation/local_mitigation_analysis.py rename to qiskit_experiments/library/mitigation/local_readout_error_analysis.py index 6aa9240404..bb891862d4 100644 --- a/qiskit_experiments/library/mitigation/local_mitigation_analysis.py +++ b/qiskit_experiments/library/mitigation/local_readout_error_analysis.py @@ -21,7 +21,7 @@ from qiskit_experiments.framework.matplotlib import get_non_gui_ax from qiskit_experiments.framework import BaseAnalysis, AnalysisResultData, Options -class LocalMitigationAnalysis(BaseAnalysis): +class LocalReadoutErrorAnalysis(BaseAnalysis): """ Measurement correction analysis for a full calibration """ diff --git a/qiskit_experiments/library/mitigation/local_mitigation_experiment.py b/qiskit_experiments/library/mitigation/local_readout_error_experiment.py similarity index 92% rename from qiskit_experiments/library/mitigation/local_mitigation_experiment.py rename to qiskit_experiments/library/mitigation/local_readout_error_experiment.py index f042735eb7..7d181b0cb5 100644 --- a/qiskit_experiments/library/mitigation/local_mitigation_experiment.py +++ b/qiskit_experiments/library/mitigation/local_readout_error_experiment.py @@ -15,11 +15,11 @@ from typing import Iterable, List from qiskit import QuantumCircuit from qiskit_experiments.framework import BaseExperiment -from .local_mitigation_analysis import LocalMitigationAnalysis +from .local_readout_error_analysis import LocalReadoutErrorAnalysis from .utils import calibration_circuit -class LocalReadoutMitigationExperiment(BaseExperiment): - """Class for local readout mitigation experiments +class LocalReadoutErrorExperiment(BaseExperiment): + """Class for local readout error characterization experiment # section: overview Readout mitigation aims to reduce the effect of errors during the measurement of the qubits in a quantum device. It is used both to obtain a more accurate @@ -60,7 +60,7 @@ def __init__(self, qubits: Iterable[int]): qubits: The qubits being mitigated """ super().__init__(qubits) - self.analysis = LocalMitigationAnalysis() + self.analysis = LocalReadoutErrorAnalysis() def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" diff --git a/test/test_mitigation.py b/test/test_mitigation.py index b0714091d0..e700ead189 100644 --- a/test/test_mitigation.py +++ b/test/test_mitigation.py @@ -19,7 +19,7 @@ from test.base import QiskitExperimentsTestCase import numpy as np from qiskit.quantum_info.operators.predicates import matrix_equal -from qiskit_experiments.library import LocalReadoutMitigationExperiment, CorrelatedReadoutMitigationExperiment +from qiskit_experiments.library import LocalReadoutErrorExperiment, CorrelatedReadoutErrorExperiment from qiskit_experiments.framework import ExperimentData @@ -50,7 +50,7 @@ def test_local_analysis(self): expdata = ExperimentData() expdata.add_data(run_data) expdata._metadata = run_meta - exp = LocalReadoutMitigationExperiment(qubits) + exp = LocalReadoutErrorExperiment(qubits) result = exp.analysis.run(expdata) mitigator = result.analysis_results(0).value @@ -120,7 +120,7 @@ def test_correlated_analysis(self): expdata = ExperimentData() expdata.add_data(run_data) expdata._metadata = run_meta - exp = CorrelatedReadoutMitigationExperiment(qubits) + exp = CorrelatedReadoutErrorExperiment(qubits) result = exp.analysis.run(expdata) mitigator = result.analysis_results(0).value From f2677d2733955d7f27d2a313ac5297836c20b538 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Mon, 17 Jan 2022 16:11:58 +0200 Subject: [PATCH 08/32] Analysis classes docs --- .../correlated_readout_error_analysis.py | 43 +++++++++++++++++-- .../correlated_readout_error_experiment.py | 2 +- .../local_readout_error_analysis.py | 25 ++++++++++- .../local_readout_error_experiment.py | 2 +- 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py b/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py index fa09e443e3..48c5ee248b 100644 --- a/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py +++ b/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py @@ -23,9 +23,43 @@ class CorrelatedReadoutErrorAnalysis(BaseAnalysis): """ - Measurement correction analysis for a full calibration + Correlated readout error characterization anaylsis + + # section: overview + + This class generates the full assignment matrix :math:`A` characterizing the + readout error for the given qubits from the experiment results. + + :math:`A` is a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` + is the probability to observe :math:`y` given the true outcome should be :math:`x`. + + In the experiment, for each :math:`x`a circuit is constructed whose expected + outcome is :math:`x`. From the observed results on the circuit, the probability for + each :math:`y` is determined, and :math:`A_{y,x}` is set accordingly. + + + # section: return value + * The `Correlated readout error mitigator _` + object (the assignment matrix can be access via its `assignment_matrix()` method). + * (Optional) A figure of the assignment matrix. + + # section: reference + .. ref_arxiv:: 1 2006.14044 """ + @classmethod + def _default_options(cls) -> Options: + """Return default analysis options. + + Analysis Options: + plot (bool): Set ``True`` to create figure for fit result. + ax (AxesSubplot): Optional. A matplotlib axis object to draw. + """ + options = super()._default_options() + options.plot = False + options.ax = None + return options + def _run_analysis( self, experiment_data: ExperimentData, **options ) -> Tuple[List[AnalysisResultData], List["matplotlib.figure.Figure"]]: @@ -35,8 +69,11 @@ def _run_analysis( matrix = self._generate_matrix(data, labels) result_mitigator = CorrelatedReadoutMitigator(matrix, qubits=qubits) analysis_results = [AnalysisResultData("Correlated Readout Mitigator", result_mitigator)] - ax = options.get("ax", None) - figures = [self._plot_calibration(matrix, labels, ax)] + if self.options.plot: + ax = options.get("ax", None) + figures = [self._plot_calibration(matrix, labels, ax)] + else: + figures = None return analysis_results, figures def _generate_matrix(self, data, labels) -> np.array: diff --git a/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py b/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py index 1ae202ae70..f528444d5a 100644 --- a/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py +++ b/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py @@ -54,7 +54,7 @@ def __init__(self, qubits: Iterable[int]): """Initialize a correlated readout mitigation calibration experiment. Args: - qubits: The qubits being mitigated + qubits: The qubits being characterized for readout error """ super().__init__(qubits) self.analysis = CorrelatedReadoutErrorAnalysis() diff --git a/qiskit_experiments/library/mitigation/local_readout_error_analysis.py b/qiskit_experiments/library/mitigation/local_readout_error_analysis.py index bb891862d4..b6be5edb30 100644 --- a/qiskit_experiments/library/mitigation/local_readout_error_analysis.py +++ b/qiskit_experiments/library/mitigation/local_readout_error_analysis.py @@ -23,7 +23,28 @@ class LocalReadoutErrorAnalysis(BaseAnalysis): """ - Measurement correction analysis for a full calibration + Local readout error characterization anaylsis + # section: overview + + This class generates the assignment matrices characterizing the + readout error for each of the given qubits from the experiment results. + + Each such matrix is a :math:`2\times 2` matrix :math:`A`. Such that :math:`A_{y,x}` + is the probability to observe :math:`y` given the true outcome should be :math:`x`, + where :math:`x,y\in\left\{0,1\right\}`. + + In the experiment, two circuits are constructed - one for 0 outcome for all + qubits and one for 1 outcome. From the observed results on the circuit, the probability for + each :math:`x,y` is determined, and :math:`A_{y,x}` is set accordingly. + + + # section: return value + * The `Local readout error mitigator _` + object (the assignment matrix can be access via its `assignment_matrix()` method). + * (Optional) A figure of the assignment matrix. + + # section: reference + .. ref_arxiv:: 1 2006.14044 """ @classmethod @@ -35,7 +56,7 @@ def _default_options(cls) -> Options: ax(AxesSubplot): Optional. A matplotlib axis object to draw. """ options = super()._default_options() - options.plot = True + options.plot = False options.ax = None return options diff --git a/qiskit_experiments/library/mitigation/local_readout_error_experiment.py b/qiskit_experiments/library/mitigation/local_readout_error_experiment.py index 7d181b0cb5..3b184c887b 100644 --- a/qiskit_experiments/library/mitigation/local_readout_error_experiment.py +++ b/qiskit_experiments/library/mitigation/local_readout_error_experiment.py @@ -57,7 +57,7 @@ def __init__(self, qubits: Iterable[int]): """Initialize a local readout mitigation calibration experiment. Args: - qubits: The qubits being mitigated + qubits: The qubits being characterized for readout error """ super().__init__(qubits) self.analysis = LocalReadoutErrorAnalysis() From 1a382abfa1608a78cdbd1a4c71dc4c387cc08257 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Mon, 17 Jan 2022 16:13:42 +0200 Subject: [PATCH 09/32] Linting --- .../library/mitigation/correlated_readout_error_analysis.py | 2 +- .../library/mitigation/correlated_readout_error_experiment.py | 4 +++- .../library/mitigation/local_readout_error_analysis.py | 1 + .../library/mitigation/local_readout_error_experiment.py | 3 ++- qiskit_experiments/library/mitigation/utils.py | 3 ++- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py b/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py index 48c5ee248b..63dea75338 100644 --- a/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py +++ b/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py @@ -118,4 +118,4 @@ def _plot_calibration(self, matrix, labels, ax=None) -> "matplotlib.figure.Figur ax.set_yticks(np.arange(len(labels))) ax.set_xticklabels(labels) ax.set_yticklabels(labels) - return figure \ No newline at end of file + return figure diff --git a/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py b/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py index f528444d5a..74bdc494cc 100644 --- a/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py +++ b/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py @@ -18,6 +18,7 @@ from .correlated_readout_error_analysis import CorrelatedReadoutErrorAnalysis from .utils import calibration_circuit + class CorrelatedReadoutErrorExperiment(BaseExperiment): """Class for correlated readout error characterization experiment # section: overview @@ -50,6 +51,7 @@ class CorrelatedReadoutErrorExperiment(BaseExperiment): # section: reference .. ref_arxiv:: 1 2006.14044 """ + def __init__(self, qubits: Iterable[int]): """Initialize a correlated readout mitigation calibration experiment. @@ -62,4 +64,4 @@ def __init__(self, qubits: Iterable[int]): def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" labels = [bin(j)[2:].zfill(self.num_qubits) for j in range(2 ** self.num_qubits)] - return [calibration_circuit(self.num_qubits, label) for label in self.helper.labels()] \ No newline at end of file + return [calibration_circuit(self.num_qubits, label) for label in self.helper.labels()] diff --git a/qiskit_experiments/library/mitigation/local_readout_error_analysis.py b/qiskit_experiments/library/mitigation/local_readout_error_analysis.py index b6be5edb30..a50a80120a 100644 --- a/qiskit_experiments/library/mitigation/local_readout_error_analysis.py +++ b/qiskit_experiments/library/mitigation/local_readout_error_analysis.py @@ -21,6 +21,7 @@ from qiskit_experiments.framework.matplotlib import get_non_gui_ax from qiskit_experiments.framework import BaseAnalysis, AnalysisResultData, Options + class LocalReadoutErrorAnalysis(BaseAnalysis): """ Local readout error characterization anaylsis diff --git a/qiskit_experiments/library/mitigation/local_readout_error_experiment.py b/qiskit_experiments/library/mitigation/local_readout_error_experiment.py index 3b184c887b..010601c077 100644 --- a/qiskit_experiments/library/mitigation/local_readout_error_experiment.py +++ b/qiskit_experiments/library/mitigation/local_readout_error_experiment.py @@ -18,6 +18,7 @@ from .local_readout_error_analysis import LocalReadoutErrorAnalysis from .utils import calibration_circuit + class LocalReadoutErrorExperiment(BaseExperiment): """Class for local readout error characterization experiment # section: overview @@ -65,4 +66,4 @@ def __init__(self, qubits: Iterable[int]): def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" labels = ["0" * self.num_qubits, "1" * self.num_qubits] - return [calibration_circuit(self.num_qubits, label) for label in labels()] \ No newline at end of file + return [calibration_circuit(self.num_qubits, label) for label in labels()] diff --git a/qiskit_experiments/library/mitigation/utils.py b/qiskit_experiments/library/mitigation/utils.py index 6e93cf17b6..2712639a9f 100644 --- a/qiskit_experiments/library/mitigation/utils.py +++ b/qiskit_experiments/library/mitigation/utils.py @@ -14,6 +14,7 @@ """ from qiskit import QuantumCircuit + def calibration_circuit(num_qubits: int, label: str) -> QuantumCircuit: """Return a calibration circuit. @@ -27,4 +28,4 @@ def calibration_circuit(num_qubits: int, label: str) -> QuantumCircuit: circ.x(i) circ.measure_all() circ.metadata = {"label": label} - return circ \ No newline at end of file + return circ From 694c291340b2c7224e26ffd67aa5d03c891b5e82 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Mon, 17 Jan 2022 16:39:16 +0200 Subject: [PATCH 10/32] Moving readout error experiments to characterization library --- qiskit_experiments/library/__init__.py | 5 ++- .../library/characterization/__init__.py | 15 +++++++ .../characterization/analysis/__init__.py | 2 + .../correlated_readout_error_analysis.py | 2 +- .../analysis}/local_readout_error_analysis.py | 2 +- .../correlated_readout_error_experiment.py | 34 +++++++++++---- .../local_readout_error_experiment.py | 34 +++++++++++---- .../library/mitigation/__init__.py | 43 ------------------- .../library/mitigation/utils.py | 31 ------------- ...st_mitigation.py => test_readout_error.py} | 8 ++-- 10 files changed, 77 insertions(+), 99 deletions(-) rename qiskit_experiments/library/{mitigation => characterization/analysis}/correlated_readout_error_analysis.py (98%) rename qiskit_experiments/library/{mitigation => characterization/analysis}/local_readout_error_analysis.py (98%) rename qiskit_experiments/library/{mitigation => characterization}/correlated_readout_error_experiment.py (66%) rename qiskit_experiments/library/{mitigation => characterization}/local_readout_error_experiment.py (69%) delete mode 100644 qiskit_experiments/library/mitigation/__init__.py delete mode 100644 qiskit_experiments/library/mitigation/utils.py rename test/{test_mitigation.py => test_readout_error.py} (95%) diff --git a/qiskit_experiments/library/__init__.py b/qiskit_experiments/library/__init__.py index 8c81fb268d..d3c4a332d6 100644 --- a/qiskit_experiments/library/__init__.py +++ b/qiskit_experiments/library/__init__.py @@ -71,6 +71,8 @@ ~characterization.RamseyXY ~characterization.FineFrequency ~characterization.ReadoutAngle + ~characterization.LocalReadoutError + ~characterization.CorrelatedReadoutError .. _calibration: @@ -138,11 +140,12 @@ class instance to manage parameters and pulse schedules. RamseyXY, FineFrequency, ReadoutAngle, + LocalReadoutError, + CorrelatedReadoutError, ) from .randomized_benchmarking import StandardRB, InterleavedRB from .tomography import StateTomography, ProcessTomography from .quantum_volume import QuantumVolume -from .mitigation import LocalReadoutErrorExperiment, CorrelatedReadoutErrorExperiment # Experiment Sub-modules from . import calibration diff --git a/qiskit_experiments/library/characterization/__init__.py b/qiskit_experiments/library/characterization/__init__.py index b845af4d3a..b0bb48db5e 100644 --- a/qiskit_experiments/library/characterization/__init__.py +++ b/qiskit_experiments/library/characterization/__init__.py @@ -41,6 +41,8 @@ FineDrag FineXDrag FineSXDrag + LocalReadoutError + CorrelatedReadoutError Analysis @@ -59,6 +61,14 @@ FineAmplitudeAnalysis RamseyXYAnalysis ReadoutAngleAnalysis + LocalReadoutErrorAnalysis + CorrelatedReadoutErrorAnalysis, + + +.. autosummary:: + :toctree: ../stubs/ + :template: autosummary/analysis.rst + """ from .analysis import ( @@ -71,8 +81,11 @@ T1Analysis, CrossResonanceHamiltonianAnalysis, ReadoutAngleAnalysis, + CorrelatedReadoutErrorAnalysis, + LocalReadoutErrorAnalysis, ) + from .t1 import T1 from .qubit_spectroscopy import QubitSpectroscopy from .ef_spectroscopy import EFSpectroscopy @@ -86,3 +99,5 @@ from .drag import RoughDrag from .readout_angle import ReadoutAngle from .fine_drag import FineDrag, FineXDrag, FineSXDrag +from .local_readout_error_experiment import LocalReadoutError +from .correlated_readout_error_experiment import CorrelatedReadoutError diff --git a/qiskit_experiments/library/characterization/analysis/__init__.py b/qiskit_experiments/library/characterization/analysis/__init__.py index e100871223..84ddbeb92c 100644 --- a/qiskit_experiments/library/characterization/analysis/__init__.py +++ b/qiskit_experiments/library/characterization/analysis/__init__.py @@ -22,3 +22,5 @@ from .t1_analysis import T1Analysis from .cr_hamiltonian_analysis import CrossResonanceHamiltonianAnalysis from .readout_angle_analysis import ReadoutAngleAnalysis +from .local_readout_error_analysis import LocalReadoutErrorAnalysis +from .correlated_readout_error_analysis import CorrelatedReadoutErrorAnalysis diff --git a/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py similarity index 98% rename from qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py rename to qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py index 63dea75338..2a7dc1ceca 100644 --- a/qiskit_experiments/library/mitigation/correlated_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py @@ -10,7 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """ -Correlated readout mitigation calibration analysis classes +Correlated readout readout_error calibration analysis classes """ from typing import List, Tuple import numpy as np diff --git a/qiskit_experiments/library/mitigation/local_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py similarity index 98% rename from qiskit_experiments/library/mitigation/local_readout_error_analysis.py rename to qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py index a50a80120a..9018b38180 100644 --- a/qiskit_experiments/library/mitigation/local_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py @@ -10,7 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """ -Local readout mitigation calibration analysis class +Local readout readout_error calibration analysis class """ from typing import List, Tuple import numpy as np diff --git a/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py b/qiskit_experiments/library/characterization/correlated_readout_error_experiment.py similarity index 66% rename from qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py rename to qiskit_experiments/library/characterization/correlated_readout_error_experiment.py index 74bdc494cc..151ecada58 100644 --- a/qiskit_experiments/library/mitigation/correlated_readout_error_experiment.py +++ b/qiskit_experiments/library/characterization/correlated_readout_error_experiment.py @@ -10,19 +10,20 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """ -Correlated readout mitigation calibration experiment class. +Correlated readout readout_error calibration experiment class. """ from typing import Iterable, List from qiskit import QuantumCircuit from qiskit_experiments.framework import BaseExperiment -from .correlated_readout_error_analysis import CorrelatedReadoutErrorAnalysis -from .utils import calibration_circuit +from qiskit_experiments.library.characterization.analysis.correlated_readout_error_analysis import ( + CorrelatedReadoutErrorAnalysis, +) -class CorrelatedReadoutErrorExperiment(BaseExperiment): +class CorrelatedReadoutError(BaseExperiment): """Class for correlated readout error characterization experiment # section: overview - Readout mitigation aims to reduce the effect of errors during the measurement + Readout readout_error aims to reduce the effect of errors during the measurement of the qubits in a quantum device. It is used both to obtain a more accurate distribution of the outputs, and more accurate measurements of expectation value for measurables. @@ -30,7 +31,7 @@ class CorrelatedReadoutErrorExperiment(BaseExperiment): The readout mitigator is generated from an *assignment matrix*: a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the probability to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used - to compute the *mitigation matrix* used in the mitigation process itself. + to compute the *readout_error matrix* used in the readout_error process itself. A *Correlated readout mitigator* uses the full :math:`2^n\times 2^n` assignment matrix, meaning it can only be used for small values of :math:`n`. @@ -43,7 +44,7 @@ class CorrelatedReadoutErrorExperiment(BaseExperiment): the assignment matrix and correlated mitigator from the results. See :class:`CorrelatedMitigationAnalysis` - documentation for additional information on correlated readout mitigation experiment analysis. + documentation for additional information on correlated readout readout_error experiment analysis. # section: analysis_ref :py:class:`CorrelatedMitigationAnalysis` @@ -53,7 +54,7 @@ class CorrelatedReadoutErrorExperiment(BaseExperiment): """ def __init__(self, qubits: Iterable[int]): - """Initialize a correlated readout mitigation calibration experiment. + """Initialize a correlated readout readout_error calibration experiment. Args: qubits: The qubits being characterized for readout error @@ -64,4 +65,19 @@ def __init__(self, qubits: Iterable[int]): def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" labels = [bin(j)[2:].zfill(self.num_qubits) for j in range(2 ** self.num_qubits)] - return [calibration_circuit(self.num_qubits, label) for label in self.helper.labels()] + return [self.calibration_circuit(self.num_qubits, label) for label in self.helper.labels()] + + def calibration_circuit(num_qubits: int, label: str) -> QuantumCircuit: + """Return a calibration circuit. + + This is an N-qubit circuit where N is the length of the label. + The circuit consists of X-gates on qubits with label bits equal to 1, + and measurements of all qubits. + """ + circ = QuantumCircuit(num_qubits, name="meas_mit_cal_" + label) + for i, val in enumerate(reversed(label)): + if val == "1": + circ.x(i) + circ.measure_all() + circ.metadata = {"label": label} + return circ diff --git a/qiskit_experiments/library/mitigation/local_readout_error_experiment.py b/qiskit_experiments/library/characterization/local_readout_error_experiment.py similarity index 69% rename from qiskit_experiments/library/mitigation/local_readout_error_experiment.py rename to qiskit_experiments/library/characterization/local_readout_error_experiment.py index 010601c077..b18fdab3fb 100644 --- a/qiskit_experiments/library/mitigation/local_readout_error_experiment.py +++ b/qiskit_experiments/library/characterization/local_readout_error_experiment.py @@ -10,19 +10,20 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """ -Local readout mitigation calibration experiment class. +Local readout readout_error calibration experiment class. """ from typing import Iterable, List from qiskit import QuantumCircuit from qiskit_experiments.framework import BaseExperiment -from .local_readout_error_analysis import LocalReadoutErrorAnalysis -from .utils import calibration_circuit +from qiskit_experiments.library.characterization.analysis.local_readout_error_analysis import ( + LocalReadoutErrorAnalysis, +) -class LocalReadoutErrorExperiment(BaseExperiment): +class LocalReadoutError(BaseExperiment): """Class for local readout error characterization experiment # section: overview - Readout mitigation aims to reduce the effect of errors during the measurement + Readout readout_error aims to reduce the effect of errors during the measurement of the qubits in a quantum device. It is used both to obtain a more accurate distribution of the outputs, and more accurate measurements of expectation value for measurables. @@ -30,7 +31,7 @@ class LocalReadoutErrorExperiment(BaseExperiment): The readout mitigator is generated from an *assignment matrix*: a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the probability to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used - to compute the *mitigation matrix* used in the mitigation process itself. + to compute the *readout_error matrix* used in the readout_error process itself. A *Local readout mitigator* works under the assumption the readout errors are mostly *local*, meaning readout errors for different qubits are independent of each other. In this case, the assignment matrix @@ -45,7 +46,7 @@ class LocalReadoutErrorExperiment(BaseExperiment): the assignment matrix and local mitigator from the results. See :class:`LocalMitigationAnalysis` - documentation for additional information on local readout mitigation experiment analysis. + documentation for additional information on local readout readout_error experiment analysis. # section: analysis_ref :py:class:`LocalMitigationAnalysis` @@ -55,7 +56,7 @@ class LocalReadoutErrorExperiment(BaseExperiment): """ def __init__(self, qubits: Iterable[int]): - """Initialize a local readout mitigation calibration experiment. + """Initialize a local readout readout_error calibration experiment. Args: qubits: The qubits being characterized for readout error @@ -66,4 +67,19 @@ def __init__(self, qubits: Iterable[int]): def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" labels = ["0" * self.num_qubits, "1" * self.num_qubits] - return [calibration_circuit(self.num_qubits, label) for label in labels()] + return [self.calibration_circuit(self.num_qubits, label) for label in labels()] + + def calibration_circuit(num_qubits: int, label: str) -> QuantumCircuit: + """Return a calibration circuit. + + This is an N-qubit circuit where N is the length of the label. + The circuit consists of X-gates on qubits with label bits equal to 1, + and measurements of all qubits. + """ + circ = QuantumCircuit(num_qubits, name="meas_mit_cal_" + label) + for i, val in enumerate(reversed(label)): + if val == "1": + circ.x(i) + circ.measure_all() + circ.metadata = {"label": label} + return circ diff --git a/qiskit_experiments/library/mitigation/__init__.py b/qiskit_experiments/library/mitigation/__init__.py deleted file mode 100644 index f7ea5bb4ed..0000000000 --- a/qiskit_experiments/library/mitigation/__init__.py +++ /dev/null @@ -1,43 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2021. -# -# 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 Mitigation Experiments (:mod:`qiskit_experiments.library.mitigation`) -=============================================================================================== - -.. currentmodule:: qiskit_experiments.library.mitigation - -Experiment -=========== -.. autosummary:: - :toctree: ../stubs/ - :template: autosummary/experiment.rst - - CorrelatedReadoutErrorExperiment - LocalReadoutErrorExperiment - - -Analysis -======== - -.. autosummary:: - :toctree: ../stubs/ - :template: autosummary/analysis.rst - - CorrelatedReadoutErrorAnalysis - LocalReadoutErrorAnalysis -""" -from .correlated_readout_error_experiment import CorrelatedReadoutErrorExperiment -from .local_readout_error_experiment import LocalReadoutErrorExperiment -from .correlated_readout_error_analysis import CorrelatedReadoutErrorAnalysis -from .local_readout_error_analysis import LocalReadoutErrorAnalysis diff --git a/qiskit_experiments/library/mitigation/utils.py b/qiskit_experiments/library/mitigation/utils.py deleted file mode 100644 index 2712639a9f..0000000000 --- a/qiskit_experiments/library/mitigation/utils.py +++ /dev/null @@ -1,31 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2022. -# -# 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. -""" -Utility functions for readout mitigation experiments -""" -from qiskit import QuantumCircuit - - -def calibration_circuit(num_qubits: int, label: str) -> QuantumCircuit: - """Return a calibration circuit. - - This is an N-qubit circuit where N is the length of the label. - The circuit consists of X-gates on qubits with label bits equal to 1, - and measurements of all qubits. - """ - circ = QuantumCircuit(num_qubits, name="meas_mit_cal_" + label) - for i, val in enumerate(reversed(label)): - if val == "1": - circ.x(i) - circ.measure_all() - circ.metadata = {"label": label} - return circ diff --git a/test/test_mitigation.py b/test/test_readout_error.py similarity index 95% rename from test/test_mitigation.py rename to test/test_readout_error.py index e700ead189..8117012d8d 100644 --- a/test/test_mitigation.py +++ b/test/test_readout_error.py @@ -11,7 +11,7 @@ # that they have been altered from the originals. """ -A Tester for the Readout Mitigation experiment +A Tester for the Readout error experiment """ @@ -19,7 +19,7 @@ from test.base import QiskitExperimentsTestCase import numpy as np from qiskit.quantum_info.operators.predicates import matrix_equal -from qiskit_experiments.library import LocalReadoutErrorExperiment, CorrelatedReadoutErrorExperiment +from qiskit_experiments.library.characterization import LocalReadoutError, CorrelatedReadoutError from qiskit_experiments.framework import ExperimentData @@ -50,7 +50,7 @@ def test_local_analysis(self): expdata = ExperimentData() expdata.add_data(run_data) expdata._metadata = run_meta - exp = LocalReadoutErrorExperiment(qubits) + exp = LocalReadoutError(qubits) result = exp.analysis.run(expdata) mitigator = result.analysis_results(0).value @@ -120,7 +120,7 @@ def test_correlated_analysis(self): expdata = ExperimentData() expdata.add_data(run_data) expdata._metadata = run_meta - exp = CorrelatedReadoutErrorExperiment(qubits) + exp = CorrelatedReadoutError(qubits) result = exp.analysis.run(expdata) mitigator = result.analysis_results(0).value From 3a01c3b66808dbf49ed4caeb2ceb0b6fa0116c33 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Mon, 17 Jan 2022 22:49:58 +0200 Subject: [PATCH 11/32] Doc fixes --- .../library/characterization/__init__.py | 9 +++-- .../correlated_readout_error_analysis.py | 25 +++++++------- .../analysis/local_readout_error_analysis.py | 19 +++++------ ...eriment.py => correlated_readout_error.py} | 30 ++++++++-------- ...r_experiment.py => local_readout_error.py} | 34 +++++++++---------- 5 files changed, 57 insertions(+), 60 deletions(-) rename qiskit_experiments/library/characterization/{correlated_readout_error_experiment.py => correlated_readout_error.py} (73%) rename qiskit_experiments/library/characterization/{local_readout_error_experiment.py => local_readout_error.py} (69%) diff --git a/qiskit_experiments/library/characterization/__init__.py b/qiskit_experiments/library/characterization/__init__.py index b0bb48db5e..8b733ee1f6 100644 --- a/qiskit_experiments/library/characterization/__init__.py +++ b/qiskit_experiments/library/characterization/__init__.py @@ -62,8 +62,7 @@ RamseyXYAnalysis ReadoutAngleAnalysis LocalReadoutErrorAnalysis - CorrelatedReadoutErrorAnalysis, - + CorrelatedReadoutErrorAnalysis .. autosummary:: :toctree: ../stubs/ @@ -81,8 +80,8 @@ T1Analysis, CrossResonanceHamiltonianAnalysis, ReadoutAngleAnalysis, - CorrelatedReadoutErrorAnalysis, LocalReadoutErrorAnalysis, + CorrelatedReadoutErrorAnalysis, ) @@ -99,5 +98,5 @@ from .drag import RoughDrag from .readout_angle import ReadoutAngle from .fine_drag import FineDrag, FineXDrag, FineSXDrag -from .local_readout_error_experiment import LocalReadoutError -from .correlated_readout_error_experiment import CorrelatedReadoutError +from .local_readout_error import LocalReadoutError +from .correlated_readout_error import CorrelatedReadoutError diff --git a/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py index 2a7dc1ceca..224d3d5e4d 100644 --- a/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py @@ -22,26 +22,25 @@ class CorrelatedReadoutErrorAnalysis(BaseAnalysis): - """ - Correlated readout error characterization anaylsis + r""" + Correlated readout error characterization analysis # section: overview - This class generates the full assignment matrix :math:`A` characterizing the - readout error for the given qubits from the experiment results. + This class generates the full assignment matrix :math:`A` characterizing the + readout error for the given qubits from the experiment results. - :math:`A` is a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` - is the probability to observe :math:`y` given the true outcome should be :math:`x`. + :math:`A` is a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` + is the probability to observe :math:`y` given the true outcome should be :math:`x`. - In the experiment, for each :math:`x`a circuit is constructed whose expected - outcome is :math:`x`. From the observed results on the circuit, the probability for - each :math:`y` is determined, and :math:`A_{y,x}` is set accordingly. + In the experiment, for each :math:`x`a circuit is constructed whose expected + outcome is :math:`x`. From the observed results on the circuit, the probability for + each :math:`y` is determined, and :math:`A_{y,x}` is set accordingly. + Returns + * The `Correlated readout error mitigator `_ object (the assignment matrix can be accessed via its ``assignment_matrix()`` method). + * (Optional) A figure of the assignment matrix. - # section: return value - * The `Correlated readout error mitigator _` - object (the assignment matrix can be access via its `assignment_matrix()` method). - * (Optional) A figure of the assignment matrix. # section: reference .. ref_arxiv:: 1 2006.14044 diff --git a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py index 9018b38180..8230857b9e 100644 --- a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py @@ -23,27 +23,26 @@ class LocalReadoutErrorAnalysis(BaseAnalysis): - """ - Local readout error characterization anaylsis + r""" + Local readout error characterization analysis # section: overview This class generates the assignment matrices characterizing the readout error for each of the given qubits from the experiment results. - Each such matrix is a :math:`2\times 2` matrix :math:`A`. Such that :math:`A_{y,x}` + Each such matrix is a :math:`2\times 2` matrix :math:`A`. Such that :math:`A_{y,x}` is the probability to observe :math:`y` given the true outcome should be :math:`x`, - where :math:`x,y\in\left\{0,1\right\}`. + where :math:`x,y \in \left\{0,1\right\}` can be 0 and 1. In the experiment, two circuits are constructed - one for 0 outcome for all - qubits and one for 1 outcome. From the observed results on the circuit, the probability for - each :math:`x,y` is determined, and :math:`A_{y,x}` is set accordingly. - + qubits and one for 1 outcome. From the observed results on the circuit, the + probability for each :math:`x,y` is determined, and :math:`A_{y,x}` is set accordingly. - # section: return value - * The `Local readout error mitigator _` - object (the assignment matrix can be access via its `assignment_matrix()` method). + Returns + * The `Local readout error mitigator `_ object (the assignment matrix can be accessed via its ``assignment_matrix()`` method). * (Optional) A figure of the assignment matrix. + # section: reference .. ref_arxiv:: 1 2006.14044 """ diff --git a/qiskit_experiments/library/characterization/correlated_readout_error_experiment.py b/qiskit_experiments/library/characterization/correlated_readout_error.py similarity index 73% rename from qiskit_experiments/library/characterization/correlated_readout_error_experiment.py rename to qiskit_experiments/library/characterization/correlated_readout_error.py index 151ecada58..8ac7894c49 100644 --- a/qiskit_experiments/library/characterization/correlated_readout_error_experiment.py +++ b/qiskit_experiments/library/characterization/correlated_readout_error.py @@ -10,7 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """ -Correlated readout readout_error calibration experiment class. +Correlated readout error calibration experiment class. """ from typing import Iterable, List from qiskit import QuantumCircuit @@ -21,40 +21,40 @@ class CorrelatedReadoutError(BaseExperiment): - """Class for correlated readout error characterization experiment + r"""Class for correlated readout error characterization experiment # section: overview - Readout readout_error aims to reduce the effect of errors during the measurement - of the qubits in a quantum device. It is used both to obtain a more accurate - distribution of the outputs, and more accurate measurements of expectation - value for measurables. + Readout errors affect quantum computation during the measurement + of the qubits in a quantum device. By characterizing the readout errors, + it is possible to construct a *readout error mitigator* that is used both + to obtain a more accurate distribution of the outputs, and more accurate + measurements of expectation value for measurables. The readout mitigator is generated from an *assignment matrix*: a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the probability to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used - to compute the *readout_error matrix* used in the readout_error process itself. + to compute the *assignment matrix* used in the readout error mitigation process itself. - A *Correlated readout mitigator* uses the full :math:`2^n\times 2^n` assignment matrix, meaning + A *Correlated readout mitigator* uses the full :math:`2^n \times 2^n` assignment matrix, meaning it can only be used for small values of :math:`n`. - The corresponding class in Qiskit is the `Correlated readout mitigator - _` - in `qiskit-terra`. + The corresponding class in Qiskit is the `Correlated readout mitigator `_ + in ``qiskit-terra``. The experiment generates :math:`2^n` circuits, for every possible :math:`n`-qubit quantum state and constructs the assignment matrix and correlated mitigator from the results. - See :class:`CorrelatedMitigationAnalysis` - documentation for additional information on correlated readout readout_error experiment analysis. + See :class:`CorrelatedReadoutErrorAnalysis` + documentation for additional information on correlated readout error experiment analysis. # section: analysis_ref - :py:class:`CorrelatedMitigationAnalysis` + :py:class:`CorrelatedReadoutErrorAnalysis` # section: reference .. ref_arxiv:: 1 2006.14044 """ def __init__(self, qubits: Iterable[int]): - """Initialize a correlated readout readout_error calibration experiment. + """Initialize a correlated readout error characterization experiment. Args: qubits: The qubits being characterized for readout error diff --git a/qiskit_experiments/library/characterization/local_readout_error_experiment.py b/qiskit_experiments/library/characterization/local_readout_error.py similarity index 69% rename from qiskit_experiments/library/characterization/local_readout_error_experiment.py rename to qiskit_experiments/library/characterization/local_readout_error.py index b18fdab3fb..f8a5d62960 100644 --- a/qiskit_experiments/library/characterization/local_readout_error_experiment.py +++ b/qiskit_experiments/library/characterization/local_readout_error.py @@ -10,7 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """ -Local readout readout_error calibration experiment class. +Local readout error calibration experiment class. """ from typing import Iterable, List from qiskit import QuantumCircuit @@ -21,42 +21,42 @@ class LocalReadoutError(BaseExperiment): - """Class for local readout error characterization experiment + r"""Class for local readout error characterization experiment # section: overview - Readout readout_error aims to reduce the effect of errors during the measurement - of the qubits in a quantum device. It is used both to obtain a more accurate - distribution of the outputs, and more accurate measurements of expectation - value for measurables. + Readout errors affect quantum computation during the measurement + of the qubits in a quantum device. By characterizing the readout errors, + it is possible to construct a *readout error mitigator* that is used both + to obtain a more accurate distribution of the outputs, and more accurate + measurements of expectation value for measurables. The readout mitigator is generated from an *assignment matrix*: - a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the probability + a :math:`2^n \times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the probability to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used - to compute the *readout_error matrix* used in the readout_error process itself. + to compute the *assignment matrix* used in the readout error mitigation process itself. A *Local readout mitigator* works under the assumption the readout errors are mostly *local*, meaning readout errors for different qubits are independent of each other. In this case, the assignment matrix - is the tensor product of :math:`n` :math:`2\times 2` matrices, one for each qubit, making it practical - to store the assignment matrix in implicit form, by storing the individual :math:`2\times 2` assignment matrices. - The corresponding class in Qiskit is the `Local readout mitigator - _` - in `qiskit-terra`. + is the tensor product of :math:`n` :math:`2 \times 2` matrices, one for each qubit, making it practical + to store the assignment matrix in implicit form, by storing the individual :math:`2 \times 2` assignment matrices. + The corresponding class in Qiskit is the `Local readout mitigator `_ + in ``qiskit-terra``. The experiment generates 2 circuits, corresponding to the states :math:`|0^n>` and :math:`|1^n>`, measuring the error in all the qubits at once, and constructs the assignment matrix and local mitigator from the results. - See :class:`LocalMitigationAnalysis` - documentation for additional information on local readout readout_error experiment analysis. + See :class:`LocalReadoutErrorAnalysis` + documentation for additional information on local readout error experiment analysis. # section: analysis_ref - :py:class:`LocalMitigationAnalysis` + :py:class:`LocalReadoutErrorAnalysis` # section: reference .. ref_arxiv:: 1 2006.14044 """ def __init__(self, qubits: Iterable[int]): - """Initialize a local readout readout_error calibration experiment. + """Initialize a local readout error characterization experiment. Args: qubits: The qubits being characterized for readout error From 4c12244b7235a1802d8cc949c52145d2ddc65816 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Tue, 18 Jan 2022 09:34:50 +0200 Subject: [PATCH 12/32] Linting and bugfix --- .../correlated_readout_error_analysis.py | 6 +++++- .../analysis/local_readout_error_analysis.py | 8 ++++++-- .../characterization/correlated_readout_error.py | 8 +++++--- .../characterization/local_readout_error.py | 16 +++++++++------- test/test_readout_error.py | 11 ++++++++++- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py index 224d3d5e4d..0e3157bb28 100644 --- a/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py @@ -38,7 +38,11 @@ class CorrelatedReadoutErrorAnalysis(BaseAnalysis): each :math:`y` is determined, and :math:`A_{y,x}` is set accordingly. Returns - * The `Correlated readout error mitigator `_ object (the assignment matrix can be accessed via its ``assignment_matrix()`` method). + + * The `Correlated readout error mitigator + `_ + object (the assignment matrix can be accessed via its ``assignment_matrix()`` method). + * (Optional) A figure of the assignment matrix. diff --git a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py index 8230857b9e..c71c118306 100644 --- a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py @@ -39,8 +39,12 @@ class LocalReadoutErrorAnalysis(BaseAnalysis): probability for each :math:`x,y` is determined, and :math:`A_{y,x}` is set accordingly. Returns - * The `Local readout error mitigator `_ object (the assignment matrix can be accessed via its ``assignment_matrix()`` method). - * (Optional) A figure of the assignment matrix. + + * The `Local readout error mitigator + `_ + object (the assignment matrix can be accessed via its ``assignment_matrix()`` method). + + * (Optional) A figure of the assignment matrix. # section: reference diff --git a/qiskit_experiments/library/characterization/correlated_readout_error.py b/qiskit_experiments/library/characterization/correlated_readout_error.py index 8ac7894c49..398fd3febe 100644 --- a/qiskit_experiments/library/characterization/correlated_readout_error.py +++ b/qiskit_experiments/library/characterization/correlated_readout_error.py @@ -36,7 +36,9 @@ class CorrelatedReadoutError(BaseExperiment): A *Correlated readout mitigator* uses the full :math:`2^n \times 2^n` assignment matrix, meaning it can only be used for small values of :math:`n`. - The corresponding class in Qiskit is the `Correlated readout mitigator `_ + The corresponding class in Qiskit is the + `Correlated readout mitigator + `_ in ``qiskit-terra``. The experiment generates :math:`2^n` circuits, for every possible @@ -65,9 +67,9 @@ def __init__(self, qubits: Iterable[int]): def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" labels = [bin(j)[2:].zfill(self.num_qubits) for j in range(2 ** self.num_qubits)] - return [self.calibration_circuit(self.num_qubits, label) for label in self.helper.labels()] + return [self.calibration_circuit(self.num_qubits, label) for label in labels] - def calibration_circuit(num_qubits: int, label: str) -> QuantumCircuit: + def calibration_circuit(self, num_qubits: int, label: str) -> QuantumCircuit: """Return a calibration circuit. This is an N-qubit circuit where N is the length of the label. diff --git a/qiskit_experiments/library/characterization/local_readout_error.py b/qiskit_experiments/library/characterization/local_readout_error.py index f8a5d62960..d582b26eef 100644 --- a/qiskit_experiments/library/characterization/local_readout_error.py +++ b/qiskit_experiments/library/characterization/local_readout_error.py @@ -34,11 +34,13 @@ class LocalReadoutError(BaseExperiment): to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used to compute the *assignment matrix* used in the readout error mitigation process itself. - A *Local readout mitigator* works under the assumption the readout errors are mostly *local*, meaning - readout errors for different qubits are independent of each other. In this case, the assignment matrix - is the tensor product of :math:`n` :math:`2 \times 2` matrices, one for each qubit, making it practical - to store the assignment matrix in implicit form, by storing the individual :math:`2 \times 2` assignment matrices. - The corresponding class in Qiskit is the `Local readout mitigator `_ + A *Local readout mitigator* works under the assumption the readout errors are mostly + *local*, meaning readout errors for different qubits are independent of each other. + In this case, the assignment matrix is the tensor product of :math:`n` :math:`2 \times 2` + matrices, one for each qubit, making it practical to store the assignment matrix in implicit + form, by storing the individual :math:`2 \times 2` assignment matrices. + The corresponding class in Qiskit is the `Local readout mitigator + `_ in ``qiskit-terra``. The experiment generates 2 circuits, corresponding to the states @@ -67,9 +69,9 @@ def __init__(self, qubits: Iterable[int]): def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" labels = ["0" * self.num_qubits, "1" * self.num_qubits] - return [self.calibration_circuit(self.num_qubits, label) for label in labels()] + return [self.calibration_circuit(self.num_qubits, label) for label in labels] - def calibration_circuit(num_qubits: int, label: str) -> QuantumCircuit: + def calibration_circuit(self, num_qubits: int, label: str) -> QuantumCircuit: """Return a calibration circuit. This is an N-qubit circuit where N is the length of the label. diff --git a/test/test_readout_error.py b/test/test_readout_error.py index 8117012d8d..fdfa4a2c6c 100644 --- a/test/test_readout_error.py +++ b/test/test_readout_error.py @@ -24,7 +24,7 @@ class TestMitigation(QiskitExperimentsTestCase): - """Test ReadoutMitigationExperiment""" + """Test Readout Error experiments""" def test_local_analysis(self): """Tests local mitigator generation from experimental data""" @@ -128,6 +128,15 @@ def test_correlated_analysis(self): self.assertEqual(qubits, mitigator._qubits) self.assertTrue(matrix_equal(expected_assignment_matrix, mitigator.assignment_matrix())) + def test_circuit_generation(self): + """Verifies circuits are generated by the experiments""" + qubits = [1, 2, 3] + exp = CorrelatedReadoutError(qubits) + self.assertEqual(len(exp.circuits()), 8) + + exp = LocalReadoutError(qubits) + self.assertEqual(len(exp.circuits()), 2) + if __name__ == "__main__": unittest.main() From 949e3a97b73f96ade0709cdc39e9bb99d92ebeea Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Tue, 18 Jan 2022 09:42:20 +0200 Subject: [PATCH 13/32] Notebook fix --- docs/tutorials/readout_mitigation.ipynb | 31 +++++++++++++------------ 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/tutorials/readout_mitigation.ipynb b/docs/tutorials/readout_mitigation.ipynb index d641bda3cc..c06882acef 100644 --- a/docs/tutorials/readout_mitigation.ipynb +++ b/docs/tutorials/readout_mitigation.ipynb @@ -27,7 +27,7 @@ "import matplotlib.pyplot as plt\n", "from qiskit import QuantumCircuit\n", "from qiskit.visualization import plot_histogram\n", - "from qiskit_experiments.library import ReadoutMitigationExperiment\n", + "from qiskit_experiments.library.characterization import LocalReadoutError, CorrelatedReadoutError\n", "# For simulation\n", "from qiskit.providers.aer import AerSimulator\n", "from qiskit.test.mock import FakeParis\n", @@ -96,7 +96,7 @@ } ], "source": [ - "exp = ReadoutMitigationExperiment(qubits)\n", + "exp = LocalReadoutError(qubits)\n", "for c in exp.circuits():\n", " print(c)" ] @@ -107,6 +107,7 @@ "metadata": {}, "outputs": [], "source": [ + "exp.set_analysis_options(plot=True)\n", "result = exp.run(backend).block_for_results()\n", "mitigator = result.analysis_results(0).value" ] @@ -125,7 +126,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAASoAAAEDCAYAAACCmUnRAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAYLklEQVR4nO3dfbBdVXnH8e/vnhBAICbhRkVAwUKrEZ1EXqe1WHkzzFhgLChIIViUsZbaGUcFtKIDOC3TqY5MEYkVEN9fqJoZoamIdDpVMAEiEKwloIVEVPICIWACSZ7+cfYJh5tzz9573XNv9ln5fWb23HP33mutfTJzn+y19l7rUURgZtZkIzv7AszMyjhQmVnjOVCZWeM5UJlZ4zlQmVnjOVCZWeMNJFBJuqDp5XJtK7Vcrm2llhuGtnYGSQsk/ULSSkkX9zj+AUkPSLpX0g8lvbLr2EJJDxbbwq79h0u6r6jzKkkqvZCImPAGLGt6uVzbGoZr9L/HYNqa6g1oAQ8BrwKmAz8D5o45583Ai4rPfw18o/g8G3i4+Dmr+DyrOPZT4BhAwC3AyWXX4q6fmY3nKGBlRDwcEc8CXwdO7T4hIn4UEc8Uv94BHFB8fgvwg4hYFxHrgR8ACyTtB8yIiDuiHbVuBE4ruxAVEa6S0Zkz4qCXzdlh/+NPbGDOzBnjFxxp9dz9+PonmTPrxb3LbNs6bnV923tR7/2Pr1nDnNHR3mW2bhm/rbXrmLPv7N4HW9PGaWstc0b3HbfOcdvqd419y/Vpb8tzvcusW8+c2bPGr3TabuO0Vf8aJ+V7DbhcU9r61SOPsGbN2vKuUB8Halpsotrf9Rq2rQA2de1aFBGLACSdDiyIiHcXv58DHB0RF/aqS9K/AL+JiCskfRDYIyKuKI59DPg9cDvwjxFxQrH/T4GLIuKt/a6z91/aOA562Rzu/PyVdYq07dUniI3n6Q31ywAj84+vX2jjuqS2NKP+Hx9Anf8ctrdVoRvfs611jyWVY9bL0solSP1uOTrijX824To2E5zBXpXOvYanNkXEERNtU9JfAkcAb5poXb2462eWoRGp0lZiNXBg1+8HFPteQNIJwEeBUyJic0nZ1TzfPRy3zh2+T9kJZjZcRPsPu8pWYilwqKSDJU0HzgQWv6AtaT5wLe0g9buuQ0uAkyTNkjQLOAlYEhGPARskHVM87TsX+F7ZhdTq+pnZcBip2pvuMwoREVskXUg76LSA6yJihaTLaD+5XAz8E7A38K2iC/9IRJwSEeskXU472AFcFhGdMZb3ATcAe9J+6ndL2WU6UJllRohpAxr3i4ibgZvH7Lu06/MJfcpeB1zXY/8y4LA61+FAZZah3MZ0SgNV8RbtBQCveGnaUy4zmzqiRtdvSJQG3ohYFBFHRMQRfd+VMrPGGNBgemO462eWG+X3bpoDlVlmOq8n5MSByixD0/K6oXKgMstNezA9r0jlQGWWoV2767fHXoy8+sjajWz77udrl2md/aHaZQC23n1r/bbeMO47a33FhjVJ5VImM6dMZAbQ7P2SysX639RvK3Ei81RO0t4V5Ph6gu+ozDK0a99RmVnjCQY2haYpHKjMMuQ7KjNrNMljVGY2BEbIK1I5UJllKLc7qtKurKQLJC2TtOzxtWlri5vZ1BngCp+NUW/1hPGysZhZY3QWzquyDQt3/cwytMt1/cxs+KjiVlpPeUr3YyXdLWlLkQews//NkpZ3bZsknVYcu0HSL7uOzSu7Dt9RmWVmUFNoJLWAq4ETgVXAUkmLI+KBrtMeAc4DPthdNiJ+BMwr6pkNrAT+o+uUD0XEt6teiwOVWYYG9HrC9pTuAJI6Kd23B6qI+FVxbFufek4HbulK/V5b/UA1Tnr2flImGG+5+iO1ywCMnPi2pHIpkjMlJ0xmTm0rVcoE45SJzADMfGlaOetpgC987g882vX7KuDohHrOBD41Zt8nJV0K/BC4uCtxaU8eozLLUKviBox2Xj8qtgsGeR2S9gNeRzs3YMclwKuBI4HZwEVl9bjrZ5aZmgvnrYmII8Y5Vimle4m3A9+JiOc6O4psyQCbJV3PmPGtXnxHZZahAT31K03pXsFZwNdecG3tuyyKlO6nAfeXVeJAZZahQQSqiNgCdFK6/xz4Zielu6RTACQdKWkVcAZwraQV269BOoj2Hdl/jqn6K5LuA+4DRoEryr6Pu35mGRrU+54VUrovpd0l7FX2V7QH5MfuP67udThQmWUmx+QOnpRsliFPSjazxpOqbcPCXT+zDMkL55lZk1WdcDxMHKjMMuRAZWYNJ1rDNABVgQOVWWbc9RtpoT33qd1IbNpYu0zrvA/XLgPw3CXvqV1m+lXfSmorVVJK9w1rE9vaN6lcUlupKd2f+G39Ql5xYXxD9kSvCt9RmWUoszjlQGWWI+f1M7NG8xiVmQ2F3LLQOFCZZchvpptZow0qC02T1Fs9YU3aI3Izm1qDyuvXFPVWTxidundyzCxdboHKXT+zDOW2cJ4DlVlmxHAtildFbt/HzBhc10/SAkm/kLRS0sU9jh8r6W5JWySdPubYVknLi21x1/6DJd1Z1PmNIsNNXw5UZhmSVGkrqaMFXA2cDMwFzpI0d8xpjwDnAV/tUcXvI2JesZ3Stf9K4NMRcQiwHji/7PvU6/pt3UI8VX/ddO0zdUsYp0ww3vrTm8tP6iV1wu/TG2oXGZl/fFpbQ0AJE4xj3WPlJ/WSOHE6RVkgmNS2B1PNUcDKiHgYQNLXgVOBBzonFJlmkLSt0nW1/1GOA95Z7Poi8Angmn7lfEdllpmq3b4imPVL6b4/8GjX76vokf6qjz2KOu+QdFqxb1/giSJnYOU6PZhulhuJVvU3PvuldJ+oV0bEakmvAm4rko4+mVKR76jMMqQRVdpKrKad6bjjgGJfJRGxuvj5MHA7MB9YC8yU1LlJqlSnA5VZZsTA0mUtBQ4tntJNB84EFpeUaV+DNEvS7sXnUeBPgAciIoAfAZ0nhAuB75XV50BllpuKQaosUBXjSBcCS4CfA9+MiBWSLpN0CoCkIyWtAs4ArpW0oij+GmCZpJ/RDkz/GBGdQfiLgA9IWkl7zOoLZV/JY1RmGRrUE8eIuBm4ecy+S7s+L6XdfRtb7sfA68ap82HaTxQrc6Ayy1BmM2jKA1XxuPICgFcc8PJJvyAzmxgBI5mt81Jv9YTZU/fippklUntScpVtWLjrZ5ahIYpBlThQmWWnfB7fsHGgMsuMAGX24pEDlVlulN9ger1A1ZqWtBJCbFxfu4z2nlW7TKqR1/5xUrltN30uqVzr3B2W9Sm19e5b09p6wwlJ5ZpOs/dLKhfrf5PWXsKqC+2XsHcOd/3MrPEyi1MOVGa5aafLyitSOVCZ5abahOOh4kBlliGPUZlZo7Wn0OzsqxgsByqz3KjSonhDxSndzTI0oIXzGsMp3c0y5EnJZtZonaWIc+JAZZah3J76ZfZswMw6c/2qbKVVJaZ0lzRP0k8krZB0r6R3dB27QdIvu9K9zyu7Dt9RmWVoEDdUXSndT6SdKHSppMVdSRrg+ZTuHxxT/Bng3Ih4UNLLgbskLYmIJ4rjH4qIb1e9Fgcqs8y0x6gG0vVLTukeEf/b9fnXkn4HzAGeSLmQKQlUKSshpKy4kNoWI62ktlJWQQDYctVFtcuMLDgjqS17oZRVECBx1YWZL01qa8JUaz2qUUnLun5fFBGLis+9UrofXftypKOA6cBDXbs/KelS4IfAxRGxuV8dvqMyy06tFT4nM6U7kvYDvgQsjIjOXdclwG9oB69FtPP8XdavHg+mm+WoNVJt629CKd0lzQC+D3w0Iu7o7I+Ix6JtM3A9FXL8OVCZ5UbtMaoqW4mJpHSfDnwHuHHsoHlxl4XaF3AacH9ZfQ5UZjkaUbWtjwmmdH87cCxwXo/XEL4i6T7gPmAUuKLs63iMyiw7g5vIN4GU7l8GvjxOncfVvQ4HKrPMSHj1BDMbApktn+DVE8wypNZIpW1YuOtnlhuVD5QPGwcqswzltnqCA5VZjnxHZWaNluHKeY0NVKkp3acyfXxs2phUrnX+JbXLPPvBv0pqa/dr/i2pnL1QUkr3J35bv6Gtz9Uv04NaDlRm1mQZZqFxoDLLkbt+ZtZ4vqMysyaT/HqCmQ0D31GZWbMJjQzP9JgqSgOVpAuACwBeceCBJWeb2U4nsruj8qRkswwNaIXPxnDXzyxHmd1ROVCZ5WbI1pqqIq8RNzMD2it8VtlK60lM6V4cWyjpwWJb2LX/cEn3FXVepQp9UAcqs9yIgaTL6krpfjIwFzhL0twxp3VSun91TNnZwMdpJyw9Cvi4pM6k2muA9wCHFtuCsq/kQGWWoQENpm9P6R4RzwKdlO7bRcSvIuJeYNuYsm8BfhAR6yJiPfADYEGRKmtGRNwREQHcSDtlVl/1xqgiiOf6Zl7uSbvtXrtMqtSVEJLa2mPvKWsrdRWErTdfl1ROf3BY7TKx8cmktkbmH1+/0MZ1SW1pxmhSufbfVM22UlK6t3arX2bHlusMpk9WSvdeZfcvtlU99vflwXSzHDUkpfuguOtnlpvOwnkTz0IzkZTu45VdzQvzAFaq04HKLDuCVqva1l9ySnfa2ZVPkjSrGEQ/CVgSEY8BGyQdUzztOxf4XlllDlRmORrAHdVEUrpHxDrgctrBbilwWbEP4H3AvwIrgYeAW8q+jseozHIzwDXTU1O6F8euA3Z4mhMRy4BaT2scqMxylNmb6TVXT+gZOM2sUQSZLfNSb/WEfb16gtlQGMxTv8Zw188sNyK7OyoHKrPs5Nf1c6Ayy9EQdeuqcKAyy41TupvZUNilA5WUtBJC01dcyNnIm96WVG7rtZfXLjPtA/+c1tby22qXac07Lqmt2LA2qZxmDM8Tb+2KWWjMbMj4qZ+ZDYVduutnZkPAryeY2TDwHZWZNdqu+HqCU7qbDRtVWRRvqDilu1mOPCnZzBptV+z6mdmwye+pX17fxszaBtT1q5DSfXdJ3yiO3ynpoGL/2ZKWd23bJM0rjt1e1Nk59pKy6/AdlVmOBtD160rpfiLtRKFLJS2OiAe6TjsfWB8Rh0g6E7gSeEdEfAX4SlHP64DvRsTyrnJnF2unV+I7KrPcaGDpskpTuhe/f7H4/G3geO2YK/6somyyKbmjSprIvOXZtLamTU8ql62RtMfUKROMt1x6flJbI+e8L6lcitTJxSmTmXfqRObqd1QTTem+/ZyI2CLpSWBfYE3XOe9gxwB3vaStwE3AFRER/S7SXT+zHDUkpbuko4FnIuL+rt1nR8RqSfvQDlTnADf2q8ddP7PcCNBIta2/Kindt58jaRrwYqD79vNM4GvdBSJidfHzKeCrtLuYfTlQmWVHMFJx669KSvfFwMLi8+nAbZ1unKQR4O10jU9JmiZptPi8G/BW4H5KuOtnlqPyu6VSxZhTJ6V7C7iuk9IdWBYRi4EvAF+StBJYRzuYdRwLPBoRD3ft2x1YUgSpFnAr8Pmya3GgMstN56nfAFRI6b4JOGOcsrcDx4zZ9zRweN3rcKAyy9GuNoXGqyeYDaEBdP2axKsnmOXIqyeYWaMpv0nJDlRmOUqckdBUDlRmuVGld6SGigOVWY4yG0x3oDLL0RANlFfR2ECVugpCyqoLOa+4oD33SSoXmzbWLtO6KC2l+8ZzT69dZp+bbk1qK1XKSghJ6eO3bqlfZgfyHZWZNZzwGJWZDQE/9TOzRvNTPzMbCh6jMrPG81M/M2u2XfCpn1dPMBsyYmDrUTWFV08wy5FXTzCzZstv9YS8vo2ZFVlodnpK94Mk/b4rbfvnusocLum+osxVPRKW7sCByixHA0iX1ZXS/WRgLnCWpLljTtue0h34NO2U7h0PRcS8Yntv1/5rgPcAhxbbgrKv40Bllp2Kd1PlNzKDSun+/JVJ+wEzIuKOIq3WjcBpZReS3RhVygTjeG5zWlsJqeqnWjy1Lqmc9pk94CsZX8oE462LF5Wf1IP+aF5SuXh6Q+0yI/OOq99QawB/kvWe+k1WSneAgyXdA2wA/j4i/qs4f9WYOvcvu8jsApWZ1XqParJSuj8GvCIi1ko6HPiupNemVuZAZZajwbx6UCel+6rulO5Ft24zQETcJekh4A+L8w8oqXMHHqMyy9EABtOZQEp3SXOKwXgkvYr2oPnDEfEYsEHSMcVY1rnA98ouxHdUZrkZ0OoJE0zpfixwmaTngG3AeyOiM2D6PuAGYE/glmLry4HKLEcDmuuXmtI9Im4CbhqnzmXAYXWuw4HKLDva9RbO86Rks+FT4WXvoeJJyWa5EYMaTG8Md/3MsrMLrkdlZkPIa6abWaOJXW8w3cyGjbt+ZjYMMnvq50BF+ioIw7DqQuoqCLFxff229p6V1FaKkePfnlRu69UfTyo37cOfqd/W8tvqN/TMU/XL9OI7KjNrNCcgNbOh4DsqM2u2XXAKjZkNIQ+mm1mjdabQZMSByiw7+eX18+oJZhny6glm1nxePcHMGk35PfUbnpBqZtXt/JTuJ0q6q0jdfpek47rK3F7U2Un3/pKy6/AdlVmOBjCY3pXS/UTaiUKXSlocEQ90nbY9pbukM2mndH8HsAb484j4taTDaCeI6E40enaxdnolvqMyy03Vu6lJTOkeEfdExK+L/SuAPSUlT3J1oDLL0WAG03uldB+bfv0FKd2B7pTuHX8B3B0R3bP4ry+6fR9ThUeU7vpNQPKqC1uerd/WtOlJbaVKWQkhZcWF1LZSB4tTVkEA2PKRheUnjTHyrvfXb6g1oEHw6k/0RiV1d8EWRcSiwVwEFGncrwRO6tp9dkSslrQP7ZRa5wA39qvHgcosO9UGygtrIuKIcY4lp3QHkHQA8B3g3Ih4qFMgIlYXP5+S9FXaXcy+gcpdP7McDWaMaiIp3WcC3wcujoj/fv6yNE3SaPF5N+CtwP1lF+I7KrMs7fSU7hcChwCXSupkVj4JeBpYUgSpFnAr8Pmya3GgMsuNGNjqCRNI6X4FcMU41R5e9zocqMxylNdUP09KNstPflloPCnZLEcDmkLTFO76mWVpeIJQFQ5UZjkaorulKhyozLLkQGVmTTZk409VOFCZ5Sizp34OVDtBygTjlInMqW2lSk3pHhufSGhrZlpbmzYmlWt9tP5k5qfe+bbaZbY+uqp2mV5yWzPdgcosRw5UZtZswoPpZtZ8vqMys0ZzpmQzGwq+ozKzxssrTpVPSpZ0gaRlkpY9vmbtVFyTmU2IamzDwasnmOXIqyeYWaMNcIXPpnCgMstRZk/98vo2Zsb2dFkD6PpJWiDpF5JWSrq4x/HdJX2jOH6npIO6jl1S7P+FpLdUrbMXByqzLE18MF1SC7gaOBmYC5wlae6Y084H1kfEIcCnaScbpTjvTOC1wALgs5JaFevcgQOVWY4Gc0d1FLAyIh6OiGeBrwOnjjnnVOCLxedvA8cXKdpPBb4eEZsj4pfAyqK+KnXuoNYY1V33LF+jvWb+X49Do8CaOnXthHK5tpVaLte2Uss1pa1XJlzDC9x1z/Il2mvmaMXT9+iT0n1/4NGuY6uAo8eU335OkQfwSWDfYv8dY8ruX3wuq3MHtQJVRMzptV/Ssj5pocc1leVybSu1XK5tpZYbhraqiogFk1X3zuKun5mNZzXQnSPvgGJfz3MkTQNeDKztU7ZKnTtwoDKz8SwFDpV0sKTptAfHF485ZzGwsPh8OnBbRESx/8ziqeDBwKHATyvWuYNBvUe1qPyUnV4u17ZSy+XaVmq5YWhrShVjThcCS4AWcF1ErJB0GbAsIhYDXwC+JGklsI524KE475vAA8AW4G8iYitArzrLrkXt4Gdm1lzu+plZ4zlQNYikkHRen+PvLs75yRRcS6etw6ten9lkcaAaEpL2Bi4vfj1Mk59mZD7tsYX7J7kds1IOVMPjYuBlwM3A3sCrJrm9ecDPI2LzJLdjVsqBaghIOhD4APBd4LPF7tdPYnsq6r9nstowq8OBajj8A+1XST7M812xSQtUtN952RsHKmsIr0fVcJKOBN4JfCYiHizudp5icgPVvOLn8klsw6wy31E136eA9cBlAMVbvw/QJ1BJOqF4Qle23T5OFfOKn8sH9i3MJsB3VA0m6XTgjcDHgJA0szj0IHCkpL0i4ukeRX8MvKZCE8+Ms38+8MuIeKLeFZtNDgeqhirmQV1Z/Ho5z7+a0O0w4M6xOyPiGeB/JtD8PGDS39Uyq8qBqrneT/sVhL8D7h1z7DW0n/69nh6BaiIkvZT2axAeSLfGcKBqIEmjwEeBf4+Iq3ocX87zgWrQ5hc/HaisMTyY3kyfAPYE/rbXwWLsaBWTE6jmFT+XT0LdZkm8ekKDSArgXRFxw86+ll6afn2WL99RmVnjOVCZWeM5UJlZ43mMyswaz3dUZtZ4DlRm1ngOVGbWeA5UZtZ4DlRm1ngOVGbWeA5UZtZ4/w9mehBeG0SepgAAAABJRU5ErkJggg==\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -157,17 +158,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[ 1.01443299 -0.04123711]\n", - " [-0.01443299 1.04123711]]\n", + "[[ 1.02063983 -0.03611971]\n", + " [-0.02063983 1.03611971]]\n", "\n", - "[[ 1.01139896 -0.04974093]\n", - " [-0.01139896 1.04974093]]\n", + "[[ 1.00606673 -0.02932255]\n", + " [-0.00606673 1.02932255]]\n", "\n", - "[[ 1.01616162 -0.01818182]\n", - " [-0.01616162 1.01818182]]\n", + "[[ 1.01515152 -0.01919192]\n", + " [-0.01515152 1.01919192]]\n", "\n", - "[[ 1.0060241 -0.02208835]\n", - " [-0.0060241 1.02208835]]\n", + "[[ 1.005 -0.019]\n", + " [-0.005 1.019]]\n", "\n" ] } @@ -233,7 +234,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAApMAAAFLCAYAAACKkwciAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABIbUlEQVR4nO3deXxVxf3/8ddkJYGEJGwhYQmbyKIhEIsogtW2uHytrVAtLtRdsUIpv7rU2mqte6sVcafVaq0Lol9tsdraLypiEcsqi7KHnbAkQDAQsszvjzkXr7dJyD259yaB9/PxOI/knnPuzNw55+R+MmdmjrHWIiIiIiLiR1xTF0BEREREWi4FkyIiIiLim4JJEREREfFNwaSIiIiI+KZgUkRERER8UzApIiIiIr4lNHUBmlL79u1tXl5eUxdDRESakQULFuyy1nYIet0xISHhD8BA1Agjxx5rjNlbXV39XE1NzZNDhgw5FLrDMR1M5uXlMX/+/KYuhoiINCPGmA3BrxMSEv6QnZ3dr0OHDqVxcXGanFmOKdZaDh06lLh169YJ+/btGwz8KHQf/YclIiJSv4EdOnTYp0BSjkXGGJKTkyu7d+++Fxhe2z4KJkVEROoXp0BSjnXeNRBf67YYl0VEREREjiIKJkVERI5yF198cbebbrqpc13bb7311uyLLrqoeyzLVJfRo0fnTZw4MSfa+UyePDnn/PPP7+HnvY8++mi7IUOG9K1r+4gRI/pMnTq1XW37pqamFqxYsSKprvf27t17wMyZM9P8lKupHNMDcERERPy45hGGRDP9aZNY0JD9cnNzT9ixY0fixo0bP+vcuXNVYH2/fv36f/HFFylffPHF0r59+x566aWXNga2zZw5M+2qq67qUVxc/Flg3f333789UmU3xgxZunTpsoEDB1ZEKs2ARx99tN1Pf/rTvOTk5Jq4uDi6dOlScccdd2wZO3bs3kjn1RizZ89eXde28vLyRYHfR48enZebm3vo0Ucf3RpYt2bNmuXRLl+kqWVSRESkBcvNzT307LPPZgVef/rppykHDhw4ar/fBw0atL+8vHzR3r17F1122WW7rrzyyp47d+78r758lZWVTVG8Y9JRe7KJiIgcCy688MLdL7/8crvA6z/84Q/tLrrool3B+wRuHe/bty9uzJgxfXbu3JmYmppakJqaWlBUVJQYesv3sccea5eTk3NCRkbGoJtuuqlzbm7uCW+++WYawPvvv586aNCg49PS0gZ16NDhxHHjxnU7ePCgASgsLOwLcNJJJ/VPTU0tmDZtWibAyy+/3Pb444/vn5aWNqigoOD4efPmpQTy+vjjj1P69+/fr3Xr1gXnnntuz4qKigbFJvHx8UyYMGHXwYMH4z7//PPkyZMn55x11lk9zz///B5t2rQpmDp1avuioqLEM844o3fbtm0HdevWbeBDDz3UPjiNiooKc+655/Zs3bp1Qf/+/fvNnTv3cLluu+227K5duw5s3bp1Qa9evQa88MILGcHvtdaacePGdUtLSxvUo0ePAW+99dbhW9Pf+MY3+j788MNfyyvAGDNk2bJlyb/73e/av/XWW1lPPvlkdmpqasEZZ5zRG1xrc6Cuq6urD5cjIyNj0DnnnNOzuLg4HqC8vNycf/75PTIyMgalpaUNGjhwYL9NmzY1yR1nBZMiIiIt2CmnnLJ///798QsXLmxVVVXFW2+9lXXVVVeV1LZvenp6zYwZM1Z36NChsry8fFF5efmivLy8rzXhLViwoNXNN9/c7bnnnlu/ffv2JXv37o0vLi5ODGxPSEjgoYce2lRSUrJ4zpw5X8yZMyftwQcf7AAwf/78lQD/+c9/VpSXly+65pprSj/++OOUH//4x3lPPPHEhtLS0sVXXnnlzgsuuKD3gQMHzMGDB80PfvCD3hdddNHukpKSxWPGjCl99913MxryuSsrK5kyZUr71NTUmgEDBlQA/Otf/8oYM2ZM6d69exdde+21u8eMGdMzJyfn0LZt25a88sora+++++7cv/71r4eDvsD+Xt4lY8aM6V1RUWEAevfuXfHRRx+t3Ldv36Jbb71163XXXddjw4YNh+vhs88+a92rV6+Du3btWnLbbbdtvfTSS3sFAr2G+NnPfrbr/PPPLxk/fvz28vLyRbNmzVoTus+9997b8e2338744IMPVm7btm1JRkZG9dVXX90N4PHHH29XVlYWv2nTps9KS0sXP/nkkxtat25d09D8I0nBpIiISAt34YUX7v7jH//Y7s0330zv1avXgR49evzXU0oa6uWXX84888wz94waNWp/q1at7EMPPbTVGHN4+2mnnVZ+5plnfpmYmEjfvn0PXX755Ts/+uijOgeMPPHEEx0uu+yynWecccaXCQkJTJgwYXdiYqKdNWtW6/fff791VVWV+eUvf7kjOTnZXnHFFaUnnHBCeX3lW7JkSZu0tLRBHTt2zJ8xY0bWX/7ylzXt2rWrBhg0aNCXl1122Z74+Hi2b9+esGjRojZTp07dnJqaak855ZQDF1988a7nn3/+cCvugAEDyq+44orS5ORke8cddxQfOnTIvP/++60BrrzyytK8vLzK+Ph4rrnmmtLu3btXfPTRR60D783KyqoMlPuaa64pzcvLq5gxY0Zbv/Vem+eee67DXXfdtaVXr16VKSkp9r777tv6zjvvZFZWVpKYmGhLS0sTVqxYkZyQkMBpp51WnpWV1STBpAbgiIiItHBXX3317tNPP73vhg0bki+55JLdjUlr69atibm5uYdbK9PS0moyMjIOD+757LPPkn/yk590Xbp0aeuDBw/GVVdX079//zoDwM2bNye98cYb7Z599tmOgXVVVVVm8+bNScYY27Fjx8q4uK/atrp06VLvwJ38/Pz9CxYsWFnbtpycnMNB9MaNG5PS09OrMjMzDwdY3bt3P7Ro0aLU2vaPj4+nU6dOlZs2bUoEd6v/scce67Rly5YkgAMHDsTv3LnzcNxUW7m3bt1a5yhtP7Zt25Z0ySWX9DbGHJ7nND4+ns2bNyeOHz++ZNOmTUkXX3xxz7KysvgLLrigZMqUKVuSk5NjPieqWiZFRERauOOOO+5Qly5dDn3wwQdtL7vssj317RscmNSmc+fOlVu2bDl8O3f//v1mz549h4Oo6667rnufPn0Orl69eun+/fsX/fznP99SX3q5ubmVEydO3FZWVrY4sBw4cGDRddddV5Kbm1u5Y8eOxJqarxrUtmzZknykz1vPZzv8e7du3Q7t27cvobS09HCss3HjxqTOnTsfDpSDg7/q6mqKi4sTu3btWrlq1aqkyZMnd58yZcrG0tLSxWVlZYt79+59wNqvqq6WcicFB6fhlrc2nTp1qnzjjTdWBdddRUXFwh49elQmJyfbhx56aNvatWuXf/TRR1+89957bZ944ol29SYYJQomRUREjgLPPfdc0d///veV6enp9d7qzMnJqdq7d2/C7t27a+3fN3bs2NJZs2ZlvPfee60PHjxobrrpppzgIGr//v3x6enp1W3btq1ZtGhRq+AWR4B27dpVrVq16nBAeP311+98/vnnO86aNat1TU0N+/bti3vllVfalpaWxp155plfxsfH23vuuadjRUWFef755zM+++yzVCKgd+/elYMGDdr/k5/8pEt5ebmZN29eyssvv9z+sssuO9xyu3z58tTnn38+o7Kykt/85jedkpKS7De/+c0vy8rK4owxZGdnVwJMmTKl3Zo1a1KC0y8pKUkMlPvZZ5/NXLduXcro0aPDmqKoY8eOlevXr68zeL7iiit23H777V1WrVqVBLB169aEF198MQPgb3/7W9qnn36aUlVVRUZGRnVCQoJtqic1KZgUERE5CgwYMKBixIgR9fY3BCgoKDh43nnnlfTq1euEtLS0QUVFRYnB2wsLCw/ed999G8eNG9czOzs7v02bNjVZWVlVrVq1sgAPPvjgptdffz2rTZs2BVdffXX3733ve18b7HPzzTdvve666/LS0tIG/eEPf8gcMWJE+WOPPVY0ceLEbm3bth3Uq1evgYF+i61atbKvvvrq2pdeeql9VlbWoOnTp2eNGjVqT6TqZPr06es2bdqU1Llz5/wxY8b0uuWWW7Z+73vfKwts/9a3vrVn+vTpWRkZGQWvvvpqu1dffXVtcnKyHTJkyMFrr722eMSIEf06dOiQv3Tp0pSCgoL9wWmfeOKJX65evbpV+/bt8++6667cF154YW12dnZ1OOUbP378rtWrV6ekpaUN+ta3vtUrdPvtt9++45xzztnzne9857jWrVsXDB069PhPPvmkNbjuCBdeeGGvtLS0gv79+w8cNmxY2Q033NCoLg5+meD/No41hYWFdv78+U1dDBERaUaMMQustYWB10uWLCnKz8/fVd97jmZ79+6Na9euXcGyZcuWHn/88b4H9kjLt2TJkvb5+fl5oevVMikiIiJf89JLL7UtKyuL27dvX9z48eO79OnT58Bxxx2nQFJqpWBSREREvuatt97KyMnJOTE3N/fE9evXt3rllVfWBo9cFgmmqYFERETka1599dUNwIamLoe0DPo3Q0RERER8UzApIiIiIr4pmBQRERER3xRMioiIiIhvCiZFRERExDcFkyIiItIgvXv3HjBz5sy0uraPGDGiz9SpU5vk+dChcnNzT3jzzTfrLGukfOMb3+j78MMPt/fz3tGjR+dNnDgxp67tqampBStWrEgK3ffdd99tk5eXN7Cu961evTopNTW1oKqqyk+xwqapgURERMK0tu+dQ6KZfq+Vdy5oyH7GmCFLly5dNnDgwIrAusmTJ+esXbs2+a233lof6XKtWbNmeX35zJ49e3Uk8pk5c2baVVdd1aO4uPizSKQXavTo0Xl//etfsxITE21iYqIdMGDAl48//vimgoKCg9HIz6/y8vJFta0/66yz9hcVFS0LvM7NzT3h8ccfLwo8KrJPnz6H6npvNKhlUkRERI4548eP315eXr5o8+bNn7Vv377q8ssvzwvdp6amhurqsB63fUxSMCkiInKUmjlzZlqnTp1OvOOOOzplZWXld+jQ4cQpU6Ycvg09evTovEsvvbTbiBEj+qSmphYMHjz4+I0bNyZceeWVXdPT0wf16NFjwMcff5wS2D9w63jGjBnpU6dOzX777bczU1NTC/r27dsfvn7Lt6qqimuuuaZLZmZmfm5u7gn33ntvB2PMkMrKSgCmTJnSrmfPngNat25d0KVLlxN++9vftgfYt29f3JgxY/rs3LkzMTU1tSA1NbWgqKgosbq6mttuuy27a9euAzMyMgadc845PYuLi+MDZXv88cezcnJyTsjIyBh0yy23ZDe0jtLS0mouvvjiktWrV6cEPsOECRNyBw8efHxqaurgzz//PPm9995rPXDgwH5paWmDBg4c2O+9995rHZzG2rVrk0844YR+bdq0KTjzzDN7BZfr7LPP7tm+ffv8tLS0QYWFhX3nz5/fKvi9u3btSjjllFP6tG7duuCkk07qu2rVqqTANmPMkGXLliXXdVwBvve97/XYtm1b0g9/+MM+qampBbfffnunlStXJgXX9e7du+MvvPDC7h06dDixY8eOJ06cODEncAt82bJlySeddFLftLS0QZmZmfnnnntuz4bWXYCCSRERkaPY7t27E/fu3Ru/bdu2zx577LENt956a7edO3ceDnbefvvtzHvuuWfLrl27FiclJdUMGzas3+DBg8tLSkoWn3feeaWTJ0/uGprmmDFj9k2YMGH7ueeeW1peXr5o5cqVK0L3efjhhzvMmjWr7fz581csXrx4xcyZMzODt3fq1Knqb3/725qysrJFTz/99Ppf/epXXefMmZOanp5eM2PGjNUdOnSoLC8vX1ReXr4oLy+v8t577+349ttvZ3zwwQcrt23btiQjI6P66quv7gawYMGCVjfddFP3P/7xj+u3bdu2ZPfu3QnFxcVJoWWqzd69e+P+8pe/ZPXr1688sG7GjBlZzzzzTFFZWdnCtm3bVo8ePbrP+PHji0tKShZPmDChePTo0X22b99+uA5fe+21ds8+++z6rVu3LklISODaa6/tFtg2atSovatXr166Y8eOJSeeeGL5pZde+rVg7a233mr3y1/+ctuuXbsWDxw4sHzs2LE9GlLugDfffHN9586dD73yyiury8vLF919993Fofv88Ic/zEtISGDt2rXLFi1atOL9999v+/vf/749wM9//vOcM844Y++ePXsWb9my5bOJEyfuCCd/UDApIiJyVEtISLC//e1vtyYnJ9uLLrpob0pKSs1nn312uHVs1KhRe0477bTy1NRUe9555+1JTk6uufHGG3cnJCRw6aWXlq5YsSLVT75vvPFG5vXXX1/cq1evyg4dOlTffPPN24K3//CHP9w7YMCAiri4OM4999z9p5566r7333+/TV3pPffccx3uuuuuLb169apMSUmx991339Z33nkns7KykpdffjnzjDPO2Hv22WfvT0lJsQ8//PBWY4ytr3xPP/10dlpa2qBevXqd8OWXX8a/8MILRYFtF1100e7CwsKDiYmJ/PWvf03v3r17xY9//OOSxMRErrvuupKePXsenD59ekZg/zFjxuw+6aSTDqanp9fce++9W/7+979nBlr+Jk2atDszM7MmJSXFPvjgg1tXrlyZsnv37sOB6De/+c3D5X7kkUe2LF68uM2aNWsSw67wOmzatCnhww8/bPvMM89sTE9Pr8nNza268cYbi2fMmJEF7vzYuHFjclFRUWJqaqodNWrU/nDz0AAcERGRFio+Pp5Dhw6Z4HWVlZUmMTHxcCDVtm3bqsTEr2KTlJSUmrKyssONSR07dqwM3ta+ffvDQ4BTU1NrDhw4cDjwCUdxcXFit27dDqfdo0ePQ8Hbp0+fnn7PPffkFBUVtaqpqeHgwYNxAwYMOFBXetu2bUu65JJLegcHifHx8WzevDlx69atibm5uYfTT09Pr8nIyKh3KPN11123/dFHH91a27auXbseTmvr1q1JXbp0qQje3qVLl0NbtmxJrG3/Pn36HKqqqjLbtm1L6Ny5c9XEiRNz//a3v2WWlpYmBsq+ffv2hHbt2lUDBJe7bdu2Nenp6VUbN25M6t27dyURsGbNmqSqqirTuXPn/MA6a63Jzs4+BDBlypTNN998c+6wYcP6paenV994443bJ02atDucPNQyKSIi0kJl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ICciJRIRERGRFiPcATgLgZOAVcAHwN3GmE7ApcBnkS2aiIiIiDR34bZM/gLY6v1+O7ATN1l5Jv89ibmIiIiIHOXCapm01s4P+n0nboogERERETlGhT3PJIAxphfQz3u5wlq7LnJFEhEREZGWItx5JtsBfwS+C9R8tdrMBK601u6OcPlEREREpBkLt8/kH4DewGlAK28ZAfQApkW2aCIiIiLS3IV7m3sUcKa1dm7Quo+NMdcB/4pcsURERESkJQi3ZXIn8GUt68sB3eIWEREROcaEG0zeBTxijMkNrPB+fwg9l1tERETkmHPE29zGmKWADVrVAygyxmzxXgee090R16dSRERERI4RDekzOSPqpRARERGRFumIwaS19texKIiIiIiItDx+Jy0/A+iPu/293Fr7QSQLJSIiIiItQ7iTlucC/wsM4atndOcYY+YD37fWbq3zzSIiIiJy1Al3NPejQDXQ21rb1VrbFejjrXs00oUTERERkeYt3Nvc3wZOt9auD6yw1q4zxkwE/i+iJRMRERGRZi/clkn4+jRB9a0TERERkaNcuMHk/wFTjTFdAyuMMd2AR1DLpIiIiMgxJ9xgciLQGlhnjNlgjNkArPXWTYx04URERESkeQu3z+Ru4BvA6cDx3rrPrbX/imShRERERKRlaHAwaYyJB/YC+dba94D3olYqEREREWkRGnyb21pbDWwAkqJXHBERERFpScLtM/kb4H5jTPtoFEZEREREWpZw+0z+DOgBbDHGbAa+DN5orT0xUgUTERERkeYv3GByBm5OSROFsoiIiIhIC9OgYNIYkwr8FvgekIibU3KCtXZX9IomIiIiIs1dQ/tM/hq4HHgbeBn4FvBklMokIiIiIi1EQ29zXwBcZa19BcAY8xfgY2NMvDfKW0RERESOQQ1tmewKfBR4Ya39FKgCcqJRKBERERFpGRoaTMYDh0LWVRH+AB4REREROYo0NBg0wIvGmIqgda2AacaY8sAKa+13I1k4EREREWneGhpMPl/LuhcjWRARERERaXkaFExaa6+IdkFEREREpOUJ93GKIiIiIiKHKZgUEREREd8UTIqIiIiIbwomRURERMQ3BZMiIiIi4puCSRERERHxTcGkiIiIiPimYFJEREREfFMwKSIiIiK+KZgUEREREd8UTIqIiIiIbwomRURERMQ3BZMiIiIi4puCSRER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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAApMAAAFLCAYAAACKkwciAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABIeElEQVR4nO3deXwV1f3/8dfJSgIJCWtI2BdRQEMglqIIVttq9WtthWpdq9YNWyjlV5daW611qbZacV9arda6IPrVFqut/eKGpVhWRZR93yEswUDI8vn9cSZ4TZOQO7n3ksD7+XjMg9yZueece2bm3g9nzjnjzAwRERERkTCSDnYBRERERKTlUjApIiIiIqEpmBQRERGR0BRMioiIiEhoCiZFREREJDQFkyIiIiISWsrBLsDB1KFDB+vZs+fBLoaIiDQjs2fP3mpmHSNed0pJSfk9MAg1wsjhx5xzO6uqqp6srq5+eOjQoftq73BYB5M9e/Zk1qxZB7sYIiLSjDjnVkW+TklJ+X1eXt5RHTt23J6UlKTJmeWwYmbs27cvdf369eN27do1BPhe7X30PywREZGGDerYseMuBZJyOHLOkZ6eXtGjR4+dwIi69lEwKSIi0rAkBZJyuAuugeQ6tyW4LCIiIiJyCFEwKSIicog777zzul9zzTVd6tt+/fXX551zzjk9Elmm+owePbrn+PHj8+Odz8SJE/PPPPPMXmHee99997UfOnRo//q2jxw5st/999/fvq59MzMzixYuXJhW33v79u07cOrUqVlhynWwHNYDcERERMK4/F6GxjP9xycwuzH7FRQUHL158+bU1atXf9ilS5fKmvVHHXXUgE8//TTj008//ah///77nn322dU126ZOnZr1/e9/v9emTZs+rFn361//emOsyu6cG/rRRx8tGDRoUHms0qxx3333tf/xj3/cMz09vTopKYmuXbuW33TTTevOPffcnbHOqynefffdJfVtKysrm1vz9+jRo3sWFBTsu++++9bXrFu6dOnH8S5frKllUkREpAUrKCjY98QTT7Sref3BBx9k7Nmz55D9fR88ePDusrKyuTt37px74YUXbr300kt7b9my5b/68lVUVByM4h2WDtmTTURE5HBw9tlnb3vuuefa17z+/e9/3/6cc87ZGrlPza3jXbt2JY0ZM6bfli1bUjMzM4syMzOLVq5cmVr7lu8DDzzQPj8//+icnJzB11xzTZeCgoKjX3nllSyAt956K3Pw4MFHZmVlDe7YseMxF110Ufe9e/c6gOLi4v4Axx577IDMzMyixx9/PBfgueeea3vkkUcOyMrKGlxUVHTkzJkzM2ryev/99zMGDBhwVOvWrYtOP/303uXl5Y2KTZKTkxk3btzWvXv3Jn3yySfpEydOzD/11FN7n3nmmb3atGlTdP/993dYuXJl6kknndS3bdu2g7t37z7o7rvv7hCZRnl5uTv99NN7t27dumjAgAFHzZgxY3+5brjhhrxu3boNat26dVGfPn0GPv300zmR7zUzd9FFF3XPysoa3KtXr4Gvvvrq/lvTX/rSl/rfc889X8irhnNu6IIFC9J/+9vfdnj11VfbPfzww3mZmZlFJ510Ul/wrc01dV1VVbW/HDk5OYNPO+203ps2bUoGKCsrc2eeeWavnJycwVlZWYMHDRp01Jo1aw7KHWcFkyIiIi3Ycccdt3v37t3Jc+bMaVVZWcmrr77a7vvf/35JXftmZ2dXT5kyZUnHjh0rysrK5paVlc3t2bPnF5rwZs+e3eraa6/t/uSTT67YuHHj/J07dyZv2rQptWZ7SkoKd99995qSkpJ506dP/3T69OlZd911V0eAWbNmLQL4z3/+s7CsrGzu5Zdfvv3999/P+MEPftDzoYceWrV9+/Z5l1566Zazzjqr7549e9zevXvdd77znb7nnHPOtpKSknljxozZ/sYbb+Q05nNXVFQwadKkDpmZmdUDBw4sB/jnP/+ZM2bMmO07d+6ce8UVV2wbM2ZM7/z8/H0bNmyY//zzzy+79dZbC/7yl7/sD/pq9g/yLhkzZkzf8vJyB9C3b9/y9957b9GuXbvmXn/99euvvPLKXqtWrdpfDx9++GHrPn367N26dev8G264Yf0FF1zQpybQa4yf/OQnW88888ySsWPHbiwrK5s7bdq0pbX3uf322zu99tprOW+//faiDRs2zM/Jyam67LLLugM8+OCD7UtLS5PXrFnz4fbt2+c9/PDDq1q3bl3d2PxjScGkiIhIC3f22Wdv+8Mf/tD+lVdeye7Tp8+eXr16/ddTShrrueeeyz355JN3nHLKKbtbtWpld99993rn3P7tJ5xwQtnJJ5/8WWpqKv3799938cUXb3nvvffqHTDy0EMPdbzwwgu3nHTSSZ+lpKQwbty4bampqTZt2rTWb731VuvKykr385//fHN6erpdcskl248++uiyhso3f/78NllZWYM7depUOGXKlHZ//vOfl7Zv374KYPDgwZ9deOGFO5KTk9m4cWPK3Llz29x///1rMzMz7bjjjttz3nnnbX3qqaf2t+IOHDiw7JJLLtmenp5uN91006Z9+/a5t956qzXApZdeur1nz54VycnJXH755dt79OhR/t5777WueW+7du0qasp9+eWXb+/Zs2f5lClT2oat97o8+eSTHW+55ZZ1ffr0qcjIyLA77rhj/euvv55bUVFBamqqbd++PWXhwoXpKSkpnHDCCWXt2rU7KMGkBuCIiIi0cJdddtm2E088sf+qVavSzz///G1NSWv9+vWpBQUF+1srs7KyqnNycvYP7vnwww/Tf/SjH3X76KOPWu/duzepqqqKAQMG1BsArl27Nu3ll19u/8QTT3SqWVdZWenWrl2b5pyzTp06VSQlfd621bVr1wYH7hQWFu6ePXv2orq25efn7w+iV69enZadnV2Zm5u7P8Dq0aPHvrlz52bWtX9ycjKdO3euWLNmTSr4W/0PPPBA53Xr1qUB7NmzJ3nLli3746a6yr1+/fp6R2mHsWHDhrTzzz+/r3Nu/zynycnJrF27NnXs2LEla9asSTvvvPN6l5aWJp911lklkyZNWpeenp7wOVHVMikiItLCHXHEEfu6du267+2332574YUX7mho38jApC5dunSpWLdu3f7bubt373Y7duzYH0RdeeWVPfr167d3yZIlH+3evXvuT3/603UNpVdQUFAxfvz4DaWlpfNqlj179sy98sorSwoKCio2b96cWl39eYPaunXr0g/0eRv4bPv/7t69+75du3albN++fX+ss3r16rQuXbrsD5Qjg7+qqio2bdqU2q1bt4rFixenTZw4scekSZNWb9++fV5paem8vn377jH7vOrqKHdaZHAabXnr0rlz54qXX355cWTdlZeXz+nVq1dFenq63X333RuWLVv28Xvvvffpm2++2fahhx5q32CCcaJgUkRE5BDw5JNPrvzb3/62KDs7u8Fbnfn5+ZU7d+5M2bZtW539+84999zt06ZNy3nzzTdb7927111zzTX5kUHU7t27k7Ozs6vatm1bPXfu3FaRLY4A7du3r1y8ePH+gPCqq67a8tRTT3WaNm1a6+rqanbt2pX0/PPPt92+fXvSySef/FlycrLddtttncrLy91TTz2V8+GHH2YSA3379q0YPHjw7h/96Eddy8rK3MyZMzOee+65DhdeeOH+ltuPP/4486mnnsqpqKjgV7/6Vee0tDT7yle+8llpaWmSc468vLwKgEmTJrVfunRpRmT6JSUlqTXlfuKJJ3KXL1+eMXr06KimKOrUqVPFihUr6g2eL7nkks033nhj18WLF6cBrF+/PuWZZ57JAfjrX/+a9cEHH2RUVlaSk5NTlZKSYgfrSU0KJkVERA4BAwcOLB85cmSD/Q0BioqK9p5xxhklffr0OTorK2vwypUrUyO3FxcX773jjjtWX3TRRb3z8vIK27RpU92uXbvKVq1aGcBdd9215qWXXmrXpk2bossuu6zHt771rS8M9rn22mvXX3nllT2zsrIG//73v88dOXJk2QMPPLBy/Pjx3du2bTu4T58+g2r6LbZq1cpeeOGFZc8++2yHdu3aDZ48eXK7U045ZUes6mTy5MnL16xZk9alS5fCMWPG9LnuuuvWf+tb3yqt2f7Vr351x+TJk9vl5OQUvfDCC+1feOGFZenp6TZ06NC9V1xxxaaRI0ce1bFjx8KPPvooo6ioaHdk2sccc8xnS5YsadWhQ4fCW265peDpp59elpeXVxVN+caOHbt1yZIlGVlZWYO/+tWv9qm9/cYbb9x82mmn7fj6179+ROvWrYuGDRt25L///e/W4LsjnH322X2ysrKKBgwYMGj48OGlV199dZO6OITlIv+3cbgpLi62WbNmHexiiIhIM+Kcm21mxTWv58+fv7KwsHBrQ+85lO3cuTOpffv2RQsWLPjoyCOPDD2wR1q++fPndygsLOxZe71aJkVEROQLnn322balpaVJu3btSho7dmzXfv367TniiCMUSEqdFEyKiIjIF7z66qs5+fn5xxQUFByzYsWKVs8///yyyJHLIpE0NZCIiIh8wQsvvLAKWHWwyyEtg/6bISIiIiKhKZgUERERkdAUTIqIiIhIaAomRURERCQ0BZMiIiIiEpqCSREREWmUvn37Dpw6dWpWfdtHjhzZ7/777z8oz4euraCg4OhXXnml3rLGype+9KX+99xzT4cw7x09enTP8ePH59e3PTMzs2jhwoVptfd944032vTs2XNQfe9bsmRJWmZmZlFlZWWYYkVNUwOJiIhEaVn/m4fGM/0+i26e3Zj9nHNDP/roowWDBg0qr1k3ceLE/GXLlqW/+uqrK2JdrqVLl37cUD7vvvvukljkM3Xq1Kzvf//7vTZt2vRhLNKrbfTo0T3/8pe/tEtNTbXU1FQbOHDgZw8++OCaoqKivfHIL6yysrK5da0/9dRTd69cuXJBzeuCgoKjH3zwwZU1j4rs16/fvvreGw9qmRQREZHDztixYzeWlZXNXbt27YcdOnSovPjii3vW3qe6upqqqqget31YUjApIiJyiJo6dWpW586dj7nppps6t2vXrrBjx47HTJo0af9t6NGjR/e84IILuo8cObJfZmZm0ZAhQ45cvXp1yqWXXtotOzt7cK9evQa+//77GTX719w6njJlSvb999+f99prr+VmZmYW9e/ffwB88ZZvZWUll19+edfc3NzCgoKCo2+//faOzrmhFRUVAEyaNKl97969B7Zu3bqoa9euR//mN7/pALBr166kMWPG9NuyZUtqZmZmUWZmZtHKlStTq6qquOGGG/K6des2KCcnZ/Bpp53We9OmTck1ZXvwwQfb5efnH52TkzP4uuuuy2tsHWVlZVWfd955JUuWLMmo+Qzjxo0rGDJkyJGZmZlDPvnkk/Q333yz9aBBg47KysoaPGjQoKPefPPN1pFpLFu2LP3oo48+qk2bNkUnn3xyn8hyfeMb3+jdoUOHwqysrMHFxcX9Z82a1SryvVu3bk057rjj+rVu3bro2GOP7b948eK0mm3OuaELFixIr++4AnzrW9/qtWHDhrTvfve7/TIzM4tuvPHGzosWLUqLrOtt27Yln3322T06dux4TKdOnY4ZP358fs0t8AULFqQfe+yx/bOysgbn5uYWnn766b0bW3c1FEyKiIgcwrZt25a6c+fO5A0bNnz4wAMPrLr++uu7b9myZX+w89prr+Xedttt67Zu3TovLS2tevjw4UcNGTKkrKSkZN4ZZ5yxfeLEid1qpzlmzJhd48aN23j66advLysrm7to0aKFtfe55557Ok6bNq3trFmzFs6bN2/h1KlTcyO3d+7cufKvf/3r0tLS0rmPPvroil/84hfdpk+fnpmdnV09ZcqUJR07dqwoKyubW1ZWNrdnz54Vt99+e6fXXnst5+233160YcOG+Tk5OVWXXXZZd4DZs2e3uuaaa3r84Q9/WLFhw4b527ZtS9m0aVNa7TLVZefOnUl//vOf2x111FFlNeumTJnS7rHHHltZWlo6p23btlWjR4/uN3bs2E0lJSXzxo0bt2n06NH9Nm7cuL8OX3zxxfZPPPHEivXr189PSUnhiiuu6F6z7ZRTTtm5ZMmSjzZv3jz/mGOOKbvgggu+EKy9+uqr7X/+859v2Lp167xBgwaVnXvuub0aU+4ar7zyyoouXbrse/7555eUlZXNvfXWWzfV3ue73/1uz5SUFJYtW7Zg7ty5C9966622v/vd7zoA/PSnP80/6aSTdu7YsWPeunXrPhw/fvzmaPIHBZMiIiKHtJSUFPvNb36zPj093c4555ydGRkZ1R9++OH+1rFTTjllxwknnFCWmZlpZ5xxxo709PTqH/7wh9tSUlK44IILti9cuDAzTL4vv/xy7lVXXbWpT58+FR07dqy69tprN0Ru/+53v7tz4MCB5UlJSZx++um7jz/++F1vvfVWm/rSe/LJJzvecsst6/r06VORkZFhd9xxx/rXX389t6Kigueeey73pJNO2vmNb3xjd0ZGht1zzz3rnXPWUPkeffTRvKysrMF9+vQ5+rPPPkt++umnV9ZsO+ecc7YVFxfvTU1N5S9/+Ut2jx49yn/wgx+UpKamcuWVV5b07t177+TJk3Nq9h8zZsy2Y489dm92dnb17bffvu5vf/tbbk3L34QJE7bl5uZWZ2Rk2F133bV+0aJFGdu2bdsfiH7lK1/ZX+5777133bx589osXbo0NeoKr8eaNWtS3nnnnbaPPfbY6uzs7OqCgoLKH/7wh5umTJnSDvz5sXr16vSVK1emZmZm2imnnLI72jw0AEdERKSFSk5OZt++fS5yXUVFhUtNTd0fSLVt27YyNfXz2CQjI6O6tLR0f2NSp06dKiK3dejQYf8Q4MzMzOo9e/bsD3yisWnTptTu3bvvT7tXr177IrdPnjw5+7bbbstfuXJlq+rqavbu3Zs0cODAPfWlt2HDhrTzzz+/b2SQmJyczNq1a1PXr1+fWlBQsD/97Ozs6pycnAaHMl955ZUb77vvvvV1bevWrdv+tNavX5/WtWvX8sjtXbt23bdu3brUuvbv16/fvsrKSrdhw4aULl26VI4fP77gr3/9a+727dtTa8q+cePGlPbt21cBRJa7bdu21dnZ2ZWrV69O69u3bwUxsHTp0rTKykrXpUuXwpp1Zuby8vL2AUyaNGnttddeWzB8+PCjsrOzq374wx9unDBhwrZo8lDLpIiISAuVl5e3b+nSpV+4nbty5cq07t2776vvPbFyoJa/Tp06VaxZs2Z/wLVixYr95dyzZ4/73ve+12fChAmbNm/ePL+0tHTeqFGjdppZvWl37ty54uWXX15cWlo6r2YpLy+f06tXr4ouXbpUrFu3bn/6paWlSTt27AjdYObc5/F5fn7+vrVr136h3+K6devSCgoK9gd7a9as2Z/30qVL01JSUqxLly6Vjz76aLs33ngj580331y8a9euuStWrPgIoOZz1qRV8/fOnTuTdu3alRLL49e7d++KtLQ0Kykp2V9vu3fvnlszMr979+6Vzz///KrNmzd/+OCDD6667rrretTVT7MhCiZFRERaqDPPPLPk17/+df6yZctSq6qqeOWVV7KmTZuWc+6555bEO+/OnTtXrl27Nq2+0c5nnXXW9kceeaTzihUrUrdu3Zp811137R8Us3fvXrdv376kTp06VaSmptrkyZOz33///eya7fn5+ZU7d+5MibwdfMkll2y+8cYbu9YMUFm/fn3KM888kwNw7rnnbp82bVrbv//972327t3r/t//+3/5ZvaFFtuwRo8evXPlypXpjzzySLuKigoef/zx3KVLl7b6zne+s7Nmn5deeqn97NmzW5WWlib97Gc/yz/11FO3p6SkUFpampyWlmadOnWq3L17d9KECRMKaqf/9ttv7y/3xIkTCwoLCz+LtlWyQ4cOFUuXLq0zAOzRo0fF8ccfv/OKK67oVlJSklRVVcXHH3+c/tprr7UBeOKJJ3KXLVuWCtC+fftK5xxJSUkN/kehNgWTIiIiLdSdd965/thjj909cuTII3NycgbfcMMNXR977LHlxx57bNznS7zoootKAHJzcwcPGDDgqNrbJ06cuGXUqFG7ioqKBhYWFg445ZRTdiYnJ1tycjK5ubnVt9566+qLLrqoT9u2bQc/++yz7U8++eT9wVlRUdHeM844o6RPnz5HZ2VlDV65cmXqjTfeuPm0007b8fWvf/2I1q1bFw0bNuzIf//7360BiouL9955552rL7744l55eXmFubm5lZ07d45J615eXl7VlClTlt5///2d27VrN/jee+/NmzJlytIuXbrsv40+ZsyYbRdffHGvLl26FJaXlyc99thjawDGjh27raCgoLxbt26F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jwEeMDMDqoB0M9sEXIemBhIRERE57EQbTO6L+HsT0CP4ezeQH5MSiYiIiEiLEe0AnDnAscBi4G3gVudcZ+AC4MPYFk1EREREmrtoWyZ/BqwP/r4R2IKfrDyX/57EXEREREQOcVG1TJrZrIi/t+CnCBIRERGRw1TU80wCOOf6AEcFLxea2fLYFUlEREREWopo55lsD/wB+CZQ/flqNxW41My2xbh8IiIiItKMRdtn8vdAX+AEoFWwjAR6AY/HtmgiIiIi0txFe5v7FOBkM5sRse5959yVwD9jVywRERERaQmibZncAnxWx/oyQLe4RURERA4z0QaTtwD3OucKalYEf9+NnsstIiIictg54G1u59xHgEWs6gWsdM6tC17XPKe7E75PpYiIiIgcJhrTZ3JK3EshIiIiIi3SAYNJM/tlIgoiIiIiIi1P2EnLTwIG4G9/f2xmb8eyUCIiIiLSMkQ7aXkB8L/AUD5/Rne+c24W8G0zW1/vm0VERETkkBPtaO77gCqgr5l1M7NuQL9g3X2xLpyIiIiING/R3ub+GnCima2oWWFmy51z44H/i2nJRERERKTZi7ZlEr44TVBD60RERETkEBdtMPl/wP3OuW41K5xz3YF7UcukiIiIyGEn2mByPNAaWO6cW+WcWwUsC9aNj3XhRERERKR5i7bP5DbgS8CJwJHBuk/M7J+xLJSIiIiItAyNDiadc8nATqDQzN4E3oxbqURERESkRWj0bW4zqwJWAWnxK46IiIiItCTR9pn8FfBr51yHeBRGRERERFqWaPtM/gToBaxzzq0FPovcaGbHxKpgIiIiItL8RRtMTsHPKeniUBYRERERaWEaFUw65zKB3wDfAlLxc0qOM7Ot8SuaiIiIiDR3je0z+UvgYuA14Dngq8DDcSqTiIiIiLQQjb3NfRbwfTN7HsA592fgfedccjDKW0REREQOQ41tmewGvFfzwsw+ACqB/HgUSkRERERahsYGk8nAvlrrKol+AI+IiIiIHEIaGww64BnnXHnEulbA4865spoVZvbNWBZORERERJq3xgaTT9Wx7plYFkREREREWp5GBZNmdkm8CyIiIiIiLU+0j1MUEREREdlPwaSIiIiIhKZgUkRERERCUzApIiIiIqEpmBQRERGR0BRMioiIiEhoCiZFREREJDQFkyIiIiISmoJJEREREQlNwaSIiIiI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\n", "text/plain": [ "
" ] @@ -278,7 +279,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 12, @@ -287,7 +288,7 @@ }, { "data": { - "image/png": "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iaQ+6rNly5botLHVZsyY4bfddpu7R6aYveaaa9zd/bnnnvMhQ4a4e2Tq265du/quXbv8448/9iOOOMJnz57t7u4//elP/c4773T3vafbjTd97IoVKzw7O9vLy8t9165d/q1vfSu6/U8++STa/xe/+IXffffd+6zX3f073/mOv/vuu+7u/sYbb3hBQYG7u59zzjn+6KOPurv7vffe623btq11HFq1ahWddjc7O9sXLlzo7u4vvviin3LKKb5gwQI/44wz/vN7An/iiSfc3f3mm2+OTgMcr44LLrggOiaVlZW+c+fOfca+oqLCS0tL3d1927Zt3rVrV//qq6/26Rf7fNasWdGphTds2OCdOnXy8vJyf+SRR7xLly6+c+dOLy8v986dO/vWrVv3ed+aPlckIPG+KDi2fdSoUcC+07cWFBTQvn376Lwt55xzDgBZWVkNmkDrz3/+MyNHjiQ1NZXU1NToeiAyGdcNN9zAzp07KSsr44wzztjn9WVlZbz++uucf/750bYvvvgiuu5nnnkGgB/+8IdMnTq11hqqD7nUNGzYMJ566ikmT57M2rVro+2tWrXiBz/4AQAXX3wxo0aNqrOOV155JfolGykpKXTo0IEdO3bstS135+c//znLly+nVatWfPDBB3z00UfxB47IpGJXXnklAD179uSEE07g3XffBWDIkCHR+XR69+7Ne++9R6dOnepcX30U6CIHsY4dO+4TLJ9++ml0XnP4zxSuKSkpe02uFTu1a6tWraLPW7VqtVe//TFu3DgWL15MdnY2c+fOrfXuzq+++oojjzyy1kCGxn27fey6N2zYwOGHH86OHTtIT0+Pu4366qjPvHnz2LZtG2+++SZt2rQhIyMjqVPvJuN3EvgxdJGWrV27dhx77LG88sorQCTM//CHP3DaaaclfVvxpo8dOHAgv/vd79izZw9lZWX8/ve/jy777LPPOPbYY6moqGDevHm1ruuII46gS5cuPPXUU0BkT7d6b3rgwIEsXLgQYK/XJ+rOO++kV69ezJ8/n/Hjx0e/nOOrr76KnpicP38+p512Wp11DBkyhNmzZwORr7IrLS3dZzxKS0s5+uijadOmDUuXLuW9996rc9wgMvVu9ft699132bp1a5PMJ19Ne+giDVDfZYZN4bHHHmPy5Mlcc801AMyYMYOuXbsmfTvV08ced9xx0ZN3ACed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\n", + "image/png": "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BbpIHaR6FL0usrKyokMbiRQVFXHHHXeQn5/Ppk2bouuPOuooHnzwQYYNG0bv3r1p2bIlrVq1AuD666/nhhtuID8/PxqGAIMGDWL9+vXRk6I33XQT5eXl9OjRg+7du3PTTTcBkZOMpaWldO3alWnTptG7d++E9V188cXRyxaHDBnCF198wYQJE3j00Uc56aSTuPPOO7n00kujYZ2ZmUl+fj6XXXYZjzzyCEDCOsaPH0+7du3o0aMHeXl50V8yEydOZNiwYQwaNIi8vDzy8/Pp0qULF110Ef3794/WFtsuVq9evRg7dix9+vShb9++jB8/nvz8/Jp/WGliXtd3VYoUFBR4fT/gIvkbqAor/12WVOs0dUWjVPVn+bJly9JaR0PbsGEDXbt2TXcZKVFaWkqLFi1wdyZNmkTHjh255ppr0l1WQoWFhcycOfOAMfcjSXXvPzN7092r7RSNoct+6nq3cbLt9csy/R5++GEef/xxvvzyS/Lz8/nRj36U7pIkxRToIkeIa6655rA+Io8X+l9/DUFj6CIigVCgi4gEQoEuIhIIBbqISCB0UlSkDuyW1H7YhU+v+fKfrVu3cu6557Ju3brouptvvpkWLVowefLkg37+adOmMWDAAIYMGcI999zDxIkTOfroo4HIhGDz5s2r14yDixYtolOnTnTr1q1Oj2vRogWlpaUHrM/IyNjvhqqioqLoDJMNZdeuXcybN48rrriiTu0+/PBDrr766kM2m2SswI/Ql5HsNegiR6LY6XVTOX1s/DS+B+uoo46KTru7Zs2aBg9ziAT1gw8+WOd2J510UlrCHIIPdJGwFRYWMmXKFPr06UOnTp149dVXgcgt/N/97ncZOnQo2dnZ3H///dx1113k5+dz+umnR2+Lr5pet7bpY2+99VY6d+7MGWecwejRo6MTYz388MOcdtpp5OXlMWrUKPbs2VPtNL6bNm2K3qV65pln8vbbbwORuVX69etHbm4uN954Y51ee0lJCZ07d+add94BIhN5Pfzww0DkSP+aa66he/fuDB48mO3btwMkrOOjjz7i/PPPJy8vj7y8PF5//XWmTp3Kpk2b6NmzJ9dddx2lpaUMHjyYXr16kZubG522N77d1q1bycnJASITh40bN47c3Fzy8/NZunRp9OczcuRIhg0bRseOHbn++uvr+qOvXqJpGBv662Cmz039DdjJT2UaOvXt/g6YPvdmUvpVmy1btkSnja0yffp0v+OOO9w9MsXstdde6+7uzz33nA8ePNjdI1PfdujQwXfv3u0ff/yxH3PMMT5r1ix3d//JT37id999t7vvP91uouljV6xY4Xl5eV5WVua7d+/2b3zjG9Hn/+STT6Ltf/7zn/u99957wH7d3b/1rW/5u+++6+7ub7zxhg8aNMjd3c877zx//PHH3d39/vvv9+bNm1fbD02aNIlOu5uXl+cLFixwd/cXX3zRTz/9dJ8/f76fddZZ//k5gf/mN79xd/dbbrklOg1wojq+973vRfukoqLCd+3adUDfl5eXe0lJibu7b9++3Tt06OD79u07oF3s8syZM6NTC2/YsMHbtm3rZWVl/thjj3n79u19165dXlZW5u3atfNt27Yd8LobZPpcMxsG/BLIAH7l7rfHbW8HPA4cW9lmqrun9qNORI5AiT4oOHb9yJEjgQOnbx00aBAtW7aMztty3nnnAZCbm1unCbT+/Oc/M2LECDIzM8nMzIzuByKTcd14443s2rWL0tJSzjrrrAMeX1payuuvv86FF14YXffFF19E9/3MM88A8IMf/IApU6ZUW0PVkEu8oUOH8tRTTzFp0iTWrl0bXd+kSRO+//3vA3DJJZcwcuTIGut45ZVXoh+ykZGRQatWrdi5c+d+z+Xu/OxnP2P58uU0adKEDz74gI8++ihxxxGZVOyqq64CoEuXLpxyyim8++67AAwePDg6n063bt147733aNu2bY37q02tgW5mGcADwFCgGFhpZovdPXaA7EbgSXefZWbdgCVA9kFVJiK0bt36gGD59NNPo/Oaw3+mcM3IyNhvcq3YqV2bNGkSXW7SpMl+7Q7G2LFjWbRoEXl5ecyZM6fauzv37dvHscceW20gQ/0+3T523xs2bODoo49m586dZGVlJXyO2uqozdy5c9m+fTtvvvkmzZo1Izs7O6VT76biZ5LMGHofYKO7b3b3L4EFwIi4Ng4cU/l9K+BDROpBn1W6vxYtWnDiiSfyyiuvAJEw/8Mf/sAZZ5yR8udKNH1s//79+d3vfsfevXspLS3l97//fXTbZ599xoknnkh5eTlz586tdl/HHHMM7du356mnngIiR7pVR9P9+/dnwYIFAPs9Pll33303Xbt2Zd68eYwbNy764Rz79u2LnpicN28eZ5xxRo11DB48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\n", "text/plain": [ "
" ] @@ -363,7 +364,7 @@ "source": [ "qubits = [0,3]\n", "num_qubits = len(qubits)\n", - "exp = ReadoutMitigationExperiment(qubits, method=\"correlated\")\n", + "exp = CorrelatedReadoutError(qubits)\n", "for c in exp.circuits():\n", " print(c)" ] From 9ac0a5269ece895376f04fa22a2034e23f5637d6 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 20 Jan 2022 12:39:09 +0200 Subject: [PATCH 14/32] Small fixes --- .../library/characterization/__init__.py | 4 ---- .../analysis/correlated_readout_error_analysis.py | 15 +++++++++------ .../analysis/local_readout_error_analysis.py | 6 +++++- .../characterization/correlated_readout_error.py | 2 +- .../characterization/local_readout_error.py | 4 ++-- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/qiskit_experiments/library/characterization/__init__.py b/qiskit_experiments/library/characterization/__init__.py index 8b733ee1f6..c651cc08b9 100644 --- a/qiskit_experiments/library/characterization/__init__.py +++ b/qiskit_experiments/library/characterization/__init__.py @@ -64,10 +64,6 @@ LocalReadoutErrorAnalysis CorrelatedReadoutErrorAnalysis -.. autosummary:: - :toctree: ../stubs/ - :template: autosummary/analysis.rst - """ from .analysis import ( diff --git a/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py index 0e3157bb28..e570c2e65b 100644 --- a/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py @@ -10,7 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """ -Correlated readout readout_error calibration analysis classes +Analysis class to characterize correlated readout error """ from typing import List, Tuple import numpy as np @@ -59,6 +59,7 @@ def _default_options(cls) -> Options: ax (AxesSubplot): Optional. A matplotlib axis object to draw. """ options = super()._default_options() + # since the plot size grows exponentially with the number of qubits, plotting is off by default options.plot = False options.ax = None return options @@ -74,7 +75,7 @@ def _run_analysis( analysis_results = [AnalysisResultData("Correlated Readout Mitigator", result_mitigator)] if self.options.plot: ax = options.get("ax", None) - figures = [self._plot_calibration(matrix, labels, ax)] + figures = [self._assignment_matrix_visualization(matrix, labels, ax)] else: figures = None return analysis_results, figures @@ -92,16 +93,18 @@ def _generate_matrix(self, data, labels) -> np.array: matrix[i][j] = count / total_counts return matrix - def _plot_calibration(self, matrix, labels, ax=None) -> "matplotlib.figure.Figure": + def _assignment_matrix_visualization( + self, matrix, labels, ax=None + ) -> "matplotlib.figure.Figure": """ - Plot the calibration matrix (2D color grid plot). + Plot the assignment matrix (2D color grid plot). Args: - matrix: calibration matrix to plot + matrix: assignment matrix to plot ax (matplotlib.axes): settings for the graph Returns: - The generated plot of the calibration matrix + The generated plot of the assignment matrix Raises: QiskitError: if _cal_matrices was not set. diff --git a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py index c71c118306..4d7ca49050 100644 --- a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py @@ -10,7 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """ -Local readout readout_error calibration analysis class +Analysis class to characterize local readout error """ from typing import List, Tuple import numpy as np @@ -60,6 +60,7 @@ def _default_options(cls) -> Options: ax(AxesSubplot): Optional. A matplotlib axis object to draw. """ options = super()._default_options() + # since the plot size grows exponentially with the number of qubits, plotting is off by default options.plot = False options.ax = None return options @@ -117,5 +118,8 @@ def assignment_matrix_visualization(assignment_matrix, ax=None): ax.set_yticklabels(n * [""]) ax.set_xticklabels(n * [""]) ax.set_xlabel(r"$|A - I|$", fontsize=16) + ax.set_xlabel("Prepared State") + ax.xaxis.set_label_position("top") + ax.set_ylabel("Measured State") figure.colorbar(im2, ax=ax) return figure diff --git a/qiskit_experiments/library/characterization/correlated_readout_error.py b/qiskit_experiments/library/characterization/correlated_readout_error.py index 398fd3febe..b68f7b4194 100644 --- a/qiskit_experiments/library/characterization/correlated_readout_error.py +++ b/qiskit_experiments/library/characterization/correlated_readout_error.py @@ -32,7 +32,7 @@ class CorrelatedReadoutError(BaseExperiment): The readout mitigator is generated from an *assignment matrix*: a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the probability to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used - to compute the *assignment matrix* used in the readout error mitigation process itself. + to compute the *mitigation matrix* used in the readout error mitigation process itself. A *Correlated readout mitigator* uses the full :math:`2^n \times 2^n` assignment matrix, meaning it can only be used for small values of :math:`n`. diff --git a/qiskit_experiments/library/characterization/local_readout_error.py b/qiskit_experiments/library/characterization/local_readout_error.py index d582b26eef..28f5a0aa64 100644 --- a/qiskit_experiments/library/characterization/local_readout_error.py +++ b/qiskit_experiments/library/characterization/local_readout_error.py @@ -32,9 +32,9 @@ class LocalReadoutError(BaseExperiment): The readout mitigator is generated from an *assignment matrix*: a :math:`2^n \times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the probability to observe :math:`y` given the true outcome should be :math:`x`. The assignment matrix is used - to compute the *assignment matrix* used in the readout error mitigation process itself. + to compute the *mitigation matrix* used in the readout error mitigation process itself. - A *Local readout mitigator* works under the assumption the readout errors are mostly + A *Local readout mitigator* works under the assumption that readout errors are mostly *local*, meaning readout errors for different qubits are independent of each other. In this case, the assignment matrix is the tensor product of :math:`n` :math:`2 \times 2` matrices, one for each qubit, making it practical to store the assignment matrix in implicit From 34a33471ddf6ce5b435d803a0fb9fca144dae31b Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 20 Jan 2022 13:28:20 +0200 Subject: [PATCH 15/32] Changes in figure display --- docs/tutorials/readout_mitigation.ipynb | 196 ++++++------------ .../analysis/local_readout_error_analysis.py | 3 +- 2 files changed, 61 insertions(+), 138 deletions(-) diff --git a/docs/tutorials/readout_mitigation.ipynb b/docs/tutorials/readout_mitigation.ipynb index c06882acef..324e480f86 100644 --- a/docs/tutorials/readout_mitigation.ipynb +++ b/docs/tutorials/readout_mitigation.ipynb @@ -12,9 +12,15 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Readout mitigation is part of `qiskit-terra`. The readout mitigators can be initalized based on existing backend data, or via a readout mitigation experiment.\n", + "Readout errors affect quantum computation during the measurement of the qubits in a quantum device. By characterizing the readout errors, it is possible to construct a *readout error mitigator* that is used both to obtain a more accurate distribution of the outputs, and more accurate measurements of expectation value for measurables.\n", "\n", - "In a readout mitigation experiment, simple circuits are generated for various combinations of \"0\" and \"1\" readout values. The results give us a matrix describing the probability to obtain a wrong measurement. This matrix is used to initialize the readout mitigation object, which is given as the result of the expriment." + "The readout mitigator is generated from an *assignment matrix*: a $2^n \\times 2^n$ matrix $A$ such that $A_{y,x}$ is the probability to observe $y$ given the true outcome should be $x$. The assignment matrix is used to compute the *mitigation matrix* used in the readout error mitigation process itself.\n", + "\n", + "A *Local readout mitigator* works under the assumption that readout errors are mostly *local*, meaning readout errors for different qubits are independent of each other. In this case, the assignment matrix is the tensor product of $n$ $2 \\times 2$ matrices, one for each qubit, making it practical to store the assignment matrix in implicit form, by storing the individual $2 \\times 2$ assignment matrices. The corresponding class in Qiskit is the [Local readout mitigator](https://qiskit.org/documentation/stubs/qiskit.result.LocalReadoutMitigator.html>) in ``qiskit-terra``.\n", + "\n", + " A *Correlated readout mitigator* uses the full $2^n \\times 2^n$ assignment matrix, meaning it can only be used for small values of $n$. The corresponding class in Qiskit is the [Correlated readout mitigator](https://qiskit.org/documentation/stubs/qiskit.result.CorrelatedReadoutMitigator.html) in ``qiskit-terra``.\n", + "\n", + "This notebook demonstrates the usage of both the local and correlated experiments to generate the corresponding mitigators." ] }, { @@ -27,7 +33,7 @@ "import matplotlib.pyplot as plt\n", "from qiskit import QuantumCircuit\n", "from qiskit.visualization import plot_histogram\n", - "from qiskit_experiments.library.characterization import LocalReadoutError, CorrelatedReadoutError\n", + "from qiskit_experiments.library import LocalReadoutError, CorrelatedReadoutError\n", "# For simulation\n", "from qiskit.providers.aer import AerSimulator\n", "from qiskit.test.mock import FakeParis\n", @@ -105,10 +111,42 @@ "cell_type": "code", "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Analysis callback .run_analysis at 0x00000209F948FCA0> failed:\n", + "Traceback (most recent call last):\n", + " File \"C:\\Users\\gadia\\anaconda3\\envs\\qiskit38\\lib\\site-packages\\qiskit_experiments\\database_service\\db_experiment_data.py\", line 299, in _wrapped_callback\n", + " callback(self, **kwargs)\n", + " File \"C:\\Users\\gadia\\anaconda3\\envs\\qiskit38\\lib\\site-packages\\qiskit_experiments\\framework\\base_analysis.py\", line 168, in run_analysis\n", + " results, figures = analysis._run_analysis(expdata)\n", + " File \"C:\\Users\\gadia\\anaconda3\\envs\\qiskit38\\lib\\site-packages\\qiskit_experiments\\library\\characterization\\analysis\\local_readout_error_analysis.py\", line 77, in _run_analysis\n", + " figure = assignment_matrix_visualization(\n", + " File \"C:\\Users\\gadia\\anaconda3\\envs\\qiskit38\\lib\\site-packages\\qiskit_experiments\\library\\characterization\\analysis\\local_readout_error_analysis.py\", line 120, in assignment_matrix_visualization\n", + " ax.title(r\"$|A - I|$\")\n", + "TypeError: 'Text' object is not callable\n", + "\n", + "Possibly incomplete analysis results: an analysis callback raised an error.\n" + ] + }, + { + "ename": "DbExperimentEntryNotFound", + "evalue": "'Analysis result 0 not found. Errors: Traceback (most recent call last):\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\database_service\\\\db_experiment_data.py\", line 299, in _wrapped_callback\\n callback(self, **kwargs)\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\framework\\\\base_analysis.py\", line 168, in run_analysis\\n results, figures = analysis._run_analysis(expdata)\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\library\\\\characterization\\\\analysis\\\\local_readout_error_analysis.py\", line 77, in _run_analysis\\n figure = assignment_matrix_visualization(\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\library\\\\characterization\\\\analysis\\\\local_readout_error_analysis.py\", line 120, in assignment_matrix_visualization\\n ax.title(r\"$|A - I|$\")\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\nTypeError: \\'Text\\' object is not callable\\n'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mDbExperimentEntryNotFound\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\DOCUME~1\\MobaXterm\\slash\\var\\log\\xwin/ipykernel_48628/3444147233.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mexp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_analysis_options\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mexp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbackend\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mmitigator\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mresult\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0manalysis_results\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32m~\\anaconda3\\envs\\qiskit38\\lib\\site-packages\\qiskit_experiments\\database_service\\db_experiment_data.py\u001b[0m in \u001b[0;36manalysis_results\u001b[1;34m(self, index, refresh, block, timeout)\u001b[0m\n\u001b[0;32m 716\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mint\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 717\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mindex\u001b[0m \u001b[1;33m>=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_analysis_results\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 718\u001b[1;33m raise DbExperimentEntryNotFound(\n\u001b[0m\u001b[0;32m 719\u001b[0m \u001b[1;34mf\"Analysis result {index} not found. \"\u001b[0m \u001b[1;34mf\"Errors: {self.errors()}\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 720\u001b[0m )\n", + "\u001b[1;31mDbExperimentEntryNotFound\u001b[0m: 'Analysis result 0 not found. Errors: Traceback (most recent call last):\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\database_service\\\\db_experiment_data.py\", line 299, in _wrapped_callback\\n callback(self, **kwargs)\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\framework\\\\base_analysis.py\", line 168, in run_analysis\\n results, figures = analysis._run_analysis(expdata)\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\library\\\\characterization\\\\analysis\\\\local_readout_error_analysis.py\", line 77, in _run_analysis\\n figure = assignment_matrix_visualization(\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\library\\\\characterization\\\\analysis\\\\local_readout_error_analysis.py\", line 120, in assignment_matrix_visualization\\n ax.title(r\"$|A - I|$\")\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\nTypeError: \\'Text\\' object is not callable\\n'" + ] + } + ], "source": [ - "exp.set_analysis_options(plot=True)\n", - "result = exp.run(backend).block_for_results()\n", + "exp.analysis.set_options(plot=True)\n", + "result = exp.run(backend)\n", "mitigator = result.analysis_results(0).value" ] }, @@ -121,21 +159,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "result.figure(0)" ] @@ -151,28 +177,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[ 1.02063983 -0.03611971]\n", - " [-0.02063983 1.03611971]]\n", - "\n", - "[[ 1.00606673 -0.02932255]\n", - " [-0.00606673 1.02932255]]\n", - "\n", - "[[ 1.01515152 -0.01919192]\n", - " [-0.01515152 1.01919192]]\n", - "\n", - "[[ 1.005 -0.019]\n", - " [-0.005 1.019]]\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "for m in mitigator._mitigation_mats:\n", " print(m)\n", @@ -188,7 +195,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -201,7 +208,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -211,7 +218,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -229,21 +236,9 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAApMAAAFLCAYAAACKkwciAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABIeElEQVR4nO3deXwV1f3/8dfJSgIJCWtI2BdRQEMglqIIVttq9WtthWpdq9YNWyjlV5daW611qbZacV9arda6IPrVFqut/eKGpVhWRZR93yEswUDI8vn9cSZ4TZOQO7n3ksD7+XjMg9yZueece2bm3g9nzjnjzAwRERERkTCSDnYBRERERKTlUjApIiIiIqEpmBQRERGR0BRMioiIiEhoCiZFREREJDQFkyIiIiISWsrBLsDB1KFDB+vZs+fBLoaIiDQjs2fP3mpmHSNed0pJSfk9MAg1wsjhx5xzO6uqqp6srq5+eOjQoftq73BYB5M9e/Zk1qxZB7sYIiLSjDjnVkW+TklJ+X1eXt5RHTt23J6UlKTJmeWwYmbs27cvdf369eN27do1BPhe7X30PywREZGGDerYseMuBZJyOHLOkZ6eXtGjR4+dwIi69lEwKSIi0rAkBZJyuAuugeQ6tyW4LCIiIiJyCFEwKSIicog777zzul9zzTVd6tt+/fXX551zzjk9Elmm+owePbrn+PHj8+Odz8SJE/PPPPPMXmHee99997UfOnRo//q2jxw5st/999/fvq59MzMzixYuXJhW33v79u07cOrUqVlhynWwHNYDcERERMK4/F6GxjP9xycwuzH7FRQUHL158+bU1atXf9ilS5fKmvVHHXXUgE8//TTj008//ah///77nn322dU126ZOnZr1/e9/v9emTZs+rFn361//emOsyu6cG/rRRx8tGDRoUHms0qxx3333tf/xj3/cMz09vTopKYmuXbuW33TTTevOPffcnbHOqynefffdJfVtKysrm1vz9+jRo3sWFBTsu++++9bXrFu6dOnH8S5frKllUkREpAUrKCjY98QTT7Sref3BBx9k7Nmz55D9fR88ePDusrKyuTt37px74YUXbr300kt7b9my5b/68lVUVByM4h2WDtmTTURE5HBw9tlnb3vuuefa17z+/e9/3/6cc87ZGrlPza3jXbt2JY0ZM6bfli1bUjMzM4syMzOLVq5cmVr7lu8DDzzQPj8//+icnJzB11xzTZeCgoKjX3nllSyAt956K3Pw4MFHZmVlDe7YseMxF110Ufe9e/c6gOLi4v4Axx577IDMzMyixx9/PBfgueeea3vkkUcOyMrKGlxUVHTkzJkzM2ryev/99zMGDBhwVOvWrYtOP/303uXl5Y2KTZKTkxk3btzWvXv3Jn3yySfpEydOzD/11FN7n3nmmb3atGlTdP/993dYuXJl6kknndS3bdu2g7t37z7o7rvv7hCZRnl5uTv99NN7t27dumjAgAFHzZgxY3+5brjhhrxu3boNat26dVGfPn0GPv300zmR7zUzd9FFF3XPysoa3KtXr4Gvvvrq/lvTX/rSl/rfc889X8irhnNu6IIFC9J/+9vfdnj11VfbPfzww3mZmZlFJ510Ul/wrc01dV1VVbW/HDk5OYNPO+203ps2bUoGKCsrc2eeeWavnJycwVlZWYMHDRp01Jo1aw7KHWcFkyIiIi3Ycccdt3v37t3Jc+bMaVVZWcmrr77a7vvf/35JXftmZ2dXT5kyZUnHjh0rysrK5paVlc3t2bPnF5rwZs+e3eraa6/t/uSTT67YuHHj/J07dyZv2rQptWZ7SkoKd99995qSkpJ506dP/3T69OlZd911V0eAWbNmLQL4z3/+s7CsrGzu5Zdfvv3999/P+MEPftDzoYceWrV9+/Z5l1566Zazzjqr7549e9zevXvdd77znb7nnHPOtpKSknljxozZ/sYbb+Q05nNXVFQwadKkDpmZmdUDBw4sB/jnP/+ZM2bMmO07d+6ce8UVV2wbM2ZM7/z8/H0bNmyY//zzzy+79dZbC/7yl7/sD/pq9g/yLhkzZkzf8vJyB9C3b9/y9957b9GuXbvmXn/99euvvPLKXqtWrdpfDx9++GHrPn367N26dev8G264Yf0FF1zQpybQa4yf/OQnW88888ySsWPHbiwrK5s7bdq0pbX3uf322zu99tprOW+//faiDRs2zM/Jyam67LLLugM8+OCD7UtLS5PXrFnz4fbt2+c9/PDDq1q3bl3d2PxjScGkiIhIC3f22Wdv+8Mf/tD+lVdeye7Tp8+eXr16/ddTShrrueeeyz355JN3nHLKKbtbtWpld99993rn3P7tJ5xwQtnJJ5/8WWpqKv3799938cUXb3nvvffqHTDy0EMPdbzwwgu3nHTSSZ+lpKQwbty4bampqTZt2rTWb731VuvKykr385//fHN6erpdcskl248++uiyhso3f/78NllZWYM7depUOGXKlHZ//vOfl7Zv374KYPDgwZ9deOGFO5KTk9m4cWPK3Llz29x///1rMzMz7bjjjttz3nnnbX3qqaf2t+IOHDiw7JJLLtmenp5uN91006Z9+/a5t956qzXApZdeur1nz54VycnJXH755dt79OhR/t5777WueW+7du0qasp9+eWXb+/Zs2f5lClT2oat97o8+eSTHW+55ZZ1ffr0qcjIyLA77rhj/euvv55bUVFBamqqbd++PWXhwoXpKSkpnHDCCWXt2rU7KMGkBuCIiIi0cJdddtm2E088sf+qVavSzz///G1NSWv9+vWpBQUF+1srs7KyqnNycvYP7vnwww/Tf/SjH3X76KOPWu/duzepqqqKAQMG1BsArl27Nu3ll19u/8QTT3SqWVdZWenWrl2b5pyzTp06VSQlfd621bVr1wYH7hQWFu6ePXv2orq25efn7w+iV69enZadnV2Zm5u7P8Dq0aPHvrlz52bWtX9ycjKdO3euWLNmTSr4W/0PPPBA53Xr1qUB7NmzJ3nLli3746a6yr1+/fp6R2mHsWHDhrTzzz+/r3Nu/zynycnJrF27NnXs2LEla9asSTvvvPN6l5aWJp911lklkyZNWpeenp7wOVHVMikiItLCHXHEEfu6du267+2332574YUX7mho38jApC5dunSpWLdu3f7bubt373Y7duzYH0RdeeWVPfr167d3yZIlH+3evXvuT3/603UNpVdQUFAxfvz4DaWlpfNqlj179sy98sorSwoKCio2b96cWl39eYPaunXr0g/0eRv4bPv/7t69+75du3albN++fX+ss3r16rQuXbrsD5Qjg7+qqio2bdqU2q1bt4rFixenTZw4scekSZNWb9++fV5paem8vn377jH7vOrqKHdaZHAabXnr0rlz54qXX355cWTdlZeXz+nVq1dFenq63X333RuWLVv28Xvvvffpm2++2fahhx5q32CCcaJgUkRE5BDw5JNPrvzb3/62KDs7u8Fbnfn5+ZU7d+5M2bZtW539+84999zt06ZNy3nzzTdb7927111zzTX5kUHU7t27k7Ozs6vatm1bPXfu3FaRLY4A7du3r1y8ePH+gPCqq67a8tRTT3WaNm1a6+rqanbt2pX0/PPPt92+fXvSySef/FlycrLddtttncrLy91TTz2V8+GHH2YSA3379q0YPHjw7h/96Eddy8rK3MyZMzOee+65DhdeeOH+ltuPP/4486mnnsqpqKjgV7/6Vee0tDT7yle+8llpaWmSc468vLwKgEmTJrVfunRpRmT6JSUlqTXlfuKJJ3KXL1+eMXr06KimKOrUqVPFihUr6g2eL7nkks033nhj18WLF6cBrF+/PuWZZ57JAfjrX/+a9cEHH2RUVlaSk5NTlZKSYgfrSU0KJkVERA4BAwcOLB85cmSD/Q0BioqK9p5xxhklffr0OTorK2vwypUrUyO3FxcX773jjjtWX3TRRb3z8vIK27RpU92uXbvKVq1aGcBdd9215qWXXmrXpk2bossuu6zHt771rS8M9rn22mvXX3nllT2zsrIG//73v88dOXJk2QMPPLBy/Pjx3du2bTu4T58+g2r6LbZq1cpeeOGFZc8++2yHdu3aDZ48eXK7U045ZUes6mTy5MnL16xZk9alS5fCMWPG9LnuuuvWf+tb3yqt2f7Vr351x+TJk9vl5OQUvfDCC+1feOGFZenp6TZ06NC9V1xxxaaRI0ce1bFjx8KPPvooo6ioaHdk2sccc8xnS5YsadWhQ4fCW265peDpp59elpeXVxVN+caOHbt1yZIlGVlZWYO/+tWv9qm9/cYbb9x82mmn7fj6179+ROvWrYuGDRt25L///e/W4LsjnH322X2ysrKKBgwYMGj48OGlV199dZO6OITlIv+3cbgpLi62WbNmHexiiIhIM+Kcm21mxTWv58+fv7KwsHBrQ+85lO3cuTOpffv2RQsWLPjoyCOPDD2wR1q++fPndygsLOxZe71aJkVEROQLnn322balpaVJu3btSho7dmzXfv367TniiCMUSEqdFEyKiIjIF7z66qs5+fn5xxQUFByzYsWKVs8///yyyJHLIpE0NZCIiIh8wQsvvLAKWHWwyyEtg/6bISIiIiKhKZgUERERkdAUTIqIiIhIaAomRURERCQ0BZMiIiIiEpqCSREREWmUvn37Dpw6dWpWfdtHjhzZ7/777z8oz4euraCg4OhXXnml3rLGype+9KX+99xzT4cw7x09enTP8ePH59e3PTMzs2jhwoVptfd944032vTs2XNQfe9bsmRJWmZmZlFlZWWYYkVNUwOJiIhEaVn/m4fGM/0+i26e3Zj9nHNDP/roowWDBg0qr1k3ceLE/GXLlqW/+uqrK2JdrqVLl37cUD7vvvvukljkM3Xq1Kzvf//7vTZt2vRhLNKrbfTo0T3/8pe/tEtNTbXU1FQbOHDgZw8++OCaoqKivfHIL6yysrK5da0/9dRTd69cuXJBzeuCgoKjH3zwwZU1j4rs16/fvvreGw9qmRQREZHDztixYzeWlZXNXbt27YcdOnSovPjii3vW3qe6upqqqqget31YUjApIiJyiJo6dWpW586dj7nppps6t2vXrrBjx47HTJo0af9t6NGjR/e84IILuo8cObJfZmZm0ZAhQ45cvXp1yqWXXtotOzt7cK9evQa+//77GTX719w6njJlSvb999+f99prr+VmZmYW9e/ffwB88ZZvZWUll19+edfc3NzCgoKCo2+//faOzrmhFRUVAEyaNKl97969B7Zu3bqoa9euR//mN7/pALBr166kMWPG9NuyZUtqZmZmUWZmZtHKlStTq6qquOGGG/K6des2KCcnZ/Bpp53We9OmTck1ZXvwwQfb5efnH52TkzP4uuuuy2tsHWVlZVWfd955JUuWLMmo+Qzjxo0rGDJkyJGZmZlDPvnkk/Q333yz9aBBg47KysoaPGjQoKPefPPN1pFpLFu2LP3oo48+qk2bNkUnn3xyn8hyfeMb3+jdoUOHwqysrMHFxcX9Z82a1SryvVu3bk057rjj+rVu3bro2GOP7b948eK0mm3OuaELFixIr++4AnzrW9/qtWHDhrTvfve7/TIzM4tuvPHGzosWLUqLrOtt27Yln3322T06dux4TKdOnY4ZP358fs0t8AULFqQfe+yx/bOysgbn5uYWnn766b0bW3c1FEyKiIgcwrZt25a6c+fO5A0bNnz4wAMPrLr++uu7b9myZX+w89prr+Xedttt67Zu3TovLS2tevjw4UcNGTKkrKSkZN4ZZ5yxfeLEid1qpzlmzJhd48aN23j66advLysrm7to0aKFtfe55557Ok6bNq3trFmzFs6bN2/h1KlTcyO3d+7cufKvf/3r0tLS0rmPPvroil/84hfdpk+fnpmdnV09ZcqUJR07dqwoKyubW1ZWNrdnz54Vt99+e6fXXnst5+233160YcOG+Tk5OVWXXXZZd4DZs2e3uuaaa3r84Q9/WLFhw4b527ZtS9m0aVNa7TLVZefOnUl//vOf2x111FFlNeumTJnS7rHHHltZWlo6p23btlWjR4/uN3bs2E0lJSXzxo0bt2n06NH9Nm7cuL8OX3zxxfZPPPHEivXr189PSUnhiiuu6F6z7ZRTTtm5ZMmSjzZv3jz/mGOOKbvgggu+EKy9+uqr7X/+859v2Lp167xBgwaVnXvuub0aU+4ar7zyyoouXbrse/7555eUlZXNvfXWWzfV3ue73/1uz5SUFJYtW7Zg7ty5C9966622v/vd7zoA/PSnP80/6aSTdu7YsWPeunXrPhw/fvzmaPIHBZMiIiKHtJSUFPvNb36zPj093c4555ydGRkZ1R9++OH+1rFTTjllxwknnFCWmZlpZ5xxxo709PTqH/7wh9tSUlK44IILti9cuDAzTL4vv/xy7lVXXbWpT58+FR07dqy69tprN0Ru/+53v7tz4MCB5UlJSZx++um7jz/++F1vvfVWm/rSe/LJJzvecsst6/r06VORkZFhd9xxx/rXX389t6Kigueeey73pJNO2vmNb3xjd0ZGht1zzz3rnXPWUPkeffTRvKysrMF9+vQ5+rPPPkt++umnV9ZsO+ecc7YVFxfvTU1N5S9/+Ut2jx49yn/wgx+UpKamcuWVV5b07t177+TJk3Nq9h8zZsy2Y489dm92dnb17bffvu5vf/tbbk3L34QJE7bl5uZWZ2Rk2F133bV+0aJFGdu2bdsfiH7lK1/ZX+5777133bx589osXbo0NeoKr8eaNWtS3nnnnbaPPfbY6uzs7OqCgoLKH/7wh5umTJnSDvz5sXr16vSVK1emZmZm2imnnLI72jw0AEdERKSFSk5OZt++fS5yXUVFhUtNTd0fSLVt27YyNfXz2CQjI6O6tLR0f2NSp06dKiK3dejQYf8Q4MzMzOo9e/bsD3yisWnTptTu3bvvT7tXr177IrdPnjw5+7bbbstfuXJlq+rqavbu3Zs0cODAPfWlt2HDhrTzzz+/b2SQmJyczNq1a1PXr1+fWlBQsD/97Ozs6pycnAaHMl955ZUb77vvvvV1bevWrdv+tNavX5/WtWvX8sjtXbt23bdu3brUuvbv16/fvsrKSrdhw4aULl26VI4fP77gr3/9a+727dtTa8q+cePGlPbt21cBRJa7bdu21dnZ2ZWrV69O69u3bwUxsHTp0rTKykrXpUuXwpp1Zuby8vL2AUyaNGnttddeWzB8+PCjsrOzq374wx9unDBhwrZo8lDLpIiISAuVl5e3b+nSpV+4nbty5cq07t2776vvPbFyoJa/Tp06VaxZs2Z/wLVixYr95dyzZ4/73ve+12fChAmbNm/ePL+0tHTeqFGjdppZvWl37ty54uWXX15cWlo6r2YpLy+f06tXr4ouXbpUrFu3bn/6paWlSTt27AjdYObc5/F5fn7+vrVr136h3+K6devSCgoK9gd7a9as2Z/30qVL01JSUqxLly6Vjz76aLs33ngj580331y8a9euuStWrPgIoOZz1qRV8/fOnTuTdu3alRLL49e7d++KtLQ0Kykp2V9vu3fvnlszMr979+6Vzz///KrNmzd/+OCDD6667rrretTVT7MhCiZFRERaqDPPPLPk17/+df6yZctSq6qqeOWVV7KmTZuWc+6555bEO+/OnTtXrl27Nq2+0c5nnXXW9kceeaTzihUrUrdu3Zp811137R8Us3fvXrdv376kTp06VaSmptrkyZOz33///eya7fn5+ZU7d+5MibwdfMkll2y+8cYbu9YMUFm/fn3KM888kwNw7rnnbp82bVrbv//972327t3r/t//+3/5ZvaFFtuwRo8evXPlypXpjzzySLuKigoef/zx3KVLl7b6zne+s7Nmn5deeqn97NmzW5WWlib97Gc/yz/11FO3p6SkUFpampyWlmadOnWq3L17d9KECRMKaqf/9ttv7y/3xIkTCwoLCz+LtlWyQ4cOFUuXLq0zAOzRo0fF8ccfv/OKK67oVlJSklRVVcXHH3+c/tprr7UBeOKJJ3KXLVuWCtC+fftK5xxJSUkN/kehNgWTIiIiLdSdd965/thjj909cuTII3NycgbfcMMNXR977LHlxx57bNznS7zoootKAHJzcwcPGDDgqNrbJ06cuGXUqFG7ioqKBhYWFg445ZRTdiYnJ1tycjK5ubnVt9566+qLLrqoT9u2bQc/++yz7U8++eT9wVlRUdHeM844o6RPnz5HZ2VlDV65cmXqjTfeuPm0007b8fWvf/2I1q1bFw0bNuzIf//7360BiouL9955552rL7744l55eXmFubm5lZ07d45J615eXl7VlClTlt5///2d27VrN/jee+/NmzJlytIuXbrsv40+ZsyYbRdffHGvLl26FJaXlyc99thjawDGjh27raCgoLxbt26F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jwEeMDMDqoB0M9sEXIemBhIRERE57EQbTO6L+HsT0CP4ezeQH5MSiYiIiEiLEe0AnDnAscBi4G3gVudcZ+AC4MPYFk1EREREmrtoWyZ/BqwP/r4R2IKfrDyX/57EXEREREQOcVG1TJrZrIi/t+CnCBIRERGRw1TU80wCOOf6AEcFLxea2fLYFUlEREREWopo55lsD/wB+CZQ/flqNxW41My2xbh8IiIiItKMRdtn8vdAX+AEoFWwjAR6AY/HtmgiIiIi0txFe5v7FOBkM5sRse5959yVwD9jVywRERERaQmibZncAnxWx/oyQLe4RURERA4z0QaTtwD3OucKalYEf9+NnsstIiIictg54G1u59xHgEWs6gWsdM6tC17XPKe7E75PpYiIiIgcJhrTZ3JK3EshIiIiIi3SAYNJM/tlIgoiIiIiIi1P2EnLTwIG4G9/f2xmb8eyUCIiIiLSMkQ7aXkB8L/AUD5/Rne+c24W8G0zW1/vm0VERETkkBPtaO77gCqgr5l1M7NuQL9g3X2xLpyIiIiING/R3ub+GnCima2oWWFmy51z44H/i2nJRERERKTZi7ZlEr44TVBD60RERETkEBdtMPl/wP3OuW41K5xz3YF7UcukiIiIyGEn2mByPNAaWO6cW+WcWwUsC9aNj3XhRERERKR5i7bP5DbgS8CJwJHBuk/M7J+xLJSIiIiItAyNDiadc8nATqDQzN4E3oxbqURERESkRWj0bW4zqwJWAWnxK46IiIiItCTR9pn8FfBr51yHeBRGRERERFqWaPtM/gToBaxzzq0FPovcaGbHxKpgIiIiItL8RRtMTsHPKeniUBYRERERaWEaFUw65zKB3wDfAlLxc0qOM7Ot8SuaiIiIiDR3je0z+UvgYuA14Dngq8DDcSqTiIiIiLQQjb3NfRbwfTN7HsA592fgfedccjDKW0REREQOQ41tmewGvFfzwsw+ACqB/HgUSkRERERahsYGk8nAvlrrKol+AI+IiIiIHEIaGww64BnnXHnEulbA4865spoVZvbNWBZORERERJq3xgaTT9Wx7plYFkREREREWp5GBZNmdkm8CyIiIiIiLU+0j1MUEREREdlPwaSIiIiIhKZgUkRERERCUzApIiIiIqEpmBQRERGR0BRMioiIiEhoCiZFREREJDQFkyIiIiISmoJJEREREQlNwaSIiIiI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\n", - "text/plain": [ - "
" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "legend = ['Mitigated Probabilities', 'Unmitigated Probabilities']\n", "plot_histogram([mitigated_probs, unmitigated_probs], legend=legend, sort=\"value_desc\", bar_labels=False)" @@ -258,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -273,32 +268,9 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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BbpIHaR6FL0usrKyokMbiRQVFXHHHXeQn5/Ppk2bouuPOuooHnzwQYYNG0bv3r1p2bIlrVq1AuD666/nhhtuID8/PxqGAIMGDWL9+vXRk6I33XQT5eXl9OjRg+7du3PTTTcBkZOMpaWldO3alWnTptG7d++E9V188cXRyxaHDBnCF198wYQJE3j00Uc56aSTuPPOO7n00kujYZ2ZmUl+fj6XXXYZjzzyCEDCOsaPH0+7du3o0aMHeXl50V8yEydOZNiwYQwaNIi8vDzy8/Pp0qULF110Ef3794/WFtsuVq9evRg7dix9+vShb9++jB8/nvz8/Jp/WGliXtd3VYoUFBR4fT/gIvkbqAor/12WVOs0dUWjVPVn+bJly9JaR0PbsGEDXbt2TXcZKVFaWkqLFi1wdyZNmkTHjh255ppr0l1WQoWFhcycOfOAMfcjSXXvPzN7092r7RSNoct+6nq3cbLt9csy/R5++GEef/xxvvzyS/Lz8/nRj36U7pIkxRToIkeIa6655rA+Io8X+l9/DUFj6CIigVCgi4gEQoEuIhIIBbqISCB0UlSkDuyW1H7YhU+v+fKfrVu3cu6557Ju3brouptvvpkWLVowefLkg37+adOmMWDAAIYMGcI999zDxIkTOfroo4HIhGDz5s2r14yDixYtolOnTnTr1q1Oj2vRogWlpaUHrM/IyNjvhqqioqLoDJMNZdeuXcybN48rrriiTu0+/PBDrr766kM2m2SswI/Ql5HsNegiR6LY6XVTOX1s/DS+B+uoo46KTru7Zs2aBg9ziAT1gw8+WOd2J510UlrCHIIPdJGwFRYWMmXKFPr06UOnTp149dVXgcgt/N/97ncZOnQo2dnZ3H///dx1113k5+dz+umnR2+Lr5pet7bpY2+99VY6d+7MGWecwejRo6MTYz388MOcdtpp5OXlMWrUKPbs2VPtNL6bNm2K3qV65pln8vbbbwORuVX69etHbm4uN954Y51ee0lJCZ07d+add94BIhN5Pfzww0DkSP+aa66he/fuDB48mO3btwMkrOOjjz7i/PPPJy8vj7y8PF5//XWmTp3Kpk2b6NmzJ9dddx2lpaUMHjyYXr16kZubG522N77d1q1bycnJASITh40bN47c3Fzy8/NZunRp9OczcuRIhg0bRseOHbn++uvr+qOvXqJpGBv662Cmz039DdjJT2UaOvXt/g6YPvdmUvpVmy1btkSnja0yffp0v+OOO9w9MsXstdde6+7uzz33nA8ePNjdI1PfdujQwXfv3u0ff/yxH3PMMT5r1ix3d//JT37id999t7vvP91uouljV6xY4Xl5eV5WVua7d+/2b3zjG9Hn/+STT6Ltf/7zn/u99957wH7d3b/1rW/5u+++6+7ub7zxhg8aNMjd3c877zx//PHH3d39/vvv9+bNm1fbD02aNIlOu5uXl+cLFixwd/cXX3zRTz/9dJ8/f76fddZZ//k5gf/mN79xd/dbbrklOg1wojq+973vRfukoqLCd+3adUDfl5eXe0lJibu7b9++3Tt06OD79u07oF3s8syZM6NTC2/YsMHbtm3rZWVl/thjj3n79u19165dXlZW5u3atfNt27Yd8LobZPpcMxsG/BLIAH7l7rfHbW8HPA4cW9lmqrun9qNORI5AiT4oOHb9yJEjgQOnbx00aBAtW7aMztty3nnnAZCbm1unCbT+/Oc/M2LECDIzM8nMzIzuByKTcd14443s2rWL0tJSzjrrrAMeX1payuuvv86FF14YXffFF19E9/3MM88A8IMf/IApU6ZUW0PVkEu8oUOH8tRTTzFp0iTWrl0bXd+kSRO+//3vA3DJJZcwcuTIGut45ZVXoh+ykZGRQatWrdi5c+d+z+Xu/OxnP2P58uU0adKEDz74gI8++ihxxxGZVOyqq64CoEuXLpxyyim8++67AAwePDg6n063bt147733aNu2bY37q02tgW5mGcADwFCgGFhpZovdPXaA7EbgSXefZWbdgCVA9kFVJiK0bt36gGD59NNPo/Oaw3+mcM3IyNhvcq3YqV2bNGkSXW7SpMl+7Q7G2LFjWbRoEXl5ecyZM6fauzv37dvHscceW20gQ/0+3T523xs2bODoo49m586dZGVlJXyO2uqozdy5c9m+fTtvvvkmzZo1Izs7O6VT76biZ5LMGHofYKO7b3b3L4EFwIi4Ng4cU/l9K+BDROpBn1W6vxYtWnDiiSfyyiuvAJEw/8Mf/sAZZ5yR8udKNH1s//79+d3vfsfevXspLS3l97//fXTbZ599xoknnkh5eTlz586tdl/HHHMM7du356mnngIiR7pVR9P9+/dnwYIFAPs9Pll33303Xbt2Zd68eYwbNy764Rz79u2LnpicN28eZ5xxRo11DB48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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "mitigated_expectation_values, mitigated_stddev = zip(*mitigated_expectation)\n", "unmitigated_expectation_values, unmitigated_stddev = zip(*unmitigated_expectation)\n", @@ -323,44 +295,9 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " ░ ┌─┐ \n", - " q_0: ─░─┤M├───\n", - " ░ └╥┘┌─┐\n", - " q_1: ─░──╫─┤M├\n", - " ░ ║ └╥┘\n", - "meas: 2/════╩══╩═\n", - " 0 1 \n", - " ┌───┐ ░ ┌─┐ \n", - " q_0: ┤ X ├─░─┤M├───\n", - " └───┘ ░ └╥┘┌─┐\n", - " q_1: ──────░──╫─┤M├\n", - " ░ ║ └╥┘\n", - "meas: 2/═════════╩══╩═\n", - " 0 1 \n", - " ░ ┌─┐ \n", - " q_0: ──────░─┤M├───\n", - " ┌───┐ ░ └╥┘┌─┐\n", - " q_1: ┤ X ├─░──╫─┤M├\n", - " └───┘ ░ ║ └╥┘\n", - "meas: 2/═════════╩══╩═\n", - " 0 1 \n", - " ┌───┐ ░ ┌─┐ \n", - " q_0: ┤ X ├─░─┤M├───\n", - " ├───┤ ░ └╥┘┌─┐\n", - " q_1: ┤ X ├─░──╫─┤M├\n", - " └───┘ ░ ║ └╥┘\n", - "meas: 2/═════════╩══╩═\n", - " 0 1 \n" - ] - } - ], + "outputs": [], "source": [ "qubits = [0,3]\n", "num_qubits = len(qubits)\n", @@ -371,22 +308,9 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "

This code is a part of Qiskit

© Copyright IBM 2017, 2022.

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.

" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import qiskit.tools.jupyter\n", "%qiskit_copyright" diff --git a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py index 4d7ca49050..ceb7651686 100644 --- a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py @@ -21,7 +21,6 @@ from qiskit_experiments.framework.matplotlib import get_non_gui_ax from qiskit_experiments.framework import BaseAnalysis, AnalysisResultData, Options - class LocalReadoutErrorAnalysis(BaseAnalysis): r""" Local readout error characterization analysis @@ -117,7 +116,7 @@ def assignment_matrix_visualization(assignment_matrix, ax=None): ax.set_xticks(np.arange(n)) ax.set_yticklabels(n * [""]) ax.set_xticklabels(n * [""]) - ax.set_xlabel(r"$|A - I|$", fontsize=16) + ax.set_title(r"$|A - I |$", fontsize=16) ax.set_xlabel("Prepared State") ax.xaxis.set_label_position("top") ax.set_ylabel("Measured State") From 85fd56745a8787ffbb87dcd5f92d5b5606d001c0 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 20 Jan 2022 14:12:45 +0200 Subject: [PATCH 16/32] Test for parallel experiment --- test/test_readout_error.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/test_readout_error.py b/test/test_readout_error.py index fdfa4a2c6c..94680b8815 100644 --- a/test/test_readout_error.py +++ b/test/test_readout_error.py @@ -19,8 +19,12 @@ from test.base import QiskitExperimentsTestCase import numpy as np from qiskit.quantum_info.operators.predicates import matrix_equal +from qiskit.providers.aer import AerSimulator +from qiskit.test.mock import FakeParis from qiskit_experiments.library.characterization import LocalReadoutError, CorrelatedReadoutError from qiskit_experiments.framework import ExperimentData +from qiskit_experiments.framework import ParallelExperiment + class TestMitigation(QiskitExperimentsTestCase): @@ -137,6 +141,18 @@ def test_circuit_generation(self): exp = LocalReadoutError(qubits) self.assertEqual(len(exp.circuits()), 2) + def test_parallel_running(self): + backend = AerSimulator.from_backend(FakeParis()) + exp1 = CorrelatedReadoutError([0, 2]) + exp2 = CorrelatedReadoutError([1, 3]) + exp = ParallelExperiment([exp1, exp2]) + expdata = exp.run(backend=backend).block_for_results() + mit1 = expdata.child_data(0).analysis_results(0).value + mit2 = expdata.child_data(1).analysis_results(0).value + assignment_matrix1 = mit1.assignment_matrix() + assignment_matrix2 = mit2.assignment_matrix() + self.assertFalse(matrix_equal(assignment_matrix1, + assignment_matrix2)) if __name__ == "__main__": unittest.main() From a2f8629077e6d41e57e54c1911146b300a5bedd6 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 20 Jan 2022 14:46:35 +0200 Subject: [PATCH 17/32] Linting --- .../characterization/analysis/local_readout_error_analysis.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py index ceb7651686..f81cc9acd5 100644 --- a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py @@ -21,6 +21,7 @@ from qiskit_experiments.framework.matplotlib import get_non_gui_ax from qiskit_experiments.framework import BaseAnalysis, AnalysisResultData, Options + class LocalReadoutErrorAnalysis(BaseAnalysis): r""" Local readout error characterization analysis From c694110b21c4ae1a0f9f2959d86363e3d5712746 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 20 Jan 2022 15:21:33 +0200 Subject: [PATCH 18/32] Linting --- test/test_readout_error.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/test_readout_error.py b/test/test_readout_error.py index 94680b8815..d9f326e93b 100644 --- a/test/test_readout_error.py +++ b/test/test_readout_error.py @@ -26,7 +26,6 @@ from qiskit_experiments.framework import ParallelExperiment - class TestMitigation(QiskitExperimentsTestCase): """Test Readout Error experiments""" @@ -151,8 +150,8 @@ def test_parallel_running(self): mit2 = expdata.child_data(1).analysis_results(0).value assignment_matrix1 = mit1.assignment_matrix() assignment_matrix2 = mit2.assignment_matrix() - self.assertFalse(matrix_equal(assignment_matrix1, - assignment_matrix2)) + self.assertFalse(matrix_equal(assignment_matrix1, assignment_matrix2)) + if __name__ == "__main__": unittest.main() From 0359c8dd58dd7e6067e6e19aecde3199a8e44d4c Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 20 Jan 2022 16:15:31 +0200 Subject: [PATCH 19/32] Doc --- test/test_readout_error.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_readout_error.py b/test/test_readout_error.py index d9f326e93b..7cdafc2e91 100644 --- a/test/test_readout_error.py +++ b/test/test_readout_error.py @@ -141,6 +141,7 @@ def test_circuit_generation(self): self.assertEqual(len(exp.circuits()), 2) def test_parallel_running(self): + """Test that parallel experiments work for this experiment""" backend = AerSimulator.from_backend(FakeParis()) exp1 = CorrelatedReadoutError([0, 2]) exp2 = CorrelatedReadoutError([1, 3]) From 7c62358d691140306cbec33287b3447ef04566c9 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Fri, 21 Jan 2022 08:44:06 +0200 Subject: [PATCH 20/32] Small fixes --- docs/tutorials/readout_mitigation.ipynb | 180 +++++++++++++----- .../correlated_readout_error_analysis.py | 11 +- .../analysis/local_readout_error_analysis.py | 6 +- .../correlated_readout_error.py | 34 ++-- .../characterization/local_readout_error.py | 22 +-- test/test_readout_error.py | 20 +- 6 files changed, 170 insertions(+), 103 deletions(-) diff --git a/docs/tutorials/readout_mitigation.ipynb b/docs/tutorials/readout_mitigation.ipynb index 324e480f86..788519010b 100644 --- a/docs/tutorials/readout_mitigation.ipynb +++ b/docs/tutorials/readout_mitigation.ipynb @@ -111,39 +111,7 @@ "cell_type": "code", "execution_count": 4, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Analysis callback .run_analysis at 0x00000209F948FCA0> failed:\n", - "Traceback (most recent call last):\n", - " File \"C:\\Users\\gadia\\anaconda3\\envs\\qiskit38\\lib\\site-packages\\qiskit_experiments\\database_service\\db_experiment_data.py\", line 299, in _wrapped_callback\n", - " callback(self, **kwargs)\n", - " File \"C:\\Users\\gadia\\anaconda3\\envs\\qiskit38\\lib\\site-packages\\qiskit_experiments\\framework\\base_analysis.py\", line 168, in run_analysis\n", - " results, figures = analysis._run_analysis(expdata)\n", - " File \"C:\\Users\\gadia\\anaconda3\\envs\\qiskit38\\lib\\site-packages\\qiskit_experiments\\library\\characterization\\analysis\\local_readout_error_analysis.py\", line 77, in _run_analysis\n", - " figure = assignment_matrix_visualization(\n", - " File \"C:\\Users\\gadia\\anaconda3\\envs\\qiskit38\\lib\\site-packages\\qiskit_experiments\\library\\characterization\\analysis\\local_readout_error_analysis.py\", line 120, in assignment_matrix_visualization\n", - " ax.title(r\"$|A - I|$\")\n", - "TypeError: 'Text' object is not callable\n", - "\n", - "Possibly incomplete analysis results: an analysis callback raised an error.\n" - ] - }, - { - "ename": "DbExperimentEntryNotFound", - "evalue": "'Analysis result 0 not found. Errors: Traceback (most recent call last):\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\database_service\\\\db_experiment_data.py\", line 299, in _wrapped_callback\\n callback(self, **kwargs)\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\framework\\\\base_analysis.py\", line 168, in run_analysis\\n results, figures = analysis._run_analysis(expdata)\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\library\\\\characterization\\\\analysis\\\\local_readout_error_analysis.py\", line 77, in _run_analysis\\n figure = assignment_matrix_visualization(\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\library\\\\characterization\\\\analysis\\\\local_readout_error_analysis.py\", line 120, in assignment_matrix_visualization\\n ax.title(r\"$|A - I|$\")\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\nTypeError: \\'Text\\' object is not callable\\n'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mDbExperimentEntryNotFound\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m~\\DOCUME~1\\MobaXterm\\slash\\var\\log\\xwin/ipykernel_48628/3444147233.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mexp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_analysis_options\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mexp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbackend\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mmitigator\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mresult\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0manalysis_results\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;32m~\\anaconda3\\envs\\qiskit38\\lib\\site-packages\\qiskit_experiments\\database_service\\db_experiment_data.py\u001b[0m in \u001b[0;36manalysis_results\u001b[1;34m(self, index, refresh, block, timeout)\u001b[0m\n\u001b[0;32m 716\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mint\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 717\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mindex\u001b[0m \u001b[1;33m>=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_analysis_results\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 718\u001b[1;33m raise DbExperimentEntryNotFound(\n\u001b[0m\u001b[0;32m 719\u001b[0m \u001b[1;34mf\"Analysis result {index} not found. \"\u001b[0m \u001b[1;34mf\"Errors: {self.errors()}\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 720\u001b[0m )\n", - "\u001b[1;31mDbExperimentEntryNotFound\u001b[0m: 'Analysis result 0 not found. Errors: Traceback (most recent call last):\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\database_service\\\\db_experiment_data.py\", line 299, in _wrapped_callback\\n callback(self, **kwargs)\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\framework\\\\base_analysis.py\", line 168, in run_analysis\\n results, figures = analysis._run_analysis(expdata)\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\library\\\\characterization\\\\analysis\\\\local_readout_error_analysis.py\", line 77, in _run_analysis\\n figure = assignment_matrix_visualization(\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\n File \"C:\\\\Users\\\\gadia\\\\anaconda3\\\\envs\\\\qiskit38\\\\lib\\\\site-packages\\\\qiskit_experiments\\\\library\\\\characterization\\\\analysis\\\\local_readout_error_analysis.py\", line 120, in assignment_matrix_visualization\\n ax.title(r\"$|A - I|$\")\\nAnalysis callback .run_analysis at 0x00000209F948FCA0> failed: \\nTypeError: \\'Text\\' object is not callable\\n'" - ] - } - ], + "outputs": [], "source": [ "exp.analysis.set_options(plot=True)\n", "result = exp.run(backend)\n", @@ -159,9 +127,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "result.figure(0)" ] @@ -177,9 +157,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 1.01564129 -0.05213764]\n", + " [-0.01564129 1.05213764]]\n", + "\n", + "[[ 1.00506586 -0.03242148]\n", + " [-0.00506586 1.03242148]]\n", + "\n", + "[[ 1.00912779 -0.02941176]\n", + " [-0.00912779 1.02941176]]\n", + "\n", + "[[ 1.00503018 -0.02515091]\n", + " [-0.00503018 1.02515091]]\n", + "\n" + ] + } + ], "source": [ "for m in mitigator._mitigation_mats:\n", " print(m)\n", @@ -195,7 +194,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -208,7 +207,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -218,7 +217,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -236,9 +235,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAApMAAAFLCAYAAACKkwciAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABIeUlEQVR4nO3deXxU1f3/8dfJSgIJSdhCwr6IAhoCsRSLYLWtVr/WVqjWtWrdsEIpv7rU2mqtS7XVr4i7rVZrXRD9aovV1hY3LMWyKqDsYd/DEgyELJ/fH2eCY5qEzM3MJIH38/G4j2TuvXPOmXPvzXxyzj3nOjNDRERERCSIhOYugIiIiIi0XgomRURERCQwBZMiIiIiEpiCSREREREJTMGkiIiIiASmYFJEREREAktq7gI0p44dO1qvXr2auxgiItKCzJ07d7uZdQp73TkpKel3wGDUCCNHHnPO7a6qqnqqurr6kWHDhh2ovcMRHUz26tWLOXPmNHcxRESkBXHOrQl/nZSU9Lvc3NxjOnXqtDMhIUGTM8sRxcw4cOBA8saNG8fv2bNnKPD92vvoPywREZGGDe7UqdMeBZJyJHLOkZqaWtGzZ8/dwMi69lEwKSIi0rAEBZJypAtdA4l1botzWURERETkMKJgUkRE5DB3/vnn97juuuu61rf9xhtvzD333HN7xrNM9RkzZkyvCRMm5MU6n0mTJuWdddZZvYO894EHHugwbNiwAfVtHzVqVP8pU6Z0qGvf9PT0wiVLlqTU995+/foNmj59ekaQcjWXI3oAjoiISBBX3M+wWKb/xETmNma//Pz8Y7du3Zq8du3aj7p27VpZs/6YY44Z+Omnn6Z9+umnHw8YMODAc889t7Zm2/Tp0zN+8IMf9N6yZctHNet+/etfb45W2Z1zwz7++ONFgwcPLo9WmjUeeOCBDj/+8Y97paamVickJNCtW7fyW265ZcN55523O9p5NcV77723vL5tZWVl82t+HzNmTK/8/PwDDzzwwMaadStWrFgc6/JFm1omRUREWrH8/PwDTz75ZE7N6w8//DBt3759h+33+5AhQ/aWlZXN37179/yLLrpo+2WXXdZn27Zt/3UvX0VFRXMU74h02J5sIiIiR4Jzzjlnx/PPP9+h5vXvfve7Dueee+728H1quo737NmTMHbs2P7btm1LTk9PL0xPTy8sLi5Ort3l++CDD3bIy8s7Nisra8h1113XNT8//9hXX301A+Dtt99OHzJkyNEZGRlDOnXqdNzFF1/cY//+/Q6gqKhoAMDxxx8/MD09vfCJJ57IBnj++efbH3300QMzMjKGFBYWHj179uy0mrw++OCDtIEDBx7Ttm3bwjPOOKNPeXl5o2KTxMRExo8fv33//v0Jn3zySeqkSZPyTjvttD5nnXVW73bt2hVOmTKlY3FxcfLJJ5/cr3379kN69Ogx+N577+0YnkZ5ebk744wz+rRt27Zw4MCBx8yaNetguW666abc7t27D27btm1h3759Bz3zzDNZ4e81M3fxxRf3yMjIGNK7d+9Br7322sGu6S996UsD7rvvvi/kVcM5N2zRokWpv/3tbzu+9tprOY888khuenp64cknn9wPfGtzTV1XVVUdLEdWVtaQ008/vc+WLVsSAcrKytxZZ53VOysra0hGRsaQwYMHH7Nu3bpm6XFWMCkiItKKnXDCCXv37t2bOG/evDaVlZW89tprOT/4wQ9K6to3MzOzetq0acs7depUUVZWNr+srGx+r169vtCEN3fu3DbXX399j6eeemr15s2bF+7evTtxy5YtyTXbk5KSuPfee9eVlJQsmDlz5qczZ87MuOeeezoBzJkzZynAf/7znyVlZWXzr7jiip0ffPBB2g9/+MNeDz/88JqdO3cuuOyyy7adffbZ/fbt2+f279/vvvvd7/Y799xzd5SUlCwYO3bszjfffDOrMZ+7oqKCyZMnd0xPT68eNGhQOcA//vGPrLFjx+7cvXv3/CuvvHLH2LFj++Tl5R3YtGnTwhdeeGHl7bffnv/nP//5YNBXs38o75KxY8f2Ky8vdwD9+vUrf//995fu2bNn/o033rjxqquu6r1mzZqD9fDRRx+17du37/7t27cvvOmmmzZeeOGFfWsCvcb4yU9+sv2ss84qGTdu3OaysrL5M2bMWFF7nzvvvLPz66+/nvXOO+8s3bRp08KsrKyqyy+/vAfAQw891KG0tDRx3bp1H+3cuXPBI488sqZt27bVjc0/mhRMioiItHLnnHPOjt///vcdXn311cy+ffvu69279389paSxnn/++exTTjll16mnnrq3TZs2du+99250zh3cfuKJJ5adcsopnyUnJzNgwIADl1xyybb333+/3gEjDz/8cKeLLrpo28knn/xZUlIS48eP35GcnGwzZsxo+/bbb7etrKx0P//5z7empqbapZdeuvPYY48ta6h8CxcubJeRkTGkc+fOBdOmTcv505/+tKJDhw5VAEOGDPnsoosu2pWYmMjmzZuT5s+f327KlCnr09PT7YQTTth3/vnnb3/66acPtuIOGjSo7NJLL92Zmppqt9xyy5YDBw64t99+uy3AZZddtrNXr14ViYmJXHHFFTt79uxZ/v7777eteW9OTk5FTbmvuOKKnb169SqfNm1a+6D1Xpennnqq02233bahb9++FWlpaXbXXXdtfOONN7IrKipITk62nTt3Ji1ZsiQ1KSmJE088sSwnJ6dZgkkNwBEREWnlLr/88h0nnXTSgDVr1qRecMEFO5qS1saNG5Pz8/MPtlZmZGRUZ2VlHRzc89FHH6X+6Ec/6v7xxx+33b9/f0JVVRUDBw6sNwBcv359yiuvvNLhySef7FyzrrKy0q1fvz7FOWedO3euSEj4vG2rW7duDQ7cKSgo2Dt37tyldW3Ly8s7GESvXbs2JTMzszI7O/tggNWzZ88D8+fPT69r/8TERLp06VKxbt26ZPBd/Q8++GCXDRs2pADs27cvcdu2bQfjprrKvXHjxnpHaQexadOmlAsuuKCfc+7gPKeJiYmsX78+edy4cSXr1q1LOf/88/uUlpYmnn322SWTJ0/ekJqaGvc5UdUyKSIi0sodddRRB7p163bgnXfeaX/RRRftamjf8MCkLl27dq3YsGHDwe7cvXv3ul27dh0Moq666qqe/fv33798+fKP9+7dO/+nP/3phobSy8/Pr5gwYcKm0tLSBTXLvn375l911VUl+fn5FVu3bk2urv68QW3Dhg2ph/q8DXy2g7/36NHjwJ49e5J27tx5MNZZu3ZtSteuXQ8GyuHBX1VVFVu2bEnu3r17xbJly1ImTZrUc/LkyWt37ty5oLS0dEG/fv32mX1edXWUOyU8OI20vHXp0qVLxSuvvLIsvO7Ky8vn9e7duyI1NdXuvffeTStXrlz8/vvvf/rWW2+1f/jhhzs0mGCMKJgUERE5DDz11FPFf/3rX5dmZmY22NWZl5dXuXv37qQdO3bUeX/feeedt3PGjBlZb731Vtv9+/e76667Li88iNq7d29iZmZmVfv27avnz5/fJrzFEaBDhw6Vy5YtOxgQXn311duefvrpzjNmzGhbXV3Nnj17El544YX2O3fuTDjllFM+S0xMtDvuuKNzeXm5e/rpp7M++uijdKKgX79+FUOGDNn7ox/9qFtZWZmbPXt22vPPP9/xoosuOthyu3jx4vSnn346q6Kigl/96lddUlJS7Ktf/epnpaWlCc45cnNzKwAmT57cYcWKFWnh6ZeUlCTXlPvJJ5/MXrVqVdqYMWMimqKoc+fOFatXr643eL700ku33nzzzd2WLVuWArBx48akZ599NgvgL3/5S8aHH36YVllZSVZWVlVSUpI115OaFEyKiIgcBgYNGlQ+atSoBu83BCgsLNx/5plnlvTt2/fYjIyMIcXFxcnh24uKivbfdddday+++OI+ubm5Be3atavOycmpbNOmjQHcc889615++eWcdu3aFV5++eU9v/3tb39hsM/111+/8aqrruqVkZEx5He/+132qFGjyh588MHiCRMm9Gjfvv2Qvn37Dq65b7FNmzb24osvrnzuuec65uTkDJk6dWrOqaeeuitadTJ16tRV69atS+natWvB2LFj+95www0bv/3tb5fWbP/a1762a+rUqTlZWVmFL774YocXX3xxZWpqqg0bNmz/lVdeuWXUqFHHdOrUqeDjjz9OKyws3Bue9nHHHffZ8uXL23Ts2LHgtttuy3/mmWdW5ubmVkVSvnHjxm1fvnx5WkZGxpCvfe1rfWtvv/nmm7eefvrpu77xjW8c1bZt28Lhw4cf/e9//7st+NsRzjnnnL4ZGRmFAwcOHDxixIjSa665pkm3OATlwv/bONIUFRXZnDlzmrsYIiLSgjjn5ppZUc3rhQsXFhcUFGxv6D2Hs927dyd06NChcNGiRR8fffTRgQf2SOu3cOHCjgUFBb1qr1fLpIiIiHzBc8891760tDRhz549CePGjevWv3//fUcddZQCSamTgkkRERH5gtdeey0rLy/vuPz8/ONWr17d5oUXXlgZPnJZJJymBhIREZEvePHFF9cAa5q7HNI66N8MEREREQlMwaSIiIiIBKZgUkREREQCUzApIiIiIoEpmBQRERGRwBRMioiISKP069dv0PTp0zPq2z5q1Kj+U6ZMaZbnQ9eWn59/7KuvvlpvWaPlS1/60oD77ruvY5D3jhkzpteECRPy6tuenp5euGTJkpTa+7755pvtevXqNbi+9y1fvjwlPT29sLKyMkixIqapgURERCK0csCtw2KZft+lt85tzH7OuWEff/zxosGDB5fXrJs0aVLeypUrU1977bXV0S7XihUrFjeUz3vvvbc8GvlMnz494wc/+EHvLVu2fBSN9GobM2ZMrz//+c85ycnJlpycbIMGDfrsoYceWldYWLg/FvkFVVZWNr+u9aeddtre4uLiRTWv8/Pzj33ooYeKax4V2b9//wP1vTcW1DIpIiIiR5xx48ZtLisrm79+/fqPOnbsWHnJJZf0qr1PdXU1VVURPW77iKRgUkRE5DA1ffr0jC5duhx3yy23dMnJySno1KnTcZMnTz7YDT1mzJheF154YY9Ro0b1T09PLxw6dOjRa9euTbrsssu6Z2ZmDundu/egDz74IK1m/5qu42nTpmVOmTIl9/XXX89OT08vHDBgwED4YpdvZWUlV1xxRbfs7OyC/Pz8Y++8885OzrlhFRUVAEyePLlDnz59BrVt27awW7dux/7mN7/pCLBnz56EsWPH9t+2bVtyenp6YXp6emFxcXFyVVUVN910U2737t0HZ2VlDTn99NP7bNmyJbGmbA899FBOXl7esVlZWUNuuOGG3MbWUUZGRvX5559fsnz58rSazzB+/Pj8oUOHHp2enj70k08+SX3rrbfaDh48+JiMjIwhgwcPPuatt95qG57GypUrU4899thj2rVrV3jKKaf0DS/XN7/5zT4dO3YsyMjIGFJUVDRgzpw5bcLfu3379qQTTjihf9u2bQuPP/74AcuWLUup2eacG7Zo0aLU+o4rwLe//e3emzZtSvne977XPz09vfDmm2/usnTp0pTwut6xY0fiOeec07NTp07Hde7c+bgJEybk1XSBL1q0KPX4448fkJGRMSQ7O7vgjDPO6NPYuquhYFJEROQwtmPHjuTdu3cnbtq06aMHH3xwzY033thj27ZtB4Od119/PfuOO+7YsH379gUpKSnVI0aMOGbo0KFlJSUlC84888ydkyZN6l47zbFjx+4ZP3785jPOOGNnWVnZ/KVLly6pvc99993XacaMGe3nzJmzZMGCBUumT5+eHb69S5culX/5y19WlJaWzn/sscdW/+IXv+g+c+bM9MzMzOpp06Yt79SpU0VZWdn8srKy+b169aq48847O7/++utZ77zzztJNmzYtzMrKqrr88st7AMydO7fNdddd1/P3v//96k2bNi3csWNH0pYtW1Jql6kuu3fvTvjTn/6Uc8wxx5TVrJs2bVrO448/XlxaWjqvffv2VWPGjOk/bty4LSUlJQvGjx+/ZcyYMf03b958sA5feumlDk8++eTqjRs3LkxKSuLKK6/sUbPt1FNP3b18+fKPt27duvC4444ru/DCC78QrL322msdfv7zn2/avn37gsGDB5edd955vRtT7hqvvvrq6q5dux544YUXlpeVlc2//fbbt9Te53vf+16vpKQkVq5cuWj+/PlL3n777fb/+7//2xHgpz/9ad7JJ5+8e9euXQs2bNjw0YQJE7ZGkj8omBQRETmsJSUl2W9+85uNqampdu655+5OS0ur/uijjw62jp166qm7TjzxxLL09HQ788wzd6WmplZfe+21O5KSkrjwwgt3LlmyJD1Ivq+88kr21VdfvaVv374VnTp1qrr++us3hW//3ve+t3vQoEHlCQkJnHHGGXu/8pWv7Hn77bfb1ZfeU0891em2227b0Ldv34q0tDS76667Nr7xxhvZFRUVPP/889knn3zy7m9+85t709LS7L777tvonLOGyvfYY4/lZmRkDOnbt++xn332WeIzzzxTXLPt3HPP3VFUVLQ/OTmZP//5z5k9e/Ys/+EPf1iSnJzMVVddVdKnT5/9U6dOzarZf+zYsTuOP/74/ZmZmdV33nnnhr/+9a/ZNS1/EydO3JGdnV2dlpZm99xzz8alS5em7dix42Ag+tWvfvVgue+///4NCxYsaLdixYrkiCu8HuvWrUt699132z/++ONrMzMzq/Pz8yuvvfbaLdOmTcsBf36sXbs2tbi4ODk9Pd1OPfXUvZHmoQE4IiIirVRiYiIHDhxw4esqKipccnLywUCqffv2lcnJn8cmaWlp1aWlpQcbkzp37lwRvq1jx44HhwCnp6dX79u372DgE4ktW7Yk9+jR42DavXv3PhC+ferUqZl33HFHXnFxcZvq6mr279+fMGjQoH31pbdp06aUCy64oF94kJiYmMj69euTN27cmJyfn38w/czMzOqsrKwGhzJfddVVmx944IGNdW3r3r37wbQ2btyY0q1bt/Lw7d26dTuwYcOG5Lr279+//4HKykq3adOmpK5du1ZOmDAh/y9/+Uv2zp07k2vKvnnz5qQOHTpUAYSXu3379tWZmZmVa9euTenXr18FUbBixYqUyspK17Vr14KadWbmcnNzDwBMnjx5/fXXX58/YsSIYzIzM6uuvfbazRMnTtwRSR5qmRQREWmlcnNzD6xYseIL3bnFxcUpPXr0OFDfe6LlUC1/nTt3rli3bt3BgGv16tUHy7lv3z73/e9/v+/EiRO3bN26dWFpaemC0aNH7zazetPu0qVLxSuvvLKstLR0Qc1SXl4+r3fv3hVdu3at2LBhw8H0S0tLE3bt2hW4wcy5z+PzvLy8A+vXr//CfYsbNmxIyc/PPxjsrVu37mDeK1asSElKSrKuXbtWPvbYYzlvvvlm1ltvvbVsz54981evXv0xQM3nrEmr5vfdu3cn7NmzJymax69Pnz4VKSkpVlJScrDe9u7dO79mZH6PHj0qX3jhhTVbt2796KGHHlpzww039KzrPs2GKJgUERFppc4666ySX//613krV65Mrqqq4tVXX82YMWNG1nnnnVcS67y7dOlSuX79+pT6RjufffbZOx999NEuq1evTt6+fXviPffcc3BQzP79+92BAwcSOnfuXJGcnGxTp07N/OCDDzJrtufl5VXu3r07Kbw7+NJLL9168803d6sZoLJx48akZ599NgvgvPPO2zljxoz2f/vb39rt37/f/b//9//yzOwLLbZBjRkzZndxcXHqo48+mlNRUcETTzyRvWLFijbf/e53d9fs8/LLL3eYO3dum9LS0oSf/exneaeddtrOpKQkSktLE1NSUqxz586Ve/fuTZg4cWJ+7fTfeeedg+WeNGlSfkFBwWeRtkp27NixYsWKFXUGgD179qz4yle+svvKK6/sXlJSklBVVcXixYtTX3/99XYATz75ZPbKlSuTATp06FDpnCMhIaHBfxRqUzApIiLSSt19990bjz/++L2jRo06Oisra8hNN93U7fHHH191/PHHx3y+xIsvvrgEIDs7e8jAgQOPqb190qRJ20aPHr2nsLBwUEFBwcBTTz11d2JioiUmJpKdnV19++23r7344ov7tm/ffshzzz3X4ZRTTjkYnBUWFu4/88wzS/r27XtsRkbGkOLi4uSbb7556+mnn77rG9/4xlFt27YtHD58+NH//ve/2wIUFRXtv/vuu9decsklvXNzcwuys7Mru3TpEpXWvdzc3Kpp06atmDJlSpecnJwh999/f+60adNWdO3a9WA3+tixY3dccsklvbt27VpQXl6e8Pjjj68DGDdu3I78/Pzy7t27Fxx99NGDvvzlL39WO/1vfetbO375y192zcnJGbJw4cL05557blWkZbzuuus233vvvV0zMjKG/OIXv+hSe/vUqVOLDxw44I455pjBWVlZQ8aOHdu3ppv+ww8/bDtixIhj0tPTC7/zne/0u/3229cOHDgworpz4U2tR5qioiKbM2dOcxdDRERaEOfcXDMrqnm9cOHC4oKCgu3NWabDwdSpUzMnTpzYc+PGjR83d1kkmIULF3YsKCjoVXu9WiZFREQk6vbu3etefPHF9hUVFaxevTr5jjvuyDvttNN2NXe5JPoUTIqIiEjUmZn71a9+lZeVlVU4bNiwgf3799//29/+dkNzl0uiT1MDiYiISNRlZGRUL1q06JPmLofEnlomRURERCQwBZMiIiINq66uro7KNDMirVXoGqhzHigFkyIiIg1btG3btvYKKOVIZGaUl5cnr1mzJguYWdc+umdSRESkAZWVlZdv3rz5d5s3bx6MGmHkyFPtnNtdVVX1QHV19SN17aBgUkREpAHDhg3bCnyrucsh0lLpPywRERERCUzBpIiIiIgEpm7uOLji/oa3PzExHqUQERERiT61TIqIiIhIYAomRURERCQwBZMiIiIiEpiCSREREREJTMGkiIiIiAQW92DSOXeNc261c26/c26uc+7ERr5vpHOu0jm3qNb6S5xzVsfSJjafQERERERqxHVqIOfcucBk4Br88x2vAd5wzg00s7UNvC8beAb4J5Bfxy5lQN/wFWa2P1rlPpSVA25teIdxh9guIiIi0krFu2VyEvAHM3vCzD4xs/HAJmDcId73e+BpYFY9283MNocvUSyziIiIiNQjbsGkcy4FGAb8vdamvwMnNPC+a4AuwO0NJJ/mnFvjnFvvnJvunCtscoFFRERE5JDi2TLZEUgEttRavwXIresNzrljgVuAC82sqp50lwKXAWcB5wH7gQ+cc/2jUWgRERERqV+LfZyicy4VeBH4iZmtrm8/M5tFWPe3c+5fwAJgPDChjnSvBK4EyMvL45133gGgT58+ZGRksHDhQgA6dOjAoEGDeO+99wBISkpi5MiRzJs3jz179gBQVFTEli21Y+PILV++nA0bNgAwYMAAEhMTWbJkCQC5ubn07t2bWbP8R0xLS2P48OHMnj2bffv2ATBixAhWr17N5s2+d3/gwIFUVVWxdOlSAPLz8+nWrRuzZ88GoF27dhQVFTFr1izK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ZluAG9DUQCIiIiJHnEiDyQNhv28BeoZ+3wvkRaVEIiIiItJqRDoAZx5wPLAMeAe43TnXBbgQ+Ci6RRMRERGRli7SlsmfARtDv98MbMNPVp7Nf09iLiIiIiKHuYhaJs1sTtjv2/BTBImIiIjIESrieSYBnHN9gWNCL5eY2aroFUlEREREWotI55nsAPwe+BZQ/flqNx24zMx2RLl8IiIiItKCRXrP5O+AfsCJQJvQMgroDTwR3aKJiIiISEsXaTf3qcApZjYrbN0HzrmrgH9Er1giIiIi0hpE2jK5DfisjvVlgLq4RURERI4wkQaTtwH3O+fya1aEfr8XPZdbRERE5IhzyG5u59zHgIWt6g0UO+c2hF7XPKe7M/6eShERERE5QjTmnslpMS+FiIiIiLRKhwwmzeyX8SiIiIiIiLQ+QSctPxkYiO/+Xmxm70SzUCIiIiLSOkQ6aXk+8H/AMD5/Rneec24O8B0z21jvm0VERETksBPpaO4HgCqgn5l1N7PuQP/QugeiXTgRERERadki7eb+OnCSma2uWWFmq5xzE4B/RrVkIiIiItLiRdoyCV+cJqihdSIiIiJymIs0mPwnMMU5171mhXOuB3A/apkUEREROeJEGkxOANoCq5xza5xza4CVoXUTol04EREREWnZIr1ncgfwJeAk4OjQuk/M7B/RLJSIiIiItA6NDiadc4nAbqDAzN4C3opZqURERESkVWh0N7eZVQFrgJTYFUdEREREWpNI75n8FfBr51zHWBRGRERERFqXSO+Z/AnQG9jgnFsPfBa+0cyOi1bBRERERKTlizSYnIafU9LFoCwiIiIi0so0Kph0zqUDvwG+DSTj55Qcb2bbY1c0EREREWnpGnvP5C+BS4DXgeeBrwGPxKhMIiIiItJKNLab+2zgB2b2AoBz7k/AB865xNAobxERERE5AjW2ZbI78H7NCzP7EKgE8mJRKBERERFpHRobTCYCB2qtqyTyATwiIiIichhpbDDogGedc+Vh69oATzjnympWmNm3olk4EREREWnZGhtMPl3HumejWRARERERaX0aFUya2aWxLoiIiIiItD6RPk5RREREROQgBZMiIiIiEpiCSREREREJTMGkiIiIiASmYFJEREREAlMwKSIiIiKBKZgUERERkcAUTIqIiIhIYAomRURERCQwBZMiIiIiEpiCSREREREJ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\n", + "text/plain": [ + "
" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "legend = ['Mitigated Probabilities', 'Unmitigated Probabilities']\n", "plot_histogram([mitigated_probs, unmitigated_probs], legend=legend, sort=\"value_desc\", bar_labels=False)" @@ -253,7 +264,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -268,9 +279,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAb10lEQVR4nO3de3iU1dnv8e9NoI0CYovoVoMGKeeEJBBBi0IoUNEqVNA2qN2ABaqitlgUbBUUffdlX/FQtbKFqqjl5GFL04r1UKFo3RawQItBKYeI0VYjQjASNKn3+8ck0yFkkglMCFn8Ptc115VZz5pn7lmZ/PLMc1hj7o6IiDR/LZq6ABERSQ4FuohIIBToIiKBUKCLiARCgS4iEoiWTfXExx13nKenpzfV04uINEtvvvnmx+7eobZlTRbo6enprFmzpqmeXkSkWTKzd+Mt0y4XEZFAKNBFRAKhQBcRCUST7UMXaQ4qKiooLi5m7969TV2KHGFSU1NJS0ujVatWCT9GgS5Sh+LiYtq2bUt6ejpm1tTlyBHC3dmxYwfFxcV06tQp4cdpl4tIHfbu3Uv79u0V5nJImRnt27dv8CdDBbpIPRTm0hQO5H2nQBcRCUTQgZ6Xl0deXl5TlyEBMUvuLbHnNC677LLo/crKSjp06MD5558PQEFBAXfccQcAS5cupbCwMNp3xowZvPzyywf0WtetW8eyZcsa/Li8vLxaLxrMy8ujW7duZGdnk52dzUUXXXRAdTXUvffey549exrc77zzzmPXrl2NWFnyBR3oIiFo3bo1GzZsoLy8HICXXnqJk08+Obp8xIgRTJ8+Hdg/0GfNmsXQoUMP6HkPNNDrsmDBAtatW8e6det4+umnk7rueA400JctW8axxx7biJUlnwJdpBk477zzeO655wBYtGgRY8aMiS6bP38+V199Na+//joFBQVcf/31ZGdns2XLFsaNGxcNzmXLltG9e3f69u3LtddeG93CX7VqFWeeeSY5OTl885vf5J133uGLL75gxowZLFmyhOzsbJYsWcJnn33G5ZdfTr9+/cjJyeG3v/0tAOXl5eTn59OjRw8uvPDC6D+eRI0cOZLHH38cgIceeohLL70UiGzR//jHPyY7O5uMjAxWrVoFELeOf//730ydOpWMjAx69+7N/fffz3333ccHH3zA4MGDGTx4MABXXnklubm59OrVi5kzZwLU2i89PZ2PP/4YgLvvvpuMjAwyMjK49957ASgqKqJHjx5MnDiRXr168e1vf7vBrz3p3L1Jbn379vXGNmjQIB80aFCjP8+R6EgZ28LCwn3uQ3JviWjdurWvX7/eR48e7eXl5Z6VleXLly/373znO+7u/uijj/rkyZPd3X3s2LH+1FNPRR9bfb+8vNzT0tJ869at7u6en58ffXxpaalXVFS4u/tLL73ko0aN2m+97u433nijP/HEE+7uvnPnTu/SpYuXlZX5XXfd5ePHj3d39/Xr13tKSoqvXr16v9cxaNAg79q1q2dlZXlWVpZPnTrV3d3/9a9/eefOnX3lypXepUsX37FjR7T/hAkT3N39T3/6k/fq1avOOh588EEfPXp09LVUr+fUU0/1kpKSaB3V7ZWVlT5o0CBfv359rf2q769Zs8YzMjK8rKzMP/30U+/Zs6f/9a9/9W3btnlKSoqvXbvW3d0vvvjiaF3JUvP95+4OrPE4uarz0EWagd69e1NUVMSiRYs477zzGvz4t99+m9NOOy16TvOYMWOYO3cuAKWlpYwdO5Z//OMfmBkVFRW1ruPFF1+koKCA2bNnA5FTOrdv387KlSu59tpro3X27t07bh0LFiwgNzd3n7YTTjiBWbNmMXjwYJ599lm+/vWvR5dVfxIZOHAgu3fvZteuXXHrePnll7niiito2TISa7HrifXkk08yd+5cKisr+ec//0lhYWGdNb/22mtceOGFtG7dGoBRo0bx6quvMmLECDp16kR2djYAffv2paioKO56DgUFukgzMWLECKZOncqKFSvYsWNH0tZ78803R8O0qKgo7okE7s4zzzxDt27dkvbc1f7+97/Tvn17Pvjgg33aa566Z2YHVce2bduYPXs2q1ev5mtf+xrjxo07qKuAv/rVr0Z/TklJafJdLtqHLtJMXH755cycOZPMzMy4fdq2bcunn366X3u3bt3YunVrdAtyyZIl0WWlpaXRg6zz58+Pu65zzjmH+++/n8infli7di0Q2XpeuHAhABs2bOBvf/tbg17XqlWreP7551m7di2zZ89m27Zt0WXVdb722mu0a9eOdu3axa1j2LBhPPTQQ1RWVgLwySef7Pc6du/eTevWrWnXrh0ffvghzz//fL1jd/bZZ7N06VL27NnDZ599xrPPPsvZZ5/doNd4qCjQRRog2XvRGyItLS26ayOe/Px87rzzTnJyctiyZUu0/aijjuLBBx9k+PDh9O3bl7Zt29KuXTsAbrjhBm688UZycnKiYQgwePBgCgsLowdFb775ZioqKujduze9evXi5ptvBiIHGcvKyujRowczZsygb9++ceu79NJLo6ctDh06lM8//5yJEyfyyCOPcNJJJ3HXXXdx+eWXR8M6NTWVnJwcrrjiCh5++GGAuHVMmDCBU045hd69e5OVlRX9JzNp0iSGDx/O4MGDycrKIicnh+7du3PJJZcwYMCAaG2x/WL16dOHcePG0a9fP/r378+ECRPIycmp+5fVRMwb+q5KktzcXG/sL7io/ui4YsWKRn2eI9GRMrYbN26kR48eTV1GUpSVldGmTRvcncmTJ9OlSxemTJnS1GXFlZeXx+zZs/fb534kqe39Z2Zvunutg9Is96E39IrYRPs30f82kUNi3rx5PPbYY3zxxRfk5OTwox/9qKlLkiRrloEuIg03ZcqUw3qLvKbQP/01BgW67EOffkSaLx0UFREJhAJdRCQQCnQRkUBoH7pIA9ityf2yC59Z98GFoqIizj//fDZs2BBtu+WWW2jTpg1Tp0496OefMWMGAwcOZOjQodx7771MmjSJo48+GohMCLZw4cIDmnFw6dKldO3alZ49ezbocW3atKGsrGy/9pSUlH0uqMrPz4/OMNlYdu3axcKFC7nqqqsa1O+DDz7g2muvPWSzScbSFrrIESx2et1kTh9bcxrfg3XUUUdFp91dt25do4c5RIL6wQcfbHC/k046qUnCHIIP9BVVN5Ew5eXlMW3aNPr160fXrl159dVXgcgl/N/97ncZNmwY6enpPPDAA9x9993k5ORwxhlnRC+Lr55et77pY2+77Ta6devGWWedxZgxY6ITY82bN4/TTz+drKwsRo8ezZ49e2qdxnfLli3Rq1TPPvts3n77bSAyt8qZZ55JZmYmN910U4Nee2lpKd26deOdd94BIhN5zZs3D4hs6U+ZMoVevXoxZMgQSkpKAOLW8eGHH3LhhReSlZVFVlYWr7/+OtOnT2fLli1kZ2dz/fXXU1ZWxpAhQ+jTpw+ZmZnRaXtr9isqKiIjIwOITBw2fvx4MjMzycnJYfny5dHfz6hRoxg+fDhdunThhhtuaOivvnbxpmFs7NvBTJ+b/AuwE5/KNHSJj9egqlvYY7vf9Lm3kNRbfbZt2xadNrbazJkz/c4773T3yBSz1113nbu7P/fccz5kyBB3j0x927lzZ9+9e7d/9NFHfswxx/icOXPc3f0nP/mJ33PPPe6+73S78aaPXbVqlWdlZXl5ebnv3r3bv/GNb0Sf/+OPP472//nPf+733Xfffut1d//Wt77lmzZtcnf3N954wwcPHuzu7hdccIE/9thj7u7+wAMPeOvWrWsdhxYtWkSn3c3KyvLFixe7u/uLL77oZ5xxhi9atMjPOeec//yewH/zm9+4u/utt94anQY4Xh3f+973omNSWVnpu3bt2m/sKyoqvLS01N3dS0pKvHPnzv7ll1/u1y/2/uzZs6NTC2/cuNE7duzo5eXl/uijj3qnTp18165dXl5e7qeccopv3759v9et6XNFAhLvi4Jj20eNGgXsP33r4MGDadu2bXTelgsuuACAzMzMBk2g9ec//5mRI0eSmppKampqdD0QmYzrpptuYteuXZSVlXHOOefs9/iysjJef/11Lr744mjb559/Hl33M888A8APfvADpk2bVmsN1btcaho2bBhPPfUUkydPZv369dH2Fi1a8P3vfx+Ayy67jFGjRtVZxyuvvBL9ko2UlBTatWvHzp0793kud+dnP/sZK1eupEWLFrz//vt8+OGH8QeOyKRi11xzDQDdu3fn1FNPZdOmTQAMGTIkOp9Oz549effdd+nYsWOd66uPAl0O0IqmLuCI0L59+/2C5ZNPPonOaw7/mcI1JSVln8m1Yqd2bdGiRfR+ixYt9ul3MMaNG8fSpUvJyspi/vz5tV7d+eWXX3LsscfWGshwYN9uH7vujRs3cvTRR7Nz507S0tLiPkd9ddRnwYIFlJSU8Oabb9KqVSvS09OTOvVuMn4nge9DF2ne2rRpw4knnsgrr7wCRML8D3/4A2eddVbSnyve9LEDBgzgd7/7HXv37qWsrIzf//730WWffvopJ554IhUVFSxYsKDWdR1zzDF06tSJp556Cohs6VZvTQ8YMIDFixcD7PP4RN1zzz306NGDhQsXMn78+OiXc3z55ZfRA5MLFy7krLPOqrOOIUOGMGfOHCDyVXalpaX7jUdpaSnHH388rVq1Yvny5bz77rt1jhtEpt6tfl2bNm1i+/btjTKffLWEttDNbDjwSyAF+LW731Fj+SnAY8CxVX2mu3tyv11W5DBQ32mGjeHx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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "mitigated_expectation_values, mitigated_stddev = zip(*mitigated_expectation)\n", "unmitigated_expectation_values, unmitigated_stddev = zip(*unmitigated_expectation)\n", @@ -295,9 +329,44 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " ░ ┌─┐ \n", + " q_0: ─░─┤M├───\n", + " ░ └╥┘┌─┐\n", + " q_1: ─░──╫─┤M├\n", + " ░ ║ └╥┘\n", + "meas: 2/════╩══╩═\n", + " 0 1 \n", + " ┌───┐ ░ ┌─┐ \n", + " q_0: ┤ X ├─░─┤M├───\n", + " └───┘ ░ └╥┘┌─┐\n", + " q_1: ──────░──╫─┤M├\n", + " ░ ║ └╥┘\n", + "meas: 2/═════════╩══╩═\n", + " 0 1 \n", + " ░ ┌─┐ \n", + " q_0: ──────░─┤M├───\n", + " ┌───┐ ░ └╥┘┌─┐\n", + " q_1: ┤ X ├─░──╫─┤M├\n", + " └───┘ ░ ║ └╥┘\n", + "meas: 2/═════════╩══╩═\n", + " 0 1 \n", + " ┌───┐ ░ ┌─┐ \n", + " q_0: ┤ X ├─░─┤M├───\n", + " ├───┤ ░ └╥┘┌─┐\n", + " q_1: ┤ X ├─░──╫─┤M├\n", + " └───┘ ░ ║ └╥┘\n", + "meas: 2/═════════╩══╩═\n", + " 0 1 \n" + ] + } + ], "source": [ "qubits = [0,3]\n", "num_qubits = len(qubits)\n", @@ -308,9 +377,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "

This code is a part of Qiskit

© Copyright IBM 2017, 2022.

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.

" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import qiskit.tools.jupyter\n", "%qiskit_copyright" diff --git a/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py index e570c2e65b..3d3eb58ba4 100644 --- a/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2022. # # 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 @@ -59,8 +59,7 @@ def _default_options(cls) -> Options: ax (AxesSubplot): Optional. A matplotlib axis object to draw. """ options = super()._default_options() - # since the plot size grows exponentially with the number of qubits, plotting is off by default - options.plot = False + options.plot = True options.ax = None return options @@ -69,7 +68,7 @@ def _run_analysis( ) -> Tuple[List[AnalysisResultData], List["matplotlib.figure.Figure"]]: data = experiment_data.data() qubits = experiment_data.metadata["physical_qubits"] - labels = [datum["metadata"]["label"] for datum in data] + labels = [datum["metadata"]["state_label"] for datum in data] matrix = self._generate_matrix(data, labels) result_mitigator = CorrelatedReadoutMitigator(matrix, qubits=qubits) analysis_results = [AnalysisResultData("Correlated Readout Mitigator", result_mitigator)] @@ -77,7 +76,7 @@ def _run_analysis( ax = options.get("ax", None) figures = [self._assignment_matrix_visualization(matrix, labels, ax)] else: - figures = None + figures = [] return analysis_results, figures def _generate_matrix(self, data, labels) -> np.array: @@ -85,7 +84,7 @@ def _generate_matrix(self, data, labels) -> np.array: matrix = np.zeros([list_size, list_size], dtype=float) # matrix[i][j] is the probability of counting i for expected j for datum in data: - expected_outcome = datum["metadata"]["label"] + expected_outcome = datum["metadata"]["state_label"] j = labels.index(expected_outcome) total_counts = sum(datum["counts"].values()) for measured_outcome, count in datum["counts"].items(): diff --git a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py index f81cc9acd5..e63756653e 100644 --- a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2022. # # 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 @@ -83,11 +83,11 @@ def _run_analysis( return analysis_results, figures def _generate_matrices(self, data) -> List[np.array]: - num_qubits = len(data[0]["metadata"]["label"]) + num_qubits = len(data[0]["metadata"]["state_label"]) counts = [None, None] for result in data: for i in range(2): - if result["metadata"]["label"] == str(i) * num_qubits: + if result["metadata"]["state_label"] == str(i) * num_qubits: counts[i] = result["counts"] matrices = [] for k in range(num_qubits): diff --git a/qiskit_experiments/library/characterization/correlated_readout_error.py b/qiskit_experiments/library/characterization/correlated_readout_error.py index b68f7b4194..72c8bd59a2 100644 --- a/qiskit_experiments/library/characterization/correlated_readout_error.py +++ b/qiskit_experiments/library/characterization/correlated_readout_error.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2022. # # 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 @@ -20,6 +20,21 @@ ) +def calibration_circuit(num_qubits: int, state_label: str) -> QuantumCircuit: + """Return a calibration circuit. + + This is an N-qubit circuit where N is the length of the label. + The circuit consists of X-gates on qubits with label bits equal to 1, + and measurements of all qubits. + """ + circ = QuantumCircuit(num_qubits, name="meas_mit_cal_" + state_label) + for i, val in enumerate(reversed(state_label)): + if val == "1": + circ.x(i) + circ.measure_all() + circ.metadata = {"state_label": state_label} + return circ + class CorrelatedReadoutError(BaseExperiment): r"""Class for correlated readout error characterization experiment # section: overview @@ -67,19 +82,4 @@ def __init__(self, qubits: Iterable[int]): def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" labels = [bin(j)[2:].zfill(self.num_qubits) for j in range(2 ** self.num_qubits)] - return [self.calibration_circuit(self.num_qubits, label) for label in labels] - - def calibration_circuit(self, num_qubits: int, label: str) -> QuantumCircuit: - """Return a calibration circuit. - - This is an N-qubit circuit where N is the length of the label. - The circuit consists of X-gates on qubits with label bits equal to 1, - and measurements of all qubits. - """ - circ = QuantumCircuit(num_qubits, name="meas_mit_cal_" + label) - for i, val in enumerate(reversed(label)): - if val == "1": - circ.x(i) - circ.measure_all() - circ.metadata = {"label": label} - return circ + return [calibration_circuit(self.num_qubits, label) for label in labels] \ No newline at end of file diff --git a/qiskit_experiments/library/characterization/local_readout_error.py b/qiskit_experiments/library/characterization/local_readout_error.py index 28f5a0aa64..c2222f443e 100644 --- a/qiskit_experiments/library/characterization/local_readout_error.py +++ b/qiskit_experiments/library/characterization/local_readout_error.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2022. # # 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 @@ -18,6 +18,7 @@ from qiskit_experiments.library.characterization.analysis.local_readout_error_analysis import ( LocalReadoutErrorAnalysis, ) +from .correlated_readout_error import calibration_circuit class LocalReadoutError(BaseExperiment): @@ -44,7 +45,7 @@ class LocalReadoutError(BaseExperiment): in ``qiskit-terra``. The experiment generates 2 circuits, corresponding to the states - :math:`|0^n>` and :math:`|1^n>`, measuring the error in all the qubits at once, and constructs + :math:`|0^n\rangle` and :math:`|1^n\rangle`, measuring the error in all the qubits at once, and constructs the assignment matrix and local mitigator from the results. See :class:`LocalReadoutErrorAnalysis` @@ -69,19 +70,4 @@ def __init__(self, qubits: Iterable[int]): def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" labels = ["0" * self.num_qubits, "1" * self.num_qubits] - return [self.calibration_circuit(self.num_qubits, label) for label in labels] - - def calibration_circuit(self, num_qubits: int, label: str) -> QuantumCircuit: - """Return a calibration circuit. - - This is an N-qubit circuit where N is the length of the label. - The circuit consists of X-gates on qubits with label bits equal to 1, - and measurements of all qubits. - """ - circ = QuantumCircuit(num_qubits, name="meas_mit_cal_" + label) - for i, val in enumerate(reversed(label)): - if val == "1": - circ.x(i) - circ.measure_all() - circ.metadata = {"label": label} - return circ + return [calibration_circuit(self.num_qubits, label) for label in labels] diff --git a/test/test_readout_error.py b/test/test_readout_error.py index 7cdafc2e91..e3c2a143a0 100644 --- a/test/test_readout_error.py +++ b/test/test_readout_error.py @@ -35,12 +35,12 @@ def test_local_analysis(self): run_data = [ { "counts": {"000": 986, "010": 10, "100": 16, "001": 12}, - "metadata": {"label": "000"}, + "metadata": {"state_label": "000"}, "shots": 1024, }, { "counts": {"111": 930, "110": 39, "011": 24, "101": 29, "010": 1, "100": 1}, - "metadata": {"label": "111"}, + "metadata": {"state_label": "111"}, "shots": 1024, }, ] @@ -67,42 +67,42 @@ def test_correlated_analysis(self): run_data = [ { "counts": {"000": 989, "010": 12, "100": 7, "001": 15, "101": 1}, - "metadata": {"label": "000"}, + "metadata": {"state_label": "000"}, "shots": 1024, }, { "counts": {"001": 971, "101": 15, "000": 36, "011": 2}, - "metadata": {"label": "001"}, + "metadata": {"state_label": "001"}, "shots": 1024, }, { "counts": {"000": 30, "010": 965, "110": 15, "011": 11, "001": 2, "100": 1}, - "metadata": {"label": "010"}, + "metadata": {"state_label": "010"}, "shots": 1024, }, { "counts": {"011": 955, "111": 15, "010": 26, "001": 27, "110": 1}, - "metadata": {"label": "011"}, + "metadata": {"state_label": "011"}, "shots": 1024, }, { "counts": {"100": 983, "101": 8, "110": 13, "000": 20}, - "metadata": {"label": "100"}, + "metadata": {"state_label": "100"}, "shots": 1024, }, { "counts": {"101": 947, "001": 34, "100": 32, "111": 11}, - "metadata": {"label": "101"}, + "metadata": {"state_label": "101"}, "shots": 1024, }, { "counts": {"100": 26, "110": 965, "010": 21, "111": 11, "000": 1}, - "metadata": {"label": "110"}, + "metadata": {"state_label": "110"}, "shots": 1024, }, { "counts": {"111": 938, "011": 23, "110": 35, "101": 27, "100": 1}, - "metadata": {"label": "111"}, + "metadata": {"state_label": "111"}, "shots": 1024, }, ] From 15ee74f2086db71014bf3528589ce7cc5dffe294 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Sun, 13 Feb 2022 08:43:53 +0200 Subject: [PATCH 21/32] Fix the release notes --- .../notes/readout-mitigation-experiment-4ea5392ee955a54c.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/releasenotes/notes/readout-mitigation-experiment-4ea5392ee955a54c.yaml b/releasenotes/notes/readout-mitigation-experiment-4ea5392ee955a54c.yaml index d630cd3637..16ab34188f 100644 --- a/releasenotes/notes/readout-mitigation-experiment-4ea5392ee955a54c.yaml +++ b/releasenotes/notes/readout-mitigation-experiment-4ea5392ee955a54c.yaml @@ -1,5 +1,5 @@ --- features: - | - Added a new experiment (`qiskit_experiments.library import ReadoutMitigationExperiment`) - for calibrating readout mitigators. + Added two new experiments (:class:`qiskit_experiments.library.LocalReadoutError` and :class:`qiskit_experiments.library.CorrelatedReadoutError`) + for characterizing the readout error of devices. From c154374bffdaf901069520fcff55bd8707b3ef23 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Sun, 13 Feb 2022 09:31:22 +0200 Subject: [PATCH 22/32] Additional doc fixes according to the PR reviews --- .../characterization/correlated_readout_error.py | 9 ++++++--- .../library/characterization/local_readout_error.py | 11 ++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/qiskit_experiments/library/characterization/correlated_readout_error.py b/qiskit_experiments/library/characterization/correlated_readout_error.py index 72c8bd59a2..2576fa1bd9 100644 --- a/qiskit_experiments/library/characterization/correlated_readout_error.py +++ b/qiskit_experiments/library/characterization/correlated_readout_error.py @@ -38,6 +38,11 @@ def calibration_circuit(num_qubits: int, state_label: str) -> QuantumCircuit: class CorrelatedReadoutError(BaseExperiment): r"""Class for correlated readout error characterization experiment # section: overview + This class constructs the a :class:`~qiskit.result.CorrelatedReadoutMitigator` containing the full + assignment matrix :math:`A` characterizing the readout error for the given qubits + from the experiment results accessible via the + :meth:`~qiskit.result.CorrelatedReadoutMitigator.assignment_matrix` method. + Readout errors affect quantum computation during the measurement of the qubits in a quantum device. By characterizing the readout errors, it is possible to construct a *readout error mitigator* that is used both @@ -52,9 +57,7 @@ class CorrelatedReadoutError(BaseExperiment): A *Correlated readout mitigator* uses the full :math:`2^n \times 2^n` assignment matrix, meaning it can only be used for small values of :math:`n`. The corresponding class in Qiskit is the - `Correlated readout mitigator - `_ - in ``qiskit-terra``. + :class:`~qiskit.result.CorrelatedReadoutMitigator` in :mod:`qiskit.result`. The experiment generates :math:`2^n` circuits, for every possible :math:`n`-qubit quantum state and constructs diff --git a/qiskit_experiments/library/characterization/local_readout_error.py b/qiskit_experiments/library/characterization/local_readout_error.py index c2222f443e..214f0f6f65 100644 --- a/qiskit_experiments/library/characterization/local_readout_error.py +++ b/qiskit_experiments/library/characterization/local_readout_error.py @@ -24,6 +24,12 @@ class LocalReadoutError(BaseExperiment): r"""Class for local readout error characterization experiment # section: overview + + This class constructs the a :class:`~qiskit.result.LocalReadoutMitigator` containing sequence + of assignment matrices :math:`A` characterizing the readout error for the given qubits + from the experiment results. The full assignment matrix is accessible via the + :meth:`~qiskit.result.LocalReadoutMitigator.assignment_matrix` method. + Readout errors affect quantum computation during the measurement of the qubits in a quantum device. By characterizing the readout errors, it is possible to construct a *readout error mitigator* that is used both @@ -40,9 +46,8 @@ class LocalReadoutError(BaseExperiment): In this case, the assignment matrix is the tensor product of :math:`n` :math:`2 \times 2` matrices, one for each qubit, making it practical to store the assignment matrix in implicit form, by storing the individual :math:`2 \times 2` assignment matrices. - The corresponding class in Qiskit is the `Local readout mitigator - `_ - in ``qiskit-terra``. + The corresponding class in Qiskit is the :class:`~qiskit.result.LocalReadoutMitigator` + in :mod:`qiskit.result`. The experiment generates 2 circuits, corresponding to the states :math:`|0^n\rangle` and :math:`|1^n\rangle`, measuring the error in all the qubits at once, and constructs From 3dd1a25e8bead1ee5f70b0ae23d7e1ed7fe4f0d8 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Sun, 13 Feb 2022 09:36:07 +0200 Subject: [PATCH 23/32] Linting --- .../library/characterization/correlated_readout_error.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qiskit_experiments/library/characterization/correlated_readout_error.py b/qiskit_experiments/library/characterization/correlated_readout_error.py index 2576fa1bd9..60c89d8557 100644 --- a/qiskit_experiments/library/characterization/correlated_readout_error.py +++ b/qiskit_experiments/library/characterization/correlated_readout_error.py @@ -35,6 +35,7 @@ def calibration_circuit(num_qubits: int, state_label: str) -> QuantumCircuit: circ.metadata = {"state_label": state_label} return circ + class CorrelatedReadoutError(BaseExperiment): r"""Class for correlated readout error characterization experiment # section: overview @@ -84,5 +85,5 @@ def __init__(self, qubits: Iterable[int]): def circuits(self) -> List[QuantumCircuit]: """Returns the experiment's circuits""" - labels = [bin(j)[2:].zfill(self.num_qubits) for j in range(2 ** self.num_qubits)] - return [calibration_circuit(self.num_qubits, label) for label in labels] \ No newline at end of file + labels = [bin(j)[2:].zfill(self.num_qubits) for j in range(2**self.num_qubits)] + return [calibration_circuit(self.num_qubits, label) for label in labels] From afa33f87cf2abd6cae499715d650faf6f4155ac4 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Sun, 13 Feb 2022 12:04:37 +0200 Subject: [PATCH 24/32] Linting --- .../library/characterization/correlated_readout_error.py | 6 +++--- .../library/characterization/local_readout_error.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qiskit_experiments/library/characterization/correlated_readout_error.py b/qiskit_experiments/library/characterization/correlated_readout_error.py index 60c89d8557..79bf7c52a6 100644 --- a/qiskit_experiments/library/characterization/correlated_readout_error.py +++ b/qiskit_experiments/library/characterization/correlated_readout_error.py @@ -39,9 +39,9 @@ def calibration_circuit(num_qubits: int, state_label: str) -> QuantumCircuit: class CorrelatedReadoutError(BaseExperiment): r"""Class for correlated readout error characterization experiment # section: overview - This class constructs the a :class:`~qiskit.result.CorrelatedReadoutMitigator` containing the full - assignment matrix :math:`A` characterizing the readout error for the given qubits - from the experiment results accessible via the + This class constructs the a :class:`~qiskit.result.CorrelatedReadoutMitigator` + containing the full assignment matrix :math:`A` characterizing the readout error + for the given qubits from the experiment results accessible via the :meth:`~qiskit.result.CorrelatedReadoutMitigator.assignment_matrix` method. Readout errors affect quantum computation during the measurement diff --git a/qiskit_experiments/library/characterization/local_readout_error.py b/qiskit_experiments/library/characterization/local_readout_error.py index 214f0f6f65..77efdfb5b1 100644 --- a/qiskit_experiments/library/characterization/local_readout_error.py +++ b/qiskit_experiments/library/characterization/local_readout_error.py @@ -50,8 +50,8 @@ class LocalReadoutError(BaseExperiment): in :mod:`qiskit.result`. The experiment generates 2 circuits, corresponding to the states - :math:`|0^n\rangle` and :math:`|1^n\rangle`, measuring the error in all the qubits at once, and constructs - the assignment matrix and local mitigator from the results. + :math:`|0^n\rangle` and :math:`|1^n\rangle`, measuring the error in all + the qubits at once, and constructs the assignment matrix and local mitigator from the results. See :class:`LocalReadoutErrorAnalysis` documentation for additional information on local readout error experiment analysis. From d9069ba0b93f7e9e6c25d5acc5743aef4397a669 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Sun, 13 Feb 2022 14:40:16 +0200 Subject: [PATCH 25/32] Added a test for db integration --- test/test_readout_error.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/test_readout_error.py b/test/test_readout_error.py index e3c2a143a0..7a437f2956 100644 --- a/test/test_readout_error.py +++ b/test/test_readout_error.py @@ -24,6 +24,7 @@ from qiskit_experiments.library.characterization import LocalReadoutError, CorrelatedReadoutError from qiskit_experiments.framework import ExperimentData from qiskit_experiments.framework import ParallelExperiment +from qiskit_experiments.test.fake_service import FakeService class TestMitigation(QiskitExperimentsTestCase): @@ -153,6 +154,20 @@ def test_parallel_running(self): assignment_matrix2 = mit2.assignment_matrix() self.assertFalse(matrix_equal(assignment_matrix1, assignment_matrix2)) + def test_database_save_and_load(self): + qubits = [0, 1] + backend = AerSimulator.from_backend(FakeParis()) + exp = LocalReadoutError(qubits) + exp_data = exp.run(backend).block_for_results() + exp_data.service = FakeService() + exp_data.save() + loaded_data = ExperimentData.load(exp_data.experiment_id, exp_data.service) + exp_res = exp_data.analysis_results() + load_res = loaded_data.analysis_results() + exp_matrix = exp_res[0].value.assignment_matrix() + load_matrix = load_res[0].value.assignment_matrix() + self.assertTrue(matrix_equal(exp_matrix, load_matrix)) + if __name__ == "__main__": unittest.main() From c1ad8e1e9253e4085a823b8ac85c0d7607e26ee8 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Sun, 13 Feb 2022 14:52:31 +0200 Subject: [PATCH 26/32] Few more doc fixes --- .../analysis/correlated_readout_error_analysis.py | 14 ++++++-------- .../analysis/local_readout_error_analysis.py | 14 +++++++------- test/test_readout_error.py | 1 + 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py index 3d3eb58ba4..6d33e57031 100644 --- a/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/correlated_readout_error_analysis.py @@ -28,7 +28,8 @@ class CorrelatedReadoutErrorAnalysis(BaseAnalysis): # section: overview This class generates the full assignment matrix :math:`A` characterizing the - readout error for the given qubits from the experiment results. + readout error for the given qubits from the experiment results + and returns the resulting :class:`~qiskit.result.CorrelatedReadoutMitigator` :math:`A` is a :math:`2^n\times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the probability to observe :math:`y` given the true outcome should be :math:`x`. @@ -37,14 +38,11 @@ class CorrelatedReadoutErrorAnalysis(BaseAnalysis): outcome is :math:`x`. From the observed results on the circuit, the probability for each :math:`y` is determined, and :math:`A_{y,x}` is set accordingly. - Returns - - * The `Correlated readout error mitigator - `_ - object (the assignment matrix can be accessed via its ``assignment_matrix()`` method). - - * (Optional) A figure of the assignment matrix. + Analysis Results: + * "Local Readout Mitigator": The :class:`~qiskit.result.LocalReadoutMitigator`. + Analysis Figures: + * (Optional) A figure of the assignment matrix. # section: reference .. ref_arxiv:: 1 2006.14044 diff --git a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py index e63756653e..f4c6ea674b 100644 --- a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py @@ -28,7 +28,8 @@ class LocalReadoutErrorAnalysis(BaseAnalysis): # section: overview This class generates the assignment matrices characterizing the - readout error for each of the given qubits from the experiment results. + readout error for each of the given qubits from the experiment result, + and returns the resulting :class:`~qiskit.result.LocalReadoutMitigator` Each such matrix is a :math:`2\times 2` matrix :math:`A`. Such that :math:`A_{y,x}` is the probability to observe :math:`y` given the true outcome should be :math:`x`, @@ -38,13 +39,12 @@ class LocalReadoutErrorAnalysis(BaseAnalysis): qubits and one for 1 outcome. From the observed results on the circuit, the probability for each :math:`x,y` is determined, and :math:`A_{y,x}` is set accordingly. - Returns + Analysis Results: + * "Local Readout Mitigator": The :class:`~qiskit.result.LocalReadoutMitigator`. - * The `Local readout error mitigator - `_ - object (the assignment matrix can be accessed via its ``assignment_matrix()`` method). - - * (Optional) A figure of the assignment matrix. + Analysis Figures: + * (Optional) A figure of the assignment matrix. + Note: producing this figure scales exponentially with the number of qubits. # section: reference diff --git a/test/test_readout_error.py b/test/test_readout_error.py index 7a437f2956..ee75ab94a6 100644 --- a/test/test_readout_error.py +++ b/test/test_readout_error.py @@ -155,6 +155,7 @@ def test_parallel_running(self): self.assertFalse(matrix_equal(assignment_matrix1, assignment_matrix2)) def test_database_save_and_load(self): + """Tests saving and loading the mitigator from the DB""" qubits = [0, 1] backend = AerSimulator.from_backend(FakeParis()) exp = LocalReadoutError(qubits) From dad27bd4c20c6fa73d6570131d2f1b4a0061a452 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Sun, 13 Feb 2022 14:59:59 +0200 Subject: [PATCH 27/32] docs fix --- .../characterization/analysis/local_readout_error_analysis.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py index f4c6ea674b..7282e19378 100644 --- a/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py +++ b/qiskit_experiments/library/characterization/analysis/local_readout_error_analysis.py @@ -44,8 +44,7 @@ class LocalReadoutErrorAnalysis(BaseAnalysis): Analysis Figures: * (Optional) A figure of the assignment matrix. - Note: producing this figure scales exponentially with the number of qubits. - + Note: producing this figure scales exponentially with the number of qubits. # section: reference .. ref_arxiv:: 1 2006.14044 From 6eabbd2f06ec80278d83f9ac9211423a1c2b36dc Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 17 Feb 2022 09:47:25 +0200 Subject: [PATCH 28/32] Specific mitigator serialization hack --- qiskit_experiments/framework/json.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/qiskit_experiments/framework/json.py b/qiskit_experiments/framework/json.py index 89ed9be863..4d5a8c4487 100644 --- a/qiskit_experiments/framework/json.py +++ b/qiskit_experiments/framework/json.py @@ -34,6 +34,7 @@ from qiskit.circuit.library import BlueprintCircuit from qiskit.quantum_info import DensityMatrix from qiskit.quantum_info.operators.channel.quantum_channel import QuantumChannel +from qiskit.result import LocalReadoutMitigator, CorrelatedReadoutMitigator from qiskit_experiments.version import __version__ @@ -500,6 +501,14 @@ def default(self, obj: Any) -> Any: # pylint: disable=arguments-differ "output_dims": obj.output_dims(), } return _serialize_object(obj, settings=settings) + if isinstance(obj, LocalReadoutMitigator): + # Temporary handling until serialization is added to terra stable release + settings = {"amats": obj._assignment_mats, "qubits": obj.qubits} + return _serialize_object(obj, settings=settings) + if isinstance(obj, CorrelatedReadoutMitigator): + # Temporary handling until serialization is added to terra stable release + settings = {"amat": obj._assignment_mat, "qubits": obj.qubits} + return _serialize_object(obj, settings=settings) if isinstance(obj, DensityMatrix): # Temporary fix for incorrect settings in qiskit-terra # See https://github.com/Qiskit/qiskit-terra/pull/7194 From 8ee9eeab1880a29ebb1cbeef50fd3342728f4fbf Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 17 Feb 2022 16:50:20 +0200 Subject: [PATCH 29/32] Testing mitigator to json encoding/decoding --- test/test_readout_error.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/test_readout_error.py b/test/test_readout_error.py index ee75ab94a6..f3bb206b8a 100644 --- a/test/test_readout_error.py +++ b/test/test_readout_error.py @@ -16,8 +16,9 @@ import unittest -from test.base import QiskitExperimentsTestCase import numpy as np +import json +from test.base import QiskitExperimentsTestCase from qiskit.quantum_info.operators.predicates import matrix_equal from qiskit.providers.aer import AerSimulator from qiskit.test.mock import FakeParis @@ -25,9 +26,11 @@ from qiskit_experiments.framework import ExperimentData from qiskit_experiments.framework import ParallelExperiment from qiskit_experiments.test.fake_service import FakeService +from qiskit_experiments.framework.json import ExperimentEncoder, ExperimentDecoder +from qiskit_experiments.library.quantum_volume import QuantumVolume -class TestMitigation(QiskitExperimentsTestCase): +class TestRedoutError(QiskitExperimentsTestCase): """Test Readout Error experiments""" def test_local_analysis(self): @@ -169,6 +172,16 @@ def test_database_save_and_load(self): load_matrix = load_res[0].value.assignment_matrix() self.assertTrue(matrix_equal(exp_matrix, load_matrix)) + def test_json_serialization(self): + qubits = [0, 1] + backend = AerSimulator.from_backend(FakeParis()) + exp = LocalReadoutError(qubits) + exp_data = exp.run(backend).block_for_results() + mitigator = exp_data.analysis_results(0).value + serialized = json.dumps(mitigator, cls=ExperimentEncoder) + loaded = json.loads(serialized, cls=ExperimentDecoder) + self.assertTrue(matrix_equal(mitigator.assignment_matrix(), loaded.assignment_matrix())) + if __name__ == "__main__": unittest.main() From 1e4ee4b8a27b7f656e4af117be275c26389f0de3 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 17 Feb 2022 17:02:03 +0200 Subject: [PATCH 30/32] Linting --- test/test_readout_error.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_readout_error.py b/test/test_readout_error.py index f3bb206b8a..73f6f00017 100644 --- a/test/test_readout_error.py +++ b/test/test_readout_error.py @@ -16,9 +16,9 @@ import unittest -import numpy as np import json from test.base import QiskitExperimentsTestCase +import numpy as np from qiskit.quantum_info.operators.predicates import matrix_equal from qiskit.providers.aer import AerSimulator from qiskit.test.mock import FakeParis @@ -27,7 +27,6 @@ from qiskit_experiments.framework import ParallelExperiment from qiskit_experiments.test.fake_service import FakeService from qiskit_experiments.framework.json import ExperimentEncoder, ExperimentDecoder -from qiskit_experiments.library.quantum_volume import QuantumVolume class TestRedoutError(QiskitExperimentsTestCase): @@ -173,6 +172,7 @@ def test_database_save_and_load(self): self.assertTrue(matrix_equal(exp_matrix, load_matrix)) def test_json_serialization(self): + """Verifies that mitigators can be serialized for DB storage""" qubits = [0, 1] backend = AerSimulator.from_backend(FakeParis()) exp = LocalReadoutError(qubits) From 09bb213e29202b075a02b98a69015594c9fd5ad6 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 17 Feb 2022 17:44:16 +0200 Subject: [PATCH 31/32] New version of the mitigation tutorial --- docs/tutorials/readout_mitigation.rst | 54 +++++++++++++++++++-------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/docs/tutorials/readout_mitigation.rst b/docs/tutorials/readout_mitigation.rst index b61284fc60..e844d039b5 100644 --- a/docs/tutorials/readout_mitigation.rst +++ b/docs/tutorials/readout_mitigation.rst @@ -1,15 +1,36 @@ Readout Mitigation ================== -Readout mitigation is part of ``qiskit-terra``. The readout mitigators -can be initalized based on existing backend data, or via a readout -mitigation experiment. - -In a readout mitigation experiment, simple circuits are generated for -various combinations of “0” and “1” readout values. The results give us -a matrix describing the probability to obtain a wrong measurement. This -matrix is used to initialize the readout mitigation object, which is -given as the result of the expriment. +Readout errors affect quantum computation during the measurement of the +qubits in a quantum device. By characterizing the readout errors, it is +possible to construct a *readout error mitigator* that is used both to +obtain a more accurate distribution of the outputs, and more accurate +measurements of expectation value for measurables. + +The readout mitigator is generated from an *assignment matrix*: a +:math:`2^n \times 2^n` matrix :math:`A` such that :math:`A_{y,x}` is the +probability to observe :math:`y` given the true outcome should be +:math:`x`. The assignment matrix is used to compute the *mitigation +matrix* used in the readout error mitigation process itself. + +A *Local readout mitigator* works under the assumption that readout +errors are mostly *local*, meaning readout errors for different qubits +are independent of each other. In this case, the assignment matrix is +the tensor product of :math:`n` :math:`2 \times 2` matrices, one for +each qubit, making it practical to store the assignment matrix in +implicit form, by storing the individual :math:`2 \times 2` assignment +matrices. The corresponding class in Qiskit is the `Local readout +mitigator `__ +in ``qiskit-terra``. + +A *Correlated readout mitigator* uses the full :math:`2^n \times 2^n` +assignment matrix, meaning it can only be used for small values of +:math:`n`. The corresponding class in Qiskit is the `Correlated readout +mitigator `__ +in ``qiskit-terra``. + +This notebook demonstrates the usage of both the local and correlated +experiments to generate the corresponding mitigators. .. jupyter-execute:: @@ -17,17 +38,17 @@ given as the result of the expriment. import matplotlib.pyplot as plt from qiskit import QuantumCircuit from qiskit.visualization import plot_histogram - from qiskit_experiments.library import ReadoutMitigationExperiment + from qiskit_experiments.library import LocalReadoutError, CorrelatedReadoutError # For simulation from qiskit.providers.aer import AerSimulator from qiskit.test.mock import FakeParis - + from qiskit.result.mitigation.utils import ( expval_with_stddev, str2diag, counts_probability_vector ) - + backend = AerSimulator.from_backend(FakeParis()) .. jupyter-execute:: @@ -45,14 +66,15 @@ circuits, one for all “0” and one for all “1” results. .. jupyter-execute:: - exp = ReadoutMitigationExperiment(qubits) + exp = LocalReadoutError(qubits) for c in exp.circuits(): print(c) .. jupyter-execute:: - result = exp.run(backend).block_for_results() + exp.analysis.set_options(plot=True) + result = exp.run(backend) mitigator = result.analysis_results(0).value The resulting measurement matrix can be illustrated by comparing it to @@ -62,6 +84,7 @@ the identity. result.figure(0) + Mitigation matrices ------------------- @@ -145,10 +168,11 @@ a few qubits. qubits = [0,3] num_qubits = len(qubits) - exp = ReadoutMitigationExperiment(qubits, method="correlated") + exp = CorrelatedReadoutError(qubits) for c in exp.circuits(): print(c) + .. jupyter-execute:: import qiskit.tools.jupyter From ed1177a99b65b92a220f192aaf36711f242ca5d7 Mon Sep 17 00:00:00 2001 From: Gadi Aleksandrowicz Date: Thu, 17 Feb 2022 18:07:39 +0200 Subject: [PATCH 32/32] Name change according to the changes in terra --- qiskit_experiments/framework/json.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiskit_experiments/framework/json.py b/qiskit_experiments/framework/json.py index 4d5a8c4487..fecd19408b 100644 --- a/qiskit_experiments/framework/json.py +++ b/qiskit_experiments/framework/json.py @@ -503,11 +503,11 @@ def default(self, obj: Any) -> Any: # pylint: disable=arguments-differ return _serialize_object(obj, settings=settings) if isinstance(obj, LocalReadoutMitigator): # Temporary handling until serialization is added to terra stable release - settings = {"amats": obj._assignment_mats, "qubits": obj.qubits} + settings = {"assignment_matrices": obj._assignment_mats, "qubits": obj.qubits} return _serialize_object(obj, settings=settings) if isinstance(obj, CorrelatedReadoutMitigator): # Temporary handling until serialization is added to terra stable release - settings = {"amat": obj._assignment_mat, "qubits": obj.qubits} + settings = {"assignment_matrix": obj._assignment_mat, "qubits": obj.qubits} return _serialize_object(obj, settings=settings) if isinstance(obj, DensityMatrix): # Temporary fix for incorrect settings in qiskit-terra