diff --git a/pygsti/modelmembers/povms/basepovm.py b/pygsti/modelmembers/povms/basepovm.py index 859d2e158..e953a9bad 100644 --- a/pygsti/modelmembers/povms/basepovm.py +++ b/pygsti/modelmembers/povms/basepovm.py @@ -75,7 +75,10 @@ def __init__(self, effects, evotype=None, state_space=None, preserve_sum=False, paramlbls = [] for k, v in items: if k == self.complement_label: continue - if isinstance(v, _POVMEffect): + if called_from_reduce: # __reduce__ should always initialize w/POVMEffects except for ... + assert isinstance(v, _POVMEffect) # complement (which hits continue above) + effect = v # don't copy as we want to preserve the gpindices in effects + elif isinstance(v, _POVMEffect): effect = v if (not preserve_sum) else v.copy() # .copy() just to de-allocate parameters else: assert(evotype is not None), "Must specify `evotype` when effect vectors are not POVMEffect objects!" @@ -108,7 +111,7 @@ def __init__(self, effects, evotype=None, state_space=None, preserve_sum=False, identity_for_complement = _np.array(sum([v.to_dense().reshape(comp_val.shape) for v in non_comp_effects]) + comp_val, 'd') # ensure shapes match before summing complement_effect = _ComplementPOVMEffect( - identity_for_complement, non_comp_effects) + identity_for_complement, non_comp_effects, called_from_reduce) items.append((self.complement_label, complement_effect)) super(_BasePOVM, self).__init__(state_space, evotype, None, items) diff --git a/pygsti/modelmembers/povms/complementeffect.py b/pygsti/modelmembers/povms/complementeffect.py index 4ca129222..16d328762 100644 --- a/pygsti/modelmembers/povms/complementeffect.py +++ b/pygsti/modelmembers/povms/complementeffect.py @@ -43,7 +43,7 @@ class ComplementPOVMEffect(_ConjugatedStatePOVMEffect): "complement" POVM effect vector. """ - def __init__(self, identity, other_effects): + def __init__(self, identity, other_effects, called_from_reduce=False): evotype = other_effects[0]._evotype state_space = other_effects[0].state_space @@ -62,8 +62,11 @@ def __init__(self, identity, other_effects): # 2) set the gpindices of the elements of other_spamvecs so # that they index into our local parameter vector. - _ConjugatedStatePOVMEffect.__init__(self, self.identity.copy()) - self.init_gpindices() # initialize our gpindices based on sub-members + _ConjugatedStatePOVMEffect.__init__(self, self.identity.copy(), called_from_reduce) + if not called_from_reduce: + self.init_gpindices() # initialize our gpindices based on sub-members + else: + self.allocate_gpindices(10000, None, submembers_already_allocated=True) self._construct_vector() # reset's self.base def _construct_vector(self): diff --git a/pygsti/modelmembers/povms/conjugatedeffect.py b/pygsti/modelmembers/povms/conjugatedeffect.py index 9ffacb76d..a97178261 100644 --- a/pygsti/modelmembers/povms/conjugatedeffect.py +++ b/pygsti/modelmembers/povms/conjugatedeffect.py @@ -139,12 +139,15 @@ class ConjugatedStatePOVMEffect(DenseEffectInterface, _POVMEffect): i.e, a (dim,1)-shaped array. """ - def __init__(self, state): + def __init__(self, state, called_from_reduce=False): self.state = state evotype = state._evotype rep = evotype.create_conjugatedstate_effect_rep(state._rep) _POVMEffect.__init__(self, rep, evotype) - self.init_gpindices() # initialize our gpindices based on sub-members + if not called_from_reduce: + self.init_gpindices() # initialize our gpindices based on sub-members + else: + self.allocate_gpindices(10000, None, submembers_already_allocated=True) @property def _basis(self):