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
@@ -29,6 +29,7 @@ from pygsti.baseobjs.basis import Basis as _Basis, DirectSumBasis as _DirectSumB
29
29
  from pygsti.baseobjs.label import Label as _Lbl
30
30
  from pygsti.baseobjs.errorgenlabel import LocalElementaryErrorgenLabel as _LEEL
31
31
  from pygsti.modelmembers.operations.lindbladcoefficients import LindbladCoefficientBlock as _LindbladCoefficientBlock
32
+ from pygsti.models.explicitmodel import ExplicitOpModel as _ExplicitOpModel
32
33
 
33
34
 
34
35
  _CVXPY_AVAILABLE = pkgutil.find_loader('cvxpy') is not None
@@ -121,7 +122,8 @@ def spam_dotprods(rho_vecs, povms):
121
122
  for povm in povms:
122
123
  for EVec in povm.values():
123
124
  ret[i, j] = _np.vdot(EVec.to_dense(on_space='HilbertSchmidt'),
124
- rhoVec.to_dense(on_space='HilbertSchmidt')); j += 1
125
+ rhoVec.to_dense(on_space='HilbertSchmidt'))
126
+ j += 1
125
127
  # to_dense() gives a 1D array, so no need to transpose EVec
126
128
  return ret
127
129
 
@@ -330,13 +332,6 @@ class CircuitEigenvalues(_modf.ModelFunction):
330
332
  # ref for eigenvalue derivatives: https://www.win.tue.nl/casa/meetings/seminar/previous/_abstract051019_files/Presentation.pdf # noqa
331
333
 
332
334
 
333
- #def circuit_eigenvalues(model, circuit):
334
- # return _np.array(sorted(_np.linalg.eigvals(model.sim.product(circuit)),
335
- # key=lambda ev: abs(ev), reverse=True))
336
- #CircuitEigenvalues = _modf.modelfn_factory(circuit_eigenvalues)
337
- ## init args == (model, circuit)
338
-
339
-
340
335
  def rel_circuit_eigenvalues(model_a, model_b, circuit):
341
336
  """
342
337
  Eigenvalues of dot(productB(circuit)^-1, productA(circuit))
@@ -537,15 +532,9 @@ if _CVXPY_AVAILABLE:
537
532
  JAstd = self.d * _tools.fast_jamiolkowski_iso_std(
538
533
  nearby_model.sim.product(self.circuit), mxBasis)
539
534
  JBstd = self.d * _tools.fast_jamiolkowski_iso_std(self.B, mxBasis)
540
- Jt = (JBstd - JAstd).T
541
- return 0.5 * _np.trace(_np.dot(Jt.real, self.W.real) + _np.dot(Jt.imag, self.W.imag))
542
-
543
- #def circuit_half_diamond_norm(model_a, model_b, circuit):
544
- # A = model_a.sim.product(circuit) # "gate"
545
- # B = model_b.sim.product(circuit) # "target gate"
546
- # return half_diamond_norm(A, B, model_b.basis)
547
- #CircuitHalfDiamondNorm = _modf.modelfn_factory(circuit_half_diamond_norm)
548
- # # init args == (model_a, model_b, circuit)
535
+ J = JBstd - JAstd
536
+ val = 0.5 * (_np.vdot(J.real, self.W.real) + _np.vdot(J.imag, self.W.imag))
537
+ return val
549
538
 
550
539
  else:
551
540
  circuit_half_diamond_norm = None
@@ -1202,7 +1191,10 @@ if _CVXPY_AVAILABLE:
1202
1191
 
1203
1192
  def __init__(self, model_a, model_b, oplabel):
1204
1193
  self.oplabel = oplabel
1205
- self.B = model_b.operations[oplabel].to_dense(on_space='HilbertSchmidt')
1194
+ if isinstance(model_b, _ExplicitOpModel):
1195
+ self.B = model_b.operations[oplabel].to_dense(on_space='HilbertSchmidt')
1196
+ else:
1197
+ self.B = model_b.operation_blks['gates'][oplabel].to_dense(on_space='HilbertSchmidt')
1206
1198
  self.d = int(round(_np.sqrt(model_a.dim)))
1207
1199
  _modf.ModelFunction.__init__(self, model_a, [("gate", oplabel)])
1208
1200
 
@@ -1220,8 +1212,13 @@ if _CVXPY_AVAILABLE:
1220
1212
  float
1221
1213
  """
1222
1214
  gl = self.oplabel
