Source code for qurry.qurrium.container.waves_static

"""WaveContainer (:mod:`qurry.qurrium.container.waves_static`)"""

from typing import Literal, Union, Optional, overload
from collections.abc import Hashable, Callable
import warnings

from qiskit import QuantumCircuit
from qiskit.quantum_info import Operator
from qiskit.circuit import Gate, Instruction

from .waves_dynamic import _add, _remove, _process
from ...exceptions import QurryUnknownExportOption


[docs] class WaveContainer(dict[Hashable, QuantumCircuit]): """WaveContainer is a customized dictionary for storing :class:`~qiskit.circuit.QuantumCircuit`.""" __name__ = "WaveContainer" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs)
[docs] def add( self, wave: QuantumCircuit, key: Optional[Hashable] = None, replace: Literal[True, False, "duplicate"] = True, ) -> Hashable: """Add wave to container. Args: wave (QuantumCircuit): The wave circuit. key (Optional[Hashable], optional): The key of wave in 'fict' `.waves`. Defaults to None. replace (Literal[True, False, "duplicate"], optional): Replace the wave with same key or not. Defaults to True. Returns: Hashable: The key of wave in 'dict' `.waves`. Raises: KeyError: If the wave with same key exists and `replace==False`. """ return _add(_wave_container=self, wave=wave, key=key, replace=replace)
[docs] def process( self, circuits: list[Union[QuantumCircuit, Hashable]] ) -> list[tuple[Hashable, QuantumCircuit]]: """Process the circuits in container. Args: circuits (list[Union[QuantumCircuit, Hashable]]): The circuits or keys of circuits in container. Returns: list[tuple[Hashable, QuantumCircuit]]: The processed circuits. """ return _process(self, circuits)
[docs] def remove(self, key: Hashable) -> None: """Remove wave from container. Args: key (Hashable): The key of wave in 'dict' `.waves`. """ _remove(self, key)
@overload def get_wave(self, wave: list[Hashable], run_by: Literal["gate"]) -> list[Gate]: ... @overload def get_wave(self, wave: list[Hashable], run_by: Literal["operator"]) -> list[Operator]: ... @overload def get_wave( self, wave: list[Hashable], run_by: Literal["instruction"] ) -> list[Instruction]: ... @overload def get_wave( self, wave: list[Hashable], run_by: Optional[Literal["copy", "call"]] ) -> list[QuantumCircuit]: ... @overload def get_wave(self, wave: Hashable, run_by: Literal["gate"]) -> Gate: ... @overload def get_wave(self, wave: Hashable, run_by: Literal["operator"]) -> Operator: ... @overload def get_wave(self, wave: Hashable, run_by: Literal["instruction"]) -> Instruction: ... @overload def get_wave( self, wave: Hashable, run_by: Optional[Literal["copy", "call"]] ) -> QuantumCircuit: ...
[docs] def get_wave(self, wave=None, run_by=None): """Parse wave Circuit into :class:`~qiskit.circuit.Instruction`, :class:`~qiskit.circuit.Gate`, or `~qiskit.quantum_info.Operator` on :class:`~qiskit.circuit.QuantumCircuit`. Args: wave (Optional[Hashable], optional): The key of wave in `wave`. Defaults to None. run_by (Optional[str], optional): Export as :class:`~qiskit.circuit.Instruction`, :class:`~qiskit.circuit.Gate`, or `~qiskit.quantum_info.Operator` or a copy when input is None. Defaults to None. Raises: ValueError: If `wave is None`. KeyError: If `wave` not in `self`. Returns: The result of the wave. """ if wave is None: raise ValueError("Need to input wave name.") if isinstance(wave, list): return [self.get_wave(w, run_by) for w in wave] if wave not in self: raise KeyError(f"Wave {wave} not found in {self}") actions: dict[ str, Callable[[QuantumCircuit], Union[Gate, Operator, Instruction, QuantumCircuit]] ] = { "operator": Operator, "gate": lambda w: w.to_gate(), "instruction": lambda w: w.to_instruction(), "copy": lambda w: w.copy(), "call": lambda w: w, } run_by = "copy" if run_by is None else run_by if run_by not in actions: warnings.warn( "run_by should be 'gate', 'operator', 'instruction', 'copy' or 'call', " + f"but got {run_by}.", category=QurryUnknownExportOption, ) return actions.get(run_by, lambda w: w.copy())(self[wave])
@overload def call(self, wave: list[Hashable]) -> list[QuantumCircuit]: ... @overload def call(self, wave: Hashable) -> QuantumCircuit: ...
[docs] def call(self, wave): """Export wave function as :class:`~qiskit.circuit.QuantumCircuit`. Args: wave (Union[list[Hashable], Hashable]): The key of wave in 'dict' `.waves`. Returns: Union[list[QuantumCircuit], QuantumCircuit]: The circuit of wave function. """ return self.get_wave( wave=wave, run_by="call", )
def __call__( self, wave: Union[list[Hashable], Hashable] ) -> Union[list[QuantumCircuit], QuantumCircuit]: return self.call(wave=wave)
[docs] def operator(self, wave: Union[list[Hashable], Hashable]) -> Union[list[Operator], Operator]: """Export wave function as `Operator`. Args: wave (Union[list[Hashable], Hashable]): The key of wave in 'dict' `.waves`. Returns: Union[list[Operator], Operator]: The operator of wave function. """ return self.get_wave( wave=wave, run_by="operator", )
[docs] def gate(self, wave: Union[list[Hashable], Hashable]) -> Union[list[Gate], Gate]: """Export wave function as `Gate`. Args: wave (Union[list[Hashable], Hashable]): The key of wave in 'dict' `.waves`. Returns: Union[list[Gate], Gate]: The gate of wave function. """ return self.get_wave( wave=wave, run_by="gate", )
[docs] def copy_circuit( self, wave: Union[list[Hashable], Hashable] ) -> Union[list[QuantumCircuit], QuantumCircuit]: """Export a copy of wave function as :class:`~qiskit.circuit.QuantumCircuit`. Args: wave (Union[list[Hashable], Hashable]): The key of wave in 'dict' `.waves`. Returns: Union[list[QuantumCircuit], QuantumCircuit]: The copy circuit of wave function. """ return self.get_wave( wave=wave, run_by="copy", )
[docs] def instruction( self, wave: Union[list[Hashable], Hashable] ) -> Union[list[Instruction], Instruction]: """Export wave function as `Instruction`. Args: wave (Union[list[Hashable], Hashable]): The key of wave in 'dict' `.waves`. Returns: Union[list[Instruction], Instruction]: The instruction of wave function. """ return self.get_wave( wave=wave, run_by="instruction", )
[docs] def has(self, wavename: Hashable) -> bool: """Is there a wave with specific name. Args: wavename (Hashable): Name of wave which is used in `.waves` Returns: bool: Exist or not. """ return wavename in self
def __repr__(self): return f"{self.__name__}({super().__repr__()})" def _repr_oneline(self): return f"{self.__name__}(" + "{...}" + f", num={len(self)})" def _repr_pretty_(self, p, cycle): if cycle: p.text(f"{self.__name__}(" + "{...}" + f", num={len(self)})") else: original_repr = super().__repr__() original_repr_split = original_repr[1:-1].split(", ") length = len(original_repr_split) with p.group(2, f"{self.__name__}(" + "{", "})"): for i, item in enumerate(original_repr_split): p.breakable() p.text(item) if i < length - 1: p.text(",") def __str__(self): return super().__repr__()