pyGSTi 0.9.12__cp39-cp39-win_amd64.whl → 0.9.13__cp39-cp39-win_amd64.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-win_amd64.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-win_amd64.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-win_amd64.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-win_amd64.pyd +0 -0
  41. pygsti/evotypes/densitymx/effectreps.pyx +1 -1
  42. pygsti/evotypes/densitymx/opreps.cp39-win_amd64.pyd +0 -0
  43. pygsti/evotypes/densitymx/opreps.pyx +2 -2
  44. pygsti/evotypes/densitymx/statereps.cp39-win_amd64.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-win_amd64.pyd +0 -0
  51. pygsti/evotypes/stabilizer/effectreps.pyx +0 -4
  52. pygsti/evotypes/stabilizer/opreps.cp39-win_amd64.pyd +0 -0
  53. pygsti/evotypes/stabilizer/opreps.pyx +0 -4
  54. pygsti/evotypes/stabilizer/statereps.cp39-win_amd64.pyd +0 -0
  55. pygsti/evotypes/stabilizer/statereps.pyx +1 -5
  56. pygsti/evotypes/stabilizer/termreps.cp39-win_amd64.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-win_amd64.pyd +0 -0
  62. pygsti/evotypes/statevec/effectreps.pyx +1 -1
  63. pygsti/evotypes/statevec/opreps.cp39-win_amd64.pyd +0 -0
  64. pygsti/evotypes/statevec/opreps.pyx +2 -2
  65. pygsti/evotypes/statevec/statereps.cp39-win_amd64.pyd +0 -0
  66. pygsti/evotypes/statevec/statereps.pyx +1 -1
  67. pygsti/evotypes/statevec/termreps.cp39-win_amd64.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-win_amd64.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-win_amd64.pyd +0 -0
  87. pygsti/forwardsims/termforwardsim_calc_statevec.cp39-win_amd64.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-win_amd64.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
@@ -23,13 +23,14 @@ from pygsti.objectivefns.objectivefns import ModelDatasetCircuitsStore as _Model
23
23
  from pygsti.report import colormaps as _colormaps
24
24
  from pygsti.report import plothelpers as _ph
25
25
  from pygsti.report.figure import ReportFigure
26
- from pygsti.report.workspace import WorkspacePlot
26
+ from pygsti.report.workspace import WorkspacePlot, NotApplicable
27
27
  from pygsti import algorithms as _alg
28
28
  from pygsti import baseobjs as _baseobjs
29
29
  from pygsti.objectivefns import objectivefns as _objfns
30
30
  from pygsti.circuits.circuit import Circuit as _Circuit
31
31
  from pygsti.circuits.circuitstructure import PlaquetteGridCircuitStructure as _PlaquetteGridCircuitStructure, \
32
32
  GermFiducialPairPlaquette as _GermFiducialPairPlaquette
33
+ from pygsti.circuits.circuitlist import CircuitList as _CircuitList
33
34
  from pygsti.data import DataSet as _DataSet
34
35
 
35
36
  #Plotly v3 changes heirarchy of graph objects
