pyGSTi 0.9.12.1__cp310-cp310-win32.whl → 0.9.13__cp310-cp310-win32.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. pyGSTi-0.9.13.dist-info/METADATA +197 -0
  2. {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/RECORD +207 -217
  3. {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/WHEEL +1 -1
  4. pygsti/_version.py +2 -2
  5. pygsti/algorithms/contract.py +1 -1
  6. pygsti/algorithms/core.py +42 -28
  7. pygsti/algorithms/fiducialselection.py +17 -8
  8. pygsti/algorithms/gaugeopt.py +2 -2
  9. pygsti/algorithms/germselection.py +87 -77
  10. pygsti/algorithms/mirroring.py +0 -388
  11. pygsti/algorithms/randomcircuit.py +165 -1333
  12. pygsti/algorithms/rbfit.py +0 -234
  13. pygsti/baseobjs/basis.py +94 -396
  14. pygsti/baseobjs/errorgenbasis.py +0 -132
  15. pygsti/baseobjs/errorgenspace.py +0 -10
  16. pygsti/baseobjs/label.py +52 -168
  17. pygsti/baseobjs/opcalc/fastopcalc.cp310-win32.pyd +0 -0
  18. pygsti/baseobjs/opcalc/fastopcalc.pyx +2 -2
  19. pygsti/baseobjs/polynomial.py +13 -595
  20. pygsti/baseobjs/statespace.py +1 -0
  21. pygsti/circuits/__init__.py +1 -1
  22. pygsti/circuits/circuit.py +682 -505
  23. pygsti/circuits/circuitconstruction.py +0 -4
  24. pygsti/circuits/circuitlist.py +47 -5
  25. pygsti/circuits/circuitparser/__init__.py +8 -8
  26. pygsti/circuits/circuitparser/fastcircuitparser.cp310-win32.pyd +0 -0
  27. pygsti/circuits/circuitstructure.py +3 -3
  28. pygsti/circuits/cloudcircuitconstruction.py +1 -1
  29. pygsti/data/datacomparator.py +2 -7
  30. pygsti/data/dataset.py +46 -44
  31. pygsti/data/hypothesistest.py +0 -7
  32. pygsti/drivers/bootstrap.py +0 -49
  33. pygsti/drivers/longsequence.py +2 -1
  34. pygsti/evotypes/basereps_cython.cp310-win32.pyd +0 -0
  35. pygsti/evotypes/chp/opreps.py +0 -61
  36. pygsti/evotypes/chp/statereps.py +0 -32
  37. pygsti/evotypes/densitymx/effectcreps.cpp +9 -10
  38. pygsti/evotypes/densitymx/effectreps.cp310-win32.pyd +0 -0
  39. pygsti/evotypes/densitymx/effectreps.pyx +1 -1
  40. pygsti/evotypes/densitymx/opreps.cp310-win32.pyd +0 -0
  41. pygsti/evotypes/densitymx/opreps.pyx +2 -2
  42. pygsti/evotypes/densitymx/statereps.cp310-win32.pyd +0 -0
  43. pygsti/evotypes/densitymx/statereps.pyx +1 -1
  44. pygsti/evotypes/densitymx_slow/effectreps.py +7 -23
  45. pygsti/evotypes/densitymx_slow/opreps.py +16 -23
  46. pygsti/evotypes/densitymx_slow/statereps.py +10 -3
  47. pygsti/evotypes/evotype.py +39 -2
  48. pygsti/evotypes/stabilizer/effectreps.cp310-win32.pyd +0 -0
  49. pygsti/evotypes/stabilizer/effectreps.pyx +0 -4
  50. pygsti/evotypes/stabilizer/opreps.cp310-win32.pyd +0 -0
  51. pygsti/evotypes/stabilizer/opreps.pyx +0 -4
  52. pygsti/evotypes/stabilizer/statereps.cp310-win32.pyd +0 -0
  53. pygsti/evotypes/stabilizer/statereps.pyx +1 -5
  54. pygsti/evotypes/stabilizer/termreps.cp310-win32.pyd +0 -0
  55. pygsti/evotypes/stabilizer/termreps.pyx +0 -7
  56. pygsti/evotypes/stabilizer_slow/effectreps.py +0 -22
  57. pygsti/evotypes/stabilizer_slow/opreps.py +0 -4
  58. pygsti/evotypes/stabilizer_slow/statereps.py +0 -4
  59. pygsti/evotypes/statevec/effectreps.cp310-win32.pyd +0 -0
  60. pygsti/evotypes/statevec/effectreps.pyx +1 -1
  61. pygsti/evotypes/statevec/opreps.cp310-win32.pyd +0 -0
  62. pygsti/evotypes/statevec/opreps.pyx +2 -2
  63. pygsti/evotypes/statevec/statereps.cp310-win32.pyd +0 -0
  64. pygsti/evotypes/statevec/statereps.pyx +1 -1
  65. pygsti/evotypes/statevec/termreps.cp310-win32.pyd +0 -0
  66. pygsti/evotypes/statevec/termreps.pyx +0 -7
  67. pygsti/evotypes/statevec_slow/effectreps.py +0 -3
  68. pygsti/evotypes/statevec_slow/opreps.py +0 -5
  69. pygsti/extras/__init__.py +0 -1
  70. pygsti/extras/drift/stabilityanalyzer.py +3 -1
  71. pygsti/extras/interpygate/__init__.py +12 -0
  72. pygsti/extras/interpygate/core.py +0 -36
  73. pygsti/extras/interpygate/process_tomography.py +44 -10
  74. pygsti/extras/rpe/rpeconstruction.py +0 -2
  75. pygsti/forwardsims/__init__.py +1 -0
  76. pygsti/forwardsims/forwardsim.py +14 -55
  77. pygsti/forwardsims/mapforwardsim.py +69 -18
  78. pygsti/forwardsims/mapforwardsim_calc_densitymx.cp310-win32.pyd +0 -0
  79. pygsti/forwardsims/mapforwardsim_calc_densitymx.pyx +65 -66
  80. pygsti/forwardsims/mapforwardsim_calc_generic.py +91 -13
  81. pygsti/forwardsims/matrixforwardsim.py +63 -15
  82. pygsti/forwardsims/termforwardsim.py +8 -110
  83. pygsti/forwardsims/termforwardsim_calc_stabilizer.cp310-win32.pyd +0 -0
  84. pygsti/forwardsims/termforwardsim_calc_statevec.cp310-win32.pyd +0 -0
  85. pygsti/forwardsims/termforwardsim_calc_statevec.pyx +0 -651
  86. pygsti/forwardsims/torchfwdsim.py +265 -0
  87. pygsti/forwardsims/weakforwardsim.py +2 -2
  88. pygsti/io/__init__.py +1 -2
  89. pygsti/io/mongodb.py +0 -2
  90. pygsti/io/stdinput.py +6 -22
  91. pygsti/layouts/copalayout.py +10 -12
  92. pygsti/layouts/distlayout.py +0 -40
  93. pygsti/layouts/maplayout.py +103 -25
  94. pygsti/layouts/matrixlayout.py +99 -60
  95. pygsti/layouts/prefixtable.py +1534 -52
  96. pygsti/layouts/termlayout.py +1 -1
  97. pygsti/modelmembers/instruments/instrument.py +3 -3
  98. pygsti/modelmembers/instruments/tpinstrument.py +2 -2
  99. pygsti/modelmembers/modelmember.py +0 -17
  100. pygsti/modelmembers/operations/__init__.py +2 -4
  101. pygsti/modelmembers/operations/affineshiftop.py +1 -0
  102. pygsti/modelmembers/operations/composederrorgen.py +1 -1
  103. pygsti/modelmembers/operations/composedop.py +1 -24
  104. pygsti/modelmembers/operations/denseop.py +5 -5
  105. pygsti/modelmembers/operations/eigpdenseop.py +2 -2
  106. pygsti/modelmembers/operations/embeddederrorgen.py +1 -1
  107. pygsti/modelmembers/operations/embeddedop.py +0 -1
  108. pygsti/modelmembers/operations/experrorgenop.py +2 -2
  109. pygsti/modelmembers/operations/fullarbitraryop.py +1 -0
  110. pygsti/modelmembers/operations/fullcptpop.py +2 -2
  111. pygsti/modelmembers/operations/fulltpop.py +28 -6
  112. pygsti/modelmembers/operations/fullunitaryop.py +5 -4
  113. pygsti/modelmembers/operations/lindbladcoefficients.py +93 -78
  114. pygsti/modelmembers/operations/lindbladerrorgen.py +268 -441
  115. pygsti/modelmembers/operations/linearop.py +7 -27
  116. pygsti/modelmembers/operations/opfactory.py +1 -1
  117. pygsti/modelmembers/operations/repeatedop.py +1 -24
  118. pygsti/modelmembers/operations/staticstdop.py +1 -1
  119. pygsti/modelmembers/povms/__init__.py +3 -3
  120. pygsti/modelmembers/povms/basepovm.py +7 -36
  121. pygsti/modelmembers/povms/complementeffect.py +4 -9
  122. pygsti/modelmembers/povms/composedeffect.py +0 -320
  123. pygsti/modelmembers/povms/computationaleffect.py +1 -1
  124. pygsti/modelmembers/povms/computationalpovm.py +3 -1
  125. pygsti/modelmembers/povms/effect.py +3 -5
  126. pygsti/modelmembers/povms/marginalizedpovm.py +0 -79
  127. pygsti/modelmembers/povms/tppovm.py +74 -2
  128. pygsti/modelmembers/states/__init__.py +2 -5
  129. pygsti/modelmembers/states/composedstate.py +0 -317
  130. pygsti/modelmembers/states/computationalstate.py +3 -3
  131. pygsti/modelmembers/states/cptpstate.py +4 -4
  132. pygsti/modelmembers/states/densestate.py +6 -4
  133. pygsti/modelmembers/states/fullpurestate.py +0 -24
  134. pygsti/modelmembers/states/purestate.py +1 -1
  135. pygsti/modelmembers/states/state.py +5 -6
  136. pygsti/modelmembers/states/tpstate.py +28 -10
  137. pygsti/modelmembers/term.py +3 -6
  138. pygsti/modelmembers/torchable.py +50 -0
  139. pygsti/modelpacks/_modelpack.py +1 -1
  140. pygsti/modelpacks/smq1Q_ZN.py +3 -1
  141. pygsti/modelpacks/smq2Q_XXYYII.py +2 -1
  142. pygsti/modelpacks/smq2Q_XY.py +3 -3
  143. pygsti/modelpacks/smq2Q_XYI.py +2 -2
  144. pygsti/modelpacks/smq2Q_XYICNOT.py +3 -3
  145. pygsti/modelpacks/smq2Q_XYICPHASE.py +3 -3
  146. pygsti/modelpacks/smq2Q_XYXX.py +1 -1
  147. pygsti/modelpacks/smq2Q_XYZICNOT.py +3 -3
  148. pygsti/modelpacks/smq2Q_XYZZ.py +1 -1
  149. pygsti/modelpacks/stdtarget.py +0 -121
  150. pygsti/models/cloudnoisemodel.py +1 -2
  151. pygsti/models/explicitcalc.py +3 -3
  152. pygsti/models/explicitmodel.py +3 -13
  153. pygsti/models/fogistore.py +5 -3
  154. pygsti/models/localnoisemodel.py +1 -2
  155. pygsti/models/memberdict.py +0 -12
  156. pygsti/models/model.py +800 -65
  157. pygsti/models/modelconstruction.py +4 -4
  158. pygsti/models/modelnoise.py +2 -2
  159. pygsti/models/modelparaminterposer.py +1 -1
  160. pygsti/models/oplessmodel.py +1 -1
  161. pygsti/models/qutrit.py +15 -14
  162. pygsti/objectivefns/objectivefns.py +73 -138
  163. pygsti/objectivefns/wildcardbudget.py +2 -7
  164. pygsti/optimize/__init__.py +1 -0
  165. pygsti/optimize/arraysinterface.py +28 -0
  166. pygsti/optimize/customcg.py +0 -12
  167. pygsti/optimize/customlm.py +129 -323
  168. pygsti/optimize/customsolve.py +2 -2
  169. pygsti/optimize/optimize.py +0 -84
  170. pygsti/optimize/simplerlm.py +841 -0
  171. pygsti/optimize/wildcardopt.py +19 -598
  172. pygsti/protocols/confidenceregionfactory.py +28 -14
  173. pygsti/protocols/estimate.py +31 -14
  174. pygsti/protocols/gst.py +142 -68
  175. pygsti/protocols/modeltest.py +6 -10
  176. pygsti/protocols/protocol.py +9 -37
  177. pygsti/protocols/rb.py +450 -79
  178. pygsti/protocols/treenode.py +8 -2
  179. pygsti/protocols/vb.py +108 -206
  180. pygsti/protocols/vbdataframe.py +1 -1
  181. pygsti/report/factory.py +0 -15
  182. pygsti/report/fogidiagram.py +1 -17
  183. pygsti/report/modelfunction.py +12 -3
  184. pygsti/report/mpl_colormaps.py +1 -1
  185. pygsti/report/plothelpers.py +8 -2
  186. pygsti/report/reportables.py +41 -37
  187. pygsti/report/templates/offline/pygsti_dashboard.css +6 -0
  188. pygsti/report/templates/offline/pygsti_dashboard.js +12 -0
  189. pygsti/report/workspace.py +2 -14
  190. pygsti/report/workspaceplots.py +326 -504
  191. pygsti/tools/basistools.py +9 -36
  192. pygsti/tools/edesigntools.py +124 -96
  193. pygsti/tools/fastcalc.cp310-win32.pyd +0 -0
  194. pygsti/tools/fastcalc.pyx +35 -81
  195. pygsti/tools/internalgates.py +151 -15
  196. pygsti/tools/jamiolkowski.py +5 -5
  197. pygsti/tools/lindbladtools.py +19 -11
  198. pygsti/tools/listtools.py +0 -114
  199. pygsti/tools/matrixmod2.py +1 -1
  200. pygsti/tools/matrixtools.py +173 -339
  201. pygsti/tools/nameddict.py +1 -1
  202. pygsti/tools/optools.py +154 -88
  203. pygsti/tools/pdftools.py +0 -25
  204. pygsti/tools/rbtheory.py +3 -320
  205. pygsti/tools/slicetools.py +64 -12
  206. pyGSTi-0.9.12.1.dist-info/METADATA +0 -155
  207. pygsti/algorithms/directx.py +0 -711
  208. pygsti/evotypes/qibo/__init__.py +0 -33
  209. pygsti/evotypes/qibo/effectreps.py +0 -78
  210. pygsti/evotypes/qibo/opreps.py +0 -376
  211. pygsti/evotypes/qibo/povmreps.py +0 -98
  212. pygsti/evotypes/qibo/statereps.py +0 -174
  213. pygsti/extras/rb/__init__.py +0 -13
  214. pygsti/extras/rb/benchmarker.py +0 -957
  215. pygsti/extras/rb/dataset.py +0 -378
  216. pygsti/extras/rb/io.py +0 -814
  217. pygsti/extras/rb/simulate.py +0 -1020
  218. pygsti/io/legacyio.py +0 -385
  219. pygsti/modelmembers/povms/denseeffect.py +0 -142
  220. {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/LICENSE +0 -0
  221. {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/top_level.txt +0 -0
@@ -128,28 +128,6 @@ class LinearOperator(_modelmember.ModelMember):
128
128
  """
129
129
  pass
130
130
 
131
- #def rep_at_time(self, t):
132
- # """
133
- # Retrieves a representation of this operator at time `t`.
134
- #
135
- # This is operationally equivalent to calling `self.set_time(t)` and
136
- # then retrieving `self._rep`. However, what is returned from this function
137
- # need not be the same rep object for different times, allowing the
138
- # operator object to cache many reps for different times to increase performance
139
- # (this avoids having to initialize the same rep at a given time).
140
- #
141
- # Parameters
142
- # ----------
143
- # t : float
144
- # The time.
145
- #
146
- # Returns
147
- # -------
148
- # object
149
- # """
150
- # self.set_time(t)
151
- # return self._rep
152
-
153
131
  def to_dense(self, on_space='minimal'):
154
132
  """
155
133
  Return this operation as a dense matrix.
@@ -483,12 +461,14 @@ class LinearOperator(_modelmember.ModelMember):
483
461
  numpy.ndarray
484
462
  A 1D-array of size equal to that of the flattened operation matrix.
485
463
  """
486
- if transform is None and inv_transform is None:
487
- return _ot.residuals(self.to_dense(on_space='minimal'), other_op.to_dense(on_space='minimal'))
464
+ dense_self = self.to_dense(on_space='minimal')
465
+ if transform is not None:
466
+ assert inv_transform is not None
467
+ dense_self = inv_transform @ (dense_self @ transform)
488
468
  else:
489
- return _ot.residuals(_np.dot(
490
- inv_transform, _np.dot(self.to_dense(on_space='minimal'), transform)),
491
- other_op.to_dense(on_space='minimal'))
469
+ assert inv_transform is None
470
+ return (dense_self - other_op.to_dense(on_space='minimal')).ravel()
471
+
492
472
 
493
473
  def jtracedist(self, other_op, transform=None, inv_transform=None):
494
474
  """
@@ -98,7 +98,7 @@ class OpFactory(_gm.ModelMember):
98
98
  def __init__(self, state_space, evotype):
99
99
  #self._paramvec = _np.zeros(nparams, 'd')
100
100
  state_space = _statespace.StateSpace.cast(state_space)
101
- evotype = _Evotype.cast(evotype)
101
+ evotype = _Evotype.cast(evotype, state_space=state_space)
102
102
  _gm.ModelMember.__init__(self, state_space, evotype)
103
103
 
104
104
  def create_object(self, args=None, sslbls=None):
@@ -45,7 +45,7 @@ class RepeatedOp(_LinearOperator):
45
45
 
46
46
  if evotype == "auto":
47
47
  evotype = op_to_repeat._evotype
48
- evotype = _Evotype.cast(evotype)
48
+ evotype = _Evotype.cast(evotype, state_space=state_space)
49
49
  rep = evotype.create_repeated_rep(self.repeated_op._rep, self.num_repetitions, state_space)
50
50
  _LinearOperator.__init__(self, rep, evotype)
51
51
  self.init_gpindices() # initialize our gpindices based on sub-members
@@ -113,29 +113,6 @@ class RepeatedOp(_LinearOperator):
113
113
  op = self.repeated_op.to_dense(on_space)
114
114
  return _np.linalg.matrix_power(op, self.num_repetitions)
115
115
 
116
- #def torep(self):
117
- # """
118
- # Return a "representation" object for this operation.
119
- #
120
- # Such objects are primarily used internally by pyGSTi to compute
121
- # things like probabilities more efficiently.
122
- #
123
- # Returns
124
- # -------
125
- # OpRep
126
- # """
127
- # if self._evotype == "densitymx":
128
- # return replib.DMOpRepExponentiated(self.repeated_op.torep(), self.power, self.dim)
129
- # elif self._evotype == "statevec":
130
- # return replib.SVOpRepExponentiated(self.repeated_op.torep(), self.power, self.dim)
131
- # elif self._evotype == "stabilizer":
132
- # nQubits = int(round(_np.log2(self.dim))) # "stabilizer" is a unitary-evolution type mode
133
- # return replib.SVOpRepExponentiated(self.repeated_op.torep(), self.power, nQubits)
134
- # assert(False), "Invalid internal _evotype: %s" % self._evotype
135
-
136
- #FUTURE: term-related functions (maybe base off of ComposedOp or use a composedop to generate them?)
137
- # e.g. ComposedOp([self.repeated_op] * power, dim, evotype)
138
-
139
116
  @property
140
117
  def parameter_labels(self):
141
118
  """
@@ -54,7 +54,7 @@ class StaticStandardOp(_LinearOperator, _NoErrorGeneratorInterface):
54
54
  else _statespace.StateSpace.cast(state_space)
55
55
  basis = _Basis.cast(basis, state_space.dim) # basis for Hilbert-Schmidt (superop) space
56
56
 
57
- evotype = _Evotype.cast(evotype)
57
+ evotype = _Evotype.cast(evotype, state_space=state_space)
58
58
  rep = evotype.create_standard_rep(name, basis, state_space)
59
59
  _LinearOperator.__init__(self, rep, evotype)
60
60
 
@@ -125,8 +125,8 @@ def create_from_dmvecs(superket_vectors, povm_type, basis='pp', evotype='default
125
125
  EffectiveExpErrorgen = _IdentityPlusErrorgenOp if lndtype.meta == '1+' else _ExpErrorgenOp
126
126
  povm = ComposedPOVM(EffectiveExpErrorgen(errorgen), base_povm, mx_basis=basis)
127
127
  elif typ in ('computational', 'static pure', 'full pure'):
128
- # RESHAPE NOTE: .flatten() added to line below (to convert pure *col* vec -> 1D) to fix unit tests
129
- pure_vectors = {k: _ot.dmvec_to_state(_bt.change_basis(superket, basis, 'std')).flatten()
128
+ # RESHAPE NOTE: .ravel() added to line below (to convert pure *col* vec -> 1D) to fix unit tests
129
+ pure_vectors = {k: _ot.dmvec_to_state(_bt.change_basis(superket, basis, 'std')).ravel()
130
130
  for k, superket in superket_vectors.items()}
131
131
  povm = create_from_pure_vectors(pure_vectors, typ, basis, evotype, state_space)
132
132
  else:
@@ -164,7 +164,7 @@ def create_effect_from_pure_vector(pure_vector, effect_type, basis='pp', evotype
164
164
  superket = _bt.change_basis(_ot.state_to_dmvec(pure_vector), 'std', basis)
165
165
  ef = create_effect_from_dmvec(superket, typ, basis, evotype, state_space)
166
166
  elif typ == 'static clifford':
167
- ef = ComputationalBasisPOVMEffect.from_pure_vector(pure_vector.flatten())
167
+ ef = ComputationalBasisPOVMEffect.from_pure_vector(pure_vector.ravel())
168
168
  elif _ot.is_valid_lindblad_paramtype(typ):
169
169
  from ..operations import LindbladErrorgen as _LindbladErrorgen, ExpErrorgenOp as _ExpErrorgenOp
170
170
  from ..operations import IdentityPlusErrorgenOp as _IdentityPlusErrorgenOp
@@ -21,7 +21,7 @@ from pygsti.modelmembers.povms.fulleffect import FullPOVMEffect as _FullPOVMEffe
21
21
  from pygsti.modelmembers.povms.povm import POVM as _POVM
22
22
  from pygsti.modelmembers import modelmember as _mm
23
23
  from pygsti.evotypes import Evotype as _Evotype
24
- from pygsti.baseobjs.statespace import StateSpace as _StateSpace
24
+ from pygsti.baseobjs.statespace import StateSpace as _StateSpace, default_space_for_dim
25
25
 
26
26
 
27
27
  class _BasePOVM(_POVM):
@@ -67,7 +67,12 @@ class _BasePOVM(_POVM):
67
67
  self.complement_label = None
68
68
 
69
69
  if evotype is not None:
70
- evotype = _Evotype.cast(evotype) # e.g., resolve "default"
70
+ if state_space is None and isinstance(items[0][1], (_np.ndarray, list)):
71
+ evotype = _Evotype.cast(evotype, default_space_for_dim(len(items[0][1]))) # e.g., resolve "default"
72
+ elif state_space is not None:
73
+ evotype = _Evotype.cast(evotype, state_space) # e.g., resolve "default"
74
+ else: #try to grab the state space from the first effect as a fall back.
75
+ evotype = _Evotype.cast(evotype, items[0][1].state_space) # e.g., resolve "default"
71
76
 
72
77
  #Copy each effect vector and set it's parent and gpindices.
73
78
  # Assume each given effect vector's parameters are independent.
@@ -167,40 +172,6 @@ class _BasePOVM(_POVM):
167
172
  for lbl, subm_serial_id in zip(mm_dict['effect_labels'], mm_dict['submembers'])}
168
173
  return cls(effects, mm_dict['evotype'], state_space) # Note: __init__ call signature of derived classes
169
174
 
170
- #def _reset_member_gpindices(self):
171
- # """
172
- # Sets gpindices for all non-complement items. Assumes all non-complement
173
- # vectors have *independent* parameters (for now).
174
- # """
175
- # Np = 0
176
- # for k, effect in self.items():
177
- # if k == self.complement_label: continue
178
- # N = effect.num_params
179
- # pslc = slice(Np, Np + N)
180
- # if effect.gpindices != pslc:
181
- # effect.set_gpindices(pslc, self)
182
- # Np += N
183
- # self.Np = Np
184
- #
185
- #def _rebuild_complement(self, identity_for_complement=None):
186
- # """ Rebuild complement vector (in case other vectors have changed) """
187
- #
188
- # if self.complement_label is not None and self.complement_label in self:
189
- # non_comp_effects = [v for k, v in self.items()
190
- # if k != self.complement_label]
191
- #
192
- # if identity_for_complement is None:
193
- # identity_for_complement = self[self.complement_label].identity
194
- #
195
- # complement_effect = _ComplementPOVMEffect(
196
- # identity_for_complement, non_comp_effects)
197
- # complement_effect.set_gpindices(slice(0, self.Np), self) # all parameters
198
- #
199
- # #Assign new complement effect without calling our __setitem__
200
- # old_ro = self._readonly; self._readonly = False
201
- # _POVM.__setitem__(self, self.complement_label, complement_effect)
202
- # self._readonly = old_ro
203
-
204
175
  def __setitem__(self, key, value):
205
176
  if not self._readonly: # when readonly == False, we're initializing
206
177
  return super(_BasePOVM, self).__setitem__(key, value)
@@ -135,16 +135,11 @@ class ComplementPOVMEffect(_ConjugatedStatePOVMEffect):
135
135
  return len(self.gpindices_as_array())
136
136
 
137
137
  def to_vector(self):
138
+ msg = """
139
+ ComplementPOVMEffect.to_vector() should never be called.
140
+ Use use TPPOVM.to_vector() instead.
138
141
  """
139
- Get the POVM effect vector parameters as an array of values.
140
-
141
- Returns
142
- -------
143
- numpy array
144
- The parameters as a 1D array with length num_params().
145
- """
146
- raise ValueError(("ComplementPOVMEffect.to_vector() should never be called"
147
- " - use TPPOVM.to_vector() instead"))
142
+ raise RuntimeError(msg)
148
143
 
149
144
  def from_vector(self, v, close=False, dirty_value=True):
150
145
  """
@@ -42,328 +42,8 @@ class ComposedPOVMEffect(_POVMEffect): # , _ErrorMapContainer
42
42
  parameters with other gates and spam vectors.)
43
43
  """
44
44
 
45
- #@classmethod
46
- #def _from_spamvec_obj(cls, spamvec, typ, param_type="GLND", purevec=None,
47
- # proj_basis="pp", mx_basis="pp", truncate=True,
48
- # lazy=False):
49
- # """
50
- # Creates a LindbladSPAMVec from an existing SPAMVec object and some additional information.
51
- #
52
- # This function is different from `from_spam_vector` in that it assumes
53
- # that `spamvec` is a :class:`SPAMVec`-derived object, and if `lazy=True`
54
- # and if `spamvec` is already a matching LindbladSPAMVec, it
55
- # is returned directly. This routine is primarily used in spam vector
56
- # conversion functions, where conversion is desired only when necessary.
57
- #
58
- # Parameters
59
- # ----------
60
- # spamvec : SPAMVec
61
- # The spam vector object to "convert" to a
62
- # `LindbladSPAMVec`.
63
- #
64
- # typ : {"prep","effect"}
65
- # Whether this is a state preparation or POVM effect vector.
66
- #
67
- # param_type : str, optional
68
- # The high-level "parameter type" of the gate to create. This
69
- # specifies both which Lindblad parameters are included and what
70
- # type of evolution is used. Examples of valid values are
71
- # `"CPTP"`, `"H+S"`, `"S terms"`, and `"GLND clifford terms"`.
72
- #
73
- # purevec : numpy array or SPAMVec object, optional
74
- # A SPAM vector which represents a pure-state, taken as the "ideal"
75
- # reference state when constructing the error generator of the
76
- # returned `LindbladSPAMVec`. Note that this vector
77
- # still acts on density matrices (if it's a SPAMVec it should have
78
- # a "densitymx", "svterm", or "cterm" evolution type, and if it's
79
- # a numpy array it should have the same dimension as `spamvec`).
80
- # If None, then it is taken to be `spamvec`, and so `spamvec` must
81
- # represent a pure state in this case.
82
- #
83
- # proj_basis : {'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object
84
- # The basis used to construct the Lindblad-term error generators onto
85
- # which the SPAM vector's error generator is projected. Allowed values
86
- # are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp),
87
- # and Qutrit (qt), list of numpy arrays, or a custom basis object.
88
- #
89
- # mx_basis : {'std', 'gm', 'pp', 'qt'} or Basis object
90
- # The source and destination basis, respectively. Allowed
91
- # values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp),
92
- # and Qutrit (qt) (or a custom basis object).
93
- #
94
- # truncate : bool, optional
95
- # Whether to truncate the projections onto the Lindblad terms in
96
- # order to meet constraints (e.g. to preserve CPTP) when necessary.
97
- # If False, then an error is thrown when the given `spamvec` cannot
98
- # be realized by the specified set of Lindblad projections.
99
- #
100
- # lazy : bool, optional
101
- # If True, then if `spamvec` is already a LindbladSPAMVec
102
- # with the requested details (given by the other arguments), then
103
- # `spamvec` is returned directly and no conversion/copying is
104
- # performed. If False, then a new object is always returned.
105
- #
106
- # Returns
107
- # -------
108
- # LindbladSPAMVec
109
- # """
110
- #
111
- # if not isinstance(spamvec, SPAMVec):
112
- # spamvec = StaticSPAMVec(spamvec, typ=typ) # assume spamvec is just a vector
113
- #
114
- # if purevec is None:
115
- # purevec = spamvec # right now, we don't try to extract a "closest pure vec"
116
- # # to spamvec - below will fail if spamvec isn't pure.
117
- # elif not isinstance(purevec, SPAMVec):
118
- # purevec = StaticSPAMVec(purevec, typ=typ) # assume spamvec is just a vector
119
- #
120
- # #Break param_type in to a "base" type and an evotype
121
- # from .operation import LindbladOp as _LPGMap
122
- # bTyp, evotype, nonham_mode, param_mode = _LPGMap.decomp_paramtype(param_type)
123
- #
124
- # ham_basis = proj_basis if (("H" == bTyp) or ("H+" in bTyp) or bTyp in ("CPTP", "GLND")) else None
125
- # nonham_basis = None if bTyp == "H" else proj_basis
126
- #
127
- # def beq(b1, b2):
128
- # """ Check if bases have equal names """
129
- # b1 = b1.name if isinstance(b1, _Basis) else b1
130
- # b2 = b2.name if isinstance(b2, _Basis) else b2
131
- # return b1 == b2
132
- #
133
- # def normeq(a, b):
134
- # if a is None and b is None: return True
135
- # if a is None or b is None: return False
136
- # return _mt.safe_norm(a - b) < 1e-6 # what about possibility of Clifford gates?
137
- #
138
- # if isinstance(spamvec, LindbladSPAMVec) \
139
- # and spamvec._evotype == evotype and spamvec.typ == typ \
140
- # and beq(ham_basis, spamvec.error_map.ham_basis) and beq(nonham_basis, spamvec.error_map.other_basis) \
141
- # and param_mode == spamvec.error_map.param_mode and nonham_mode == spamvec.error_map.nonham_mode \
142
- # and beq(mx_basis, spamvec.error_map.matrix_basis) and lazy:
143
- # #normeq(gate.pure_state_vec,purevec) \ # TODO: more checks for equality?!
144
- # return spamvec # no creation necessary!
145
- # else:
146
- # #Convert vectors (if possible) to SPAMVecs
147
- # # of the appropriate evotype and 0 params.
148
- # bDiff = spamvec is not purevec
149
- # spamvec = _convert_to_lindblad_base(spamvec, typ, evotype, mx_basis)
150
- # purevec = _convert_to_lindblad_base(purevec, typ, evotype, mx_basis) if bDiff else spamvec
151
- # assert(spamvec._evotype == evotype)
152
- # assert(purevec._evotype == evotype)
153
- #
154
- # return cls.from_spam_vector(
155
- # spamvec, purevec, typ, ham_basis, nonham_basis,
156
- # param_mode, nonham_mode, truncate, mx_basis, evotype)
157
- #
158
- #@classmethod
159
- #def from_spam_vector(cls, spam_vec, pure_vec, typ,
160
- # ham_basis="pp", nonham_basis="pp", param_mode="cptp",
161
- # nonham_mode="all", truncate=True, mx_basis="pp",
162
- # evotype="densitymx"):
163
- # """
164
- # Creates a Lindblad-parameterized spamvec from a state vector and a basis.
165
- #
166
- # The basis specifies how to decompose (project) the vector's error generator.
167
- #
168
- # Parameters
169
- # ----------
170
- # spam_vec : SPAMVec
171
- # the SPAM vector to initialize from. The error generator that
172
- # tranforms `pure_vec` into `spam_vec` forms the parameterization
173
- # of the returned LindbladSPAMVec.
174
- #
175
- # pure_vec : numpy array or SPAMVec
176
- # An array or SPAMVec in the *full* density-matrix space (this
177
- # vector will have the same dimension as `spam_vec` - 4 in the case
178
- # of a single qubit) which represents a pure-state preparation or
179
- # projection. This is used as the "base" preparation/projection
180
- # when computing the error generator that will be parameterized.
181
- # Note that this argument must be specified, as there is no natural
182
- # default value (like the identity in the case of gates).
183
- #
184
- # typ : {"prep","effect"}
185
- # Whether this is a state preparation or POVM effect vector.
186
- #
187
- # ham_basis: {'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object
188
- # The basis is used to construct the Hamiltonian-type lindblad error
189
- # Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp),
190
- # and Qutrit (qt), list of numpy arrays, or a custom basis object.
191
- #
192
- # nonham_basis: {'std', 'gm', 'pp', 'qt'}, list of matrices, or Basis object
193
- # The basis is used to construct the Stochastic-type lindblad error
194
- # Allowed values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp),
195
- # and Qutrit (qt), list of numpy arrays, or a custom basis object.
196
- #
197
- # param_mode : {"unconstrained", "cptp", "depol", "reldepol"}
198
- # Describes how the Lindblad coefficients/projections relate to the
199
- # SPAM vector's parameter values. Allowed values are:
200
- # `"unconstrained"` (coeffs are independent unconstrained parameters),
201
- # `"cptp"` (independent parameters but constrained so map is CPTP),
202
- # `"reldepol"` (all non-Ham. diagonal coeffs take the *same* value),
203
- # `"depol"` (same as `"reldepol"` but coeffs must be *positive*)
204
- #
205
- # nonham_mode : {"diagonal", "diag_affine", "all"}
206
- # Which non-Hamiltonian Lindblad projections are potentially non-zero.
207
- # Allowed values are: `"diagonal"` (only the diagonal Lind. coeffs.),
208
- # `"diag_affine"` (diagonal coefficients + affine projections), and
209
- # `"all"` (the entire matrix of coefficients is allowed).
210
- #
211
- # truncate : bool, optional
212
- # Whether to truncate the projections onto the Lindblad terms in
213
- # order to meet constraints (e.g. to preserve CPTP) when necessary.
214
- # If False, then an error is thrown when the given `gate` cannot
215
- # be realized by the specified set of Lindblad projections.
216
- #
217
- # mx_basis : {'std', 'gm', 'pp', 'qt'} or Basis object
218
- # The source and destination basis, respectively. Allowed
219
- # values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp),
220
- # and Qutrit (qt) (or a custom basis object).
221
- #
222
- # evotype : {"densitymx","svterm","cterm"}
223
- # The evolution type of the spamvec being constructed. `"densitymx"` is
224
- # usual Lioville density-matrix-vector propagation via matrix-vector
225
- # products. `"svterm"` denotes state-vector term-based evolution
226
- # (spamvec is obtained by evaluating the rank-1 terms up to
227
- # some order). `"cterm"` is similar but stabilizer states.
228
- #
229
- # Returns
230
- # -------
231
- # LindbladSPAMVec
232
- # """
233
- # #Compute a (errgen, pure_vec) pair from the given
234
- # # (spam_vec, pure_vec) pair.
235
- #
236
- # assert(pure_vec is not None), "Must supply `pure_vec`!" # since there's no good default?
237
- #
238
- # if not isinstance(spam_vec, SPAMVec):
239
- # spam_vec = StaticSPAMVec(spam_vec, evotype, typ) # assume spamvec is just a vector
240
- # if not isinstance(pure_vec, SPAMVec):
241
- # pure_vec = StaticSPAMVec(pure_vec, evotype, typ) # assume spamvec is just a vector
242
- # d2 = pure_vec.dim
243
- #
244
- # #Determine whether we're using sparse bases or not
245
- # sparse = None
246
- # if ham_basis is not None:
247
- # if isinstance(ham_basis, _Basis): sparse = ham_basis.sparse
248
- # elif not isinstance(ham_basis, str) and len(ham_basis) > 0:
249
- # sparse = _sps.issparse(ham_basis[0])
250
- # if sparse is None and nonham_basis is not None:
251
- # if isinstance(nonham_basis, _Basis): sparse = nonham_basis.sparse
252
- # elif not isinstance(nonham_basis, str) and len(nonham_basis) > 0:
253
- # sparse = _sps.issparse(nonham_basis[0])
254
- # if sparse is None: sparse = False # the default
255
- #
256
- # if spam_vec is None or spam_vec is pure_vec:
257
- # if sparse: errgen = _sps.csr_matrix((d2, d2), dtype='d')
258
- # else: errgen = _np.zeros((d2, d2), 'd')
259
- # else:
260
- # #Construct "spam error generator" by comparing *dense* vectors
261
- # pvdense = pure_vec.to_dense()
262
- # svdense = spam_vec.to_dense()
263
- # errgen = _ot.spam_error_generator(svdense, pvdense, mx_basis)
264
- # if sparse: errgen = _sps.csr_matrix(errgen)
265
- #
266
- # assert(pure_vec._evotype == evotype), "`pure_vec` must have evotype == '%s'" % evotype
267
- #
268
- # from .operation import LindbladErrorgen as _LErrorgen
269
- # from .operation import LindbladOp as _LPGMap
270
- # from .operation import LindbladDenseOp as _LPOp
271
- #
272
- # errgen = _LErrorgen.from_error_generator(errgen, ham_basis,
273
- # nonham_basis, param_mode, nonham_mode,
274
- # mx_basis, truncate, evotype)
275
- # errcls = _LPOp if (pure_vec.dim <= 64 and evotype == "densitymx") else _LPGMap
276
- # errmap = errcls(None, errgen)
277
- #
278
- # return cls(pure_vec, errmap, typ)
279
-
280
- #@classmethod
281
- #def from_lindblad_terms(cls, pure_vec, lindblad_term_dict, typ, basisdict=None,
282
- # param_mode="cptp", nonham_mode="all", truncate=True,
283
- # mx_basis="pp", evotype="densitymx"):
284
- # """
285
- # Create a Lindblad-parameterized spamvec with a given set of Lindblad terms.
286
- #
287
- # Parameters
288
- # ----------
289
- # pure_vec : numpy array or SPAMVec
290
- # An array or SPAMVec in the *full* density-matrix space (this
291
- # vector will have dimension 4 in the case of a single qubit) which
292
- # represents a pure-state preparation or projection. This is used as
293
- # the "base" preparation or projection that is followed or preceded
294
- # by, respectively, the parameterized Lindblad-form error generator.
295
- #
296
- # lindblad_term_dict : dict
297
- # A dictionary specifying which Linblad terms are present in the gate
298
- # parameteriztion. Keys are `(termType, basisLabel1, <basisLabel2>)`
299
- # tuples, where `termType` can be `"H"` (Hamiltonian), `"S"`
300
- # (Stochastic), or `"A"` (Affine). Hamiltonian and Affine terms always
301
- # have a single basis label (so key is a 2-tuple) whereas Stochastic
302
- # tuples with 1 basis label indicate a *diagonal* term, and are the
303
- # only types of terms allowed when `nonham_mode != "all"`. Otherwise,
304
- # Stochastic term tuples can include 2 basis labels to specify
305
- # "off-diagonal" non-Hamiltonian Lindblad terms. Basis labels can be
306
- # strings or integers. Values are complex coefficients (error rates).
307
- #
308
- # typ : {"prep","effect"}
309
- # Whether this is a state preparation or POVM effect vector.
310
- #
311
- # basisdict : dict, optional
312
- # A dictionary mapping the basis labels (strings or ints) used in the
313
- # keys of `lindblad_term_dict` to basis matrices (numpy arrays or Scipy sparse
314
- # matrices).
315
- #
316
- # param_mode : {"unconstrained", "cptp", "depol", "reldepol"}
317
- # Describes how the Lindblad coefficients/projections relate to the
318
- # SPAM vector's parameter values. Allowed values are:
319
- # `"unconstrained"` (coeffs are independent unconstrained parameters),
320
- # `"cptp"` (independent parameters but constrained so map is CPTP),
321
- # `"reldepol"` (all non-Ham. diagonal coeffs take the *same* value),
322
- # `"depol"` (same as `"reldepol"` but coeffs must be *positive*)
323
- #
324
- # nonham_mode : {"diagonal", "diag_affine", "all"}
325
- # Which non-Hamiltonian Lindblad projections are potentially non-zero.
326
- # Allowed values are: `"diagonal"` (only the diagonal Lind. coeffs.),
327
- # `"diag_affine"` (diagonal coefficients + affine projections), and
328
- # `"all"` (the entire matrix of coefficients is allowed).
329
- #
330
- # truncate : bool, optional
331
- # Whether to truncate the projections onto the Lindblad terms in
332
- # order to meet constraints (e.g. to preserve CPTP) when necessary.
333
- # If False, then an error is thrown when the given dictionary of
334
- # Lindblad terms doesn't conform to the constrains.
335
- #
336
- # mx_basis : {'std', 'gm', 'pp', 'qt'} or Basis object
337
- # The source and destination basis, respectively. Allowed
338
- # values are Matrix-unit (std), Gell-Mann (gm), Pauli-product (pp),
339
- # and Qutrit (qt) (or a custom basis object).
340
- #
341
- # evotype : {"densitymx","svterm","cterm"}
342
- # The evolution type of the spamvec being constructed. `"densitymx"` is
343
- # usual Lioville density-matrix-vector propagation via matrix-vector
344
- # products. `"svterm"` denotes state-vector term-based evolution
345
- # (spamvec is obtained by evaluating the rank-1 terms up to
346
- # some order). `"cterm"` is similar but stabilizer states.
347
- #
348
- # Returns
349
- # -------
350
- # LindbladOp
351
- # """
352
- # #Need a dimension for error map construction (basisdict could be completely empty)
353
- # if not isinstance(pure_vec, SPAMVec):
354
- # pure_vec = StaticSPAMVec(pure_vec, evotype, typ) # assume spamvec is just a vector
355
- # d2 = pure_vec.dim
356
- #
357
- # from .operation import LindbladOp as _LPGMap
358
- # errmap = _LPGMap(d2, lindblad_term_dict, basisdict, param_mode, nonham_mode,
359
- # truncate, mx_basis, evotype)
360
- # return cls(pure_vec, errmap, typ)
361
-
362
45
  def __init__(self, static_effect, errormap):
363
46
  evotype = errormap._evotype
364
- #from .operation import LindbladOp as _LPGMap
365
- #assert(evotype in ("densitymx", "svterm", "cterm")), \
366
- # "Invalid evotype: %s for %s" % (evotype, self.__class__.__name__)
367
47
 
368
48
  if not isinstance(static_effect, _POVMEffect):
369
49
  # UNSPECIFIED BASIS -- should be able to use static_effect._rep.basis once we get std attribute setup
@@ -151,7 +151,7 @@ class ComputationalBasisPOVMEffect(_POVMEffect):
151
151
  # or maybe remove and use self._rep.basis if that's the std attribute
152
152
  self._basis = basis
153
153
 
154
- evotype = _Evotype.cast(evotype)
154
+ evotype = _Evotype.cast(evotype, state_space=state_space)
155
155
  self._evotype = evotype # set this before call to _State.__init__ so self.to_dense() can work...
156
156
  rep = evotype.create_computational_effect_rep(zvals, basis, state_space)
157
157
  _POVMEffect.__init__(self, rep, evotype)
@@ -72,11 +72,13 @@ class ComputationalBasisPOVM(_POVM, _NoErrorGeneratorInterface):
72
72
  #LATER - do something with qubit_filter here
73
73
  # qubits = self.qubit_filter if (self.qubit_filter is not None) else list(range(self.nqubits))
74
74
 
75
- evotype = _Evotype.cast(evotype)
76
75
  items = [] # init as empty (lazy creation of members)
77
76
  if state_space is None:
78
77
  state_space = _statespace.QubitSpace(nqubits)
79
78
  assert(state_space.num_qubits == nqubits), "`state_space` must describe %d qubits!" % nqubits
79
+
80
+ evotype = _Evotype.cast(evotype, state_space=state_space)
81
+
80
82
  try:
81
83
  rep = evotype.create_computational_povm_rep(self.nqubits, self.qubit_filter)
82
84
  except AttributeError:
@@ -170,11 +170,9 @@ class POVMEffect(_modelmember.ModelMember):
170
170
  float
171
171
  """
172
172
  vec = self.to_dense()
173
- if transform is None:
174
- return _ot.residuals(vec, other_spam_vec.to_dense())
175
- else:
176
- return _ot.residuals(_np.dot(_np.transpose(transform),
177
- vec), other_spam_vec.to_dense())
173
+ if transform is not None:
174
+ vec = transform.T @ vec
175
+ return (vec - other_spam_vec.to_dense()).ravel()
178
176
 
179
177
  def transform_inplace(self, s):
180
178
  """