Source code for qiskit_qryd_provider.pcz_gate

from cmath import exp
from typing import List
from typing import TYPE_CHECKING

from qiskit.circuit import Gate
from qiskit.circuit import QuantumCircuit
from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary
from qiskit.circuit.library import CXGate
from qiskit.circuit.library import CZGate
from qiskit.quantum_info import Kraus

if TYPE_CHECKING:
    import qiskit


[docs]class PCZGate(Gate): r"""Implements the phase-shifted controlled-Z gate (PCZ). The PCZ gate is the controlled-Z gate up to single-qubit phase gates. It can be realized by the Rydberg platform in multiple ways [`1 <https://doi.org/10.1103/PhysRevLett.123.170503>`__, `2 <https://doi.org/10.1103/PhysRevResearch.4.033019>`__, `3 <https://doi.org/10.22331/q-2022-05-13-712>`__]. Unitary matrix representation: .. math:: PCZ = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & e^{i\theta} & 0 & 0 \\ 0 & 0 & e^{i\theta} & 0 \\ 0 & 0 & 0 & e^{i(2\theta-\pi)} \end{pmatrix} The phase shift :math:`\theta` has the default value 2.13, as calculated for experimentally realistic parameters [`2 <https://doi.org/10.1103/PhysRevResearch.4.033019>`__]. It can be modified before using the :class:`~qiskit_qryd_provider.QRydProvider` via: .. testcode:: from qiskit_qryd_provider import PCZGate PCZGate.set_theta(1.234) assert PCZGate.get_theta() == 1.234 """
[docs] def __init__(self, label: str = None) -> None: """Create a new PCZ gate. Args: label: Optional label for the gate. """ super().__init__("pcz", 2, [], label=label)
def _define(self) -> None: """Define the gate.""" qc = QuantumCircuit(2) qc.u(0, 0, self._theta, 0) qc.u(0, 0, self._theta, 1) qc.cz(0, 1) self.definition = qc
[docs] def to_matrix(self) -> List[List[complex]]: """Return the unitary matrix of the gate. Returns: A two-dimensional array for the gate unitary matrix. """ return [ [1, 0, 0, 0], [0, exp(1j * self._theta), 0, 0], [0, 0, exp(1j * self._theta), 0], [0, 0, 0, -exp(2j * self._theta)], ]
[docs] def to_kraus(self) -> "qiskit.circuit.Instruction": """Return the Kraus representation of the gate. Raises: NotImplementedError: If the Kraus representation is not set. Returns: An instruction encapsulating the Kraus representation. """ if self._kraus is None: raise NotImplementedError("The Kraus representation is not implemented.") return self._kraus
[docs] @classmethod def set_theta(cls, theta: float) -> None: """Set the phase shift of the gate. Note that after setting the phase shift to a new value, an updated decomposition of the PCZ gate is stored to Qiskit's SessionEquivalenceLibrary. Args: theta: Angle of the phase shift. """ cls._theta = theta # Reset equivalence library default = [] for c in SessionEquivalenceLibrary.get_entry(CXGate()): if not c.get_instructions("pcz"): default.append(c) SessionEquivalenceLibrary.set_entry(CXGate(), default) default = [] for c in SessionEquivalenceLibrary.get_entry(CZGate()): if not c.get_instructions("pcz"): default.append(c) SessionEquivalenceLibrary.set_entry(CZGate(), default) SessionEquivalenceLibrary.set_entry(CZGate(), []) # Attach new decomposition to the equivalence library def_pcz_cz = QuantumCircuit(2) def_pcz_cz.append(PCZGate(), [0, 1]) def_pcz_cz.u(0, 0, -cls._theta, 0) def_pcz_cz.u(0, 0, -cls._theta, 1) SessionEquivalenceLibrary.add_equivalence(CZGate(), def_pcz_cz) def_pcz_cx = QuantumCircuit(2) def_pcz_cx.h(1) def_pcz_cx.append(PCZGate(), [0, 1]) def_pcz_cx.u(0, 0, -cls._theta, 0) def_pcz_cx.u(0, 0, -cls._theta, 1) def_pcz_cx.h(1) SessionEquivalenceLibrary.add_equivalence(CXGate(), def_pcz_cx) def_cz_pcz = QuantumCircuit(2) def_cz_pcz.append(CZGate(), [0, 1]) def_cz_pcz.u(0, 0, cls._theta, 0) def_cz_pcz.u(0, 0, cls._theta, 1) SessionEquivalenceLibrary.add_equivalence(PCZGate(), def_cz_pcz) def_cx_pcz = QuantumCircuit(2) def_cx_pcz.h(1) def_cx_pcz.append(CXGate(), [0, 1]) def_cx_pcz.h(1) def_cx_pcz.u(0, 0, cls._theta, 0) def_cx_pcz.u(0, 0, cls._theta, 1) SessionEquivalenceLibrary.add_equivalence(PCZGate(), def_cx_pcz)
[docs] @classmethod def get_theta(cls) -> float: """Get the phase shift of the gate. Returns: Angle of the phase shift. """ return cls._theta
[docs] @classmethod def set_kraus(cls, kraus: List[List[List[complex]]] = None) -> None: """Set the Kraus representation of the gate. Args: kraus: A three-dimensional array encoding the Kraus representation of the gate. """ if kraus is not None: cls._kraus = Kraus(kraus).to_instruction() else: cls._kraus = None
PCZGate.set_theta(2.13) PCZGate.set_kraus(None)