Source code for qugrad._hilbert_space

  1"""
  2Defines a class representing a Hilbert space.
  3"""
  4
  5import numpy as np
  6from typing import Optional, Any, Union
  7
[docs] 8class HilbertSpace(): 9 """ 10 Represents a Hilbert space with a prefered basis indexed by non-negative 11 integers. 12 13 Note 14 ---- 15 The class also can be treated as an iterator and will return :attr:`basis` 16 as the iterator. 17 18 19 --- 20 """ 21 22 _basis: np.ndarray[int] 23 "An array of positive integers labeling the Hilbert space basis" 24 _inverse: np.ndarray[int] 25 "An array satisfying the property ``_inverse[basis[i]]=i``" 26
[docs] 27 def __init__(self, basis: np.ndarray[int]): 28 """ 29 Initialises a new :class:`HilbertSpace`. 30 31 Parameters 32 ---------- 33 basis : NDArray[Shape[:attr:`dim`], int] 34 The labels for the basis vectors. 35 """ 36 self._basis = np.array(basis) 37 self._basis.flags.writeable = False 38 if len(self._basis) == 0: 39 self._inverse = np.empty(0, dtype=np.int64) 40 else: 41 self._inverse = np.zeros(self._basis.max()+1, dtype=np.int64) 42 for i, x in enumerate(self._basis): 43 self._inverse[x] = i 44 self._inverse.flags.writeable = False
45 def __iter__(self): return iter(self._basis) 46 def __getitem__(self, key): return self._basis[key] 47 def __len__(self): return len(self._basis) 48 def __eq__(self, other: "HilbertSpace") -> bool: 49 if isinstance(other, self.__class__): 50 return np.array_equal(self._basis, other._basis) 51 return False 52 @property 53 def dim(self): 54 """ 55 The Hilbert space dimension 56 """ 57 return len(self) 58 @property 59 def basis(self) -> np.ndarray[int]: 60 """ 61 An array of positive integers labeling the Hilbert space basis 62 """ 63 return self._basis 64 @property 65 def inverse(self) -> np.ndarray[int]: 66 "An array satisfying the property ``self.inverse[self.basis[i]]=i``" 67 return self._inverse
[docs] 68 def basis_vector(self, basis_state_label: int) -> np.ndarray[np.complex128]: 69 """Returns a column vector represnetation corresponding to the input 70 basis state label. 71 72 Parameters 73 ---------- 74 basis_state_label : int 75 A positive integer denoting the label of the basis state to generate 76 the basis vector for. 77 78 Returns 79 ------- 80 NDArray[Shape[:attr:`dim`], np.complex128] 81 The basis vector corresponding to the input basis state label. 82 """ 83 return np.eye(1, 84 len(self._basis), 85 self._inverse[basis_state_label] 86 ).flatten().astype(np.complex128)
[docs] 87 def get_subspace(self, filter: np.ndarray[bool]) -> "HilbertSpace": 88 """Generates a new subspace by filtering the basis state labels. 89 90 Parameters 91 ---------- 92 filter : NDArray[Shape[:attr:`dim`], bool] 93 ``True`` entries are retained in the new subspace. 94 95 Returns 96 ------- 97 HilbertSpace 98 The filtered subspace. 99 """ 100 return HilbertSpace(self._basis[filter])
101 @staticmethod 102 def _labels(state: Any) -> str: 103 """ 104 Generates a strings that represent the state. 105 106 Parameters 107 ---------- 108 state : Any 109 The state to label. 110 111 Returns 112 ------- 113 str 114 The label for the specified state. 115 """ 116 return f"|{repr(state)}⟩"
[docs] 117 def labels(self, 118 states: Optional[Union[int, list[int]]] = None 119 ) -> Union[str, list[str]]: 120 """ 121 Generates a string (list of strings) that represent the state(s). 122 123 Parameters 124 ---------- 125 states : int | list[int], optional 126 The state(s) to label. If ``None`` then the labels for all states in 127 :attr:`basis` are returned. By default ``None``. 128 129 Returns 130 ------- 131 str | list[str] 132 The label(s) for the specified states. 133 """ 134 if isinstance(states, int): 135 return self._labels(states) 136 elif states is None: states = self.basis 137 return [self._labels(int(s)) for s in states]