@@ -379,9 +380,9 @@ def _summable_color_boxplot(sub_mxs, xlabels, ylabels, xlabel, ylabel,
379
380
 
380
381
  def sum_up_mx(mx):
381
382
  """ Sum up `mx` in a NAN-ignoring way """
382
- flat_mx = mx.flatten()
383
- if any([_np.isnan(x) for x in flat_mx]):
384
- if all([_np.isnan(x) for x in flat_mx]):
383
+ flat_mx = mx.ravel()
384
+ if _np.any(_np.isnan(flat_mx)):
385
+ if _np.all(_np.isnan(flat_mx)):
385
386
  return _np.nan
386
387
  # replace NaNs with zeros for purpose of summing (when there's at least one non-NaN)
387
388
  return sum(_np.nan_to_num(flat_mx))
@@ -529,6 +530,40 @@ def _create_hover_info_fn(circuit_structure, xvals, yvals, sum_up, addl_hover_su
529
530
  txt += "<br>%s: %s" % (lbl, str(addl_subMxs[iy][ix][iiy][iix]))
530
531
  return txt
531
532
  return hover_label_fn
533
+
534
+ def _create_hover_info_fn_circuit_list(circuit_structure, sum_up, addl_hover_submxs):
535
+
536
+ if sum_up:
537
+ pass
538
+ else:
539
+ if isinstance(circuit_structure, _CircuitList):
540
+ def hover_label_fn(val, i):
541
+ """ Standard hover labels """
542
+ #Note: in this case, we need to "flip" the iiy index because
543
+ # the matrices being plotted are flipped within _summable_color_boxplot(...)
544
+ if _np.isnan(val): return ""
545
+ ckt = circuit_structure[i].copy(editable=True)
546
+ ckt.factorize_repetitions_inplace()
547
+ txt = ckt.layerstr # note: *row* index = iiy
548
+ txt += ("<br>value: %g" % val)
549
+ for lbl, addl_subMxs in addl_hover_submxs.items():
550
+ txt += "<br>%s: %s" % (lbl, str(addl_subMxs[i]))
551
+ return txt
552
+
553
+ elif isinstance(circuit_structure, list) and all([isinstance(el, _CircuitList) for el in circuit_structure]):
554
+ def hover_label_fn(val, i, j):
555
+ """ Standard hover labels """
556
+ #Note: in this case, we need to "flip" the iiy index because
557
+ # the matrices being plotted are flipped within _summable_color_boxplot(...)
558
+ if _np.isnan(val): return ""
559
+ ckt = circuit_structure[i][j].copy(editable=True)
560
+ ckt.factorize_repetitions_inplace()
561
+ txt = ckt.layerstr # note: *row* index = iiy
562
+ txt += ("<br>value: %g" % val)
563
+ for lbl, addl_subMxs in addl_hover_submxs.items():
564
+ txt += "<br>%s: %s" % (lbl, str(addl_subMxs[i][j]))
565
+ return txt
566
+ return hover_label_fn
532
567
 
533
568
 
534
569
  def _circuit_color_boxplot(circuit_structure, sub_mxs, colormap,
@@ -662,42 +697,78 @@ def _circuit_color_scatterplot(circuit_structure, sub_mxs, colormap,
662
697
  plotly.Figure
663
698
  """
664
699
  g = circuit_structure
665
- xvals = g.used_xs
666
- yvals = g.used_ys
667
700
 
668
701
  if addl_hover_submxs is None:
669
702
  addl_hover_submxs = {}
670
703
 
671
704
  if hover_info:
672
- hover_info = _create_hover_info_fn(circuit_structure, xvals, yvals, sum_up, addl_hover_submxs)
673
-
705
+ if isinstance(g, _PlaquetteGridCircuitStructure):
706
+ hover_info = _create_hover_info_fn(circuit_structure, g.used_xs, g.used_ys, sum_up, addl_hover_submxs)
707
+ elif isinstance(g, _CircuitList) or (isinstance(g, list) and all([isinstance(el, _CircuitList) for el in g])):
708
+ hover_info = _create_hover_info_fn_circuit_list(circuit_structure, sum_up, addl_hover_submxs)
709
+
674
710
  xs = []; ys = []; texts = []
675
711
  gstrs = set() # to eliminate duplicate strings
676
- for ix, x in enumerate(g.used_xs):
677
- for iy, y in enumerate(g.used_ys):
678
- plaq = g.plaquette(x, y, empty_if_missing=True)
679
- if sum_up:
680
- if plaq.base not in gstrs:
681
- tot = sum([sub_mxs[iy][ix][iiy][iix] for iiy, iix, _ in plaq])
682
- xs.append(len(plaq.base)) # x-coord is len of *base* string
683
- ys.append(tot)
684
- gstrs.add(plaq.base)
685
- if hover_info:
686
- if callable(hover_info):
687
- texts.append(hover_info(tot, iy, ix))
688
- else:
689
- texts.append(str(tot))
712
+
713
+ if isinstance(g, _PlaquetteGridCircuitStructure):
714
+ for ix, x in enumerate(g.used_xs):
715
+ for iy, y in enumerate(g.used_ys):
716
+ plaq = g.plaquette(x, y, empty_if_missing=True)
717
+ if sum_up:
718
+ if plaq.base not in gstrs:
719
+ tot = sum([sub_mxs[iy][ix][iiy][iix] for iiy, iix, _ in plaq])
720
+ xs.append(len(plaq.base)) # x-coord is len of *base* string
721
+ ys.append(tot)
722
+ gstrs.add(plaq.base)
723
+ if hover_info:
724
+ if callable(hover_info):
725
+ texts.append(hover_info(tot, iy, ix))
726
+ else:
727
+ texts.append(str(tot))
728
+ else:
729
+ for iiy, iix, opstr in plaq:
730
+ if opstr in gstrs: continue # skip duplicates
731
+ xs.append(len(opstr))
732
+ ys.append(sub_mxs[iy][ix][iiy][iix])
733
+ gstrs.add(opstr)
734
+ if hover_info:
735
+ if callable(hover_info):
736
+ texts.append(hover_info(sub_mxs[iy][ix][iiy][iix], iy, ix, iiy, iix))
737
+ else:
738
+ texts.append(str(sub_mxs[iy][ix][iiy][iix]))
739
+ elif isinstance(g, _CircuitList):
740
+ for i, ckt in enumerate(g):
741
+ if ckt in gstrs:
742
+ continue
690
743
  else:
691
- for iiy, iix, opstr in plaq:
692
- if opstr in gstrs: continue # skip duplicates
693
- xs.append(len(opstr))
694
- ys.append(sub_mxs[iy][ix][iiy][iix])
695
- gstrs.add(opstr)
744
+ if sum_up:
745
+ pass
746
+ #TODO: Implement sum_up behavior mirroring that above.
747
+ gstrs.add(ckt)
748
+ ys.append(sub_mxs[i])
749
+ xs.append(len(ckt))
750
+ if hover_info:
751
+ if callable(hover_info):
752
+ texts.append(hover_info(sub_mxs[i], i))
753
+ else:
754
+ texts.append(str(sub_mxs[i]))
755
+ elif isinstance(g, list) and all([isinstance(el, _CircuitList) for el in g]):
756
+ for i, circuit_list in enumerate(g):
757
+ for j, ckt in enumerate(circuit_list):
758
+ if ckt in gstrs:
759
+ continue
760
+ else:
761
+ if sum_up:
762
+ pass
763
+ #TODO: Implement sum_up behavior mirroring that above.
764
+ gstrs.add(ckt)
765
+ ys.append(sub_mxs[i][j])
766
+ xs.append(len(ckt))
696
767
  if hover_info:
697
768
  if callable(hover_info):
698
- texts.append(hover_info(sub_mxs[iy][ix][iiy][iix], iy, ix, iiy, iix))
769
+ texts.append(hover_info(sub_mxs[i][j], i, j))
699
770
  else:
700
- texts.append(str(sub_mxs[iy][ix][iiy][iix]))
771
+ texts.append(str(sub_mxs[i][j]))
701
772
 
702
773
  #This GL version works, but behaves badly, sometimes failing to render...
703
774
  #trace = go.Scattergl(x=xs, y=ys, mode="markers",
@@ -768,17 +839,42 @@ def _circuit_color_histogram(circuit_structure, sub_mxs, colormap,
768
839
  plotly.Figure
769
840
  """
770
841
  g = circuit_structure
771
-
842
+
843
+ #For all of the fanciness below, this all essentially looks like it just produces
844
+ #a flattened list of all of the contents of sub_mxs, so we can still do that with the
845
+ #submx structures we get from using CircuitList objects.
772
846
  ys = [] # artificially add minval so
773
847
  gstrs = set() # to eliminate duplicate strings
774
- for ix, x in enumerate(g.used_xs):
775
- for iy, y in enumerate(g.used_ys):
776
- plaq = g.plaquette(x, y, empty_if_missing=True)
777
- #TODO: if sum_up then need to sum before appending...
778
- for iiy, iix, opstr in plaq:
779
- if opstr in gstrs: continue # skip duplicates
780
- ys.append(sub_mxs[iy][ix][iiy][iix])
781
- gstrs.add(opstr)
848
+
849
+ if isinstance(g, _PlaquetteGridCircuitStructure):
850
+ for ix, x in enumerate(g.used_xs):
851
+ for iy, y in enumerate(g.used_ys):
852
+ plaq = g.plaquette(x, y, empty_if_missing=True)
853
+ #TODO: if sum_up then need to sum before appending...
854
+ for iiy, iix, opstr in plaq:
855
+ if opstr in gstrs: continue # skip duplicates
856
+ ys.append(sub_mxs[iy][ix][iiy][iix])
857
+ gstrs.add(opstr)
858
+
859
+ elif isinstance(g, _CircuitList):
860
+ for i, ckt in enumerate(g):
861
+ if ckt in gstrs:
862
+ continue
863
+ else:
864
+ gstrs.add(ckt)
865
+ ys.append(sub_mxs[i])
866
+
867
+ elif isinstance(g, list) and all([isinstance(el, _CircuitList) for el in g]):
868
+ for i, circuit_list in enumerate(g):
869
+ for j, ckt in enumerate(circuit_list):
870
+ if ckt in gstrs:
871
+ continue
872
+ else:
873
+ gstrs.add(ckt)
874
+ ys.append(sub_mxs[i][j])
875
+ else:
876
+ raise ValueError('Can only handle PlaquetteGridCircuitStructure, CircuitList or lists of CircuitList objects at present.')
877
+
782
878
  if len(ys) == 0: ys = [0] # case of no data - dummy so max works below
783
879
 
784
880
  minval = 0
@@ -1607,19 +1703,6 @@ class ColorBoxPlot(WorkspacePlot):
1607
1703
  dataset = mdc_store.dataset
1608
1704
  model = mdc_store.model
1609
1705
 
1610
- #DEBUG: for checking
1611
- #def _addl_mx_fn_chk(plaq,x,y):
1612
- # gsplaq_ds = plaq.expand_aliases(dataset)
1613
- # spamlabels = model.get_spam_labels()
1614
- # cntMxs = _ph.total_count_matrix( gsplaq_ds, dataset)[None,:,:]
1615
- # probMxs = _ph.probability_matrices( plaq, model, spamlabels,
1616
- # probs_precomp_dict)
1617
- # freqMxs = _ph.frequency_matrices( gsplaq_ds, dataset, spamlabels)
1618
- # logLMxs = _tools.two_delta_logl_term( cntMxs, probMxs, freqMxs, 1e-4)
1619
- # return logLMxs.sum(axis=0) # sum over spam labels
1620
-
1621
- # End "Additional sub-matrix" functions
1622
-
1623
1706
  if not isinstance(plottypes, (list, tuple)):
1624
1707
  plottypes = [plottypes]
1625
1708
 
@@ -1641,7 +1724,6 @@ class ColorBoxPlot(WorkspacePlot):
1641
1724
 
1642
1725
  if isinstance(objfn, (_objfns.PoissonPicDeltaLogLFunction, _objfns.DeltaLogLFunction)):
1643
1726
  terms *= 2.0 # show 2 * deltaLogL values, not just deltaLogL
1644
-
1645
1727
  if isinstance(objfn, _objfns.TVDFunction):
1646
1728
  colormapType = "blueseq"
1647
1729
  else:
@@ -1649,16 +1731,34 @@ class ColorBoxPlot(WorkspacePlot):
1649
1731
  linlog_color = "red"
1650
1732
 
1651
1733
  ytitle = objfn.description # "chi<sup>2</sup>" OR "2 log(L ratio)"
1652
-
1653
- mx_fn = _mx_fn_from_elements # use a *global* function so cache can tell it's the same
1734
+
1735
+ if isinstance(circuits, _PlaquetteGridCircuitStructure):
1736
+ mx_fn = _mx_fn_from_elements # use a *global* function so cache can tell it's the same
1737
+ elif isinstance(circuits, _CircuitList):
1738
+ mx_fn = _mx_fn_from_elements_circuit_list
1739
+ elif isinstance(circuits, list) and all([isinstance(el, _CircuitList) for el in circuits]):
1740
+ mx_fn = _mx_fn_from_elements_circuit_list
1741
+
1654
1742
  extra_arg = (terms, objfn.layout, "sum")
1655
-
1656
- # (function, extra_arg) tuples
1657
- addl_hover_info_fns['outcomes'] = (_addl_mx_fn_outcomes, objfn.layout)
1658
- addl_hover_info_fns['p'] = (_mx_fn_from_elements, (objfn.probs, objfn.layout, "%.5g"))
1659
- addl_hover_info_fns['f'] = (_mx_fn_from_elements, (objfn.freqs, objfn.layout, "%.5g"))
1660
- addl_hover_info_fns['counts'] = (_mx_fn_from_elements, (objfn.counts, objfn.layout, "%d"))
1661
-
1743
+
1744
+ if isinstance(circuits, _PlaquetteGridCircuitStructure):
1745
+ # (function, extra_arg) tuples
1746
+ addl_hover_info_fns['outcomes'] = (_addl_mx_fn_outcomes, objfn.layout)
1747
+ addl_hover_info_fns['p'] = (_mx_fn_from_elements, (objfn.probs, objfn.layout, "%.5g"))
1748
+ addl_hover_info_fns['f'] = (_mx_fn_from_elements, (objfn.freqs, objfn.layout, "%.5g"))
1749
+ addl_hover_info_fns['counts'] = (_mx_fn_from_elements, (objfn.counts, objfn.layout, "%d"))
1750
+ elif isinstance(circuits, _CircuitList):
1751
+ # (function, extra_arg) tuples
1752
+ addl_hover_info_fns['outcomes'] = (_addl_mx_fn_outcomes_circuit_list, objfn.layout)
1753
+ addl_hover_info_fns['p'] = (_mx_fn_from_elements_circuit_list, (objfn.probs, objfn.layout, "%.5g"))
1754
+ addl_hover_info_fns['f'] = (_mx_fn_from_elements_circuit_list, (objfn.freqs, objfn.layout, "%.5g"))
1755
+ addl_hover_info_fns['counts'] = (_mx_fn_from_elements_circuit_list, (objfn.counts, objfn.layout, "%d"))
1756
+ elif isinstance(circuits, list) and all([isinstance(el, _CircuitList) for el in circuits]):
1757
+ addl_hover_info_fns['outcomes'] = (_addl_mx_fn_outcomes_circuit_list, objfn.layout)
1758
+ addl_hover_info_fns['p'] = (_mx_fn_from_elements_circuit_list, (objfn.probs, objfn.layout, "%.5g"))
1759
+ addl_hover_info_fns['f'] = (_mx_fn_from_elements_circuit_list, (objfn.freqs, objfn.layout, "%.5g"))
1760
+ addl_hover_info_fns['counts'] = (_mx_fn_from_elements_circuit_list, (objfn.counts, objfn.layout, "%d"))
1761
+
1662
1762
  elif ptyp == "blank":
1663
1763
  colormapType = "trivial"
1664
1764
  ytitle = ""
@@ -1777,23 +1877,116 @@ class ColorBoxPlot(WorkspacePlot):
1777
1877
  colormapType = submatrices.get(ptyp + ".colormap", "seq")
1778
1878
  else:
1779
1879
  raise ValueError("Invalid plot type: %s" % ptyp)
1780
-
1781
- circuit_struct = _PlaquetteGridCircuitStructure.cast(circuits) # , dataset?
1782
-
1880
+
1783
1881
  #TODO: propagate mdc_store down into compute_sub_mxs?
1784
1882
  if (submatrices is not None) and ptyp in submatrices:
1785
1883
  subMxs = submatrices[ptyp] # "custom" type -- all mxs precomputed by user
1786
- else:
1787
- subMxs = self._ccompute(_ph._compute_sub_mxs, circuit_struct, model, mx_fn, dataset, extra_arg)
1788
1884
 
1789
- addl_hover_info = _collections.OrderedDict()
1790
- for lbl, (addl_mx_fn, addl_extra_arg) in addl_hover_info_fns.items():
1791
- if (submatrices is not None) and lbl in submatrices:
1792
- addl_subMxs = submatrices[lbl] # ever useful?
1885
+ #some of the branches below rely on circuit_struct being defined, which is previously
1886
+ #wasn't when hitting this condition on the if statement, so add those definitions here.
1887
+ #also need to built the addl_hover_info as well, based on circuit_struct.
1888
+ if isinstance(circuits, _PlaquetteGridCircuitStructure):
1889
+ circuit_struct = circuits
1890
+
1891
+ addl_hover_info = _collections.OrderedDict()
1892
+ for lbl, (addl_mx_fn, addl_extra_arg) in addl_hover_info_fns.items():
1893
+ if (submatrices is not None) and lbl in submatrices:
1894
+ addl_subMxs = submatrices[lbl] # ever useful?
1895
+ else:
1896
+ addl_subMxs = self._ccompute(_ph._compute_sub_mxs, circuit_struct, model,
1897
+ addl_mx_fn, dataset, addl_extra_arg)
1898
+ addl_hover_info[lbl] = addl_subMxs
1899
+
1900
+ elif isinstance(circuits, _CircuitList):
1901
+ circuit_struct = [circuits]
1902
+
1903
+ addl_hover_info = _collections.OrderedDict()
1904
+ for lbl, (addl_mx_fn, addl_extra_arg) in addl_hover_info_fns.items():
1905
+ if (submatrices is not None) and lbl in submatrices:
1906
+ addl_subMxs = submatrices[lbl] # ever useful?
1907
+ else:
1908
+ addl_subMxs = self._ccompute(_ph._compute_sub_mxs_circuit_list, circuit_struct, model,
1909
+ addl_mx_fn, dataset, addl_extra_arg)
1910
+ addl_hover_info[lbl] = addl_subMxs
1911
+
1912
+ elif isinstance(circuits, list) and all([isinstance(el, _CircuitList) for el in circuits]):
1913
+ circuit_struct = circuits
1914
+
1915
+ addl_hover_info = _collections.OrderedDict()
1916
+ for lbl, (addl_mx_fn, addl_extra_arg) in addl_hover_info_fns.items():
1917
+ if (submatrices is not None) and lbl in submatrices:
1918
+ addl_subMxs = submatrices[lbl] # ever useful?
1919
+ else:
1920
+ addl_subMxs = self._ccompute(_ph._compute_sub_mxs_circuit_list, circuit_struct, model,
1921
+ addl_mx_fn, dataset, addl_extra_arg)
1922
+ addl_hover_info[lbl] = addl_subMxs
1923
+
1924
+ #Otherwise fall-back to the old casting behavior and proceed
1793
1925
  else:
1794
- addl_subMxs = self._ccompute(_ph._compute_sub_mxs, circuit_struct, model,
1795
- addl_mx_fn, dataset, addl_extra_arg)
1796
- addl_hover_info[lbl] = addl_subMxs
1926
+ circuit_struct = _PlaquetteGridCircuitStructure.cast(circuits)
1927
+ addl_hover_info = _collections.OrderedDict()
1928
+ for lbl, (addl_mx_fn, addl_extra_arg) in addl_hover_info_fns.items():
1929
+ if (submatrices is not None) and lbl in submatrices:
1930
+ addl_subMxs = submatrices[lbl] # ever useful?
1931
+ else:
1932
+ addl_subMxs = self._ccompute(_ph._compute_sub_mxs, circuit_struct, model,
1933
+ addl_mx_fn, dataset, addl_extra_arg)
1934
+ addl_hover_info[lbl] = addl_subMxs
1935
+
1936
+ elif isinstance(circuits, _PlaquetteGridCircuitStructure):
1937
+ circuit_struct= circuits
1938
+ subMxs = self._ccompute(_ph._compute_sub_mxs, circuit_struct, model, mx_fn, dataset, extra_arg)
1939
+
1940
+ addl_hover_info = _collections.OrderedDict()
1941
+ for lbl, (addl_mx_fn, addl_extra_arg) in addl_hover_info_fns.items():
1942
+ if (submatrices is not None) and lbl in submatrices:
1943
+ addl_subMxs = submatrices[lbl] # ever useful?
1944
+ else:
1945
+ addl_subMxs = self._ccompute(_ph._compute_sub_mxs, circuit_struct, model,
1946
+ addl_mx_fn, dataset, addl_extra_arg)
1947
+ addl_hover_info[lbl] = addl_subMxs
1948
+
1949
+ #Add in alternative logic for constructing sub-matrices when we have either a CircuitList or a
1950
+ #list of circuit lists:
1951
+ elif isinstance(circuits, _CircuitList):
1952
+ circuit_struct= [circuits]
1953
+ subMxs = self._ccompute(_ph._compute_sub_mxs_circuit_list, circuit_struct, model, mx_fn, dataset, extra_arg)
1954
+
1955
+ addl_hover_info = _collections.OrderedDict()
1956
+ for lbl, (addl_mx_fn, addl_extra_arg) in addl_hover_info_fns.items():
1957
+ if (submatrices is not None) and lbl in submatrices:
1958
+ addl_subMxs = submatrices[lbl] # ever useful?
1959
+ else:
1960
+ addl_subMxs = self._ccompute(_ph._compute_sub_mxs_circuit_list, circuit_struct, model,
1961
+ addl_mx_fn, dataset, addl_extra_arg)
1962
+ addl_hover_info[lbl] = addl_subMxs
1963
+
1964
+ elif isinstance(circuits, list) and all([isinstance(el, _CircuitList) for el in circuits]):
1965
+ circuit_struct= circuits
1966
+ subMxs = self._ccompute(_ph._compute_sub_mxs_circuit_list, circuit_struct, model, mx_fn, dataset, extra_arg)
1967
+
1968
+ addl_hover_info = _collections.OrderedDict()
1969
+ for lbl, (addl_mx_fn, addl_extra_arg) in addl_hover_info_fns.items():
1970
+ if (submatrices is not None) and lbl in submatrices:
1971
+ addl_subMxs = submatrices[lbl] # ever useful?
1972
+ else:
1973
+ addl_subMxs = self._ccompute(_ph._compute_sub_mxs_circuit_list, circuit_struct, model,
1974
+ addl_mx_fn, dataset, addl_extra_arg)
1975
+ addl_hover_info[lbl] = addl_subMxs
1976
+
1977
+ #Otherwise fall-back to the old casting behavior and proceed
1978
+ else:
1979
+ circuit_struct = _PlaquetteGridCircuitStructure.cast(circuits) # , dataset?
1980
+ subMxs = self._ccompute(_ph._compute_sub_mxs, circuit_struct, model, mx_fn, dataset, extra_arg)
1981
+
1982
+ addl_hover_info = _collections.OrderedDict()
1983
+ for lbl, (addl_mx_fn, addl_extra_arg) in addl_hover_info_fns.items():
1984
+ if (submatrices is not None) and lbl in submatrices:
1985
+ addl_subMxs = submatrices[lbl] # ever useful?
1986
+ else:
1987
+ addl_subMxs = self._ccompute(_ph._compute_sub_mxs, circuit_struct, model,
1988
+ addl_mx_fn, dataset, addl_extra_arg)
1989
+ addl_hover_info[lbl] = addl_subMxs
1797
1990
 
1798
1991
  if colormapType == "linlog":
1799
1992
  if dataset is None:
@@ -1827,9 +2020,17 @@ class ColorBoxPlot(WorkspacePlot):
1827
2020
 
1828
2021
  elif colormapType in ("seq", "revseq", "blueseq", "redseq"):
1829
2022
  if len(subMxs) > 0:
1830
- max_abs = max([_np.max(_np.abs(_np.nan_to_num(subMxs[iy][ix])))
1831
- for ix in range(len(circuit_struct.used_xs))
1832
- for iy in range(len(circuit_struct.used_ys))])
2023
+ if isinstance(circuit_struct, _PlaquetteGridCircuitStructure):
2024
+ max_abs = max([_np.max(_np.abs(_np.nan_to_num(subMxs[iy][ix])))
2025
+ for ix in range(len(circuit_struct.used_xs))
2026
+ for iy in range(len(circuit_struct.used_ys))])
2027
+ #circuit_struct logic above should mean that we always have at least a length 1 list of
2028
+ #CircuitList objects if not a plaquette circuit structure by this point.
2029
+ elif isinstance(circuit_struct, list) and all([isinstance(el, _CircuitList) for el in circuit_struct]):
2030
+ max_abs = max([_np.max(_np.abs(_np.nan_to_num(subMxs[i][j])))
2031
+ for i, ckt_list in enumerate(circuit_struct)
2032
+ for j in range(len(ckt_list))])
2033
+
1833
2034
  else: max_abs = 0
1834
2035
  if max_abs == 0: max_abs = 1e-6 # pick a nonzero value if all entries are zero or nan
1835
2036
  if colormapType == "seq": color = "whiteToBlack"
@@ -1841,7 +2042,15 @@ class ColorBoxPlot(WorkspacePlot):
1841
2042
  else: assert(False), "Internal logic error" # pragma: no cover
1842
2043
 
1843
2044
  if typ == "boxes":
1844
- newfig = _circuit_color_boxplot(circuit_struct, subMxs, colormap,
2045
+ if not isinstance(circuit_struct, _PlaquetteGridCircuitStructure):
2046
+ #if not a plaquette structure then maybe try returning a NotApplicable object
2047
+ #for the figure?
2048
+ return NotApplicable(self.ws)
2049
+ else:
2050
+ #I am expecting this cast won't do anything at the moment, but
2051
+ #maybe down the line it will.
2052
+ circuit_struct= _PlaquetteGridCircuitStructure.cast(circuits)
2053
+ newfig = _circuit_color_boxplot(circuit_struct, subMxs, colormap,
1845
2054
  colorbar, box_labels, prec,
1846
2055
  hover_info, sum_up, invert,
1847
2056
  scale, bgcolor, addl_hover_info)
@@ -1897,16 +2106,33 @@ class ColorBoxPlot(WorkspacePlot):
1897
2106
 
1898
2107
  #Helper function for ColorBoxPlot matrix computation
1899
2108
  def _mx_fn_from_elements(plaq, x, y, extra):
1900
- return plaq.elementvec_to_matrix(extra[0], extra[1], mergeop=extra[2])
1901
-
2109
+ return plaq.elementvec_to_array(extra[0], extra[1], mergeop=extra[2])
2110
+
2111
+ #modified version of the above meant for working with circuit lists
2112
+ def _mx_fn_from_elements_circuit_list(circuit_list, extra):
2113
+ #Based on the convention above in the ColorBoxPlot code it looks likelihood
2114
+ #extra[0] is the thing we want to index into, extra[1] is the layout and extra[2]
2115
+ #is something called the merge op, which indicated how to combine the elements of extra[0]
2116
+ #for each circuit in the circuit_list
2117
+ if isinstance(circuit_list, _CircuitList):
2118
+ pass
2119
+ elif isinstance(circuit_list, list) and all([isinstance(el, _CircuitList) for el in circuit_list]):
2120
+ circuit_list = _CircuitList.cast(circuit_list)
2121
+ else:
2122
+ msg = 'Invalid type. _mx_fn_from_elements_circuit_list is only presently implemented for CircuitList'\
2123
+ +'objects and lists of Circuit objects.'
2124
+ raise ValueError(msg)
1902
2125
 
2126
+ return circuit_list.elementvec_to_array(extra[0], extra[1], mergeop=extra[2])
2127
+
1903
2128
  def _mx_fn_blank(plaq, x, y, unused):
1904
2129
  return _np.nan * _np.zeros((plaq.num_rows, plaq.num_cols), 'd')
1905
2130
 
1906
2131
 
1907
2132
  def _mx_fn_errorrate(plaq, x, y, direct_gst_models): # error rate as 1x1 matrix which we have plotting function sum up
1908
2133
  base_circuit = plaq.base if isinstance(plaq, _GermFiducialPairPlaquette) \
1909
- else _Circuit(())
2134
+ else _Circuit((), line_labels=list(direct_gst_models.keys())[0].line_labels) #Taking the line labels from the first circuit in direct_gst_models will probably work
2135
+ #most of the time. TODO: Cook up a better scheme.
1910
2136
  return _np.array([[_ph.small_eigenvalue_err_rate(base_circuit, direct_gst_models)]])
1911
2137
 
1912
2138
 
@@ -1939,12 +2165,6 @@ def _mx_fn_driftpv(plaq, x, y, instabilityanalyzertuple):
1939
2165
  def _mx_fn_drifttvd(plaq, x, y, instabilityanalyzertuple):
1940
2166
  return _ph.drift_maxtvd_matrices(plaq, instabilityanalyzertuple)
1941
2167
 
1942
- # future: delete this, or update it and added it back in.
1943
- # def _mx_fn_driftpwr(plaq, x, y, driftresults):
1944
- # return _ph.drift_maxpower_matrices(plaq, driftresults)
1945
-
1946
- # Begin "Additional sub-matrix" functions for adding more info to hover text
1947
-
1948
2168
 
1949
2169
  def _outcome_to_str(x): # same function as in writers.py
1950
2170
  if isinstance(x, str): return x
@@ -1957,6 +2177,15 @@ def _addl_mx_fn_outcomes(plaq, x, y, layout):
1957
2177
  slmx[i, j] = ", ".join([_outcome_to_str(ol) for ol in layout.outcomes(opstr)])
1958
2178
  return slmx
1959
2179
 
2180
+ #modified version of the above function meant to work for CircuitList objects
2181
+ def _addl_mx_fn_outcomes_circuit_list(circuit_list, layout):
2182
+ slmx = _np.empty(len(circuit_list), dtype=_np.object_)
2183
+ for i,ckt in enumerate(circuit_list):
2184
+ slmx[i] = ", ".join([_outcome_to_str(ol) for ol in layout.outcomes(ckt)])
2185
+ return slmx
2186
+
2187
+
2188
+
1960
2189
 
1961
2190
  class GateMatrixPlot(WorkspacePlot):
1962
2191
  """
@@ -2318,8 +2547,8 @@ class PolarEigenvaluePlot(WorkspacePlot):
2318
2547
  for i, evals in enumerate(evals_list):
2319
2548
  color = colors[i] if (colors is not None) else "black"
2320
2549
  trace = go.Scatterpolar(
2321
- r=list(_np.absolute(evals).flat),
2322
- theta=list(_np.angle(evals).flatten() * (180.0 / _np.pi)),
2550
+ r=list(_np.absolute(evals).ravel()),
2551
+ theta=list(_np.angle(evals).ravel() * (180.0 / _np.pi)),
2323
2552
  mode='markers',
2324
2553
  marker=dict(
2325
2554
  color=color,
@@ -2339,8 +2568,8 @@ class PolarEigenvaluePlot(WorkspacePlot):
2339
2568
  if amp is not None:
2340
2569
  amp_evals = evals**amp
2341
2570
  trace = go.Scatterpolar(
2342
- r=list(_np.absolute(amp_evals).flat),
2343
- theta=list(_np.angle(amp_evals).flatten() * (180.0 / _np.pi)),
2571
+ r=list(_np.absolute(amp_evals).ravel()),
2572
+ theta=list(_np.angle(amp_evals).ravel() * (180.0 / _np.pi)),
2344
2573
  showlegend=False,
2345
2574
  mode='markers',
2346
2575
  marker=dict(
@@ -2650,16 +2879,17 @@ class ChoiEigenvalueBarPlot(WorkspacePlot):
2650
2879
  errbars, scale)
2651
2880
 
2652
2881
  def _create(self, evals, errbars, scale):
2653
-
2882
+ if errbars is not None:
2883
+ flat_errbars = errbars.ravel()
2654
2884
  HOVER_PREC = 7
2655
2885
  xs = list(range(evals.size))
2656
- ys = []; colors = []; texts = []
2657
- for i, ev in enumerate(evals.flatten()):
2886
+ ys, colors, texts = [], [], []
2887
+ for i, ev in enumerate(evals.ravel()):
2658
2888
  ys.append(abs(ev.real))
2659
2889
  colors.append('rgb(200,200,200)' if ev.real > 0 else 'red')
2660
2890
  if errbars is not None:
2661
2891
  texts.append("%g +/- %g" % (round(ev.real, HOVER_PREC),
2662
- round(errbars.flatten()[i].real, HOVER_PREC)))
2892
+ round(flat_errbars[i].real, HOVER_PREC)))
2663
2893
  else:
2664
2894
  texts.append("%g" % round(ev.real, HOVER_PREC))
2665
2895
 
@@ -2785,13 +3015,13 @@ class GramMatrixBarPlot(WorkspacePlot):
2785
3015
 
2786
3016
  xs = list(range(svals.size))
2787
3017
  trace1 = go.Bar(
2788
- x=xs, y=list(svals.flatten()),
3018
+ x=xs, y=list(svals.ravel()),
2789
3019
  marker=dict(color="blue"),
2790
3020
  hoverinfo='y',
2791
3021
  name="from Data"
2792
3022
  )
2793
3023
  trace2 = go.Bar(
2794
- x=xs, y=list(target_svals.flatten()),
3024
+ x=xs, y=list(target_svals.ravel()),
2795
3025
  marker=dict(color="black"),
2796
3026
  hoverinfo='y',
2797
3027
  name="from Target"
@@ -2802,7 +3032,8 @@ class GramMatrixBarPlot(WorkspacePlot):
2802
3032
  ymax = max(_np.max(svals), _np.max(target_svals))
2803
3033
  ymin = max(ymin, 1e-8) # prevent lower y-limit from being riduculously small
2804
3034
  else:
2805
- ymin = 0.1; ymax = 1.0 # just pick some values for empty plot
3035
+ ymin = 0.1
3036
+ ymax = 1.0 # just pick some values for empty plot
2806
3037
 
2807
3038
  data = [trace1, trace2]
2808
3039
  layout = go.Layout(
@@ -3705,411 +3936,3 @@ class RandomizedBenchmarkingPlot(WorkspacePlot):
3705
3936
  #reverse order of data so z-ordering is nicer
3706
3937
  return ReportFigure(go.Figure(data=list(data), layout=layout),
3707
3938
  None, pythonVal)
3708
-
3709
-
3710
- #This older version on an RB decay plot contained a lot more theory detail
3711
- # compared with the current one - so we'll keep it around (commented out)
3712
- # in case we want to steal/revive pieces of it in the future.
3713
- #class OLDRandomizedBenchmarkingPlot(WorkspacePlot):
3714
- # """ Plot of RB Decay curve """
3715
- # def __init__(self, ws, rb_r,xlim=None, ylim=None,
3716
- # fit='standard', Magesan_zeroth=False, Magesan_first=False,
3717
- # exact_decay=False,L_matrix_decay=False, Magesan_zeroth_SEB=False,
3718
- # Magesan_first_SEB=False, L_matrix_decay_SEB=False,mdl=False,
3719
- # target_model=False,group=False, group_to_model=None, norm='1to1', legend=True,
3720
- # title='Randomized Benchmarking Decay', scale=1.0):
3721
- # """
3722
- # Plot RB decay curve, as a function of some the sequence length
3723
- # computed using the `gstyp` gate-label-set.
3724
- #
3725
- # Parameters
3726
- # ----------
3727
- # rb_r : RBResults
3728
- # The RB results object containing all the relevant RB data.
3729
- #
3730
- # gstyp : str, optional
3731
- # The gate-label-set specifying which translation (i.e. strings with
3732
- # which operation labels) to use when computing sequence lengths.
3733
- #
3734
- # xlim : tuple, optional
3735
- # The x-range as (xmin,xmax).
3736
- #
3737
- # ylim : tuple, optional
3738
- # The y-range as (ymin,ymax).
3739
- #
3740
- # save_fig_path : str, optional
3741
- # If not None, the filename where the resulting plot should be saved.
3742
- #
3743
- # fitting : str, optional
3744
- # Allowed values are 'standard', 'first order' or 'all'. Specifies
3745
- # whether the zeroth or first order fitting model results are plotted,
3746
- # or both.
3747
- #
3748
- # Magesan_zeroth : bool, optional
3749
- # If True, plots the decay predicted by the 'zeroth order' theory of Magesan
3750
- # et al. PRA 85 042311 2012. Requires mdl and target_model to be specified.
3751
- #
3752
- # Magesan_first : bool, optional
3753
- # If True, plots the decay predicted by the 'first order' theory of Magesan
3754
- # et al. PRA 85 042311 2012. Requires mdl and target_model to be specified.
3755
- #
3756
- # Magesan_zeroth_SEB : bool, optional
3757
- # If True, plots the systematic error bound for the 'zeroth order' theory
3758
- # predicted decay. This is the region around the zeroth order decay in which
3759
- # the exact RB average survival probabilities are guaranteed to fall.
3760
- #
3761
- # Magesan_first_SEB : bool, optional
3762
- # As above, but for 'first order' theory.
3763
- #
3764
- # exact_decay : bool, optional
3765
- # If True, plots the exact RB decay, as predicted by the 'R matrix' theory
3766
- # of arXiv:1702.01853. Requires mdl and group to be specified
3767
- #
3768
- # L_matrix_decay : bool, optional
3769
- # If True, plots the RB decay, as predicted by the approximate 'L matrix'
3770
- # theory of arXiv:1702.01853. Requires mdl and target_model to be specified.
3771
- #
3772
- # L_matrix_decay_SEB : bool, optional
3773
- # If True, plots the systematic error bound for approximate 'L matrix'
3774
- # theory of arXiv:1702.01853. This is the region around predicted decay
3775
- # in which the exact RB average survival probabilities are guaranteed
3776
- # to fall.
3777
- #
3778
- # mdl : model, optional
3779
- # Required, if plotting any of the theory decays. The model for which
3780
- # these decays should be plotted for.
3781
- #
3782
- # target_model : Model, optional
3783
- # Required, if plotting certain theory decays. The target model for which
3784
- # these decays should be plotted for.
3785
- #
3786
- # group : MatrixGroup, optional
3787
- # Required, if plotting R matrix theory decay. The matrix group that mdl
3788
- # is an implementation of.
3789
- #
3790
- # group_to_model : dict, optional
3791
- # If not None, a dictionary that maps labels of group elements to labels
3792
- # of mdl. Only used if subset_sampling is not None. If subset_sampling is
3793
- # not None and the mdl and group elements have the same labels, this dictionary
3794
- # is not required. Otherwise it is necessary.
3795
- #
3796
- # norm : str, optional
3797
- # The norm used for calculating the Magesan theory bounds.
3798
- #
3799
- # legend : bool, optional
3800
- # Specifies whether a legend is added to the graph
3801
- #
3802
- # title : str, optional
3803
- # Specifies a title for the graph
3804
- #
3805
- # Returns
3806
- # -------
3807
- # None
3808
- # """
3809
- # # loc : str, optional
3810
- # # Specifies the location of the legend.
3811
- # super(RandomizedBenchmarkingPlot,self).__init__(
3812
- # ws, self._create, rb_r, xlim, ylim, fit, Magesan_zeroth,
3813
- # Magesan_first, exact_decay, L_matrix_decay, Magesan_zeroth_SEB,
3814
- # Magesan_first_SEB, L_matrix_decay_SEB, mdl, target_model, group,
3815
- # group_to_model, norm, legend, title, scale)
3816
- #
3817
- # def _create(self, rb_r, xlim, ylim, fit, Magesan_zeroth,
3818
- # Magesan_first, exact_decay, L_matrix_decay, Magesan_zeroth_SEB,
3819
- # Magesan_first_SEB, L_matrix_decay_SEB, mdl, target_model, group,
3820
- # group_to_model, norm, legend, title, scale):
3821
- #
3822
- # from ..extras.rb import rbutils as _rbutils
3823
- # #TODO: maybe move the computational/fitting part of this function
3824
- # # back to the RBResults object to reduce the logic (and dependence
3825
- # # on rbutils) here.
3826
- #
3827
- # #newplot = _plt.figure(figsize=(8, 4))
3828
- # #newplotgca = newplot.gca()
3829
- #
3830
- # # Note: minus one to get xdata that discounts final Clifford-inverse
3831
- # xdata = _np.asarray(rb_r.results['lengths']) - 1
3832
- # ydata = _np.asarray(rb_r.results['successes'])
3833
- # A = rb_r.results['A']
3834
- # B = rb_r.results['B']
3835
- # f = rb_r.results['f']
3836
- # if fit == 'first order':
3837
- # C = rb_r.results['C']
3838
- # pre_avg = rb_r.pre_avg
3839
- #
3840
- # if (Magesan_zeroth_SEB is True) and (Magesan_zeroth is False):
3841
- # print("As Magesan_zeroth_SEB is True, Setting Magesan_zeroth to True\n")
3842
- # Magesan_zeroth = True
3843
- # if (Magesan_first_SEB is True) and (Magesan_first is False):
3844
- # print("As Magesan_first_SEB is True, Setting Magesan_first to True\n")
3845
- # Magesan_first = True
3846
- #
3847
- # if (Magesan_zeroth is True) or (Magesan_first is True):
3848
- # if (mdl is False) or (target_model is False):
3849
- # raise ValueError("To plot Magesan et al theory decay curves a model" +
3850
- # " and a target model is required.")
3851
- # else:
3852
- # MTP = _rbutils.Magesan_theory_parameters(mdl, target_model,
3853
- # success_outcomelabel=rb_r.success_outcomelabel,
3854
- # norm=norm,d=rb_r.d)
3855
- # f_an = MTP['p']
3856
- # A_an = MTP['A']
3857
- # B_an = MTP['B']
3858
- # A1_an = MTP['A1']
3859
- # B1_an = MTP['B1']
3860
- # C1_an = MTP['C1']
3861
- # delta = MTP['delta']
3862
- #
3863
- # if exact_decay is True:
3864
- # if (mdl is False) or (group is False):
3865
- # raise ValueError("To plot the exact decay curve a model" +
3866
- # " and the target group are required.")
3867
- # else:
3868
- # mvalues,ASPs = _rbutils.exact_rb_asps(mdl,group,max(xdata),m_min=1,m_step=1,
3869
- # d=rb_r.d, group_to_model=group_to_model,
3870
- # success_outcomelabel=rb_r.success_outcomelabel)
3871
- #
3872
- # if L_matrix_decay is True:
3873
- # if (mdl is False) or (target_model is False):
3874
- # raise ValueError("To plot the L matrix theory decay curve a model" +
3875
- # " and a target model is required.")
3876
- # else:
3877
- # mvalues, LM_ASPs, LM_ASPs_SEB_lower, LM_ASPs_SEB_upper = \
3878
- # _rbutils.L_matrix_asps(mdl,target_model,max(xdata),m_min=1,m_step=1,d=rb_r.d,
3879
- # success_outcomelabel=rb_r.success_outcomelabel, error_bounds=True)
3880
- #
3881
- # xlabel = 'Sequence length'
3882
- #
3883
- # data = [] # list of traces
3884
- # data.append( go.Scatter(
3885
- # x = xdata, y = ydata,
3886
- # mode = 'markers',
3887
- # marker = dict(
3888
- # color = "rgb(0,0,0)",
3889
- # size = 6 if pre_avg else 3
3890
- # ),
3891
- # name = 'Averaged RB data' if pre_avg else 'RB data',
3892
- # ))
3893
- #
3894
- # if fit=='standard' or fit=='first order':
3895
- # fit_label_1='Fit'
3896
- # fit_label_2='Fit'
3897
- # color2 = "black"
3898
- #
3899
- # theory_color2 = "green"
3900
- # theory_fill2 = "rgba(0,128,0,0.1)"
3901
- # if Magesan_zeroth is True and Magesan_first is True:
3902
- # theory_color2 = "magenta"
3903
- # theory_fill2 = "rgba(255,0,255,0.1)"
3904
- #
3905
- # if fit=='standard':
3906
- # data.append( go.Scatter(
3907
- # x = _np.arange(max(xdata)),
3908
- # y = _rbutils.standard_fit_function(_np.arange(max(xdata)),A,B,f),
3909
- # mode = 'lines',
3910
- # line = dict(width=1, color="black"),
3911
- # name = fit_label_1,
3912
- # showlegend=legend,
3913
- # ))
3914
- #
3915
- # if fit=='first order':
3916
- # data.append( go.Scatter(
3917
- # x = _np.arange(max(xdata)),
3918
- # y = _rbutils.first_order_fit_function(_np.arange(max(xdata)),A,B,C,f),
3919
- # mode = 'lines',
3920
- # line = dict(width=1, color=color2),
3921
- # name = fit_label_2,
3922
- # showlegend=legend,
3923
- # ))
3924
- #
3925
- # if Magesan_zeroth is True:
3926
- # data.append( go.Scatter(
3927
- # x = _np.arange(max(xdata)),
3928
- # y = _rbutils.standard_fit_function(_np.arange(max(xdata)),A_an,B_an,f_an),
3929
- # mode = 'lines',
3930
- # line = dict(width=2, color="green", dash='dash'),
3931
- # name = '0th order theory',
3932
- # showlegend=legend,
3933
- # ))
3934
- #
3935
- # if Magesan_zeroth_SEB is True:
3936
- # data.append( go.Scatter(
3937
- # x = _np.arange(max(xdata)),
3938
- # y = _rbutils.seb_upper(
3939
- # _rbutils.standard_fit_function(_np.arange(max(xdata)),A_an,B_an,f_an),
3940
- # _np.arange(max(xdata)), delta, order='zeroth'),
3941
- # mode = 'lines',
3942
- # line = dict(width=0.5, color="green"),
3943
- # name = '0th order bound',
3944
- # fill='tonexty',
3945
- # fillcolor='rgba(0,128,0,0.1)',
3946
- # showlegend=False,
3947
- # ))
3948
- # data.append( go.Scatter(
3949
- # x = _np.arange(max(xdata)),
3950
- # y = _rbutils.seb_lower(
3951
- # _rbutils.standard_fit_function(_np.arange(max(xdata)),A_an,B_an,f_an),
3952
- # _np.arange(max(xdata)), delta, order='zeroth'),
3953
- # mode = 'lines',
3954
- # line = dict(width=0.5, color="green"),
3955
- # name = '0th order bound',
3956
- # showlegend=False,
3957
- # ))
3958
- #
3959
- #
3960
- # if Magesan_first is True:
3961
- # data.append( go.Scatter(
3962
- # x = _np.arange(max(xdata)),
3963
- # y = _rbutils.first_order_fit_function(_np.arange(max(xdata)),A1_an,B1_an,C1_an,f_an),
3964
- # mode = 'lines',
3965
- # line = dict(width=2, color=theory_color2, dash='dash'),
3966
- # name = '1st order theory',
3967
- # showlegend=legend,
3968
- # ))
3969
- #
3970
- # if Magesan_first_SEB is True:
3971
- # data.append( go.Scatter(
3972
- # x = _np.arange(max(xdata)),
3973
- # y = _rbutils.seb_upper(
3974
- # _rbutils.first_order_fit_function(_np.arange(max(xdata)),A1_an,B1_an,C1_an,f_an),
3975
- # _np.arange(max(xdata)), delta, order='first'),
3976
- # mode = 'lines',
3977
- # line = dict(width=0.5, color=theory_color2), #linewidth=4?
3978
- # name = '1st order bound',
3979
- # fill='tonexty',
3980
- # fillcolor=theory_fill2,
3981
- # showlegend=False,
3982
- # ))
3983
- # data.append( go.Scatter(
3984
- # x = _np.arange(max(xdata)),
3985
- # y = _rbutils.seb_lower(
3986
- # _rbutils.first_order_fit_function(_np.arange(max(xdata)),A1_an,B1_an,C1_an,f_an),
3987
- # _np.arange(max(xdata)), delta, order='first'),
3988
- # mode = 'lines',
3989
- # line = dict(width=0.5, color=theory_color2),
3990
- # name = '1st order bound',
3991
- # showlegend=False,
3992
- # ))
3993
- #
3994
- #
3995
- # if exact_decay is True:
3996
- # data.append( go.Scatter(
3997
- # x = mvalues,
3998
- # y = ASPs,
3999
- # mode = 'lines',
4000
- # line = dict(width=2, color="blue",dash='dash'),
4001
- # name = 'Exact decay',
4002
- # showlegend=legend,
4003
- # ))
4004
- #
4005
- # if L_matrix_decay is True:
4006
- # data.append( go.Scatter(
4007
- # x = mvalues,
4008
- # y = LM_ASPs,
4009
- # mode = 'lines',
4010
- # line = dict(width=2, color="cyan",dash='dash'),
4011
- # name = 'L matrix decay',
4012
- # showlegend=legend,
4013
- # ))
4014
- # if L_matrix_decay_SEB is True:
4015
- # data.append( go.Scatter(
4016
- # x = mvalues,
4017
- # y = LM_ASPs_SEB_upper,
4018
- # mode = 'lines',
4019
- # line = dict(width=0.5, color="cyan"),
4020
- # name = 'LM bound',
4021
- # fill='tonexty',
4022
- # fillcolor='rgba(0,255,255,0.1)',
4023
- # showlegend=False,
4024
- # ))
4025
- # data.append( go.Scatter(
4026
- # x = mvalues,
4027
- # y = LM_ASPs_SEB_lower,
4028
- # mode = 'lines',
4029
- # line = dict(width=0.5, color="cyan"),
4030
- # name = 'LM bound',
4031
- # showlegend=False,
4032
- # ))
4033
- #
4034
- # ymin = min([min(trace['y']) for trace in data])
4035
- # ymin -= 0.1*abs(1.0-ymin) #pad by 10%
4036
- #
4037
- # layout = go.Layout(
4038
- # width=800*scale,
4039
- # height=400*scale,
4040
- # title=title,
4041
- # titlefont=dict(size=16),
4042
- # xaxis=dict(
4043
- # title=xlabel,
4044
- # titlefont=dict(size=14),
4045
- # range=xlim if xlim else [0,max(xdata)],
4046
- # ),
4047
- # yaxis=dict(
4048
- # title='Mean survival probability',
4049
- # titlefont=dict(size=14),
4050
- # range=ylim if ylim else [ymin,1.0],
4051
- # ),
4052
- # legend=dict(
4053
- # font=dict(
4054
- # size=13,
4055
- # ),
4056
- # )
4057
- # )
4058
- #
4059
- # pythonVal = {}
4060
- # for i,tr in enumerate(data):
4061
- # key = tr['name'] if ("name" in tr) else "trace%d" % i
4062
- # pythonVal[key] = {'x': tr['x'], 'y': tr['y']}
4063
- #
4064
- # #reverse order of data so z-ordering is nicer
4065
- # return ReportFigure(go.Figure(data=list(reversed(data)), layout=layout),
4066
- # None, pythonVal)
4067
- #
4068
- # #newplotgca.set_xlabel(xlabel, fontsize=15)
4069
- # #newplotgca.set_ylabel('Mean survival probability',fontsize=15)
4070
- # #if title==True:
4071
- # # newplotgca.set_title('Randomized Benchmarking Decay', fontsize=18)
4072
- # #newplotgca.set_frame_on(True)
4073
- # #newplotgca.yaxis.grid(False)
4074
- # #newplotgca.tick_params(axis='x', top='off', labelsize=12)
4075
- # #newplotgca.tick_params(axis='y', left='off', right='off', labelsize=12)
4076
- #
4077
- # #if legend==True:
4078
- # # leg = _plt.legend(fancybox=True, loc=loc)
4079
- # # leg.get_frame().set_alpha(0.9)
4080
- #
4081
- # #newplotgca.spines["top"].set_visible(False)
4082
- # #newplotgca.spines["right"].set_visible(False)
4083
- # #newplotgca.spines["bottom"].set_alpha(.7)
4084
- # #newplotgca.spines["left"].set_alpha(.7)
4085
-
4086
-
4087
- #Histograms??
4088
- #TODO: histogram
4089
- # if histogram:
4090
- # fig = _plt.figure()
4091
- # histdata = subMxSums.flatten()
4092
- # #take gives back (1,N) shaped array (why?)
4093
- # histdata_finite = _np.take(histdata, _np.where(_np.isfinite(histdata)))[0]
4094
- # histMin = min( histdata_finite ) if cmapFactory.vmin is None else cmapFactory.vmin
4095
- # histMax = max( histdata_finite ) if cmapFactory.vmax is None else cmapFactory.vmax
4096
- # _plt.hist(_np.clip(histdata_finite,histMin,histMax), histBins,
4097
- # range=[histMin, histMax], facecolor='gray', align='mid')
4098
- # if save_to is not None:
4099
- # if len(save_to) > 0:
4100
- # _plt.savefig( _makeHistFilename(save_to) )
4101
- # _plt.close(fig)
4102
-
4103
- # if histogram:
4104
- # fig = _plt.figure()
4105
- # histdata = _np.concatenate( [ sub_mxs[iy][ix].flatten() for ix in range(nXs) for iy in range(nYs)] )
4106
- # #take gives back (1,N) shaped array (why?)
4107
- # histdata_finite = _np.take(histdata, _np.where(_np.isfinite(histdata)))[0]
4108
- # histMin = min( histdata_finite ) if cmapFactory.vmin is None else cmapFactory.vmin
4109
- # histMax = max( histdata_finite ) if cmapFactory.vmax is None else cmapFactory.vmax
4110
- # _plt.hist(_np.clip(histdata_finite,histMin,histMax), histBins,
4111
- # range=[histMin, histMax], facecolor='gray', align='mid')
4112
- # if save_to is not None:
4113
- # if len(save_to) > 0:
4114
- # _plt.savefig( _makeHistFilename(save_to) )
4115
- # _plt.close(fig)