1223
- dm, W = _tools.diamonddist(model.operations[gl].to_dense(on_space='HilbertSchmidt'),
1224
- self.B, model.basis, return_x=True)
1215
+ if isinstance(model, _ExplicitOpModel):
1216
+ dm, W = _tools.diamonddist(model.operations[gl].to_dense(on_space='HilbertSchmidt'),
1217
+ self.B, model.basis, return_x=True)
1218
+ else:
1219
+ dm, W = _tools.diamonddist(model.operation_blks['gates'][gl].to_dense(on_space='HilbertSchmidt'),
1220
+ self.B, 'pp', return_x=True) # HACK - need to get basis from model 'pp' HARDCODED for now
1221
+
1225
1222
  self.W = W
1226
1223
  return 0.5 * dm
1227
1224
 
@@ -1238,12 +1235,17 @@ if _CVXPY_AVAILABLE:
1238
1235
  -------
1239
1236
  float
1240
1237
  """
1241
- gl = self.oplabel; mxBasis = nearby_model.basis
1242
- JAstd = self.d * _tools.fast_jamiolkowski_iso_std(
1243
- nearby_model.operations[gl].to_dense(on_space='HilbertSchmidt'), mxBasis)
1238
+ mxBasis = nearby_model.basis
1239
+ if isinstance(nearby_model, _ExplicitOpModel):
1240
+ A = nearby_model.operations[self.oplabel].to_dense(on_space='HilbertSchmidt')
1241
+ else:
1242
+ A = nearby_model.operation_blks['gates'][self.oplabel].to_dense(on_space='HilbertSchmidt')
1243
+ mxBasis = 'pp' # HACK need to set mxBasis based on model but not the full model basis
1244
+ JAstd = self.d * _tools.fast_jamiolkowski_iso_std(A, mxBasis)
1244
1245
  JBstd = self.d * _tools.fast_jamiolkowski_iso_std(self.B, mxBasis)
1245
- Jt = (JBstd - JAstd).T
1246
- return 0.5 * _np.trace(_np.dot(Jt.real, self.W.real) + _np.dot(Jt.imag, self.W.imag))
1246
+ J = JBstd - JAstd
1247
+ val = 0.5 * (_np.vdot(J.real, self.W.real) + _np.vdot(J.imag, self.W.imag))
1248
+ return val
1247
1249
 
1248
1250
  def half_diamond_norm(a, b, mx_basis):
1249
1251
  """
@@ -1311,7 +1313,7 @@ def eigenvalue_unitarity(a, b):
1311
1313
  Lambda = _np.dot(a, _np.linalg.inv(b))
1312
1314
  d2 = Lambda.shape[0]
1313
1315
  lmb = _np.linalg.eigvals(Lambda)
1314
- return float(_np.real(_np.vdot(lmb, lmb)) - 1.0) / (d2 - 1.0)
1316
+ return float(_np.real(_np.linalg.norm(lmb)**2) - 1.0) / (d2 - 1.0)
1315
1317
 
1316
1318
 
1317
1319
  def nonunitary_entanglement_infidelity(a, b, mx_basis):
@@ -1776,7 +1778,6 @@ def errorgen_and_projections(errgen, mx_basis):
1776
1778
  'stochastic', and 'affine'.
