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:
@@ -211,22 +210,26 @@ def __eq__(self, other: object) -> bool:
211
210
# Not ndarray
212
211
return np .equal (self , other )
213
212
214
- return np .allclose (self .view (ndarray ), other .view (ndarray ),
213
+ return np .allclose (self .view (np . ndarray ), other .view (np . ndarray ),
215
214
atol = self ._atol , rtol = self ._rtol )
216
215
217
- def __contains__ (self , item : ndarray ) -> bool :
216
+ def __contains__ (self , item : np . ndarray ) -> bool :
218
217
"""Implement 'in' operator."""
219
- return any (np .isclose (item .view (ndarray ), self .view (ndarray ),
218
+ return any (np .isclose (item .view (np . ndarray ), self .view (np . ndarray ),
220
219
rtol = self ._rtol , atol = self ._atol ).all (axis = (1 , 2 )))
221
220
222
- def __array_wrap__ (self , out_arr , context = None ):
221
+ def __array_wrap__ (self , arr , context = None , return_scalar = False ):
223
222
"""
224
223
Fixes problem that ufuncs return 0-d arrays instead of scalars.
225
224
226
225
https://github.com/numpy/numpy/issues/5819#issue-72454838
227
226
"""
228
- if out_arr .ndim :
229
- return ndarray .__array_wrap__ (self , out_arr , context )
227
+ try :
228
+ return super ().__array_wrap__ (arr , context , return_scalar = True )
229
+ except TypeError :
230
+ if arr .ndim :
231
+ # Numpy < 2
232
+ return np .ndarray .__array_wrap__ (self , arr , context )
230
233
231
234
def _print_checks (self ) -> None :
232
235
"""Print checks for debug purposes."""
@@ -595,7 +598,7 @@ def _full_from_partial(elems: Sequence, traceless: bool, labels: Sequence[str])
595
598
# sort Identity label to the front, default to first if not found
596
599
# (should not happen since traceless checks that it is present)
597
600
id_idx = next ((i for i , elem in enumerate (elems )
598
- if np .allclose (Id .view (ndarray ), elem .view (ndarray ),
601
+ if np .allclose (Id .view (np . ndarray ), elem .view (np . ndarray ),
599
602
rtol = elems ._rtol , atol = elems ._atol )), 0 )
600
603
labels .insert (0 , labels .pop (id_idx ))
601
604
@@ -604,7 +607,7 @@ def _full_from_partial(elems: Sequence, traceless: bool, labels: Sequence[str])
604
607
return basis , labels
605
608
606
609
607
- def _norm (b : Sequence ) -> ndarray :
610
+ def _norm (b : Sequence ) -> np . ndarray :
608
611
"""Frobenius norm with two singleton dimensions inserted at the end."""
609
612
b = np .asanyarray (b )
610
613
norm = nla .norm (b , axis = (- 1 , - 2 ))
@@ -631,8 +634,8 @@ def normalize(b: Basis) -> Basis:
631
634
return (b / _norm (b )).squeeze ().view (Basis )
632
635
633
636
634
- def expand (M : Union [ndarray , Basis ], basis : Union [ndarray , Basis ],
635
- normalized : bool = True , hermitian : bool = False , tidyup : bool = False ) -> ndarray :
637
+ def expand (M : Union [np . ndarray , Basis ], basis : Union [np . ndarray , Basis ],
638
+ normalized : bool = True , hermitian : bool = False , tidyup : bool = False ) -> np . ndarray :
636
639
r"""
637
640
Expand the array *M* in the basis given by *basis*.
638
641
@@ -682,7 +685,7 @@ def cast(arr):
682
685
return util .remove_float_errors (coefficients ) if tidyup else coefficients
683
686
684
687
685
- def ggm_expand (M : Union [ndarray , Basis ], traceless : bool = False ,
688
+ def ggm_expand (M : Union [np . ndarray , Basis ], traceless : bool = False ,
686
689
hermitian : bool = False , tidyup : bool = False ) -> ndarray :
687
690
r"""
688
691
Expand the matrix *M* in a Generalized Gell-Mann basis [Bert08]_.
@@ -771,7 +774,7 @@ def cast(arr):
771
774
return coeffs
772
775
773
776
774
- def equivalent_pauli_basis_elements (idx : Union [Sequence [int ], int ], N : int ) -> ndarray :
777
+ def equivalent_pauli_basis_elements (idx : Union [Sequence [int ], int ], N : int ) -> np . ndarray :
775
778
"""
776
779
Get the indices of the equivalent (up to identities tensored to it)
777
780
basis elements of Pauli bases of qubits at position idx in the total
@@ -784,7 +787,7 @@ def equivalent_pauli_basis_elements(idx: Union[Sequence[int], int], N: int) -> n
784
787
return elem_idx
785
788
786
789
787
- def remap_pauli_basis_elements (order : Sequence [int ], N : int ) -> ndarray :
790
+ def remap_pauli_basis_elements (order : Sequence [int ], N : int ) -> np . ndarray :
788
791
"""
789
792
For a N-qubit Pauli basis, transpose the order of the subsystems and
790
793
return the indices that permute the old basis to the new.
0 commit comments