Skip to content

Commit d962130

Browse files
applied many PR change requests made by Riley
1 parent 085188f commit d962130

File tree

4 files changed

+30
-31
lines changed

4 files changed

+30
-31
lines changed

pygsti/modelmembers/povms/__init__.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ def povm_type_from_op_type(op_type):
422422
return povm_type_preferences
423423

424424

425-
def convert(povm, to_type, basis, cp_penalty=1e-7, ideal_povm=None, flatten_structure=False):
425+
def convert(povm, to_type, basis, ideal_povm=None, flatten_structure=False, cp_penalty=1e-7):
426426
"""
427427
TODO: update docstring
428428
Convert a POVM to a new type of parameterization.
@@ -559,27 +559,26 @@ def calc_physical_subspace(dense_ideal_povm, epsilon = 1e-9):
559559
num_errgens = errgen.num_params
560560
#TODO: Maybe we can use the num of params instead of number of matrix entries, as some of them are linearly dependent.
561561
#i.e E0 completely determines E1 if those are the only two povm elements (E0 + E1 = Identity)
562-
num_entries = dense_ideal_povm.shape[0]*dense_ideal_povm.shape[1]
562+
num_entries = dense_ideal_povm.size
563563

564564
#Compute the jacobian with respect to the error generators. This will allow us to see which
565565
#error generators change the POVM entries
566566
J = _np.zeros((num_entries,num_errgens))
567-
567+
new_vec = _np.zeros(num_errgens)
568568
for i in range(num_errgens):
569-
new_vec = _np.zeros(num_errgens)
569+
570570
new_vec[i] = epsilon
571571
exp_errgen.from_vector(new_vec)
572+
new_vec[i] = 0
572573
vectorized_povm = _np.zeros(num_entries)
573574
perturbed_povm = (dense_ideal_povm @ exp_errgen.to_dense() - dense_ideal_povm)/epsilon
574575

575-
perturbed_povm_t = perturbed_povm.transpose()
576-
for j, column in enumerate(perturbed_povm_t):
577-
vectorized_povm[j*len(perturbed_povm_t[0]):(j+1)*len(perturbed_povm_t[0])] = column
576+
vectorized_povm = perturbed_povm.flatten(order='F')
578577

579-
J[:,i] = vectorized_povm.transpose()
578+
J[:,i] = vectorized_povm
580579

581-
_,S,V = _np.linalg.svd(J)
582-
return V[:len(S),]
580+
_,S,Vt = _np.linalg.svd(J)
581+
return Vt[:len(S),]
583582

584583
phys_directions = calc_physical_subspace(dense_ideal_povm)
585584

@@ -605,7 +604,7 @@ def _objfn(v):
605604
tol=1e-13)
606605
if not soln.success and soln.fun > 1e-6: # not "or" because success is often not set correctly
607606
raise ValueError("Failed to find an errorgen such that <ideal|exp(errorgen) = <effect|")
608-
errgen_vec = _np.linalg.pinv(phys_directions) @ soln.x
607+
errgen_vec = _np.linalg.lstsq(phys_directions, soln.x)[0]
609608
errorgen.from_vector(errgen_vec)
610609

611610
EffectiveExpErrorgen = _IdentityPlusErrorgenOp if lndtype.meta == '1+' else _ExpErrorgenOp

pygsti/modelmembers/states/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def state_type_from_op_type(op_type):
187187
return state_type_preferences
188188

189189

190-
def convert(state, to_type, basis, cp_penalty=1e-7, ideal_state=None, flatten_structure=False):
190+
def convert(state, to_type, basis, ideal_state=None, flatten_structure=False, cp_penalty=1e-7):
191191
"""
192192
TODO: update docstring
193193
Convert SPAM vector to a new type of parameterization.
@@ -307,7 +307,7 @@ def _objfn(v):
307307
if not soln.success and soln.fun > 1e-6: # not "or" because success is often not set correctly
308308
raise ValueError("Failed to find an errorgen such that exp(errorgen)|ideal> = |state>")
309309

310-
errgen_vec = _np.linalg.pinv(phys_directions) @ soln.x
310+
errgen_vec = _np.linalg.lstsq(phys_directions, soln.x)[0]
311311
errorgen.from_vector(errgen_vec)
312312

313313
EffectiveExpErrorgen = _IdentityPlusErrorgenOp if lndtype.meta == '1+' else _ExpErrorgenOp

pygsti/models/modelparaminterposer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ def __init__(self, transform_matrix):
6868
super().__init__(transform_matrix.shape[1], transform_matrix.shape[0])
6969

7070
def model_paramvec_to_ops_paramvec(self, v):
71-
return _np.dot(self.transform_matrix, v)
71+
return self.transform_matrix @ v
7272

7373
def ops_paramvec_to_model_paramvec(self, w):
74-
return _np.dot(self.inv_transform_matrix, w)
74+
return self.inv_transform_matrix @ w
7575

7676
def ops_paramlbls_to_model_paramlbls(self, wl):
7777
# This can and should be improved later - particularly this will be awful when labels (els of wl) are tuples.

