Source code for bqskit.qis.state.system

"""This module implements the StateSystem class."""
from __future__ import annotations

from typing import Any
from typing import Dict
from typing import Iterator
from typing import Mapping
from typing import TYPE_CHECKING
from typing import Union

import numpy as np

from bqskit.qis.state.state import StateVector

if TYPE_CHECKING:
    import numpy.typing as npt
    from typing import TypeGuard


[docs] class StateSystem(Mapping[StateVector, StateVector]): """A system of input and output states."""
[docs] def __init__(self, system: StateSystemLike) -> None: """Construct a state system.""" if isinstance(system, StateSystem): self._system: dict[StateVector, StateVector] = system._system self._radixes: tuple[int, ...] = system._radixes self._dim: int = system._dim self._vec_count: int = system._vec_count self.target: npt.NDArray[np.complex128] = system.target return self._system = { StateVector(k): StateVector(v) for k, v in system.items() } self._radixes = list(self._system.keys())[0].radixes self._dim = list(self._system.keys())[0].dim self._vec_count = len(self._system) for k, v in self._system.items(): if k.radixes != self.radixes: raise ValueError('States in system have mismatch in dimension.') if v.radixes != self.radixes: raise ValueError('States in system have mismatch in dimension.') # Check overlap matrices V = np.column_stack(list(self._system.keys())) W = np.column_stack(list(self._system.values())) Ov = V.conj().T @ V Wv = W.conj().T @ W if not np.allclose(Ov, Wv): raise ValueError( 'State system is unsolvable:' ' input and output overlap matrices do not match.', ) self.target = W @ V.conj().T
@property def num_qudits(self) -> int: """The number of qudits in the state.""" return len(self.radixes) @property def dim(self) -> int: """The vector dimension for this state.""" return self._dim @property def radixes(self) -> tuple[int, ...]: """The number of orthogonal states for each qudit.""" return self._radixes def __iter__(self) -> Iterator[StateVector]: return self._system.__iter__() def __len__(self) -> int: return self._system.__len__() def __getitem__(self, _key: StateVector) -> StateVector: return self._system.__getitem__(_key) def __contains__(self, _key: object) -> bool: return self._system.__contains__(_key)
[docs] def is_qubit_only(self) -> bool: """Return true if this unitary can only act on qubits.""" return all([radix == 2 for radix in self.radixes])
[docs] def is_qutrit_only(self) -> bool: """Return true if this unitary can only act on qutrits.""" return all([radix == 3 for radix in self.radixes])
[docs] @staticmethod def is_state_system(V: Any) -> TypeGuard[StateSystemLike]: """ Check if V is a system of pure states. Args: V (Any): The vector to check. Returns: bool: True if V is a system of pure states. """ if isinstance(V, StateSystem): return True if not isinstance(V, dict): return False for k, v in V.items(): if not StateVector.is_pure_state(k): return False if not StateVector.is_pure_state(v): return False return True
StateSystemLike = Union[StateSystem, Dict[Any, Any]]