Source code for qurry.recipe.simple.paramagnet

"""Paramagnet (:mod:`qurry.recipe.simple.paramagnet`)

The circuits :class:`~qurry.recipe.simple.paramagnet.TrivialParamagnet` and
:class:`~qurry.recipe.simple.paramagnet.TopologicalParamagnet`,
which has been mentioned in the following reference.

Reference:
    -   Measurement of the Entanglement Spectrum of a Symmetry-Protected Topological State
        Using the IBM Quantum Computer - Choo, Kenny and von Keyserlingk, Curt W. and
        Regnault, Nicolas and Neupert, Titus
        `doi:10.1103/PhysRevLett.121.086808 <https://doi.org/10.1103/PhysRevLett.121.086808>`_

    .. code-block:: bibtex

        @article{PhysRevLett.121.086808,
            title = {
                Measurement of the Entanglement Spectrum of a Symmetry-Protected Topological State
                Using the IBM Quantum Computer},
            author = {
                Choo, Kenny and von Keyserlingk, Curt W. and Regnault, Nicolas and Neupert, Titus},
            journal = {Phys. Rev. Lett.},
            volume = {121},
            issue = {8},
            pages = {086808},
            numpages = {5},
            year = {2018},
            month = {Aug},
            publisher = {American Physical Society},
            doi = {10.1103/PhysRevLett.121.086808},
            url = {https://link.aps.org/doi/10.1103/PhysRevLett.121.086808}
        }

"""

from typing import Literal

from ..n_body import OneBody