test/unit/objects/test_model.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,14 @@ class ThresholdMethodBase(object):
344344

345345
def test_product(self):
346346
circuit = ('Gx', 'Gy')
347-
p1 = np.dot(self.model['Gy'].to_dense(), self.model['Gx'].to_dense())
347+
p1 = self.model['Gy'].to_dense() @ self.model['Gx'].to_dense()
348348
p2 = self.model.sim.product(circuit, scale=False)
349349
p3, scale = self.model.sim.product(circuit, scale=True)
350350
self.assertArraysAlmostEqual(p1, p2)
351351
self.assertArraysAlmostEqual(p1, scale * p3)
352352

353353
circuit = ('Gx', 'Gy', 'Gy')
354-
p1 = np.dot(self.model['Gy'].to_dense(), np.dot(self.model['Gy'].to_dense(), self.model['Gx'].to_dense()))
354+
p1 = self.model['Gy'].to_dense() @ self.model['Gy'].to_dense() @ self.model['Gx'].to_dense()
355355
p2 = self.model.sim.product(circuit, scale=False)
356356
p3, scale = self.model.sim.product(circuit, scale=True)
357357
self.assertArraysAlmostEqual(p1, p2)
@@ -362,8 +362,8 @@ def test_bulk_product(self):
362362
gatestring2 = ('Gx', 'Gy', 'Gy')
363363
circuits = [gatestring1, gatestring2]
364364

365-
p1 = np.dot(self.model['Gy'].to_dense(), self.model['Gx'].to_dense())
366-
p2 = np.dot(self.model['Gy'].to_dense(), np.dot(self.model['Gy'].to_dense(), self.model['Gx'].to_dense()))
365+
p1 = self.model['Gy'].to_dense() @ self.model['Gx'].to_dense()
366+
p2 = self.model['Gy'].to_dense() @ self.model['Gy'].to_dense() @ self.model['Gx'].to_dense()
367367

368368
bulk_prods = self.model.sim.bulk_product(circuits)
369369
bulk_prods_scaled, scaleVals = self.model.sim.bulk_product(circuits, scale=True)
@@ -405,15 +405,15 @@ def setUpClass(cls):
405405
cls.gatestring1 = ('Gx', 'Gy')
406406
cls.gatestring2 = ('Gx', 'Gy', 'Gy')
407407
cls._expected_probs = {
408-
cls.gatestring1: np.dot(np.transpose(cls._model.povms['Mdefault']['0'].to_dense()),
409-
np.dot(cls._model['Gy'].to_dense(),
410-
np.dot(cls._model['Gx'].to_dense(),
411-
cls._model.preps['rho0'].to_dense()))).reshape(-1)[0],
412-
cls.gatestring2: np.dot(np.transpose(cls._model.povms['Mdefault']['0'].to_dense()),
413-
np.dot(cls._model['Gy'].to_dense(),
414-
np.dot(cls._model['Gy'].to_dense(),
415-
np.dot(cls._model['Gx'].to_dense(),
416-
cls._model.preps['rho0'].to_dense())))).reshape(-1)[0]
408+
cls.gatestring1: np.transpose(cls._model.povms['Mdefault']['0'].to_dense()) @
409+
cls._model['Gy'].to_dense() @
410+
cls._model['Gx'].to_dense() @
411+
cls._model.preps['rho0'].to_dense().reshape(-1)[0],
412+
cls.gatestring2: np.transpose(cls._model.povms['Mdefault']['0'].to_dense()) @
413+
cls._model['Gy'].to_dense() @
414+
cls._model['Gy'].to_dense() @
415+
cls._model['Gx'].to_dense() @
416+
cls._model.preps['rho0'].to_dense().reshape(-1)[0]
417417
}
418418
# TODO expected dprobs & hprobs
419419

@@ -611,12 +611,12 @@ def test_transform(self):
611611

612612
# TODO is this needed?
613613
for opLabel in cp.operations:
614-
self.assertArraysAlmostEqual(cp[opLabel], np.dot(Tinv, np.dot(self.model[opLabel], T)))
614+
self.assertArraysAlmostEqual(cp[opLabel], Tinv @ self.model[opLabel] @ T)
615615
for prepLabel in cp.preps:
616-
self.assertArraysAlmostEqual(cp[prepLabel], np.dot(Tinv, self.model[prepLabel]))
616+
self.assertArraysAlmostEqual(cp[prepLabel], Tinv @ self.model[prepLabel])
617617
for povmLabel in cp.povms:
618618
for effectLabel, eVec in cp.povms[povmLabel].items():
619-
self.assertArraysAlmostEqual(eVec, np.dot(np.transpose(T), self.model.povms[povmLabel][effectLabel]))
619+
self.assertArraysAlmostEqual(eVec, np.transpose(T) @ self.model.povms[povmLabel][effectLabel])
620620

621621
def test_gpindices(self):
622622
# Test instrument construction with elements whose gpindices

0 commit comments

Comments
 (0)