14
14
"""Classes and methods for quantum states."""
15
15
16
16
import itertools
17
- from typing import Any , cast , Iterable , Optional , Sequence , TYPE_CHECKING , Tuple , Type , Union
17
+ from typing import Any , cast , Iterable , Optional , Sequence , TYPE_CHECKING , Tuple , Union
18
18
19
19
import numpy as np
20
20
23
23
24
24
if TYPE_CHECKING :
25
25
import cirq
26
+ from numpy .typing import DTypeLike
26
27
27
28
DEFAULT_COMPLEX_DTYPE = np .complex64
28
29
@@ -61,7 +62,7 @@ def __init__(
61
62
data : np .ndarray ,
62
63
qid_shape : Optional [Tuple [int , ...]] = None ,
63
64
* , # Force keyword arguments
64
- dtype : Optional [Type [ np . number ] ] = None ,
65
+ dtype : Optional ['DTypeLike' ] = None ,
65
66
validate : bool = True ,
66
67
atol : float = 1e-7 ,
67
68
) -> None :
@@ -87,7 +88,7 @@ def __init__(
87
88
)
88
89
self ._data = data
89
90
self ._qid_shape = qid_shape
90
- self ._dim = np .prod (self .qid_shape , dtype = int )
91
+ self ._dim = np .prod (self .qid_shape , dtype = int ). item ()
91
92
if validate :
92
93
self .validate (dtype = dtype , atol = atol )
93
94
@@ -102,7 +103,7 @@ def qid_shape(self) -> Tuple[int, ...]:
102
103
return self ._qid_shape
103
104
104
105
@property
105
- def dtype (self ) -> np .ndarray :
106
+ def dtype (self ) -> np .dtype :
106
107
"""The data type of the quantum state."""
107
108
return self ._data .dtype
108
109
@@ -136,15 +137,27 @@ def density_matrix(self) -> np.ndarray:
136
137
"""
137
138
if not self ._is_density_matrix ():
138
139
state_vector = self .state_vector ()
140
+ assert state_vector is not None , 'only None if _is_density_matrix'
139
141
return np .outer (state_vector , np .conj (state_vector ))
140
142
return self .data
141
143
144
+ def state_vector_or_density_matrix (self ) -> np .ndarray :
145
+ """Return the state vector or density matrix of this state.
146
+
147
+ If the state is a denity matrix, return the density matrix. Otherwise, return the state
148
+ vector.
149
+ """
150
+ state_vector = self .state_vector ()
151
+ if state_vector is not None :
152
+ return state_vector
153
+ return self .data
154
+
142
155
def _is_density_matrix (self ) -> bool :
143
156
"""Whether this quantum state is a density matrix."""
144
157
return self .data .shape == (self ._dim , self ._dim )
145
158
146
159
def validate (
147
- self , * , dtype : Optional [Type [ np . number ] ] = None , atol = 1e-7 # Force keyword arguments
160
+ self , * , dtype : Optional ['DTypeLike' ] = None , atol = 1e-7 # Force keyword arguments
148
161
) -> None :
149
162
"""Check if this quantum state is valid.
150
163
@@ -158,8 +171,13 @@ def validate(
158
171
is_state_vector = self .data .shape == (self ._dim ,)
159
172
is_state_tensor = self .data .shape == self .qid_shape
160
173
if is_state_vector or is_state_tensor :
174
+ state_vector = self .state_vector ()
175
+ assert state_vector is not None
161
176
validate_normalized_state_vector (
162
- self .state_vector (), qid_shape = self .qid_shape , dtype = dtype , atol = atol
177
+ state_vector ,
178
+ qid_shape = self .qid_shape ,
179
+ dtype = dtype ,
180
+ atol = atol ,
163
181
)
164
182
elif self ._is_density_matrix ():
165
183
validate_density_matrix (
@@ -179,7 +197,7 @@ def quantum_state(
179
197
* , # Force keyword arguments
180
198
copy : bool = False ,
181
199
validate : bool = True ,
182
- dtype : Optional [Type [ np . number ] ] = None ,
200
+ dtype : Optional ['DTypeLike' ] = None ,
183
201
atol : float = 1e-7 ,
184
202
) -> QuantumState :
185
203
"""Create a QuantumState object from a state-like object.
@@ -239,7 +257,7 @@ def quantum_state(
239
257
'Please specify the qid shape explicitly using '
240
258
'the qid_shape argument.'
241
259
)
242
- dim = np .prod (qid_shape , dtype = int )
260
+ dim = np .prod (qid_shape , dtype = int ). item ()
243
261
if dtype is None :
244
262
dtype = DEFAULT_COMPLEX_DTYPE
245
263
data = one_hot (index = state , shape = (dim ,), dtype = dtype )
@@ -279,7 +297,7 @@ def density_matrix(
279
297
* , # Force keyword arguments
280
298
copy : bool = False ,
281
299
validate : bool = True ,
282
- dtype : Optional [Type [ np . number ] ] = None ,
300
+ dtype : Optional ['DTypeLike' ] = None ,
283
301
atol : float = 1e-7 ,
284
302
) -> QuantumState :
285
303
"""Create a QuantumState object from a density matrix.
@@ -494,7 +512,7 @@ def to_valid_state_vector(
494
512
num_qubits : Optional [int ] = None ,
495
513
* , # Force keyword arguments
496
514
qid_shape : Optional [Sequence [int ]] = None ,
497
- dtype : Optional [Type [ np . number ] ] = None ,
515
+ dtype : Optional ['DTypeLike' ] = None ,
498
516
atol : float = 1e-7 ,
499
517
) -> np .ndarray :
500
518
"""Verifies the state_rep is valid and converts it to ndarray form.
@@ -555,7 +573,7 @@ def _state_like_to_state_tensor(
555
573
* ,
556
574
state_like : 'cirq.STATE_VECTOR_LIKE' ,
557
575
qid_shape : Tuple [int , ...],
558
- dtype : Optional [Type [ np . number ] ],
576
+ dtype : Optional ['DTypeLike' ],
559
577
atol : float ,
560
578
) -> np .ndarray :
561
579
@@ -619,7 +637,7 @@ def _amplitudes_to_validated_state_tensor(
619
637
* ,
620
638
state_vector : np .ndarray ,
621
639
qid_shape : Tuple [int , ...],
622
- dtype : Optional [Type [ np . number ] ],
640
+ dtype : Optional ['DTypeLike' ],
623
641
atol : float ,
624
642
) -> np .ndarray :
625
643
if dtype is None :
@@ -630,7 +648,7 @@ def _amplitudes_to_validated_state_tensor(
630
648
631
649
632
650
def _qudit_values_to_state_tensor (
633
- * , state_vector : np .ndarray , qid_shape : Tuple [int , ...], dtype : Optional [Type [ np . number ] ]
651
+ * , state_vector : np .ndarray , qid_shape : Tuple [int , ...], dtype : Optional ['DTypeLike' ]
634
652
) -> np .ndarray :
635
653
636
654
for i in range (len (qid_shape )):
@@ -661,9 +679,9 @@ def _qudit_values_to_state_tensor(
661
679
662
680
663
681
def _computational_basis_state_to_state_tensor (
664
- * , state_rep : int , qid_shape : Tuple [int , ...], dtype : Optional [Type [ np . number ] ]
682
+ * , state_rep : int , qid_shape : Tuple [int , ...], dtype : Optional ['DTypeLike' ]
665
683
) -> np .ndarray :
666
- n = np .prod (qid_shape , dtype = int )
684
+ n = np .prod (qid_shape , dtype = int ). item ()
667
685
if not 0 <= state_rep < n :
668
686
raise ValueError (
669
687
f'Computational basis state is out of range.\n '
@@ -682,7 +700,7 @@ def validate_normalized_state_vector(
682
700
state_vector : np .ndarray ,
683
701
* , # Force keyword arguments
684
702
qid_shape : Tuple [int , ...],
685
- dtype : Optional [np . dtype ] = None ,
703
+ dtype : Optional ['DTypeLike' ] = None ,
686
704
atol : float = 1e-7 ,
687
705
) -> None :
688
706
"""Checks that the given state vector is valid.
@@ -754,7 +772,7 @@ def to_valid_density_matrix(
754
772
num_qubits : Optional [int ] = None ,
755
773
* , # Force keyword arguments
756
774
qid_shape : Optional [Tuple [int , ...]] = None ,
757
- dtype : Optional [np . dtype ] = None ,
775
+ dtype : Optional ['DTypeLike' ] = None ,
758
776
atol : float = 1e-7 ,
759
777
) -> np .ndarray :
760
778
"""Verifies the density_matrix_rep is valid and converts it to ndarray form.
@@ -799,7 +817,7 @@ def validate_density_matrix(
799
817
density_matrix : np .ndarray ,
800
818
* , # Force keyword arguments
801
819
qid_shape : Tuple [int , ...],
802
- dtype : Optional [Type [ np . number ] ] = None ,
820
+ dtype : Optional ['DTypeLike' ] = None ,
803
821
atol : float = 1e-7 ,
804
822
) -> None :
805
823
"""Checks that the given density matrix is valid.
@@ -867,7 +885,7 @@ def one_hot(
867
885
index : Union [None , int , Sequence [int ]] = None ,
868
886
shape : Union [int , Sequence [int ]],
869
887
value : Any = 1 ,
870
- dtype : Type [ np . number ] ,
888
+ dtype : 'DTypeLike' ,
871
889
) -> np .ndarray :
872
890
"""Returns a numpy array with all 0s and a single non-zero entry(default 1).
873
891
@@ -888,7 +906,7 @@ def one_hot(
888
906
return result
889
907
890
908
891
- def eye_tensor (half_shape : Tuple [int , ...], * , dtype : np . dtype ) -> np .ndarray :
909
+ def eye_tensor (half_shape : Tuple [int , ...], * , dtype : 'DTypeLike' ) -> np .ndarray :
892
910
"""Returns an identity matrix reshaped into a tensor.
893
911
894
912
Args:
0 commit comments