-
Notifications
You must be signed in to change notification settings - Fork 57
FOGI model serialization and some FOGI model optimization #598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
106ecbe
f13821d
67f31f7
f358b32
8fc9fa2
b15ff9b
5b4679e
dd679e8
8b2f676
2a46692
6703ab8
bc39b12
f40ee35
acf96f1
17dab75
3d5b33d
6ffdf9e
b6fde07
4f2ce40
2f00ce8
ad2526c
ca32580
f5aa81e
3f66504
965c785
b1078dc
e392502
67deafd
6784b87
001cbce
2df848a
3b401b2
f17d24a
2171e3b
b68f182
18043b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,11 +16,12 @@ | |
from pygsti.baseobjs import Basis as _Basis | ||
from pygsti.baseobjs.errorgenlabel import GlobalElementaryErrorgenLabel as _GlobalElementaryErrorgenLabel,\ | ||
LocalElementaryErrorgenLabel as _LocalElementaryErrorgenLabel | ||
|
||
from pygsti.baseobjs.nicelyserializable import NicelySerializable as _NicelySerializable | ||
from pygsti.tools import optools as _ot | ||
from pygsti.baseobjs.statespace import StateSpace as _StateSpace | ||
|
||
|
||
class ElementaryErrorgenBasis(object): | ||
class ElementaryErrorgenBasis(_NicelySerializable): | ||
""" | ||
A basis for error-generator space defined by a set of elementary error generators. | ||
|
||
|
@@ -49,6 +50,7 @@ def __len__(self): | |
Number of elementary errorgen elements in this basis. | ||
""" | ||
return len(self.labels) | ||
|
||
|
||
#helper function for checking label types. | ||
def _all_elements_same_type(lst): | ||
|
@@ -88,6 +90,7 @@ def __init__(self, state_space, labels, basis_1q=None): | |
comprise the basis element labels for the values of the | ||
`ElementaryErrorgenLabels` in `labels`. | ||
""" | ||
super().__init__() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Every object that is nicely serializable needs to have this init statement |
||
labels = tuple(labels) | ||
|
||
#add an assertion that the labels are ElementaryErrorgenLabels and that all of the labels are the same type. | ||
|
@@ -116,6 +119,34 @@ def __init__(self, state_space, labels, basis_1q=None): | |
self._cached_dual_matrices = None | ||
self._cached_supports = None | ||
|
||
def __eq__(self, other): | ||
juangmendoza19 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""Compare self with other. Return true only if they are identical, including the order of their labels. | ||
|
||
Args: | ||
other (ExplicitElementaryErrorgenBasis): Error generator basis to compare against | ||
|
||
Returns: | ||
Boolean: True if they are identical, False otherwise | ||
""" | ||
if not isinstance(other, ExplicitElementaryErrorgenBasis): | ||
return False | ||
return self.state_space.__eq__(other.state_space) and [label.__str__() for label in self.labels] == [label.__str__() for label in other.labels] and self._basis_1q.__eq__(other._basis_1q) | ||
|
||
def _to_nice_serialization(self): | ||
state = super()._to_nice_serialization() | ||
state.update({'state_space' : self.state_space._to_nice_serialization(), | ||
'labels' : [label.__str__() for label in self.labels], | ||
'label_type' : 'global' if isinstance(self.labels[0], _GlobalElementaryErrorgenLabel) else 'local', | ||
'_basis_1q' : self._basis_1q if isinstance(self._basis_1q, str) else self._basis_1q._to_nice_serialization() | ||
}) | ||
return state | ||
@classmethod | ||
def from_nice_serialization(cls, state): | ||
if state['label_type'] == 'global': | ||
cast = _GlobalElementaryErrorgenLabel.cast | ||
else: | ||
cast = _LocalElementaryErrorgenLabel.cast | ||
return cls(_StateSpace.from_nice_serialization(state['state_space']), [cast(label) for label in state['labels']], state['_basis_1q'] if isinstance(state['_basis_1q'], str) else _Basis.from_nice_serialization(state['_basis_1q'])) | ||
@property | ||
def labels(self): | ||
return self._labels | ||
|
@@ -259,7 +290,7 @@ def union(self, other_basis): | |
#assert that these two bases have compatible label types. | ||
msg = 'Incompatible `ElementaryErrrogenLabel` types, the two `ElementaryErrorgenBasis` should have the same label type.' | ||
assert type(self._labels[0]) == type(other_basis.labels[0]), msg | ||
|
||
#Get the union of the two bases labels. | ||
union_labels = set(self._labels) | set(other_basis.labels) | ||
union_state_space = self.state_space.union(other_basis.state_space) | ||
|
@@ -516,7 +547,7 @@ def __init__(self, basis_1q, state_space, elementary_errorgen_types=('H', 'S', ' | |
`GlobalElementaryErrorgenLabel` and `LocalElementaryErrorgenLabel`, | ||
respectively. | ||
""" | ||
|
||
super().__init__() | ||
if isinstance(basis_1q, _Basis): | ||
self._basis_1q = basis_1q | ||
elif isinstance(basis_1q, str): | ||
|
@@ -589,6 +620,24 @@ def __init__(self, basis_1q, state_space, elementary_errorgen_types=('H', 'S', ' | |
# (IXX,XXI) # on right, loop over all possible choices of at least one, an at most m, | ||
# (IXX,XXX) # nontrivial indices to place within the m nontriv left indices (1 & 2 here) | ||
|
||
def _to_nice_serialization(self): | ||
|
||
state = super()._to_nice_serialization() | ||
state.update({'basis_1q' : self._basis_1q.to_nice_serialization(), | ||
'state_space' : self.state_space.to_nice_serialization(), | ||
'elementary_errorgen_types': self._elementary_errorgen_types, | ||
'max_weights' : self.max_weights, | ||
'sslbl_overlap' : self._sslbl_overlap, | ||
'default_label_type': self._default_lbl_typ | ||
}) | ||
return state | ||
|
||
@classmethod | ||
def from_nice_serialization(cls, state): | ||
|
||
return cls(_Basis.from_nice_serialization(state['basis_1q']), _StateSpace.from_nice_serialization(state['state_space']), \ | ||
state['elementary_errorgen_types'], max_weights=state['max_weights'], sslbl_overlap=state['sslbl_overlap'], \ | ||
default_label_type=state['default_label_type']) | ||
def __len__(self): | ||
""" Number of elementary errorgen elements in this basis """ | ||
return self._offsets[self._elementary_errorgen_types[-1]]['END'] | ||
|
@@ -741,6 +790,7 @@ def label_index(self, label, ok_if_missing=False, identity_label='I'): | |
identity_label : str, optional (default 'I') | ||
An optional string specifying the label used to denote the identity in basis element labels. | ||
""" | ||
|
||
if isinstance(label, _LocalElementaryErrorgenLabel): | ||
label = _GlobalElementaryErrorgenLabel.cast(label, self.sslbls, identity_label=identity_label) | ||
|
||
|
@@ -762,8 +812,10 @@ def label_index(self, label, ok_if_missing=False, identity_label='I'): | |
elif eetype in ('C', 'A'): | ||
assert(len(trivial_bel) == 1) # assumes this is a single character | ||
nontrivial_inds = [i for i, letter in enumerate(bels[0]) if letter != trivial_bel] | ||
left_support = tuple([self.sslbls[i] for i in nontrivial_inds]) | ||
|
||
left_support = tuple([label.sslbls[i] for i in nontrivial_inds]) | ||
juangmendoza19 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#left_support = tuple([self.sslbls[i] for i in nontrivial_inds]) | ||
#This line above is supposed to be a bugfix, I want to verify this with | ||
#Corey before removing this comment | ||
if ok_if_missing and (support, left_support) not in self._offsets[eetype]: | ||
return None | ||
base = self._offsets[eetype][(support, left_support)] | ||
|
@@ -772,7 +824,6 @@ def label_index(self, label, ok_if_missing=False, identity_label='I'): | |
support, left_support, eetype, [trivial_bel], nontrivial_bels))} | ||
else: | ||
raise ValueError("Invalid elementary errorgen type: %s" % str(eetype)) | ||
|
||
return base + indices[label] | ||
|
||
def create_subbasis(self, sslbl_overlap, retain_max_weights=True): | ||
|
@@ -829,4 +880,4 @@ def difference(self, other_basis): | |
other_basis : `ElementaryErrorgenBasis` | ||
`ElementaryErrorgenBasis` to construct the difference with. | ||
""" | ||
return self.to_explicit_basis().difference(other_basis) | ||
return self.to_explicit_basis().difference(other_basis) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -418,7 +418,7 @@ def create_subspace(self, labels): | |
StateSpace | ||
""" | ||
# Default, generic, implementation constructs an explicit state space | ||
labels = set(labels) | ||
labels = sorted(set(labels)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change was made with @coreyostrove to make FOGI model construction deterministic |
||
sub_tpb_labels = [] | ||
sub_tpb_udims = [] | ||
sub_tpb_types = [] | ||
|
@@ -1389,7 +1389,6 @@ def __str__(self): | |
['*'.join(["%s(%d%s)" % (lbl, self.label_dims[lbl], 'c' if (self.label_types[lbl] == 'C') else '') | ||
for lbl in tpb]) for tpb in self._labels]) | ||
|
||
|
||
def default_space_for_dim(dim): | ||
""" | ||
Create a state space for a given superoperator dimension. | ||
|
Uh oh!
There was an error while loading. Please reload this page.