Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…eriments into issue-qiskit-community#1238-draft2

update local2/issue-#1238-draft2 with upstream/main
  • Loading branch information
Naohnakazawa committed Nov 19, 2024
2 parents f754951 + 519bb53 commit 32e749f
Show file tree
Hide file tree
Showing 15 changed files with 1,390 additions and 33 deletions.
47 changes: 20 additions & 27 deletions docs/manuals/measurement/readout_mitigation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,16 @@ experiments to generate the corresponding mitigators.
import numpy as np
import matplotlib.pyplot as plt
from qiskit import QuantumCircuit
from qiskit.quantum_info import Operator
from qiskit.visualization import plot_distribution
from qiskit_experiments.data_processing import LocalReadoutMitigator
from qiskit_experiments.library import LocalReadoutError, CorrelatedReadoutError

from qiskit_aer import AerSimulator
from qiskit_ibm_runtime.fake_provider import FakePerth

from qiskit.result.mitigation.utils import (
expval_with_stddev,
str2diag,
counts_probability_vector
)

backend = AerSimulator.from_backend(FakePerth())

.. jupyter-execute::

shots = 1024
qubits = [0,1,2,3]
num_qubits = len(qubits)

Standard mitigation experiment
------------------------------
Expand All @@ -76,13 +67,14 @@ circuits, one for all “0” and one for all “1” results.

.. jupyter-execute::

shots = 1024
qubits = [0,1,2,3]
num_qubits = len(qubits)

exp = LocalReadoutError(qubits)
for c in exp.circuits():
print(c)


.. jupyter-execute::

exp.analysis.set_options(plot=True)
result = exp.run(backend)
mitigator = result.analysis_results("Local Readout Mitigator").value
Expand All @@ -102,9 +94,9 @@ The individual mitigation matrices can be read off the mitigator.

.. jupyter-execute::

for m in mitigator._mitigation_mats:
print(m)
print()
for qubit in mitigator.qubits:
print(f"Qubit: {qubit}")
print(mitigator.mitigation_matrix(qubits=qubit))


Mitigation example
Expand All @@ -118,13 +110,9 @@ Mitigation example
qc.cx(i - 1, i)
qc.measure_all()

.. jupyter-execute::

counts = backend.run(qc, shots=shots, seed_simulator=42, method="density_matrix").result().get_counts()
unmitigated_probs = {label: count / shots for label, count in counts.items()}

.. jupyter-execute::

mitigated_quasi_probs = mitigator.quasi_probabilities(counts)
mitigated_stddev = mitigated_quasi_probs._stddev_upper_bound
mitigated_probs = (mitigated_quasi_probs.nearest_probability_distribution().binary_probabilities())
Expand All @@ -144,15 +132,20 @@ Expectation value
.. jupyter-execute::

diagonal_labels = ["ZZZZ", "ZIZI", "IZII", "1ZZ0"]
ideal_expectation = []
diagonals = [str2diag(d) for d in diagonal_labels]
diagonals = [
np.diag(np.real(Operator.from_label(d).to_matrix()))
for d in diagonal_labels
]

# Create a mitigator with no mitigation so that we can use its
# expectation_values method to generate an unmitigated expectation value to
# compare to the mitigated one.
identity_mitigator = LocalReadoutMitigator([np.eye(2) for _ in range(4)])

qubit_index = {i: i for i in range(num_qubits)}
unmitigated_probs_vector, _ = counts_probability_vector(unmitigated_probs, qubit_index=qubit_index)
unmitigated_expectation = [expval_with_stddev(d, unmitigated_probs_vector, shots) for d in diagonals]
unmitigated_expectation = [identity_mitigator.expectation_value(counts, d) for d in diagonals]
mitigated_expectation = [mitigator.expectation_value(counts, d) for d in diagonals]

.. jupyter-execute::

mitigated_expectation_values, mitigated_stddev = zip(*mitigated_expectation)
unmitigated_expectation_values, unmitigated_stddev = zip(*unmitigated_expectation)
legend = ['Mitigated Expectation', 'Unmitigated Expectation']
Expand Down
12 changes: 12 additions & 0 deletions qiskit_experiments/data_processing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@
BaseDiscriminator
SkLDA
SkQDA
Mitigators
==========
.. autosummary::
:toctree: ../stubs/
BaseReadoutMitigator
LocalReadoutMitigator
CorrelatedReadoutMitigator
"""

from .data_action import DataAction, TrainableDataAction
Expand All @@ -104,4 +113,7 @@

from .data_processor import DataProcessor
from .discriminator import BaseDiscriminator
from .mitigation.base_readout_mitigator import BaseReadoutMitigator
from .mitigation.correlated_readout_mitigator import CorrelatedReadoutMitigator
from .mitigation.local_readout_mitigator import LocalReadoutMitigator
from .sklearn_discriminators import SkLDA, SkQDA
22 changes: 22 additions & 0 deletions qiskit_experiments/data_processing/mitigation/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 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 error mitigation."""
from .base_readout_mitigator import BaseReadoutMitigator
from .correlated_readout_mitigator import CorrelatedReadoutMitigator
from .local_readout_mitigator import LocalReadoutMitigator
from .utils import (
counts_probability_vector,
expval_with_stddev,
stddev,
str2diag,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 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.
"""
Base class for readout error mitigation.
"""

from abc import ABC, abstractmethod
from typing import Optional, List, Iterable, Tuple, Union, Callable

import numpy as np

from qiskit.result.counts import Counts
from qiskit.result.distributions.quasi import QuasiDistribution


class BaseReadoutMitigator(ABC):
"""Base readout error mitigator class."""

@abstractmethod
def quasi_probabilities(
self,
data: Counts,
qubits: Iterable[int] = None,
clbits: Optional[List[int]] = None,
shots: Optional[int] = None,
) -> QuasiDistribution:
"""Convert counts to a dictionary of quasi-probabilities
Args:
data: Counts to be mitigated.
qubits: the physical qubits measured to obtain the counts clbits.
If None these are assumed to be qubits [0, ..., N-1]
for N-bit counts.
clbits: Optional, marginalize counts to just these bits.
shots: Optional, the total number of shots, if None shots will
be calculated as the sum of all counts.
Returns:
QuasiDistribution: A dictionary containing pairs of [output, mean] where "output"
is the key in the dictionaries,
which is the length-N bitstring of a measured standard basis state,
and "mean" is the mean of non-zero quasi-probability estimates.
"""

@abstractmethod
def expectation_value(
self,
data: Counts,
diagonal: Union[Callable, dict, str, np.ndarray],
qubits: Iterable[int] = None,
clbits: Optional[List[int]] = None,
shots: Optional[int] = None,
) -> Tuple[float, float]:
"""Calculate the expectation value of a diagonal Hermitian operator.
Args:
data: Counts object to be mitigated.
diagonal: the diagonal operator. This may either be specified
as a string containing I,Z,0,1 characters, or as a
real valued 1D array_like object supplying the full diagonal,
or as a dictionary, or as Callable.
qubits: the physical qubits measured to obtain the counts clbits.
If None these are assumed to be qubits [0, ..., N-1]
for N-bit counts.
clbits: Optional, marginalize counts to just these bits.
shots: Optional, the total number of shots, if None shots will
be calculated as the sum of all counts.
Returns:
The mean and an upper bound of the standard deviation of operator
expectation value calculated from the current counts.
"""
Loading

0 comments on commit 32e749f

Please sign in to comment.