1777
1779
  """
1778
1780
  ret = {}
1779
- #egnorm = _np.linalg.norm(errgen.flatten())
1780
1781
  ret['error generator'] = errgen
1781
1782
 
1782
1783
  if set(mx_basis.name.split('*')) == set(['pp']):
@@ -2019,13 +2020,15 @@ def robust_log_gti_and_projections(model_a, model_b, synthetic_idle_circuits):
2019
2020
  for i, gl in enumerate(opLabels):
2020
2021
  for k, errOnGate in enumerate(error_superops):
2021
2022
  noise = first_order_noise(opstr, errOnGate, gl)
2022
- jac[:, i * nSuperOps + k] = [_np.vdot(errOut.flatten(), noise.flatten()) for errOut in error_superops]
2023
+ jac[:, i * nSuperOps + k] = [_np.vdot(errOut, noise) for errOut in error_superops]
2024
+
2025
+ # DEBUG CHECK
2026
+ check = []
2027
+ for errOut in error_superops:
2028
+ arg1 = _tools.jamiolkowski_iso(errOut, mxBasis, mxBasis)
2029
+ arg2 = _tools.jamiolkowski_iso(noise, mxBasis, mxBasis)
2030
+ check.append(_np.vdot(arg1, arg2) * 4)
2023
2031
 
2024
- #DEBUG CHECK
2025
- check = [_np.trace(_np.dot(
2026
- _tools.jamiolkowski_iso(errOut, mxBasis, mxBasis).conj().T,
2027
- _tools.jamiolkowski_iso(noise, mxBasis, mxBasis))) * 4 # for 1-qubit...
2028
- for errOut in error_superops]
2029
2032
  assert(_np.allclose(jac[:, i * nSuperOps + k], check))
2030
2033
 
2031
2034
  assert(_np.linalg.norm(jac.imag) < 1e-6), "error generator jacobian should be real!"
@@ -2157,10 +2160,11 @@ def general_decomposition(model_a, model_b):
2157
2160
  if gl == gl_other or abs(rotnAngle) < 1e-4 or abs(rotnAngle_other) < 1e-4:
2158
2161
  decomp[str(gl) + "," + str(gl_other) + " axis angle"] = 10000.0 # sentinel for irrelevant angle
2159
2162
 
2160
- real_dot = _np.clip(
2161
- _np.real(_np.dot(decomp[str(gl) + ' axis'].flatten(),
2162
- decomp[str(gl_other) + ' axis'].flatten())),
2163
- -1.0, 1.0)
2163
+ arg1 = decomp[str(gl) + ' axis']
2164
+ arg2 = decomp[str(gl_other) + ' axis']
2165
+ # ^ assert not (_np.iscomplexobj(arg1) or _np.iscomplexobj(arg2) or arg1.ndim > 1 or arg2.ndim > 1)
2166
+ real_dot = arg1 @ arg2
2167
+ real_dot = _np.clip(real_dot, -1.0, 1.0)
2164
2168
  angle = _np.arccos(real_dot) / _np.pi
2165
2169
  decomp[str(gl) + "," + str(gl_other) + " axis angle"] = angle
2166
2170
 
@@ -598,6 +598,12 @@ div.sidenav div.linkgroup a.active {
598
598
  display: block !important;
599
599
  }
600
600
 
601
+ .defaultcaptiondetail {
602
+ display: none;
603
+ font-weight: normal;
604
+ }
605
+
606
+
601
607
  #status {
602
608
  color: #777;
603
609
  background:#ccc;
@@ -158,10 +158,22 @@ $(document).ready(function() {
158
158
  // Render KaTeX
159
159
  render_katex('body');
160
160
 
161
+ // Iterate through all figure captions and add a default caption detail
162
+ const figcaptions = document.getElementsByTagName("figcaption")
163
+ for (const figcap of figcaptions) {
164
+ const defaultcaption = document.createElement('span')
165
+ defaultcaption.className = 'defaultcaptiondetail'
166
+ defaultcaption.innerHTML = '(Click to expand details)'
167
+ defaultcaption.classList.toggle("showcaption")
168
+ figcap.appendChild(defaultcaption)
169
+ }
170
+
161
171
  // Enable figure caption toggling
162
172
  $('figcaption').on('click', function() {
163
173
  // captiondetails should be divs, not spans
164
174
  $(this).children('.captiondetail').toggleClass('showcaption')
175
+ // Also turn off default caption
176
+ $(this).children('.defaultcaptiondetail').toggleClass('showcaption')
165
177
  });
166
178
  });
167
179
 
@@ -1444,13 +1444,8 @@ class SwitchValue(object):
1444
1444
  #use __dict__ so no chance for recursive __getattr__
1445
1445
  return getattr(self.__dict__['base'], attr)
1446
1446
 
1447
- def __len__(self): return len(self.base)
1448
- #Future - arithmetic ops should return a new SwitchValue
1449
- #def __add__(self,x): return self.base + x
1450
- #def __sub__(self,x): return self.base - x
1451
- #def __mul__(self,x): return self.base * x
1452
- #def __truediv__(self, x): return self.base / x
1453
-
1447
+ def __len__(self):
1448
+ return len(self.base)
1454
1449
 
1455
1450
  class WorkspaceOutput(object):
1456
1451
  """
@@ -2516,13 +2511,6 @@ class WorkspacePlot(WorkspaceOutput):
2516
2511
  plotID = "plot_" + id
2517
2512
 
2518
2513
  if typ == "html":
2519
-
2520
- #def getPlotlyDivID(html):
2521
- # #could make this more robust using lxml or something later...
2522
- # iStart = html.index('div id="')
2523
- # iEnd = html.index('"', iStart+8)
2524
- # return html[iStart+8:iEnd]
2525
-
2526
2514
  ##pick "master" plot, whose resizing dictates the resizing of other plots,
2527
2515
  ## as the largest-height plot.
2528
2516
  #iMaster = None; maxH = 0;