Source code for qiskit_experiments.library.tomography.basis.pauli_basis

# 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.
"""
Pauli preparation and measurement tomography bases.
"""
from typing import Optional
import numpy as np
from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import HGate, XGate, ZGate, SGate, SdgGate
from qiskit.quantum_info import DensityMatrix
from qiskit.exceptions import QiskitError
from qiskit_experiments.data_processing import LocalReadoutMitigator
from .local_basis import LocalMeasurementBasis, LocalPreparationBasis


[docs] class PauliMeasurementBasis(LocalMeasurementBasis): r"""Standard Pauli measurement basis. This basis has 3 indices each with with 2 measurement outcomes. The corresponding single-qubit measurement circuits and outcome POVM matrices are: .. table:: Single-qubit measurement circuits and POVM matrices +-------+-------+---------------+---------+-------------------------------+ | Index | Basis | Circuit | Outcome | POVM Matrix | +=======+=======+===============+=========+===============================+ | 0 | Z |``-[I]-`` | 0 |``[[1, 0], [0, 0]]`` | +-------+-------+---------------+---------+-------------------------------+ | | | | 1 |``[[0, 0], [0, 1]]`` | +-------+-------+---------------+---------+-------------------------------+ | 1 | X | ``-[H]-`` | 0 |``[[0.5, 0.5], [0.5, 0.5]]`` | +-------+-------+---------------+---------+-------------------------------+ | | | | 1 |``[[0.5, -0.5], [-0.5, 0.5]]`` | +-------+-------+---------------+---------+-------------------------------+ | 2 | Y |``-[SDG]-[H]-``| 0 |``[[0.5, -0.5j], [0.5j, 0.5]]``| +-------+-------+---------------+---------+-------------------------------+ | | | | 1 |``[[0.5, 0.5j], [-0.5j, 0.5]]``| +-------+-------+---------------+---------+-------------------------------+ """ def __init__(self, mitigator: Optional[LocalReadoutMitigator] = None): """Initialize Pauli measurement basis""" # Z-meas rotation meas_z = QuantumCircuit(1, name="PauliMeasZ") # X-meas rotation meas_x = QuantumCircuit(1, name="PauliMeasX") meas_x.append(HGate(), [0]) # Y-meas rotation meas_y = QuantumCircuit(1, name="PauliMeasY") meas_y.append(SdgGate(), [0]) meas_y.append(HGate(), [0]) instructions = [meas_z, meas_x, meas_y] self._mitigator = mitigator super().__init__( "PauliMeasurementBasis", instructions, qubit_povms=self._mitigator_povm(self._mitigator) ) @staticmethod def _mitigator_povm(mitigator: Optional[LocalReadoutMitigator] = None): """Construct LocalMeasurementBasis qubit_povm from mitigator.""" if mitigator is None: return None povm = {} if isinstance(mitigator, LocalReadoutMitigator): povm = {} for qubit in mitigator.qubits: amat = mitigator.assignment_matrix(qubit) povm[(qubit,)] = {(0,): [DensityMatrix(np.diag(row)) for row in amat]} else: raise QiskitError("Invalid mitigator: must be LocalReadoutMitigator") return povm def __json_encode__(self): # Override LocalMeasurementBasis's encoder if self._mitigator is not None: return {"mitigator": self._mitigator} return {}
[docs] class PauliPreparationBasis(LocalPreparationBasis): """Minimal 4-element Pauli measurement basis. This is a minimal size 4 preparation basis where each qubit index corresponds to the following initial state preparation circuits and density matrices: .. table:: Single-qubit preparation circuits and states +-------+-------+---------------------+---------------------------------+ | Index | State | Preparation Circuit | Density Matrix | +=======+=======+=====================+=================================+ | 0 | Zp | ``-[I]-`` | ``[[1, 0], [0, 0]]`` | +-------+-------+---------------------+---------------------------------+ | 1 | Zm | ``-[X]-`` | ``[[0, 0], [0, 1]]`` | +-------+-------+---------------------+---------------------------------+ | 2 | Xp | ``-[H]-`` | ``[[0.5, 0.5], [0.5, 0.5]]`` | +-------+-------+---------------------+---------------------------------+ | 3 | Yp | ``-[H]-[S]-`` | ``[[0.5, -0.5j], [0.5j, 0.5]]`` | +-------+-------+---------------------+---------------------------------+ """ def __init__(self): """Initialize Pauli preparation basis""" # |0> Zp rotation prep_zp = QuantumCircuit(1, name="PauliPrepZp") # |1> Zm rotation prep_zm = QuantumCircuit(1, name="PauliPrepZm") prep_zm.append(XGate(), [0]) # |+> Xp rotation prep_xp = QuantumCircuit(1, name="PauliPrepXp") prep_xp.append(HGate(), [0]) # |+i> Yp rotation prep_yp = QuantumCircuit(1, name="PauliPrepYp") prep_yp.append(HGate(), [0]) prep_yp.append(SGate(), [0]) super().__init__("PauliPreparationBasis", [prep_zp, prep_zm, prep_xp, prep_yp]) def __json_encode__(self): # Override LocalPreparationBasis's encoder return {}
[docs] class Pauli6PreparationBasis(LocalPreparationBasis): """Over-complete 6-element Pauli preparation basis. This is an over-complete size 6 preparation basis where each qubit index corresponds to the following initial state density matrices: .. table:: Single-qubit preparation circuits and states +-------+-------+---------------------+---------------------------------+ | Index | State | Preparation Circuit | Density Matrix | +=======+=======+=====================+=================================+ | 0 | Zp | ``-[I]-`` | ``[[1, 0], [0, 0]]`` | +-------+-------+---------------------+---------------------------------+ | 1 | Zm | ``-[X]-`` | ``[[0, 0], [0, 1]]`` | +-------+-------+---------------------+---------------------------------+ | 2 | Xp | ``-[H]-`` | ``[[0.5, 0.5], [0.5, 0.5]]`` | +-------+-------+---------------------+---------------------------------+ | 3 | Xm | ``-[H]-[Z]-`` | ``[[0.5, -0.5], [-0.5, 0.5]]`` | +-------+-------+---------------------+---------------------------------+ | 2 | Yp | ``-[H]-[S]-`` | ``[[0.5, -0.5j], [0.5j, 0.5]]`` | +-------+-------+---------------------+---------------------------------+ | 3 | Ym | ``-[H]-[Sdg]-`` | ``[[0.5, 0.5j], [-0.5j, 0.5]]`` | +-------+-------+---------------------+---------------------------------+ """ def __init__(self): # |0> Zp rotation prep_zp = QuantumCircuit(1, name="PauliPrepZp") # |1> Zm rotation prep_zm = QuantumCircuit(1, name="PauliPrepZm") prep_zm.append(XGate(), [0]) # |+> Xp rotation prep_xp = QuantumCircuit(1, name="PauliPrepXp") prep_xp.append(HGate(), [0]) # |-> Xm rotation prep_xm = QuantumCircuit(1, name="PauliPrepXm") prep_xm.append(HGate(), [0]) prep_xm.append(ZGate(), [0]) # |+i> Yp rotation prep_yp = QuantumCircuit(1, name="PauliPrepYp") prep_yp.append(HGate(), [0]) prep_yp.append(SGate(), [0]) # |-i> Ym rotation prep_ym = QuantumCircuit(1, name="PauliPrepYm") prep_ym.append(HGate(), [0]) prep_ym.append(SdgGate(), [0]) super().__init__( "Pauli6PreparationBasis", [ prep_zp, prep_zm, prep_xp, prep_xm, prep_yp, prep_ym, ], ) def __json_encode__(self): # Override LocalPreparationBasis's encoder return {}