47
47
import numpy as np
48
48
import opt_einsum as oe
49
49
from numpy import linalg as nla
50
- from numpy .core import ndarray
51
50
from scipy import linalg as sla
52
51
from sparse import COO
53
52
56
55
__all__ = ['Basis' , 'expand' , 'ggm_expand' , 'normalize' ]
57
56
58
57
59
- class Basis (ndarray ):
58
+ class Basis (np . ndarray ):
60
59
r"""
61
60
Class for operator bases. There are several ways to instantiate a
62
61
Basis object:
@@ -217,12 +216,12 @@ def __eq__(self, other: object) -> bool:
217
216
# Not ndarray
218
217
return np .equal (self , other )
219
218
220
- return np .allclose (self .view (ndarray ), other .view (ndarray ),
219
+ return np .allclose (self .view (np . ndarray ), other .view (np . ndarray ),
221
220
atol = self ._atol , rtol = self ._rtol )
222
221
223
- def __contains__ (self , item : ndarray ) -> bool :
222
+ def __contains__ (self , item : np . ndarray ) -> bool :
224
223
"""Implement 'in' operator."""
225
- return any (np .isclose (item .view (ndarray ), self .view (ndarray ),
224
+ return any (np .isclose (item .view (np . ndarray ), self .view (np . ndarray ),
226
225
rtol = self ._rtol , atol = self ._atol ).all (axis = (1 , 2 )))
227
226
228
227
def __array_wrap__ (self , out_arr , context = None ):
@@ -232,7 +231,7 @@ def __array_wrap__(self, out_arr, context=None):
232
231
https://github.com/numpy/numpy/issues/5819#issue-72454838
233
232
"""
234
233
if out_arr .ndim :
235
- return ndarray .__array_wrap__ (self , out_arr , context )
234
+ return np . ndarray .__array_wrap__ (self , out_arr , context )
236
235
237
236
def _print_checks (self ) -> None :
238
237
"""Print checks for debug purposes."""
@@ -265,7 +264,7 @@ def isorthonorm(self) -> bool:
265
264
actual = U .conj () @ U .T
266
265
target = np .identity (dim )
267
266
atol = self ._eps * (self .d ** 2 )** 3
268
- self ._isorthonorm = np .allclose (actual .view (ndarray ), target ,
267
+ self ._isorthonorm = np .allclose (actual .view (np . ndarray ), target ,
269
268
atol = atol , rtol = self ._rtol )
270
269
271
270
return self ._isorthonorm
@@ -284,7 +283,10 @@ def istraceless(self) -> bool:
284
283
elif nonzero [0 ].size == 1 :
285
284
# Single element has nonzero trace, check if (proportional to)
286
285
# identity
287
- elem = self [nonzero ][0 ].view (ndarray ) if self .ndim == 3 else self .view (ndarray )
286
+ if self .ndim == 3 :
287
+ elem = self [nonzero ][0 ].view (np .ndarray )
288
+ else :
289
+ elem = self .view (np .ndarray )
288
290
offdiag_nonzero = elem [~ np .eye (self .d , dtype = bool )].nonzero ()
289
291
diag_equal = np .diag (elem ) == elem [0 , 0 ]
290
292
if diag_equal .all () and not offdiag_nonzero [0 ].any ():
@@ -597,7 +599,7 @@ def _full_from_partial(elems: Sequence, traceless: bool, labels: Sequence[str])
597
599
# sort Identity label to the front, default to first if not found
598
600
# (should not happen since traceless checks that it is present)
599
601
id_idx = next ((i for i , elem in enumerate (elems )
600
- if np .allclose (Id .view (ndarray ), elem .view (ndarray ),
602
+ if np .allclose (Id .view (np . ndarray ), elem .view (np . ndarray ),
601
603
rtol = elems ._rtol , atol = elems ._atol )), 0 )
602
604
labels .insert (0 , labels .pop (id_idx ))
603
605
@@ -606,7 +608,7 @@ def _full_from_partial(elems: Sequence, traceless: bool, labels: Sequence[str])
606
608
return basis , labels
607
609
608
610
609
- def _norm (b : Sequence ) -> ndarray :
611
+ def _norm (b : Sequence ) -> np . ndarray :
610
612
"""Frobenius norm with two singleton dimensions inserted at the end."""
611
613
b = np .asanyarray (b )
612
614
norm = nla .norm (b , axis = (- 1 , - 2 ))
@@ -633,8 +635,8 @@ def normalize(b: Basis) -> Basis:
633
635
return (b / _norm (b )).squeeze ().view (Basis )
634
636
635
637
636
- def expand (M : Union [ndarray , Basis ], basis : Union [ndarray , Basis ],
637
- normalized : bool = True , hermitian : bool = False , tidyup : bool = False ) -> ndarray :
638
+ def expand (M : Union [np . ndarray , Basis ], basis : Union [np . ndarray , Basis ],
639
+ normalized : bool = True , hermitian : bool = False , tidyup : bool = False ) -> np . ndarray :
638
640
r"""
639
641
Expand the array *M* in the basis given by *basis*.
640
642
@@ -684,8 +686,8 @@ def cast(arr):
684
686
return util .remove_float_errors (coefficients ) if tidyup else coefficients
685
687
686
688
687
- def ggm_expand (M : Union [ndarray , Basis ], traceless : bool = False ,
688
- hermitian : bool = False ) -> ndarray :
689
+ def ggm_expand (M : Union [np . ndarray , Basis ], traceless : bool = False ,
690
+ hermitian : bool = False ) -> np . ndarray :
689
691
r"""
690
692
Expand the matrix *M* in a Generalized Gell-Mann basis [Bert08]_.
691
693
This function makes use of the explicit construction prescription of
@@ -767,7 +769,7 @@ def cast(arr):
767
769
return coeffs .squeeze () if square else coeffs
768
770
769
771
770
- def equivalent_pauli_basis_elements (idx : Union [Sequence [int ], int ], N : int ) -> ndarray :
772
+ def equivalent_pauli_basis_elements (idx : Union [Sequence [int ], int ], N : int ) -> np . ndarray :
771
773
"""
772
774
Get the indices of the equivalent (up to identities tensored to it)
773
775
basis elements of Pauli bases of qubits at position idx in the total
@@ -780,7 +782,7 @@ def equivalent_pauli_basis_elements(idx: Union[Sequence[int], int], N: int) -> n
780
782
return elem_idx
781
783
782
784
783
- def remap_pauli_basis_elements (order : Sequence [int ], N : int ) -> ndarray :
785
+ def remap_pauli_basis_elements (order : Sequence [int ], N : int ) -> np . ndarray :
784
786
"""
785
787
For a N-qubit Pauli basis, transpose the order of the subsystems and
786
788
return the indices that permute the old basis to the new.
0 commit comments