-
Notifications
You must be signed in to change notification settings - Fork 55
/
evotype.py
206 lines (161 loc) · 8.97 KB
/
evotype.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
import importlib as _importlib
from . import basereps as _basereps
class Evotype(object):
"""
The base class for all other evotype classes.
Provides an interface for creating representations. The `create_*` methods specify an API used by the
operation classes so they can create the representation they need.
Parameters
----------
name : str
The (module) name of the evolution type
prefer_dense_reps : bool, optional
Whether the dense representation provided by this evolution type should be preferred
over more specific types, such as those for composed, embedded, and exponentiated
operations. Most often this is set to `True` when using a :class:`MatrixForwardSimulator`
in order to get a performance gain.
"""
default_evotype = None
_reptype_to_attrs = {
'dense superop': 'OpRepDenseSuperop',
'dense unitary': 'OpRepDenseUnitary',
'composed': 'OpRepComposed',
'embedded': 'OpRepEmbedded',
'experrorgen': 'OpRepExpErrorgen',
'stochastic': 'OpRepStochastic',
'sum': 'OpRepSum',
'clifford': 'OpRepClifford',
'repeated': 'OpRepRepeated',
'standard': 'OpRepStandard',
'sparse superop': 'OpRepSparse',
'lindblad errorgen': 'OpRepLindbladErrorgen',
'dense state': 'StateRepDense',
'pure state': 'StateRepDensePure',
'computational state': 'StateRepComputational',
'composed state': 'StateRepComposed',
'tensorproduct state': 'StateRepTensorProduct',
'conjugatedstate effect': 'EffectRepConjugatedState',
'computational effect': 'EffectRepComputational',
'tensorproduct effect': 'EffectRepTensorProduct',
'composed effect': 'EffectRepComposed',
'term': 'TermRep',
'direct term': 'TermDirectRep'
}
@classmethod
def cast(cls, obj, default_prefer_dense_reps=False):
if isinstance(obj, Evotype):
return obj
elif obj == "default":
return Evotype(cls.default_evotype, default_prefer_dense_reps)
else: # assume obj is a string naming an evotype
return Evotype(str(obj), default_prefer_dense_reps)
def __init__(self, name, prefer_dense_reps=False):
self.name = name
self.module = _importlib.import_module("pygsti.evotypes." + self.name)
self.prefer_dense_reps = prefer_dense_reps
def __getstate__(self):
state = self.__dict__.copy()
del state['module'] # can't pickle module
return state
def __setstate__(self, state):
self.__dict__.update(state)
self.module = _importlib.import_module("pygsti.evotypes." + self.name)
def __hash__(self):
return hash((self.name, self.prefer_dense_reps))
def __eq__(self, other_evotype):
if isinstance(other_evotype, Evotype):
return self.name == other_evotype.name
elif other_evotype == "default":
return self.name == self.default_evotype
else:
return self.name == str(other_evotype)
def __str__(self):
return self.name
@property
def minimal_space(self):
return self.module.minimal_space
def minimal_dim(self, state_space):
return state_space.udim if self.minimal_space == 'Hilbert' else state_space.dim
def supported_reptypes(self):
return [reptype for reptype, attr in self._reptype_to_attrs.items() if hasattr(self.module, attr)]
def supports(self, reptype):
return hasattr(self.module, self._reptype_to_attrs[reptype])
def create_dense_superop_rep(self, mx, state_space): # process_mx=None,
return self.module.OpRepDenseSuperop(mx, state_space)
def create_dense_unitary_rep(self, mx, super_basis, state_space): # process_mx=None,
return self.module.OpRepDenseUnitary(mx, super_basis, state_space)
def create_composed_rep(self, factor_op_reps, state_space):
return self.module.OpRepComposed(factor_op_reps, state_space)
def create_embedded_rep(self, state_space, targetLabels, embedded_rep):
return self.module.OpRepEmbedded(state_space, targetLabels, embedded_rep)
def create_experrorgen_rep(self, errorgen_rep):
return self.module.OpRepExpErrorgen(errorgen_rep)
def create_stochastic_rep(self, basis, rate_poly_dicts, initial_rates, seed_or_state, state_space):
return self.module.OpRepStochastic(basis, rate_poly_dicts, initial_rates, seed_or_state, state_space)
def create_sum_rep(self, factor_reps, state_space):
return self.module.OpRepSum(factor_reps, state_space)
def create_clifford_rep(self, unitarymx, symplecticrep, super_basis, state_space):
return self.module.OpRepClifford(unitarymx, symplecticrep, super_basis, state_space)
def create_repeated_rep(self, rep_to_repeat, num_repetitions, state_space):
return self.module.OpRepRepeated(rep_to_repeat, num_repetitions, state_space)
def create_standard_rep(self, standard_name, super_basis, state_space):
return self.module.OpRepStandard(standard_name, super_basis, state_space)
def create_sparse_rep(self, data, indices, indptr, state_space):
return self.module.OpRepSparse(data, indices, indptr, state_space)
def create_lindblad_errorgen_rep(self, lindblad_term_dict, basis, state_space):
return self.module.OpRepLindbladErrorgen(lindblad_term_dict, basis, state_space)
# STATE REPS
def create_dense_state_rep(self, vec, state_space):
return self.module.StateRepDense(vec, state_space)
def create_pure_state_rep(self, purevec, super_basis, state_space):
return self.module.StateRepDensePure(purevec, state_space, super_basis)
def create_computational_state_rep(self, zvals, super_basis, state_space):
return self.module.StateRepComputational(zvals, super_basis, state_space)
def create_composed_state_rep(self, state_rep, op_rep, state_space):
return self.module.StateRepComposed(state_rep, op_rep, state_space)
def create_tensorproduct_state_rep(self, factor_state_reps, state_space):
return self.module.StateRepTensorProduct(factor_state_reps, state_space)
# EFFECT REPS
def create_conjugatedstate_effect_rep(self, state_rep):
return self.module.EffectRepConjugatedState(state_rep)
def create_computational_effect_rep(self, zvals, super_basis, state_space):
return self.module.EffectRepComputational(zvals, super_basis, state_space)
def create_tensorproduct_effect_rep(self, povm_factors, effect_labels, state_space):
return self.module.EffectRepTensorProduct(povm_factors, effect_labels, state_space)
def create_composed_effect_rep(self, errmap_rep, effect_rep, errmap_name, state_space):
return self.module.EffectRepComposed(errmap_rep, effect_rep, errmap_name, state_space)
# TERM REPS
def create_term_rep(self, coeff, mag, logmag, pre_state, post_state,
pre_effect, post_effect, pre_ops, post_ops):
try: # see if module implements its own term rep, otherwise use "stock" version
return self.module.TermRep(coeff, mag, logmag, pre_state, post_state,
pre_effect, post_effect, pre_ops, post_ops)
except Exception:
return _basereps.StockTermRep(coeff, mag, logmag, pre_state, post_state,
pre_effect, post_effect, pre_ops, post_ops)
def create_direct_term_rep(self, coeff, mag, logmag, pre_state, post_state,
pre_effect, post_effect, pre_ops, post_ops):
try: # see if module implements its own term rep, otherwise use "stock" version
return self.module.TermDirectRep(coeff, mag, logmag, pre_state, post_state,
pre_effect, post_effect, pre_ops, post_ops)
except Exception:
return _basereps.StockTermDirectRep(coeff, mag, logmag, pre_state, post_state,
pre_effect, post_effect, pre_ops, post_ops)
def conjugate_state_term_rep(self, term_rep):
""" Turns a state term => effect term via conjugation of the state """
coeff = term_rep.coeff
mag = term_rep.magnitude
logmag = term_rep.logmagnitude
pre_effect = self.create_conjugatedstate_effect_rep(term_rep.pre_state)
post_effect = self.create_conjugatedstate_effect_rep(term_rep.post_state)
try: # see if module implements its own term rep, otherwise use "stock" version
return self.module.TermRep(coeff, mag, logmag, None, None,
pre_effect, post_effect, term_rep.pre_ops, term_rep.post_ops)
except Exception:
return _basereps.StockTermRep(coeff, mag, logmag, None, None,
pre_effect, post_effect, term_rep.pre_ops, term_rep.post_ops)
try:
from . import densitymx as _dummy
Evotype.default_evotype = "densitymx"
except ImportError:
Evotype.default_evotype = "densitymx_slow"