24
24
from copy import copy
25
25
from itertools import product
26
26
27
- import filter_functions as ff
28
27
import numpy as np
29
28
import pytest
30
29
from opt_einsum import contract
@@ -109,6 +108,7 @@ def test_basis_properties(self):
109
108
pauli_basis = ff .Basis .pauli (n )
110
109
from_partial_basis = ff .Basis .from_partial (testutil .rand_herm (d ), traceless = False )
111
110
custom_basis = ff .Basis (testutil .rand_herm_traceless (d ))
111
+ custom_basis /= np .linalg .norm (custom_basis , ord = 'fro' , axis = (- 1 , - 2 ))
112
112
113
113
btypes = ('Pauli' , 'GGM' , 'From partial' , 'Custom' )
114
114
bases = (pauli_basis , ggm_basis , from_partial_basis , custom_basis )
@@ -127,6 +127,8 @@ def test_basis_properties(self):
127
127
self .assertTrue (base [rng .integers (0 , len (base ))] in base )
128
128
# Check if all elements of each basis are orthonormal and hermitian
129
129
self .assertArrayEqual (base .T , base .view (np .ndarray ).swapaxes (- 1 , - 2 ))
130
+ self .assertTrue (base .isnorm )
131
+ self .assertTrue (base .isorthogonal )
130
132
self .assertTrue (base .isorthonorm )
131
133
self .assertTrue (base .isherm )
132
134
# Check if basis spans the whole space and all elems are traceless
@@ -137,6 +139,9 @@ def test_basis_properties(self):
137
139
138
140
if not btype == 'Custom' :
139
141
self .assertTrue (base .iscomplete )
142
+ else :
143
+ self .assertFalse (base .iscomplete )
144
+
140
145
# Check sparse representation
141
146
self .assertArrayEqual (base .sparse .todense (), base )
142
147
# Test sparse cache
@@ -154,9 +159,17 @@ def test_basis_properties(self):
154
159
155
160
base ._print_checks ()
156
161
157
- # single element always considered orthonormal
158
- orthonorm = rng .normal (size = (d , d ))
159
- self .assertTrue (orthonorm .view (ff .Basis ).isorthonorm )
162
+ # single element always considered orthogonal
163
+ orthogonal = rng .normal (size = (d , d ))
164
+ self .assertTrue (orthogonal .view (ff .Basis ).isorthogonal )
165
+
166
+ orthogonal /= np .linalg .norm (orthogonal , 'fro' , axis = (- 1 , - 2 ))
167
+ self .assertTrue (orthogonal .view (ff .Basis ).isorthonorm )
168
+
169
+ nonorthogonal = rng .normal (size = (3 , d , d )).view (ff .Basis )
170
+ self .assertFalse (nonorthogonal .isnorm )
171
+ nonorthogonal .normalize ()
172
+ self .assertTrue (nonorthogonal .isnorm )
160
173
161
174
herm = testutil .rand_herm (d ).squeeze ()
162
175
self .assertTrue (herm .view (ff .Basis ).isherm )
@@ -206,6 +219,22 @@ def test_basis_expansion_and_normalization(self):
206
219
r = ff .basis .ggm_expand (rng .standard_normal ((3 , 3 )), hermitian = False )
207
220
self .assertTrue (r .dtype == 'complex128' )
208
221
222
+ # test the method
223
+ pauli = ff .Basis .pauli (1 )
224
+ ggm = ff .Basis .ggm (2 )
225
+
226
+ M = testutil .rand_herm (2 , 3 )
227
+ self .assertArrayAlmostEqual (pauli .expand (M , hermitian = True , traceless = False , tidyup = True ),
228
+ ggm .expand (M , hermitian = True , traceless = False , tidyup = True ))
229
+
230
+ M = testutil .rand_herm_traceless (2 , 3 )
231
+ self .assertArrayAlmostEqual (pauli .expand (M , hermitian = True , traceless = True , tidyup = True ),
232
+ ggm .expand (M , hermitian = True , traceless = True , tidyup = True ))
233
+
234
+ M = testutil .rand_unit (2 , 3 )
235
+ self .assertArrayAlmostEqual (pauli .expand (M , hermitian = False , traceless = False , tidyup = True ),
236
+ ggm .expand (M , hermitian = False , traceless = False , tidyup = True ))
237
+
209
238
for _ in range (10 ):
210
239
d = rng .integers (2 , 16 )
211
240
ggm_basis = ff .Basis .ggm (d )
0 commit comments