pyGSTi 0.9.12__cp39-cp39-win32.whl → 0.9.13__cp39-cp39-win32.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (225) hide show
  1. pyGSTi-0.9.13.dist-info/METADATA +197 -0
  2. {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/RECORD +211 -220
  3. {pyGSTi-0.9.12.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 +62 -35
  7. pygsti/algorithms/fiducialpairreduction.py +95 -110
  8. pygsti/algorithms/fiducialselection.py +17 -8
  9. pygsti/algorithms/gaugeopt.py +2 -2
  10. pygsti/algorithms/germselection.py +87 -77
  11. pygsti/algorithms/mirroring.py +0 -388
  12. pygsti/algorithms/randomcircuit.py +165 -1333
  13. pygsti/algorithms/rbfit.py +0 -234
  14. pygsti/baseobjs/basis.py +94 -396
  15. pygsti/baseobjs/errorgenbasis.py +0 -132
  16. pygsti/baseobjs/errorgenspace.py +0 -10
  17. pygsti/baseobjs/label.py +52 -168
  18. pygsti/baseobjs/opcalc/fastopcalc.cp39-win32.pyd +0 -0
  19. pygsti/baseobjs/opcalc/fastopcalc.pyx +2 -2
  20. pygsti/baseobjs/polynomial.py +13 -595
  21. pygsti/baseobjs/protectedarray.py +72 -132
  22. pygsti/baseobjs/statespace.py +1 -0
  23. pygsti/circuits/__init__.py +1 -1
  24. pygsti/circuits/circuit.py +753 -504
  25. pygsti/circuits/circuitconstruction.py +0 -4
  26. pygsti/circuits/circuitlist.py +47 -5
  27. pygsti/circuits/circuitparser/__init__.py +8 -8
  28. pygsti/circuits/circuitparser/fastcircuitparser.cp39-win32.pyd +0 -0
  29. pygsti/circuits/circuitstructure.py +3 -3
  30. pygsti/circuits/cloudcircuitconstruction.py +27 -14
  31. pygsti/data/datacomparator.py +4 -9
  32. pygsti/data/dataset.py +51 -46
  33. pygsti/data/hypothesistest.py +0 -7
  34. pygsti/drivers/bootstrap.py +0 -49
  35. pygsti/drivers/longsequence.py +46 -10
  36. pygsti/evotypes/basereps_cython.cp39-win32.pyd +0 -0
  37. pygsti/evotypes/chp/opreps.py +0 -61
  38. pygsti/evotypes/chp/statereps.py +0 -32
  39. pygsti/evotypes/densitymx/effectcreps.cpp +9 -10
  40. pygsti/evotypes/densitymx/effectreps.cp39-win32.pyd +0 -0
  41. pygsti/evotypes/densitymx/effectreps.pyx +1 -1
  42. pygsti/evotypes/densitymx/opreps.cp39-win32.pyd +0 -0
  43. pygsti/evotypes/densitymx/opreps.pyx +2 -2
  44. pygsti/evotypes/densitymx/statereps.cp39-win32.pyd +0 -0
  45. pygsti/evotypes/densitymx/statereps.pyx +1 -1
  46. pygsti/evotypes/densitymx_slow/effectreps.py +7 -23
  47. pygsti/evotypes/densitymx_slow/opreps.py +16 -23
  48. pygsti/evotypes/densitymx_slow/statereps.py +10 -3
  49. pygsti/evotypes/evotype.py +39 -2
  50. pygsti/evotypes/stabilizer/effectreps.cp39-win32.pyd +0 -0
  51. pygsti/evotypes/stabilizer/effectreps.pyx +0 -4
  52. pygsti/evotypes/stabilizer/opreps.cp39-win32.pyd +0 -0
  53. pygsti/evotypes/stabilizer/opreps.pyx +0 -4
  54. pygsti/evotypes/stabilizer/statereps.cp39-win32.pyd +0 -0
  55. pygsti/evotypes/stabilizer/statereps.pyx +1 -5
  56. pygsti/evotypes/stabilizer/termreps.cp39-win32.pyd +0 -0
  57. pygsti/evotypes/stabilizer/termreps.pyx +0 -7
  58. pygsti/evotypes/stabilizer_slow/effectreps.py +0 -22
  59. pygsti/evotypes/stabilizer_slow/opreps.py +0 -4
  60. pygsti/evotypes/stabilizer_slow/statereps.py +0 -4
  61. pygsti/evotypes/statevec/effectreps.cp39-win32.pyd +0 -0
  62. pygsti/evotypes/statevec/effectreps.pyx +1 -1
  63. pygsti/evotypes/statevec/opreps.cp39-win32.pyd +0 -0
  64. pygsti/evotypes/statevec/opreps.pyx +2 -2
  65. pygsti/evotypes/statevec/statereps.cp39-win32.pyd +0 -0
  66. pygsti/evotypes/statevec/statereps.pyx +1 -1
  67. pygsti/evotypes/statevec/termreps.cp39-win32.pyd +0 -0
  68. pygsti/evotypes/statevec/termreps.pyx +0 -7
  69. pygsti/evotypes/statevec_slow/effectreps.py +0 -3
  70. pygsti/evotypes/statevec_slow/opreps.py +0 -5
  71. pygsti/extras/__init__.py +0 -1
  72. pygsti/extras/drift/signal.py +1 -1
  73. pygsti/extras/drift/stabilityanalyzer.py +3 -1
  74. pygsti/extras/interpygate/__init__.py +12 -0
  75. pygsti/extras/interpygate/core.py +0 -36
  76. pygsti/extras/interpygate/process_tomography.py +44 -10
  77. pygsti/extras/rpe/rpeconstruction.py +0 -2
  78. pygsti/forwardsims/__init__.py +1 -0
  79. pygsti/forwardsims/forwardsim.py +50 -93
  80. pygsti/forwardsims/mapforwardsim.py +78 -20
  81. pygsti/forwardsims/mapforwardsim_calc_densitymx.cp39-win32.pyd +0 -0
  82. pygsti/forwardsims/mapforwardsim_calc_densitymx.pyx +65 -66
  83. pygsti/forwardsims/mapforwardsim_calc_generic.py +91 -13
  84. pygsti/forwardsims/matrixforwardsim.py +72 -17
  85. pygsti/forwardsims/termforwardsim.py +9 -111
  86. pygsti/forwardsims/termforwardsim_calc_stabilizer.cp39-win32.pyd +0 -0
  87. pygsti/forwardsims/termforwardsim_calc_statevec.cp39-win32.pyd +0 -0
  88. pygsti/forwardsims/termforwardsim_calc_statevec.pyx +0 -651
  89. pygsti/forwardsims/torchfwdsim.py +265 -0
  90. pygsti/forwardsims/weakforwardsim.py +2 -2
  91. pygsti/io/__init__.py +1 -2
  92. pygsti/io/mongodb.py +0 -2
  93. pygsti/io/stdinput.py +6 -22
  94. pygsti/layouts/copalayout.py +10 -12
  95. pygsti/layouts/distlayout.py +0 -40
  96. pygsti/layouts/maplayout.py +103 -25
  97. pygsti/layouts/matrixlayout.py +99 -60
  98. pygsti/layouts/prefixtable.py +1534 -52
  99. pygsti/layouts/termlayout.py +1 -1
  100. pygsti/modelmembers/instruments/instrument.py +3 -3
  101. pygsti/modelmembers/instruments/tpinstrument.py +2 -2
  102. pygsti/modelmembers/modelmember.py +0 -17
  103. pygsti/modelmembers/operations/__init__.py +3 -4
  104. pygsti/modelmembers/operations/affineshiftop.py +206 -0
  105. pygsti/modelmembers/operations/composederrorgen.py +1 -1
  106. pygsti/modelmembers/operations/composedop.py +1 -24
  107. pygsti/modelmembers/operations/denseop.py +5 -5
  108. pygsti/modelmembers/operations/eigpdenseop.py +2 -2
  109. pygsti/modelmembers/operations/embeddederrorgen.py +1 -1
  110. pygsti/modelmembers/operations/embeddedop.py +0 -1
  111. pygsti/modelmembers/operations/experrorgenop.py +5 -2
  112. pygsti/modelmembers/operations/fullarbitraryop.py +1 -0
  113. pygsti/modelmembers/operations/fullcptpop.py +2 -2
  114. pygsti/modelmembers/operations/fulltpop.py +28 -6
  115. pygsti/modelmembers/operations/fullunitaryop.py +5 -4
  116. pygsti/modelmembers/operations/lindbladcoefficients.py +93 -78
  117. pygsti/modelmembers/operations/lindbladerrorgen.py +268 -441
  118. pygsti/modelmembers/operations/linearop.py +7 -27
  119. pygsti/modelmembers/operations/opfactory.py +1 -1
  120. pygsti/modelmembers/operations/repeatedop.py +1 -24
  121. pygsti/modelmembers/operations/staticstdop.py +1 -1
  122. pygsti/modelmembers/povms/__init__.py +3 -3
  123. pygsti/modelmembers/povms/basepovm.py +7 -36
  124. pygsti/modelmembers/povms/complementeffect.py +4 -9
  125. pygsti/modelmembers/povms/composedeffect.py +0 -320
  126. pygsti/modelmembers/povms/computationaleffect.py +1 -1
  127. pygsti/modelmembers/povms/computationalpovm.py +3 -1
  128. pygsti/modelmembers/povms/effect.py +3 -5
  129. pygsti/modelmembers/povms/marginalizedpovm.py +3 -81
  130. pygsti/modelmembers/povms/tppovm.py +74 -2
  131. pygsti/modelmembers/states/__init__.py +2 -5
  132. pygsti/modelmembers/states/composedstate.py +0 -317
  133. pygsti/modelmembers/states/computationalstate.py +3 -3
  134. pygsti/modelmembers/states/cptpstate.py +4 -4
  135. pygsti/modelmembers/states/densestate.py +10 -8
  136. pygsti/modelmembers/states/fullpurestate.py +0 -24
  137. pygsti/modelmembers/states/purestate.py +1 -1
  138. pygsti/modelmembers/states/state.py +5 -6
  139. pygsti/modelmembers/states/tpstate.py +28 -10
  140. pygsti/modelmembers/term.py +3 -6
  141. pygsti/modelmembers/torchable.py +50 -0
  142. pygsti/modelpacks/_modelpack.py +1 -1
  143. pygsti/modelpacks/smq1Q_ZN.py +3 -1
  144. pygsti/modelpacks/smq2Q_XXYYII.py +2 -1
  145. pygsti/modelpacks/smq2Q_XY.py +3 -3
  146. pygsti/modelpacks/smq2Q_XYI.py +2 -2
  147. pygsti/modelpacks/smq2Q_XYICNOT.py +3 -3
  148. pygsti/modelpacks/smq2Q_XYICPHASE.py +3 -3
  149. pygsti/modelpacks/smq2Q_XYXX.py +1 -1
  150. pygsti/modelpacks/smq2Q_XYZICNOT.py +3 -3
  151. pygsti/modelpacks/smq2Q_XYZZ.py +1 -1
  152. pygsti/modelpacks/stdtarget.py +0 -121
  153. pygsti/models/cloudnoisemodel.py +1 -2
  154. pygsti/models/explicitcalc.py +3 -3
  155. pygsti/models/explicitmodel.py +3 -13
  156. pygsti/models/fogistore.py +5 -3
  157. pygsti/models/localnoisemodel.py +1 -2
  158. pygsti/models/memberdict.py +0 -12
  159. pygsti/models/model.py +801 -68
  160. pygsti/models/modelconstruction.py +4 -4
  161. pygsti/models/modelnoise.py +2 -2
  162. pygsti/models/modelparaminterposer.py +1 -1
  163. pygsti/models/oplessmodel.py +1 -1
  164. pygsti/models/qutrit.py +15 -14
  165. pygsti/objectivefns/objectivefns.py +75 -140
  166. pygsti/objectivefns/wildcardbudget.py +2 -7
  167. pygsti/optimize/__init__.py +1 -0
  168. pygsti/optimize/arraysinterface.py +28 -0
  169. pygsti/optimize/customcg.py +0 -12
  170. pygsti/optimize/customlm.py +129 -323
  171. pygsti/optimize/customsolve.py +2 -2
  172. pygsti/optimize/optimize.py +0 -84
  173. pygsti/optimize/simplerlm.py +841 -0
  174. pygsti/optimize/wildcardopt.py +19 -598
  175. pygsti/protocols/confidenceregionfactory.py +28 -14
  176. pygsti/protocols/estimate.py +31 -14
  177. pygsti/protocols/gst.py +238 -142
  178. pygsti/protocols/modeltest.py +19 -12
  179. pygsti/protocols/protocol.py +9 -37
  180. pygsti/protocols/rb.py +450 -79
  181. pygsti/protocols/treenode.py +8 -2
  182. pygsti/protocols/vb.py +108 -206
  183. pygsti/protocols/vbdataframe.py +1 -1
  184. pygsti/report/factory.py +0 -15
  185. pygsti/report/fogidiagram.py +1 -17
  186. pygsti/report/modelfunction.py +12 -3
  187. pygsti/report/mpl_colormaps.py +1 -1
  188. pygsti/report/plothelpers.py +11 -3
  189. pygsti/report/report.py +16 -0
  190. pygsti/report/reportables.py +41 -37
  191. pygsti/report/templates/offline/pygsti_dashboard.css +6 -0
  192. pygsti/report/templates/offline/pygsti_dashboard.js +12 -0
  193. pygsti/report/workspace.py +2 -14
  194. pygsti/report/workspaceplots.py +328 -505
  195. pygsti/tools/basistools.py +9 -36
  196. pygsti/tools/edesigntools.py +124 -96
  197. pygsti/tools/fastcalc.cp39-win32.pyd +0 -0
  198. pygsti/tools/fastcalc.pyx +35 -81
  199. pygsti/tools/internalgates.py +151 -15
  200. pygsti/tools/jamiolkowski.py +5 -5
  201. pygsti/tools/lindbladtools.py +19 -11
  202. pygsti/tools/listtools.py +0 -114
  203. pygsti/tools/matrixmod2.py +1 -1
  204. pygsti/tools/matrixtools.py +173 -339
  205. pygsti/tools/nameddict.py +1 -1
  206. pygsti/tools/optools.py +154 -88
  207. pygsti/tools/pdftools.py +0 -25
  208. pygsti/tools/rbtheory.py +3 -320
  209. pygsti/tools/slicetools.py +64 -12
  210. pyGSTi-0.9.12.dist-info/METADATA +0 -157
  211. pygsti/algorithms/directx.py +0 -711
  212. pygsti/evotypes/qibo/__init__.py +0 -33
  213. pygsti/evotypes/qibo/effectreps.py +0 -78
  214. pygsti/evotypes/qibo/opreps.py +0 -376
  215. pygsti/evotypes/qibo/povmreps.py +0 -98
  216. pygsti/evotypes/qibo/statereps.py +0 -174
  217. pygsti/extras/rb/__init__.py +0 -13
  218. pygsti/extras/rb/benchmarker.py +0 -957
  219. pygsti/extras/rb/dataset.py +0 -378
  220. pygsti/extras/rb/io.py +0 -814
  221. pygsti/extras/rb/simulate.py +0 -1020
  222. pygsti/io/legacyio.py +0 -385
  223. pygsti/modelmembers/povms/denseeffect.py +0 -142
  224. {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/LICENSE +0 -0
  225. {pyGSTi-0.9.12.dist-info → pyGSTi-0.9.13.dist-info}/top_level.txt +0 -0
@@ -79,11 +79,6 @@ class ExplicitElementaryErrorgenBasis(ElementaryErrorgenBasis):
79
79
  return None
80
80
  return self._label_indices[label]
81
81
 
82
- #@property
83
- #def sslbls(self):
84
- # """ The support of this errorgen space, e.g., the qubits where its elements may be nontrivial """
85
- # return self.sslbls
86
-
87
82
  def create_subbasis(self, must_overlap_with_these_sslbls):
88
83
  """
89
84
  Create a sub-basis of this basis by including only the elements
@@ -491,11 +486,6 @@ class CompleteElementaryErrorgenBasis(ElementaryErrorgenBasis):
491
486
 
492
487
  return base + indices[elemgen_label]
493
488
 
494
- #@property
495
- #def sslbls(self):
496
- # """ The support of this errorgen space, e.g., the qubits where its elements may be nontrivial """
497
- # return self.sslbls
498
-
499
489
  def create_subbasis(self, must_overlap_with_these_sslbls, retain_max_weights=True):
500
490
  """
501
491
  Create a sub-basis of this basis by including only the elements
@@ -524,125 +514,3 @@ class CompleteElementaryErrorgenBasis(ElementaryErrorgenBasis):
524
514
 
525
515
  def difference(self, other_basis):
526
516
  return self.to_explicit_basis().difference(other_basis)
527
-
528
-
529
- #OLD - maybe not needed?
530
- #class LowWeightElementaryErrorgenBasis(ElementaryErrorgenBasis):
531
- # """
532
- # Spanned by the elementary error generators of given type(s) (e.g. "Hamiltonian" and/or "other")
533
- # and with elements corresponding to a `Basis`, usually of Paulis.
534
- # """
535
- #
536
- # def __init__(self, basis_1q, state_space, other_mode, max_ham_weight=None, max_other_weight=None,
537
- # must_overlap_with_these_sslbls=None):
538
- # self._basis_1q = basis_1q
539
- # self._other_mode = other_mode
540
- # self.state_space = state_space
541
- # self._max_ham_weight = max_ham_weight
542
- # self._max_other_weight = max_other_weight
543
- # self._must_overlap_with_these_sslbls = must_overlap_with_these_sslbls
544
- #
545
- # assert(self.state_space.is_entirely_qubits), "FOGI only works for models containing just qubits (so far)"
546
- # sslbls = self.state_space.sole_tensor_product_block_labels # all the model's state space labels
547
- # self.sslbls = sslbls # the "support" of this space - the qubit labels
548
- #
549
- # self._cached_label_indices = None
550
- # self._cached_labels_by_support = None
551
- # self._cached_elements = None
552
- #
553
- # #Needed?
554
- # # self.dim = len(self.labels) # TODO - update this so we don't always need to build labels
555
- # # # (this defeats lazy building via property below) - we can just compute this, especially if
556
- # # # not too fancy
557
- #
558
- # @property
559
- # def labels(self):
560
- # if self._cached_label_indices is None:
561
- #
562
- # def _basis_el_strs(possible_bels, wt):
563
- # for els in _itertools.product(*([possible_bels] * wt)):
564
- # yield ''.join(els)
565
- #
566
- # labels = {}
567
- # all_bels = self.basis_1q.labels[1:] # assume first element is identity
568
- # nontrivial_bels = self.basis_1q.labels[1:] # assume first element is identity
569
- #
570
- # max_weight = self._max_ham_weight if (self._max_ham_weight is not None) else len(self.sslbls)
571
- # for weight in range(1, max_weight + 1):
572
- # for support in _itertools.combinations(self.sslbls, weight):
573
- # if (self._must_overlap_with_these_sslbls is not None
574
- # and len(self._must_overlap_with_these_sslbls.intersection(support)) == 0):
575
- # continue
576
- # if support not in labels: labels[support] = [] # always True?
577
- # labels[support].extend([('H', bel) for bel in _basis_el_strs(nontrivial_bels, weight)])
578
- #
579
- # max_weight = self._max_other_weight if (self._max_other_weight is not None) else len(self.sslbls)
580
- # if self._other_mode != "all":
581
- # for weight in range(1, max_weight + 1):
582
- # for support in _itertools.combinations(self.sslbls, weight):
583
- # if (self._must_overlap_with_these_sslbls is not None
584
- # and len(self._must_overlap_with_these_sslbls.intersection(support)) == 0):
585
- # continue
586
- # if support not in labels: labels[support] = []
587
- # labels[support].extend([('S', bel) for bel in _basis_el_strs(nontrivial_bels, weight)])
588
- # else:
589
- # #This is messy code that relies on basis labels being single characters -- TODO improve(?)
590
- # idle_char = self.basis_1q.labels[1:] # assume first element is identity
591
- # assert(len(idle_char) == 1 and all([len(c) == 1 for c in nontrivial_bels])), \
592
- # "All basis el labels must be single chars for other_mode=='all'!"
593
- # for support in _itertools.combinations(self.sslbls, max_weight):
594
- # # Loop over all possible basis elements for this max-weight support, computing the actual support
595
- # # of each one individually and appending it to the appropriate list
596
- # for bel1 in _basis_el_strs(all_bels, max_weight):
597
- # nonidle_indices1 = [i for i in range(max_weight) if bel1[i] != idle_char]
598
- # for bel2 in _basis_el_strs(all_bels, max_weight):
599
- # nonidle_indices2 = [i for i in range(max_weight) if bel2[i] != idle_char]
600
- # nonidle_indices = list(sorted(set(nonidle_indices1) + set(nonidle_indices2)))
601
- # bel1 = ''.join([bel1[i] for i in nonidle_indices]) # trim to actual support
602
- # bel2 = ''.join([bel2[i] for i in nonidle_indices]) # trim to actual support
603
- # actual_support = tuple([support[i] for i in nonidle_indices])
604
- #
605
- # if (self._must_overlap_with_these_sslbls is not None
606
- # and len(self._must_overlap_with_these_sslbls.intersection(actual_support)) == 0):
607
- # continue
608
- #
609
- # if actual_support not in labels: labels[actual_support] = []
610
- # labels[actual_support].append(('S', bel1, bel2))
611
- #
612
- # self._cached_labels_by_support = labels
613
- # self._cached_label_indices = _collections.OrderedDict(((support_lbl, i) for i, support_lbl in enumerate(
614
- # ((support, lbl) for support, lst in labels.items() for lbl in lst))))
615
- #
616
- # return tuple(self._cached_label_indices.keys())
617
- #
618
- # @property
619
- # def element_supports_and_matrices(self):
620
- # if self._cached_elements is None:
621
- # self._cached_elements = tuple(
622
- # ((support, _ot.lindblad_error_generator(elemgen_label, self.basis_1q, normalize=True, sparse=False))
623
- # for support, elemgen_label in self.labels))
624
- # return self._cached_elements
625
- #
626
- # def element_index(self, label):
627
- # """
628
- # TODO: docstring
629
- # """
630
- # if self._cached_label_indices is None:
631
- # self.labels # triggers building of labels
632
- # return self._cached_label_indices[label]
633
- #
634
- # @property
635
- # def sslbls(self):
636
- # """ The support of this errorgen space, e.g., the qubits where its elements may be nontrivial """
637
- # return self.sslbls
638
- #
639
- # def create_subbasis(self, must_overlap_with_these_sslbls, retain_max_weights=True):
640
- # """
641
- # Create a sub-basis of this basis by including only the elements
642
- # that overlap the given support (state space labels)
643
- # """
644
- # #Note: can we reduce self.state_space?
645
- # return CompleteErrorgenBasis(self._basis_1q, self.state_space, self._other_mode,
646
- # self._max_ham_weight if retain_max_weights else None,
647
- # self._max_other_weight if retain_max_weights else None,
648
- # self._must_overlap_with_these_sslbls)
@@ -97,13 +97,3 @@ class ErrorgenSpace(object):
97
97
  for j in range(self.vectors.shape[1]):
98
98
  sign = +1 if max(self.vectors[:, j]) >= -min(self.vectors[:, j]) else -1
99
99
  self.vectors[:, j] /= sign * _np.linalg.norm(self.vectors[:, j], ord=norm_order)
100
-
101
-
102
- #class LowWeightErrorgenSpace(ErrorgenSpace):
103
- # """
104
- # Like a SimpleErrorgenSpace but spanned by only the elementary error generators corresponding to
105
- # low-weight (up to some maximum weight) basis elements
106
- # (so far, only Pauli-product bases work for this, since `Basis` objects don't keep track of each
107
- # element's weight (?)).
108
- # """
109
- # pass
pygsti/baseobjs/label.py CHANGED
@@ -14,8 +14,6 @@ import itertools as _itertools
14
14
  import numbers as _numbers
15
15
  import sys as _sys
16
16
 
17
- _debug_record = {}
18
-
19
17
 
20
18
  class Label(object):
21
19
  """
@@ -63,12 +61,11 @@ class Label(object):
63
61
  could be an argument of a gate label, and one might create a label:
64
62
  `Label('Gx', (0,), args=(pi/3,))`
65
63
  """
66
- #print("Label.__new__ with name=", name, "sslbls=", state_space_labels, "t=", time, "args=", args)
64
+
67
65
  if isinstance(name, Label) and state_space_labels is None:
68
66
  return name # Note: Labels are immutable, so no need to copy
69
67
 
70
- if not isinstance(name, str) and state_space_labels is None \
71
- and isinstance(name, (tuple, list)):
68
+ if isinstance(name, (tuple, list)) and state_space_labels is None:
72
69
 
73
70
  #We're being asked to initialize from a non-string with no
74
71
  # state_space_labels, explicitly given. `name` could either be:
@@ -190,6 +187,15 @@ class Label(object):
190
187
  :class:`CircuitLabel` objects).
191
188
  """
192
189
  return (self,) # most labels just expand to themselves
190
+
191
+ @property
192
+ def is_simple(self):
193
+ """
194
+ Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
195
+ """
196
+
197
+ return self.IS_SIMPLE
198
+
193
199
 
194
200
 
195
201
  class LabelTup(Label, tuple):
@@ -201,6 +207,10 @@ class LabelTup(Label, tuple):
201
207
  acted upon by the object this label refers to.
202
208
  """
203
209
 
210
+ #flag used in certain Circuit subroutines
211
+ #Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
212
+ IS_SIMPLE = True
213
+
204
214
  @classmethod
205
215
  def init(cls, name, state_space_labels):
206
216
  """
@@ -250,10 +260,6 @@ class LabelTup(Label, tuple):
250
260
  return tuple.__new__(cls, tup)
251
261
 
252
262
  __new__ = tuple.__new__
253
- #def __new__(cls, tup, time=0.0):
254
- # ret = tuple.__new__(cls, tup) # creates a LabelTup object using tuple's __new__
255
- # ret.time = time
256
- # return ret
257
263
 
258
264
  @property
259
265
  def time(self):
@@ -354,26 +360,10 @@ class LabelTup(Label, tuple):
354
360
  mapped_sslbls = [mapper(sslbl) for sslbl in self.sslbls]
355
361
  return Label(self.name, mapped_sslbls)
356
362
 
357
- #OLD
358
- #def __iter__(self):
359
- # return self.tup.__iter__()
360
-
361
- #OLD
362
- #def __iter__(self):
363
- # """ Iterate over the name + state space labels """
364
- # # Note: tuple(.) uses __iter__ to construct tuple rep.
365
- # yield self.name
366
- # if self.sslbls is not None:
367
- # for ssl in self.sslbls:
368
- # yield ssl
369
-
370
363
  def __str__(self):
371
364
  """
372
365
  Defines how a Label is printed out, e.g. Gx:0 or Gcnot:1:2
373
366
  """
374
- #caller = inspect.getframeinfo(inspect.currentframe().f_back)
375
- #ky = "%s:%s:%d" % (caller[2],os.path.basename(caller[0]),caller[1])
376
- #_debug_record[ky] = _debug_record.get(ky, 0) + 1
377
367
  s = str(self.name)
378
368
  if self.sslbls: # test for None and len == 0
379
369
  s += ":" + ":".join(map(str, self.sslbls))
@@ -393,13 +383,7 @@ class LabelTup(Label, tuple):
393
383
  Defines equality between gates, so that they are equal if their values
394
384
  are equal.
395
385
  """
396
- #Unnecessary now that we have a separate LabelStr
397
- #if isinstance(other, str):
398
- # if self.sslbls: return False # tests for None and len > 0
399
- # return self.name == other
400
-
401
386
  return tuple.__eq__(self, other)
402
- #OLD return self.name == other.name and self.sslbls == other.sslbls # ok to compare None
403
387
 
404
388
  def __lt__(self, x):
405
389
  return tuple.__lt__(self, tuple(x))
@@ -445,16 +429,6 @@ class LabelTup(Label, tuple):
445
429
  """
446
430
  return LabelTup.init(newname, self.sslbls) if (self.name == oldname) else self
447
431
 
448
- def is_simple(self):
449
- """
450
- Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
451
-
452
- Returns
453
- -------
454
- bool
455
- """
456
- return True
457
-
458
432
  __hash__ = tuple.__hash__ # this is why we derive from tuple - using the
459
433
  # native tuple.__hash__ directly == speed boost
460
434
 
@@ -468,6 +442,10 @@ class LabelTupWithTime(Label, tuple):
468
442
  acted upon by the object this label refers to.
469
443
  """
470
444
 
445
+ #flag used in certain Circuit subroutines
446
+ #Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
447
+ IS_SIMPLE = True
448
+
471
449
  @classmethod
472
450
  def init(cls, name, state_space_labels, time=0.0):
473
451
  """
@@ -617,19 +595,6 @@ class LabelTupWithTime(Label, tuple):
617
595
  mapped_sslbls = [mapper(sslbl) for sslbl in self.sslbls]
618
596
  return Label(self.name, mapped_sslbls)
619
597
 
620
- #OLD
621
- #def __iter__(self):
622
- # return self.tup.__iter__()
623
-
624
- #OLD
625
- #def __iter__(self):
626
- # """ Iterate over the name + state space labels """
627
- # # Note: tuple(.) uses __iter__ to construct tuple rep.
628
- # yield self.name
629
- # if self.sslbls is not None:
630
- # for ssl in self.sslbls:
631
- # yield ssl
632
-
633
598
  def __str__(self):
634
599
  """
635
600
  Defines how a Label is printed out, e.g. Gx:0 or Gcnot:1:2
@@ -659,13 +624,8 @@ class LabelTupWithTime(Label, tuple):
659
624
  Defines equality between gates, so that they are equal if their values
660
625
  are equal.
661
626
  """
662
- #Unnecessary now that we have a separate LabelStr
663
- #if isinstance(other, str):
664
- # if self.sslbls: return False # tests for None and len > 0
665
- # return self.name == other
666
627
 
667
628
  return tuple.__eq__(self, other)
668
- #OLD return self.name == other.name and self.sslbls == other.sslbls # ok to compare None
669
629
 
670
630
  def __lt__(self, x):
671
631
  return tuple.__lt__(self, tuple(x))
@@ -711,16 +671,6 @@ class LabelTupWithTime(Label, tuple):
711
671
  """
712
672
  return LabelTupWithTime(newname, self.sslbls) if (self.name == oldname) else self
713
673
 
714
- def is_simple(self):
715
- """
716
- Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
717
-
718
- Returns
719
- -------
720
- bool
721
- """
722
- return True
723
-
724
674
  __hash__ = tuple.__hash__ # this is why we derive from tuple - using the
725
675
  # native tuple.__hash__ directly == speed boost
726
676
 
@@ -736,6 +686,10 @@ class LabelStr(Label, str):
736
686
  the hashing gets *much* slower.
737
687
  """
738
688
 
689
+ #flag used in certain Circuit subroutines
690
+ #Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
691
+ IS_SIMPLE = True
692
+
739
693
  @classmethod
740
694
  def init(cls, name, time=0.0):
741
695
  """
@@ -863,6 +817,10 @@ class LabelStr(Label, str):
863
817
  # Need to tell serialization logic how to create a new Label since it's derived
864
818
  # from the immutable tuple type (so cannot have its state set after creation)
865
819
  return (LabelStr, (str(self), self.time), None)
820
+
821
+ def __contains__(self, x):
822
+ #need to get a string rep of the tested label.
823
+ return str(x) in str(self)
866
824
 
867
825
  def to_native(self):
868
826
  """
@@ -894,16 +852,6 @@ class LabelStr(Label, str):
894
852
  """
895
853
  return LabelStr(newname) if (self.name == oldname) else self
896
854
 
897
- def is_simple(self):
898
- """
899
- Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
900
-
901
- Returns
902
- -------
903
- bool
904
- """
905
- return True
906
-
907
855
  __hash__ = str.__hash__ # this is why we derive from tuple - using the
908
856
  # native tuple.__hash__ directly == speed boost
909
857
 
@@ -915,6 +863,10 @@ class LabelTupTup(Label, tuple):
915
863
  This typically labels a layer of a circuit (a parallel level of gates).
916
864
  """
917
865
 
866
+ #flag used in certain Circuit subroutines
867
+ #Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
868
+ IS_SIMPLE = False
869
+
918
870
  @classmethod
919
871
  def init(cls, tup_of_tups):
920
872
  """
@@ -934,9 +886,9 @@ class LabelTupTup(Label, tuple):
934
886
  -------
935
887
  LabelTupTup
936
888
  """
937
- tupOfLabels = tuple((Label(tup) for tup in tup_of_tups)) # Note: tup can also be a Label obj
938
- if len(tupOfLabels) > 0:
939
- assert(max([lbl.time for lbl in tupOfLabels]) == 0.0), \
889
+ tupOfLabels = tuple([Label(tup) for tup in tup_of_tups]) # Note: tup can also be a Label obj
890
+ if tupOfLabels:
891
+ assert(all([lbl.time==0.0 for lbl in tupOfLabels])), \
940
892
  "Cannot create a LabelTupTup containing labels with time != 0"
941
893
  return cls.__new__(cls, tupOfLabels)
942
894
 
@@ -1071,13 +1023,7 @@ class LabelTupTup(Label, tuple):
1071
1023
  Defines equality between gates, so that they are equal if their values
1072
1024
  are equal.
1073
1025
  """
1074
- #Unnecessary now that we have a separate LabelStr
1075
- #if isinstance(other, str):
1076
- # if self.sslbls: return False # tests for None and len > 0
1077
- # return self.name == other
1078
-
1079
1026
  return tuple.__eq__(self, other)
1080
- #OLD return self.name == other.name and self.sslbls == other.sslbls # ok to compare None
1081
1027
 
1082
1028
  def __lt__(self, x):
1083
1029
  return tuple.__lt__(self, tuple(x))
@@ -1127,16 +1073,6 @@ class LabelTupTup(Label, tuple):
1127
1073
  """
1128
1074
  return LabelTupTup(tuple((x.replace_name(oldname, newname) for x in self)))
1129
1075
 
1130
- def is_simple(self):
1131
- """
1132
- Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
1133
-
1134
- Returns
1135
- -------
1136
- bool
1137
- """
1138
- return False
1139
-
1140
1076
  @property
1141
1077
  def depth(self):
1142
1078
  """
@@ -1182,6 +1118,10 @@ class LabelTupTupWithTime(Label, tuple):
1182
1118
  This typically labels a layer of a circuit (a parallel level of gates).
1183
1119
  """
1184
1120
 
1121
+ #flag used in certain Circuit subroutines
1122
+ #Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
1123
+ IS_SIMPLE = False
1124
+
1185
1125
  @classmethod
1186
1126
  def init(cls, tup_of_tups, time=None):
1187
1127
  """
@@ -1340,13 +1280,7 @@ class LabelTupTupWithTime(Label, tuple):
1340
1280
  Defines equality between gates, so that they are equal if their values
1341
1281
  are equal.
1342
1282
  """
1343
- #Unnecessary now that we have a separate LabelStr
1344
- #if isinstance(other, str):
1345
- # if self.sslbls: return False # tests for None and len > 0
1346
- # return self.name == other
1347
-
1348
1283
  return tuple.__eq__(self, other)
1349
- #OLD return self.name == other.name and self.sslbls == other.sslbls # ok to compare None
1350
1284
 
1351
1285
  def __lt__(self, x):
1352
1286
  return tuple.__lt__(self, tuple(x))
@@ -1396,16 +1330,6 @@ class LabelTupTupWithTime(Label, tuple):
1396
1330
  """
1397
1331
  return LabelTupTupWithTime(tuple((x.replace_name(oldname, newname) for x in self)))
1398
1332
 
1399
- def is_simple(self):
1400
- """
1401
- Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
1402
-
1403
- Returns
1404
- -------
1405
- bool
1406
- """
1407
- return False
1408
-
1409
1333
  @property
1410
1334
  def depth(self):
1411
1335
  """
@@ -1454,6 +1378,11 @@ class CircuitLabel(Label, tuple):
1454
1378
  (held as the label's components) and line labels (held as the label's
1455
1379
  state-space labels)
1456
1380
  """
1381
+
1382
+ #flag used in certain Circuit subroutines
1383
+ #Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
1384
+ IS_SIMPLE = True
1385
+
1457
1386
  def __new__(cls, name, tup_of_layers, state_space_labels, reps=1, time=None):
1458
1387
  # Note: may need default args for all but 1st for pickling!
1459
1388
  """
@@ -1633,13 +1562,7 @@ class CircuitLabel(Label, tuple):
1633
1562
  Defines equality between gates, so that they are equal if their values
1634
1563
  are equal.
1635
1564
  """
1636
- #Unnecessary now that we have a separate LabelStr
1637
- #if isinstance(other, str):
1638
- # if self.sslbls: return False # tests for None and len > 0
1639
- # return self.name == other
1640
-
1641
1565
  return tuple.__eq__(self, other)
1642
- #OLD return self.name == other.name and self.sslbls == other.sslbls # ok to compare None
1643
1566
 
1644
1567
  def __lt__(self, x):
1645
1568
  return tuple.__lt__(self, tuple(x))
@@ -1692,16 +1615,6 @@ class CircuitLabel(Label, tuple):
1692
1615
  self.sslbls,
1693
1616
  self[2])
1694
1617
 
1695
- def is_simple(self):
1696
- """
1697
- Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
1698
-
1699
- Returns
1700
- -------
1701
- bool
1702
- """
1703
- return True # still true - even though can have components!
1704
-
1705
1618
  @property
1706
1619
  def depth(self):
1707
1620
  """
@@ -1729,11 +1642,6 @@ class CircuitLabel(Label, tuple):
1729
1642
  # native tuple.__hash__ directly == speed boost
1730
1643
 
1731
1644
 
1732
- #class NamedLabelTupTup(Label,tuple):
1733
- # def __new__(cls,name,tup_of_tups):
1734
- # pass
1735
-
1736
-
1737
1645
  class LabelTupWithArgs(Label, tuple):
1738
1646
  """
1739
1647
  A label consisting of a string along with a tuple of integers or state-space-names.
@@ -1743,6 +1651,10 @@ class LabelTupWithArgs(Label, tuple):
1743
1651
  refers to. This label type also supports having arguments and a time value.
1744
1652
  """
1745
1653
 
1654
+ #flag used in certain Circuit subroutines
1655
+ #Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
1656
+ IS_SIMPLE = True
1657
+
1746
1658
  @classmethod
1747
1659
  def init(cls, name, state_space_labels, time=0.0, args=()):
1748
1660
  """
@@ -1943,13 +1855,7 @@ class LabelTupWithArgs(Label, tuple):
1943
1855
  Defines equality between gates, so that they are equal if their values
1944
1856
  are equal.
1945
1857
  """
1946
- #Unnecessary now that we have a separate LabelStr
1947
- #if isinstance(other, str):
1948
- # if self.sslbls: return False # tests for None and len > 0
1949
- # return self.name == other
1950
-
1951
1858
  return tuple.__eq__(self, other)
1952
- #OLD return self.name == other.name and self.sslbls == other.sslbls # ok to compare None
1953
1859
 
1954
1860
  def __lt__(self, x):
1955
1861
  try:
@@ -2001,16 +1907,6 @@ class LabelTupWithArgs(Label, tuple):
2001
1907
  """
2002
1908
  return LabelTupWithArgs(newname, self.sslbls, self.time, self.args) if (self.name == oldname) else self
2003
1909
 
2004
- def is_simple(self):
2005
- """
2006
- Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
2007
-
2008
- Returns
2009
- -------
2010
- bool
2011
- """
2012
- return True
2013
-
2014
1910
  __hash__ = tuple.__hash__ # this is why we derive from tuple - using the
2015
1911
  # native tuple.__hash__ directly == speed boost
2016
1912
 
@@ -2023,6 +1919,10 @@ class LabelTupTupWithArgs(Label, tuple):
2023
1919
  This label type also supports having arguments and a time value.
2024
1920
  """
2025
1921
 
1922
+ #flag used in certain Circuit subroutines
1923
+ #Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
1924
+ IS_SIMPLE = False
1925
+
2026
1926
  @classmethod
2027
1927
  def init(cls, tup_of_tups, time=None, args=()):
2028
1928
  """
@@ -2199,14 +2099,8 @@ class LabelTupTupWithArgs(Label, tuple):
2199
2099
  Defines equality between gates, so that they are equal if their values
2200
2100
  are equal.
2201
2101
  """
2202
- #Unnecessary now that we have a separate LabelStr
2203
- #if isinstance(other, str):
2204
- # if self.sslbls: return False # tests for None and len > 0
2205
- # return self.name == other
2206
-
2207
2102
  return tuple.__eq__(self, other)
2208
- #OLD return self.name == other.name and self.sslbls == other.sslbls # ok to compare None
2209
-
2103
+
2210
2104
  def __lt__(self, x):
2211
2105
  return tuple.__lt__(self, tuple(x))
2212
2106
 
@@ -2256,16 +2150,6 @@ class LabelTupTupWithArgs(Label, tuple):
2256
2150
  return LabelTupTupWithArgs(tuple((x.replace_name(oldname, newname) for x in self.components)),
2257
2151
  self.time, self.args)
2258
2152
 
2259
- def is_simple(self):
2260
- """
2261
- Whether this is a "simple" (opaque w/a true name, from a circuit perspective) label or not.
2262
-
2263
- Returns
2264
- -------
2265
- bool
2266
- """
2267
- return False
2268
-
2269
2153
  @property
2270
2154
  def depth(self):
2271
2155
  """
@@ -69,7 +69,7 @@ def bulk_eval_compact_polynomials_real(np.ndarray[np.int64_t, ndim=1, mode="c"]
69
69
  np.ndarray[double, ndim=1, mode="c"] ctape,
70
70
  np.ndarray[double, ndim=1, mode="c"] paramvec,
71
71
  dest_shape):
72
- cdef INT dest_size = np.product(dest_shape)
72
+ cdef INT dest_size = np.prod(dest_shape)
73
73
  cdef np.ndarray[np.float64_t, ndim=1, mode="c"] res = np.empty(dest_size, np.float64)
74
74
 
75
75
  cdef INT c = 0
@@ -108,7 +108,7 @@ def bulk_eval_compact_polynomials_complex(np.ndarray[np.int64_t, ndim=1, mode="c
108
108
  np.ndarray[double, ndim=1, mode="c"] paramvec,
109
109
  dest_shape):
110
110
  cdef INT k
111
- cdef INT dest_size = 1 # np.product(dest_shape) #SLOW!
111
+ cdef INT dest_size = 1 # np.prod(dest_shape) #SLOW!
112
112
  for k in range(len(dest_shape)):
113
113
  dest_size *= dest_shape[k]
114
114
  cdef np.ndarray[np.complex128_t, ndim=1, mode="c"] res = np.empty(dest_size, np.complex128)