[docs] class TrivialParamagnet(OneBody): r"""The product state circuit :class:`~qurry.recipe.simple.paramagnet.TrivialParamagnet`. .. code-block:: text # At 8 qubits: ┌───┐ q0: ┤ H ├ ├───┤ q1: ┤ H ├ ├───┤ q2: ┤ H ├ ├───┤ q3: ┤ H ├ ├───┤ q4: ┤ H ├ ├───┤ q5: ┤ H ├ ├───┤ q6: ┤ H ├ ├───┤ q7: ┤ H ├ └───┘ .. math:: {|+\rangle}^{\otimes N}, N = 8 Args: num_qubits (int): Number of qubits. name (str, optional): Name of case. Defaults to "trivial_paramagnet". """ def __init__(self, num_qubits: int, name: str = "trivial_paramagnet") -> None: """Initializing the case. Args: num_qubits (int): Number of qubits. name (str, optional): Name of case. Defaults to "trivial_paramagnet". """ super().__init__(name=name) self.num_qubits = num_qubits def _build(self) -> None: if self._is_built: return super()._build() num_qubits = self.num_qubits if num_qubits == 0: return for i in range(num_qubits): self.h(i)
[docs] class TopologicalParamagnet(OneBody): """The entangled circuit :class:`~qurry.recipe.simple.paramagnet.TopologicalParamagnet`. .. code-block:: text # With ACTUAL CZGate, Open boundary at 8 qubits: ┌───┐ q0: ┤ H ├─■──── ├───┤ │ q1: ┤ H ├─■──■─ ├───┤ │ q2: ┤ H ├─■──■─ ├───┤ │ q3: ┤ H ├─■──■─ ├───┤ │ q4: ┤ H ├─■──■─ ├───┤ │ q5: ┤ H ├─■──■─ ├───┤ │ q6: ┤ H ├─■──■─ ├───┤ │ q7: ┤ H ├─■──── └───┘ .. code-block:: text # With ACTUAL CZGate, Open boundary at 5 qubits: ┌───┐ q0: ┤ H ├─■──── ├───┤ │ q1: ┤ H ├─■──■─ ├───┤ │ q2: ┤ H ├─■──■─ ├───┤ │ q3: ┤ H ├─■──■─ ├───┤ │ q4: ┤ H ├────■─ └───┘ .. code-block:: text # With ACTUAL CZGate, Period boundary at 8 qubits: ┌───┐ q0: ┤ H ├─■─────■─ ├───┤ │ │ q1: ┤ H ├─■──■──┼─ ├───┤ │ │ q2: ┤ H ├─■──■──┼─ ├───┤ │ │ q3: ┤ H ├─■──■──┼─ ├───┤ │ │ q4: ┤ H ├─■──■──┼─ ├───┤ │ │ q5: ┤ H ├─■──■──┼─ ├───┤ │ │ q6: ┤ H ├─■──■──┼─ ├───┤ │ │ q7: ┤ H ├─■─────■─ └───┘ .. code-block:: text # With ACTUAL CZGate, Period boundary at 5 qubits: ┌───┐ q0: ┤ H ├─■──■──── ├───┤ │ │ q1: ┤ H ├─■──┼──■─ ├───┤ │ │ q2: ┤ H ├─■──┼──■─ ├───┤ │ │ q3: ┤ H ├─■──┼──■─ ├───┤ │ │ q4: ┤ H ├────■──■─ └───┘ Args: num_qubits (int): Number of qubits. border_cond (str, optional): Boundary condition is `open` or `period`. Defaults to "period". name (str, optional): Name of case. Defaults to "cluster". Raises: ValueError: When given number of qubits is not even. """ @property def border_cond(self) -> Literal["open", "period"]: """The border condition.""" return self._border_cond @border_cond.setter def border_cond(self, value: Literal["open", "period"]) -> None: if hasattr(self, "_border_cond"): raise AttributeError("The border_cond can't be changed.") if value not in ["open", "period"]: raise ValueError("The border_cond must be 'open' or 'period'.") self._border_cond: Literal["open", "period"] = value def __init__( self, num_qubits: int, border_cond: Literal["open", "period"] = "period", name: str = "cluster", ) -> None: """Initializing the case. Args: num_qubits (int): Number of qubits. border_cond (str, optional): Boundary condition is `open` or `period`. Defaults to "period". name (str, optional): Name of case. Defaults to "cluster". Raises: ValueError: When given number of qubits is not even. """ super().__init__(name=name) self.border_cond = border_cond self.num_qubits = num_qubits def _build(self) -> None: if self._is_built: return super()._build() num_qubits = self.num_qubits if num_qubits == 0: return for i in range(num_qubits): self.h(i) iter_range = num_qubits - 1 if self.border_cond == "open" else num_qubits for i in range(0, iter_range, 2): self.cz(i, (i + 1) % num_qubits) for i in range(1, iter_range, 2): self.cz(i, (i + 1) % num_qubits)
[docs] class Cluster(TopologicalParamagnet): """:class:`~qurry.recipe.simple.paramagnet.Cluster`, another name of the entangled circuit :class:`~qurry.recipe.simple.paramagnet.TopologicalParamagnet`. .. code-block:: text # With ACTUAL `CZGate`, Open boundary at 8 qubits: ┌───┐ q0: ┤ H ├─■──── ├───┤ │ q1: ┤ H ├─■──■─ ├───┤ │ q2: ┤ H ├─■──■─ ├───┤ │ q3: ┤ H ├─■──■─ ├───┤ │ q4: ┤ H ├─■──■─ ├───┤ │ q5: ┤ H ├─■──■─ ├───┤ │ q6: ┤ H ├─■──■─ ├───┤ │ q7: ┤ H ├─■──── └───┘ .. code-block:: text # With ACTUAL `CZGate`, Period boundary at 8 qubits: ┌───┐ q0: ┤ H ├─■─────■─ ├───┤ │ │ q1: ┤ H ├─■──■──┼─ ├───┤ │ │ q2: ┤ H ├─■──■──┼─ ├───┤ │ │ q3: ┤ H ├─■──■──┼─ ├───┤ │ │ q4: ┤ H ├─■──■──┼─ ├───┤ │ │ q5: ┤ H ├─■──■──┼─ ├───┤ │ │ q6: ┤ H ├─■──■──┼─ ├───┤ │ │ q7: ┤ H ├─■─────■─ └───┘ Args: num_qubits (int): Number of qubits. border_cond (str, optional): Boundary condition is `open` or `period`. Defaults to "period". name (str, optional): Name of case. Defaults to "cluster". Raises: ValueError: When given number of qubits is not even. """