pyGSTi 0.9.12__cp38-cp38-win_amd64.whl → 0.9.13__cp38-cp38-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 +185 -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.cp38-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.cp38-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.cp38-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.cp38-win_amd64.pyd +0 -0
  41. pygsti/evotypes/densitymx/effectreps.pyx +1 -1
  42. pygsti/evotypes/densitymx/opreps.cp38-win_amd64.pyd +0 -0
  43. pygsti/evotypes/densitymx/opreps.pyx +2 -2
  44. pygsti/evotypes/densitymx/statereps.cp38-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.cp38-win_amd64.pyd +0 -0
  51. pygsti/evotypes/stabilizer/effectreps.pyx +0 -4
  52. pygsti/evotypes/stabilizer/opreps.cp38-win_amd64.pyd +0 -0
  53. pygsti/evotypes/stabilizer/opreps.pyx +0 -4
  54. pygsti/evotypes/stabilizer/statereps.cp38-win_amd64.pyd +0 -0
  55. pygsti/evotypes/stabilizer/statereps.pyx +1 -5
  56. pygsti/evotypes/stabilizer/termreps.cp38-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.cp38-win_amd64.pyd +0 -0
  62. pygsti/evotypes/statevec/effectreps.pyx +1 -1
  63. pygsti/evotypes/statevec/opreps.cp38-win_amd64.pyd +0 -0
  64. pygsti/evotypes/statevec/opreps.pyx +2 -2
  65. pygsti/evotypes/statevec/statereps.cp38-win_amd64.pyd +0 -0
  66. pygsti/evotypes/statevec/statereps.pyx +1 -1
  67. pygsti/evotypes/statevec/termreps.cp38-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.cp38-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.cp38-win_amd64.pyd +0 -0
  87. pygsti/forwardsims/termforwardsim_calc_statevec.cp38-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.cp38-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
@@ -153,12 +153,7 @@ def find_sufficient_fiducial_pairs(target_model, prep_fiducials, meas_fiducials,
153
153
  #like)
154
154
 
155
155
  #tol = 0.5 #fraction of expected amplification that must be observed to call a parameter "amplified"
156
- if prep_povm_tuples == "first":
157
- firstRho = list(target_model.preps.keys())[0]
158
- firstPOVM = list(target_model.povms.keys())[0]
159
- prep_povm_tuples = [(firstRho, firstPOVM)]
160
- prep_povm_tuples = [(_circuits.Circuit((prepLbl,)), _circuits.Circuit((povmLbl,)))
161
- for prepLbl, povmLbl in prep_povm_tuples]
156
+ prep_povm_tuples = _set_up_prep_POVM_tuples(target_model, prep_povm_tuples, return_meas_dofs = False)
162
157
 
163
158
  def _get_derivs(length):
164
159
  """ Compute all derivative info: get derivative of each `<E_i|germ^exp|rho_j>`
@@ -305,7 +300,7 @@ def find_sufficient_fiducial_pairs(target_model, prep_fiducials, meas_fiducials,
305
300
  return listOfAllPairs
306
301
 
307
302
  def find_sufficient_fiducial_pairs_per_germ(target_model, prep_fiducials, meas_fiducials,
308
- germs, pre_povm_tuples="first",
303
+ germs, prep_povm_tuples="first",
309
304
  search_mode="random", constrain_to_tp=True,
310
305
  n_random=100, min_iterations=None, base_loweig_tol= 1e-1,
311
306
  seed=None ,verbosity=0, num_soln_returned=1, type_soln_returned='best', retry_for_smaller=True,
@@ -350,7 +345,7 @@ def find_sufficient_fiducial_pairs_per_germ(target_model, prep_fiducials, meas_f
350
345
  germs : list of Circuits
351
346
  The germ circuits that are repeated to amplify errors.
352
347
 
353
- pre_povm_tuples : list or "first", optional
348
+ prep_povm_tuples : list or "first", optional
354
349
  A list of `(prepLabel, povmLabel)` tuples to consider when
355
350
  checking for completeness. Usually this should be left as the special
356
351
  (and default) value "first", which considers the first prep and POVM
@@ -414,20 +409,9 @@ def find_sufficient_fiducial_pairs_per_germ(target_model, prep_fiducials, meas_f
414
409
  """
415
410
 
416
411
  printer = _baseobjs.VerbosityPrinter.create_printer(verbosity)
417
-
418
- if pre_povm_tuples == "first":
419
- firstRho = list(target_model.preps.keys())[0]
420
- firstPOVM = list(target_model.povms.keys())[0]
421
- pre_povm_tuples = [(firstRho, firstPOVM)]
422
412
 
423
- #brief intercession to calculate the number of degrees of freedom for the povm.
424
- num_effects= len(list(target_model.povms[pre_povm_tuples[0][1]].keys()))
425
- dof_per_povm= num_effects-1
426
-
427
- pre_povm_tuples = [(_circuits.Circuit((prepLbl,)), _circuits.Circuit((povmLbl,)))
428
- for prepLbl, povmLbl in pre_povm_tuples]
429
-
430
-
413
+ prep_povm_tuples, dof_per_povm = _set_up_prep_POVM_tuples(target_model, prep_povm_tuples, return_meas_dofs = True)
414
+
431
415
  pairListDict = {} # dict of lists of 2-tuples: one pair list per germ
432
416
 
433
417
  if min_iterations is None:
@@ -449,7 +433,8 @@ def find_sufficient_fiducial_pairs_per_germ(target_model, prep_fiducials, meas_f
449
433
  gsGerm = target_model.copy()
450
434
  gsGerm.set_all_parameterizations("static")
451
435
  germMx = gsGerm.sim.product(germ)
452
- gsGerm.operations["Ggerm"] = _EigenvalueParamDenseOp(
436
+ #give this state space labels equal to the line_labels of
437
+ gsGerm.operations['Ggerm'] = _EigenvalueParamDenseOp(
453
438
  germMx, True, constrain_to_tp)
454
439
 
455
440
  printer.show_progress(i, len(germs),
@@ -458,11 +443,12 @@ def find_sufficient_fiducial_pairs_per_germ(target_model, prep_fiducials, meas_f
458
443
 
459
444
  #Determine which fiducial-pair indices to iterate over
460
445
  #initial run
461
- candidate_solution_list, bestFirstEval = _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, pre_povm_tuples,
446
+ candidate_solution_list, bestFirstEval = _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, prep_povm_tuples,
462
447
  gsGerm, 1, mem_limit,
463
448
  printer, search_mode, seed, n_random, dof_per_povm,
464
449
  min_iterations, base_loweig_tol, candidate_set_seed=None,
465
- num_soln_returned=num_soln_returned, type_soln_returned=type_soln_returned)
450
+ num_soln_returned=num_soln_returned, type_soln_returned=type_soln_returned,
451
+ germ_circuit=germ)
466
452
 
467
453
  #the algorithm isn't guaranteed to actually find the requested number of solutions, so check how many there actually are
468
454
  #by checking the length of the list of returned eigenvalues.
@@ -482,11 +468,12 @@ def find_sufficient_fiducial_pairs_per_germ(target_model, prep_fiducials, meas_f
482
468
  for candidate_solution in candidate_solution_list.values():
483
469
  #now do a seeded run for each of the candidate solutions returned in the initial run:
484
470
  #for these internal runs just return a single solution.
485
- reducedPairlist, bestFirstEval = _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, pre_povm_tuples,
471
+ reducedPairlist, bestFirstEval = _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, prep_povm_tuples,
486
472
  gsGerm, 1, mem_limit,
487
473
  printer, search_mode, seed, n_random, dof_per_povm,
488
474
  min_iterations, base_loweig_tol, candidate_set_seed=candidate_solution,
489
- num_soln_returned= 1, type_soln_returned='best')
475
+ num_soln_returned= 1, type_soln_returned='best',
476
+ germ_circuit=germ)
490
477
  #This should now return a dictionary with a single entry. Append that entry to a running list which we'll process at the end.
491
478
  updated_solns.append(list(reducedPairlist.values())[0])
492
479
 
@@ -523,7 +510,7 @@ def find_sufficient_fiducial_pairs_per_germ(target_model, prep_fiducials, meas_f
523
510
  return pairListDict
524
511
 
525
512
  def find_sufficient_fiducial_pairs_per_germ_greedy(target_model, prep_fiducials, meas_fiducials,
526
- germs, pre_povm_tuples="first", constrain_to_tp=True,
513
+ germs, prep_povm_tuples="first", constrain_to_tp=True,
527
514
  inv_trace_tol= 10, initial_seed_mode='random',
528
515
  evd_tol=1e-10, sensitivity_threshold=1e-10, seed=None ,verbosity=0, check_complete_fid_set=True,
529
516
  mem_limit=None):
@@ -567,7 +554,7 @@ def find_sufficient_fiducial_pairs_per_germ_greedy(target_model, prep_fiducials,
567
554
  germs : list of Circuits
568
555
  The germ circuits that are repeated to amplify errors.
569
556
 
570
- pre_povm_tuples : list or "first", optional
557
+ prep_povm_tuples : list or "first", optional
571
558
  A list of `(prepLabel, povmLabel)` tuples to consider when
572
559
  checking for completeness. Usually this should be left as the special
573
560
  (and default) value "first", which considers the first prep and POVM
@@ -630,17 +617,7 @@ def find_sufficient_fiducial_pairs_per_germ_greedy(target_model, prep_fiducials,
630
617
 
631
618
  printer = _baseobjs.VerbosityPrinter.create_printer(verbosity)
632
619
 
633
- if pre_povm_tuples == "first":
634
- firstRho = list(target_model.preps.keys())[0]
635
- firstPOVM = list(target_model.povms.keys())[0]
636
- pre_povm_tuples = [(firstRho, firstPOVM)]
637
-
638
- #brief intercession to calculate the number of degrees of freedom for the povm.
639
- num_effects= len(list(target_model.povms[pre_povm_tuples[0][1]].keys()))
640
- dof_per_povm= num_effects-1
641
-
642
- pre_povm_tuples = [(_circuits.Circuit((prepLbl,)), _circuits.Circuit((povmLbl,)))
643
- for prepLbl, povmLbl in pre_povm_tuples]
620
+ prep_povm_tuples, dof_per_povm = _set_up_prep_POVM_tuples(target_model, prep_povm_tuples, return_meas_dofs=True)
644
621
 
645
622
  pairListDict = {} # dict of lists of 2-tuples: one pair list per germ
646
623
 
@@ -667,12 +644,13 @@ def find_sufficient_fiducial_pairs_per_germ_greedy(target_model, prep_fiducials,
667
644
 
668
645
  #Determine which fiducial-pair indices to iterate over
669
646
  #initial run
670
- candidate_solution_list, best_score = _get_per_germ_power_fidpairs_greedy(prep_fiducials, meas_fiducials, pre_povm_tuples,
647
+ candidate_solution_list, best_score = _get_per_germ_power_fidpairs_greedy(prep_fiducials, meas_fiducials, prep_povm_tuples,
671
648
  gsGerm, 1, mem_limit,
672
649
  printer, seed, dof_per_povm,
673
650
  inv_trace_tol, initial_seed_mode=initial_seed_mode,
674
651
  check_complete_fid_set=check_complete_fid_set, evd_tol=evd_tol,
675
- sensitivity_threshold=sensitivity_threshold)
652
+ sensitivity_threshold=sensitivity_threshold,
653
+ germ_circuit= germ)
676
654
 
677
655
  #print some output about the minimum eigenvalue acheived.
678
656
  printer.log('Score Achieved: ' + str(best_score), 2)
@@ -691,7 +669,7 @@ def find_sufficient_fiducial_pairs_per_germ_greedy(target_model, prep_fiducials,
691
669
 
692
670
  def find_sufficient_fiducial_pairs_per_germ_power(target_model, prep_fiducials, meas_fiducials,
693
671
  germs, max_lengths,
694
- pre_povm_tuples="first",
672
+ prep_povm_tuples="first",
695
673
  search_mode="random", constrain_to_tp=True,
696
674
  trunc_scheme="whole germ powers",
697
675
  n_random=100, min_iterations=None, base_loweig_tol= 1e-1, seed=None,
@@ -746,7 +724,7 @@ def find_sufficient_fiducial_pairs_per_germ_power(target_model, prep_fiducials,
746
724
  max_lengths: list of int
747
725
  The germ powers (number of repetitions) to be used to amplify errors.
748
726
 
749
- pre_povm_tuples : list or "first", optional
727
+ prep_povm_tuples : list or "first", optional
750
728
  A list of `(prepLabel, povmLabel)` tuples to consider when
751
729
  checking for completeness. Usually this should be left as the special
752
730
  (and default) value "first", which considers the first prep and POVM
@@ -805,16 +783,9 @@ def find_sufficient_fiducial_pairs_per_germ_power(target_model, prep_fiducials,
805
783
 
806
784
  printer = _baseobjs.VerbosityPrinter.create_printer(verbosity)
807
785
 
808
- if pre_povm_tuples == "first":
809
- firstRho = list(target_model.preps.keys())[0]
810
- firstPOVM = list(target_model.povms.keys())[0]
811
- pre_povm_tuples = [(firstRho, firstPOVM)]
812
-
813
- pre_povm_tuples = [(_circuits.Circuit((prepLbl,)), _circuits.Circuit((povmLbl,)))
814
- for prepLbl, povmLbl in pre_povm_tuples]
786
+ prep_povm_tuples = _set_up_prep_POVM_tuples(target_model, prep_povm_tuples, return_meas_dofs=False)
787
+
815
788
  pairListDict = {} # dict of lists of 2-tuples: one pair list per germ
816
- low_eigvals = {}
817
- #base_loweig_threshold = 1e-2 # HARDCODED
818
789
 
819
790
  #Check whether the user has passed in a candidate set as a seed from a previous run of
820
791
  #per-germ FPR.
@@ -881,11 +852,11 @@ def find_sufficient_fiducial_pairs_per_germ_power(target_model, prep_fiducials,
881
852
  else:
882
853
  candidate_set_seed= None
883
854
 
884
- goodPairList, _ = _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, pre_povm_tuples,
855
+ goodPairList, _ = _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, prep_povm_tuples,
885
856
  gsGerm, power, mem_limit,
886
857
  printer, search_mode, seed, n_random,
887
858
  min_iterations, base_loweig_tol, candidate_set_seed,
888
- num_soln_returned=1, type_soln_returned='best')
859
+ num_soln_returned=1, type_soln_returned='best', germ_circuit = germ)
889
860
 
890
861
  #This should now return a dictionary with a single entry. pull that entry out.
891
862
  goodPairList= list(goodPairList.values())[0]
@@ -900,7 +871,7 @@ def find_sufficient_fiducial_pairs_per_germ_power(target_model, prep_fiducials,
900
871
  return pairListDict
901
872
 
902
873
  def test_fiducial_pairs(fid_pairs, target_model, prep_fiducials, meas_fiducials, germs,
903
- test_lengths=(256, 2048), pre_povm_tuples="first", tol=0.75,
874
+ test_lengths=(256, 2048), prep_povm_tuples="first", tol=0.75,
904
875
  verbosity=0, mem_limit=None):
905
876
  """
906
877
  Tests a set of global or per-germ fiducial pairs.
@@ -936,7 +907,7 @@ def test_fiducial_pairs(fid_pairs, target_model, prep_fiducials, meas_fiducials,
936
907
  A tuple of integers specifying the germ-power lengths to use when
937
908
  checking for amplificational completeness.
938
909
 
939
- pre_povm_tuples : list or "first", optional
910
+ prep_povm_tuples : list or "first", optional
940
911
  A list of `(prepLabel, povmLabel)` tuples to consider when
941
912
  checking for completeness. Usually this should be left as the special
942
913
  (and default) value "first", which considers the first prep and POVM
@@ -958,12 +929,7 @@ def test_fiducial_pairs(fid_pairs, target_model, prep_fiducials, meas_fiducials,
958
929
  """
959
930
  printer = _baseobjs.VerbosityPrinter.create_printer(verbosity)
960
931
 
961
- if pre_povm_tuples == "first":
962
- firstRho = list(target_model.preps.keys())[0]
963
- firstPOVM = list(target_model.povms.keys())[0]
964
- pre_povm_tuples = [(firstRho, firstPOVM)]
965
- pre_povm_tuples = [(_circuits.Circuit((prepLbl,)), _circuits.Circuit((povmLbl,)))
966
- for prepLbl, povmLbl in pre_povm_tuples]
932
+ prep_povm_tuples = _set_up_prep_POVM_tuples(target_model, prep_povm_tuples, return_meas_dofs=False)
967
933
 
968
934
  def _get_derivs(length):
969
935
  """ Compute all derivative info: get derivative of each `<E_i|germ^exp|rho_j>`
@@ -975,7 +941,7 @@ def test_fiducial_pairs(fid_pairs, target_model, prep_fiducials, meas_fiducials,
975
941
  pairList = fid_pairs[germ] if isinstance(fid_pairs, dict) else fid_pairs
976
942
  circuits += _gsc.create_circuits("pp[0]+p[0]+expGerm+p[1]+pp[1]",
977
943
  p=[(prep_fiducials[i], meas_fiducials[j]) for i, j in pairList],
978
- pp=pre_povm_tuples, expGerm=expGerm, order=['p', 'pp'])
944
+ pp=prep_povm_tuples, expGerm=expGerm, order=['p', 'pp'])
979
945
  circuits = _remove_duplicates(circuits)
980
946
 
981
947
  resource_alloc = _baseobjs.ResourceAllocation(comm=None, mem_limit=mem_limit)
@@ -1023,10 +989,11 @@ def test_fiducial_pairs(fid_pairs, target_model, prep_fiducials, meas_fiducials,
1023
989
 
1024
990
 
1025
991
  # Helper function for per_germ and per_germ_power FPR
1026
- def _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, pre_povm_tuples,
992
+ def _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, prep_povm_tuples,
1027
993
  gsGerm, power, mem_limit, printer, search_mode, seed, n_random, dof_per_povm,
1028
994
  min_iterations=1, lowest_eigenval_tol=1e-1,
1029
- candidate_set_seed=None, num_soln_returned=1, type_soln_returned='best'):
995
+ candidate_set_seed=None, num_soln_returned=1, type_soln_returned='best',
996
+ germ_circuit = None):
1030
997
  #Get dP-matrix for full set of fiducials, where
1031
998
  # P_ij = <E_i|germ^exp|rho_j>, i = composite EVec & fiducial index,
1032
999
  # j is similar, and derivs are wrt the "eigenvalues" of the germ
@@ -1048,17 +1015,18 @@ def _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, pre_povm_tuples
1048
1015
 
1049
1016
  min_pairs_needed= ceil((gsGerm.num_params/(nPossiblePairs*dof_per_povm))*nPossiblePairs)
1050
1017
  printer.log('Minimum Number of Pairs Needed for this Germ: %d'%(min_pairs_needed), 2)
1018
+ line_labels = germ_circuit.line_labels if germ_circuit is not None else 'auto'
1051
1019
 
1052
1020
  lst = _gsc.create_circuits(
1053
1021
  "pp[0]+f0+germ*power+f1+pp[1]", f0=prep_fiducials, f1=meas_fiducials,
1054
- germ=_circuits.Circuit('Ggerm'), pp=pre_povm_tuples, power=power,
1022
+ germ=_circuits.Circuit(['Ggerm'], line_labels=line_labels), pp=prep_povm_tuples, power=power,
1055
1023
  order=('f0', 'f1', 'pp'))
1056
1024
 
1057
1025
  resource_alloc = _baseobjs.ResourceAllocation(comm=None, mem_limit=mem_limit)
1058
1026
  layout = gsGerm.sim.create_layout(lst, None, resource_alloc, array_types=('ep',), verbosity=0)
1059
1027
 
1060
1028
  elIndicesForPair = [[] for i in range(len(prep_fiducials) * len(meas_fiducials))]
1061
- nPrepPOVM = len(pre_povm_tuples)
1029
+ nPrepPOVM = len(prep_povm_tuples)
1062
1030
  for k in range(len(prep_fiducials) * len(meas_fiducials)):
1063
1031
  for o in range(k * nPrepPOVM, (k + 1) * nPrepPOVM):
1064
1032
  # "original" indices into lst for k-th fiducial pair
@@ -1249,7 +1217,6 @@ def _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, pre_povm_tuples
1249
1217
  # subset of the total fiducial pairs.
1250
1218
  elementIndicesToTest = _np.concatenate([elIndicesForPair[i] for i in pairIndicesToTest])
1251
1219
  dP = _np.take(dPall, elementIndicesToTest, axis=0) # subset_of_num_elements x num_params
1252
- #print('Rank of candidate set: ', _np.linalg.matrix_rank(dP))
1253
1220
 
1254
1221
  spectrum = _np.abs(_np.linalg.eigvalsh(_np.dot(dP, dP.T)))
1255
1222
  current_rank= _np.count_nonzero(spectrum>1e-10)
@@ -1282,8 +1249,8 @@ def _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, pre_povm_tuples
1282
1249
  try:
1283
1250
  bestPairs.pop(bestFirstEval[-1])
1284
1251
  except KeyError as err:
1285
- print("trying to drop the element from bestPairs with key: ", bestFirstEval[-1])
1286
- print("current keys in this dictionary: ", bestPairs.keys())
1252
+ printer.log(f"Trying to drop the element from bestPairs with key: {bestFirstEval[-1]}", 3)
1253
+ printer.log(f"Current keys in this dictionary: {bestPairs.keys()}", 3)
1287
1254
 
1288
1255
  #This seems to be happening when there are multiple entries with virtually
1289
1256
  #identical values for the keys.
@@ -1328,10 +1295,11 @@ def _get_per_germ_power_fidpairs(prep_fiducials, meas_fiducials, pre_povm_tuples
1328
1295
  # This version uses a greedy style algorithm and an
1329
1296
  # alternative objective function which leverages the performance enhancements
1330
1297
  # utilized for the germ selection algorithm using low-rank updates.
1331
- def _get_per_germ_power_fidpairs_greedy(prep_fiducials, meas_fiducials, pre_povm_tuples,
1298
+ def _get_per_germ_power_fidpairs_greedy(prep_fiducials, meas_fiducials, prep_povm_tuples,
1332
1299
  gsGerm, power, mem_limit, printer, seed, dof_per_povm,
1333
1300
  inv_trace_tol=10, initial_seed_mode= 'random',
1334
- check_complete_fid_set= True, evd_tol=1e-10, sensitivity_threshold= 1e-10):
1301
+ check_complete_fid_set= True, evd_tol=1e-10, sensitivity_threshold= 1e-10,
1302
+ germ_circuit = None):
1335
1303
  #Get dP-matrix for full set of fiducials, where
1336
1304
  # P_ij = <E_i|germ^exp|rho_j>, i = composite EVec & fiducial index,
1337
1305
  # j is similar, and derivs are wrt the "eigenvalues" of the germ
@@ -1352,17 +1320,18 @@ def _get_per_germ_power_fidpairs_greedy(prep_fiducials, meas_fiducials, pre_povm
1352
1320
 
1353
1321
  min_pairs_needed= ceil((gsGerm.num_params/(nPossiblePairs*dof_per_povm))*nPossiblePairs)
1354
1322
  printer.log('Minimum Number of Pairs Needed for this Germ: %d'%(min_pairs_needed), 2)
1355
-
1323
+ line_labels = germ_circuit.line_labels if germ_circuit is not None else 'auto'
1324
+
1356
1325
  lst = _gsc.create_circuits(
1357
1326
  "pp[0]+f0+germ*power+f1+pp[1]", f0=prep_fiducials, f1=meas_fiducials,
1358
- germ=_circuits.Circuit('Ggerm'), pp=pre_povm_tuples, power=power,
1327
+ germ=_circuits.Circuit(['Ggerm'], line_labels=line_labels), pp=prep_povm_tuples, power=power,
1359
1328
  order=('f0', 'f1', 'pp'))
1360
1329
 
1361
1330
  resource_alloc = _baseobjs.ResourceAllocation(comm=None, mem_limit=mem_limit)
1362
1331
  layout = gsGerm.sim.create_layout(lst, None, resource_alloc, array_types=('ep',), verbosity=0)
1363
1332
 
1364
1333
  elIndicesForPair = [[] for i in range(len(prep_fiducials) * len(meas_fiducials))]
1365
- nPrepPOVM = len(pre_povm_tuples)
1334
+ nPrepPOVM = len(prep_povm_tuples)
1366
1335
  for k in range(len(prep_fiducials) * len(meas_fiducials)):
1367
1336
  for o in range(k * nPrepPOVM, (k + 1) * nPrepPOVM):
1368
1337
  # "original" indices into lst for k-th fiducial pair
@@ -1586,7 +1555,7 @@ def filter_useless_fid_pairs(fiducial_indices, element_map, complete_jacobian, s
1586
1555
  #about the amplificational properties of the germ set as a whole.
1587
1556
 
1588
1557
  def find_sufficient_fiducial_pairs_per_germ_global(target_model, prep_fiducials, meas_fiducials,
1589
- germ_vector_spanning_set=None, germs=None, pre_povm_tuples="first",
1558
+ germ_vector_spanning_set=None, germs=None, prep_povm_tuples="first",
1590
1559
  mem_limit=None, inv_trace_tol= 10, initial_seed_mode='greedy',
1591
1560
  evd_tol=1e-10, seed=None ,verbosity=0, float_type = _np.cdouble,
1592
1561
  germ_set_spanning_kwargs = None, precomputed_jacobians = None):
@@ -1633,7 +1602,7 @@ def find_sufficient_fiducial_pairs_per_germ_global(target_model, prep_fiducials,
1633
1602
  If passed in and germ_vector_spanning_set is None then we'll use this
1634
1603
  in the calculation of the germ vector spanning set.
1635
1604
 
1636
- pre_povm_tuples : list or "first", optional
1605
+ prep_povm_tuples : list or "first", optional
1637
1606
  A list of `(prepLabel, povmLabel)` tuples to consider when
1638
1607
  checking for completeness. Usually this should be left as the special
1639
1608
  (and default) value "first", which considers the first prep and POVM
@@ -1711,17 +1680,7 @@ def find_sufficient_fiducial_pairs_per_germ_global(target_model, prep_fiducials,
1711
1680
  verbosity=verbosity,
1712
1681
  **used_kwargs)
1713
1682
 
1714
- if pre_povm_tuples == "first":
1715
- firstRho = list(target_model.preps.keys())[0]
1716
- firstPOVM = list(target_model.povms.keys())[0]
1717
- pre_povm_tuples = [(firstRho, firstPOVM)]
1718
-
1719
- #brief intercession to calculate the number of degrees of freedom for the povm.
1720
- num_effects= len(list(target_model.povms[pre_povm_tuples[0][1]].keys()))
1721
- dof_per_povm= num_effects-1
1722
-
1723
- pre_povm_tuples = [(_circuits.Circuit((prepLbl,)), _circuits.Circuit((povmLbl,)))
1724
- for prepLbl, povmLbl in pre_povm_tuples]
1683
+ prep_povm_tuples, dof_per_povm = _set_up_prep_POVM_tuples(target_model, prep_povm_tuples, return_meas_dofs=True)
1725
1684
 
1726
1685
  pairListDict = {} # dict of lists of 2-tuples: one pair list per germ
1727
1686
 
@@ -1733,7 +1692,7 @@ def find_sufficient_fiducial_pairs_per_germ_global(target_model, prep_fiducials,
1733
1692
  printer.log("------ Per Germ Global Fiducial Pair Reduction --------")
1734
1693
  with printer.progress_logging(1):
1735
1694
  for i, (germ, germ_vector_list) in enumerate(germ_vector_spanning_set.items()):
1736
- candidate_solution_list, best_score = get_per_germ_fid_pairs_global(prep_fiducials, meas_fiducials, pre_povm_tuples,
1695
+ candidate_solution_list, best_score = get_per_germ_fid_pairs_global(prep_fiducials, meas_fiducials, prep_povm_tuples,
1737
1696
  target_model, germ, germ_vector_list, mem_limit,
1738
1697
  printer, dof_per_povm, inv_trace_tol,
1739
1698
  initial_seed_mode=initial_seed_mode, evd_tol=evd_tol,
@@ -1754,7 +1713,7 @@ def find_sufficient_fiducial_pairs_per_germ_global(target_model, prep_fiducials,
1754
1713
 
1755
1714
  return pairListDict
1756
1715
 
1757
- def get_per_germ_fid_pairs_global(prep_fiducials, meas_fiducials, pre_povm_tuples,
1716
+ def get_per_germ_fid_pairs_global(prep_fiducials, meas_fiducials, prep_povm_tuples,
1758
1717
  target_model, germ, germ_vector_list, mem_limit, printer, dof_per_povm,
1759
1718
  inv_trace_tol=10, initial_seed_mode= 'greedy', evd_tol=1e-10,
1760
1719
  float_type = _np.cdouble, dprobs_dict = None):
@@ -1782,8 +1741,7 @@ def get_per_germ_fid_pairs_global(prep_fiducials, meas_fiducials, pre_povm_tuple
1782
1741
 
1783
1742
  allPairIndices = list(range(nPossiblePairs))
1784
1743
 
1785
- print('Current Germ: ')
1786
- print(germ)
1744
+ printer.log(f'Current Germ: {germ}', 2)
1787
1745
 
1788
1746
  printer.log('Number of possible pairs: %d'%(nPossiblePairs), 3)
1789
1747
 
@@ -1797,10 +1755,10 @@ def get_per_germ_fid_pairs_global(prep_fiducials, meas_fiducials, pre_povm_tuple
1797
1755
  #loops over a number of pairs between min_pairs_needed and up to and not including the number of possible pairs
1798
1756
  min_pairs_needed= ceil((num_germ_vecs/(nPossiblePairs*dof_per_povm))*nPossiblePairs)
1799
1757
  printer.log('Minimum Number of Pairs Needed for this Germ: %d'%(min_pairs_needed), 2)
1800
-
1758
+
1801
1759
  lst = _gsc.create_circuits(
1802
1760
  "pp[0]+f0+germ*power+f1+pp[1]", f0=prep_fiducials, f1=meas_fiducials,
1803
- germ=germ, pp=pre_povm_tuples, power=1,
1761
+ germ=germ, pp=prep_povm_tuples, power=1,
1804
1762
  order=('f0', 'f1', 'pp'))
1805
1763
 
1806
1764
  printer.log('Constructing Directional Derivatives for Full Fiducial Set' , 2)
@@ -2054,9 +2012,7 @@ def _compute_bulk_directional_ddd_compact(model, circuits, vec_mat, eps,
2054
2012
 
2055
2013
  #now calculate the direction derivative matrix.
2056
2014
  directional_deriv = jac@vec_mat
2057
- #print('directional deriv shape: ' + str(directional_deriv.shape))
2058
- direc_deriv_gram = directional_deriv.T@directional_deriv
2059
- #print('directional deriv gram shape: ' + str(direc_deriv_gram.shape))
2015
+ direc_deriv_gram = directional_deriv.T@directional_deriv
2060
2016
  #now take twirledDerivDerivDagger and construct its compact EVD.
2061
2017
  e, U= compact_EVD(direc_deriv_gram, evd_tol)
2062
2018
  e_list.append(e)
@@ -2117,7 +2073,8 @@ def _make_spam_static(model):
2117
2073
  #write a helper function for precomputing the jacobian dictionaries from bulk_dprobs
2118
2074
  #which can then be passed into the construction of the compactEVD caches.
2119
2075
 
2120
- def compute_jacobian_dicts(model, germs, prep_fiducials, meas_fiducials, pre_povm_tuples = 'first', comm=None, mem_limit=None):
2076
+ def compute_jacobian_dicts(model, germs, prep_fiducials, meas_fiducials, prep_povm_tuples = 'first', comm=None,
2077
+ mem_limit=None, verbosity = 0):
2121
2078
  """
2122
2079
  Function for precomputing the jacobian dictionaries from bulk_dprobs
2123
2080
  for a model with its SPAM parameters frozen, as needed for certain
@@ -2136,7 +2093,7 @@ def compute_jacobian_dicts(model, germs, prep_fiducials, meas_fiducials, pre_pov
2136
2093
  meas_fiducials : list of Circuits
2137
2094
  A list of measurement fiducial circuits.
2138
2095
 
2139
- pre_povm_tuples : str or list of tuples (default 'first')
2096
+ prep_povm_tuples : str or list of tuples (default 'first')
2140
2097
  Either a string or list of tuples. When a list of tuples
2141
2098
  these correspond to native state prep and native POVM pairs.
2142
2099
  When the special keyword argument 'first' is passed in the first
@@ -2160,14 +2117,10 @@ def compute_jacobian_dicts(model, germs, prep_fiducials, meas_fiducials, pre_pov
2160
2117
  """
2161
2118
  resource_alloc = _baseobjs.ResourceAllocation(comm= comm, mem_limit = mem_limit)
2162
2119
 
2120
+ printer = _baseobjs.VerbosityPrinter.create_printer(verbosity, comm= comm)
2121
+
2163
2122
  #construct the list of circuits
2164
- if pre_povm_tuples == "first":
2165
- firstRho = list(model.preps.keys())[0]
2166
- firstPOVM = list(model.povms.keys())[0]
2167
- pre_povm_tuples = [(firstRho, firstPOVM)]
2168
-
2169
- pre_povm_tuples = [(_circuits.Circuit((prepLbl,)), _circuits.Circuit((povmLbl,)))
2170
- for prepLbl, povmLbl in pre_povm_tuples]
2123
+ prep_povm_tuples = _set_up_prep_POVM_tuples(model, prep_povm_tuples, return_meas_dofs=False)
2171
2124
 
2172
2125
  #freeze the SPAM model parameters:
2173
2126
  static_spam_model = _make_spam_static(model)
@@ -2175,16 +2128,48 @@ def compute_jacobian_dicts(model, germs, prep_fiducials, meas_fiducials, pre_pov
2175
2128
  jacobian_dicts = {}
2176
2129
 
2177
2130
  for germ in germs:
2178
- if comm is None or comm.Get_rank() ==0:
2179
- print('Current germ:', germ, flush=True)
2131
+ printer.log(f'Current germ: {germ}', 1)
2180
2132
 
2181
2133
  lst = _gsc.create_circuits(
2182
2134
  "pp[0]+f0+germ*power+f1+pp[1]", f0=prep_fiducials, f1=meas_fiducials,
2183
- germ=germ, pp=pre_povm_tuples, power=1,
2135
+ germ=germ, pp=prep_povm_tuples, power=1,
2184
2136
  order=('f0', 'f1', 'pp'))
2185
2137
 
2186
2138
  #calculate the dprobs dictionary in bulk.
2187
2139
  dprobs_dict = static_spam_model.sim.bulk_dprobs(lst, resource_alloc)
2188
2140
  jacobian_dicts[germ] = dprobs_dict
2189
2141
 
2190
- return jacobian_dicts
2142
+ return jacobian_dicts
2143
+
2144
+ #helper function for configuring the list of circuit tuples needed for prep-POVM pairs used in FPR.
2145
+ def _set_up_prep_POVM_tuples(target_model, prep_povm_tuples, return_meas_dofs= False):
2146
+
2147
+ if prep_povm_tuples == "first":
2148
+ firstRho = list(target_model.preps.keys())[0]
2149
+ prep_ssl = [target_model.preps[firstRho].state_space.state_space_labels]
2150
+ firstPOVM = list(target_model.povms.keys())[0]
2151
+ POVM_ssl = [target_model.povms[firstPOVM].state_space.state_space_labels]
2152
+ prep_povm_tuples = [(firstRho, firstPOVM)]
2153
+ #I think using the state space labels for firstRho and firstPOVM as the
2154
+ #circuit labels should work most of the time (new stricter line_label enforcement means
2155
+ # we need to enforce compatibility here), but this might break for
2156
+ #ImplicitModels? Not sure how those handle the state space labels for preps and povms
2157
+ #Time will tell...
2158
+ #if not we still need to extract state space labels for all of these to meet new circuit
2159
+ #label handling requirements.
2160
+ else:
2161
+ prep_ssl = [target_model.preps[lbl_tup[0]].state_space.state_space_labels for lbl_tup in prep_povm_tuples]
2162
+ POVM_ssl = [target_model.povms[lbl_tup[1]].state_space.state_space_labels for lbl_tup in prep_povm_tuples]
2163
+
2164
+ #brief intercession to calculate the number of degrees of freedom for the povm.
2165
+ num_effects= len(list(target_model.povms[prep_povm_tuples[0][1]].keys()))
2166
+ dof_per_povm= num_effects-1
2167
+
2168
+ prep_povm_tuples = [(_circuits.Circuit([prepLbl], line_labels=prep_ssl[i]),
2169
+ _circuits.Circuit([povmLbl], line_labels=POVM_ssl[i]))
2170
+ for i, (prepLbl, povmLbl) in enumerate(prep_povm_tuples)]
2171
+
2172
+ if return_meas_dofs:
2173
+ return prep_povm_tuples, dof_per_povm
2174
+ else:
2175
+ return prep_povm_tuples
@@ -409,13 +409,6 @@ def find_fiducials(target_model, omit_identity=True, eq_thresh=1e-6,
409
409
  return prepFidList, measFidList
410
410
 
411
411
 
412
- #def bool_list_to_ind_list(boolList):
413
- # output = _np.array([])
414
- # for i, boolVal in boolList:
415
- # if boolVal == 1:
416
- # output = _np.append(i)
417
- # return output
418
-
419
412
  def xor(*args):
420
413
  """
421
414
  Implements logical xor function for arbitrary number of inputs.
@@ -2013,7 +2006,23 @@ def create_candidate_fiducial_list(target_model, omit_identity= True, ops_to_omi
2013
2006
  else:
2014
2007
  availableFidList.extend(_circuits.list_random_circuits_onelen(
2015
2008
  fidOps, fidLength, count, seed=candidate_seed))
2016
- return availableFidList
2009
+
2010
+ #force the line labels on each circuit to match the state space labels for the target model.
2011
+ #this is suboptimal for many-qubit models, so will probably want to revisit this. #TODO
2012
+ finalFidList = []
2013
+ for ckt in availableFidList:
2014
+ if ckt._static:
2015
+ new_ckt = ckt.copy(editable=True)
2016
+ new_ckt.line_labels = target_model.state_space.state_space_labels
2017
+ new_ckt.done_editing()
2018
+
2019
+ finalFidList.append(new_ckt)
2020
+ else:
2021
+ ckt.line_labels = target_model.state_space.state_space_labels
2022
+
2023
+ finalFidList.append(ckt)
2024
+
2025
+ return finalFidList
2017
2026
 
2018
2027
 
2019
2028
 
@@ -290,7 +290,7 @@ def gaugeopt_custom(model, objective_fn, gauge_group=None,
290
290
  gaugeGroupEl = gauge_group.compute_element(x0) # re-used element for evals
291
291
 
292
292
  def _call_objective_fn(gauge_group_el_vec, oob_check=False):
293
- # Note: oob_check can be True if oob_check_interval>=1 is given to the custom_leastsq below
293
+ # Note: oob_check can be True if oob_check_interval>=1 is given to the simplish_leastsq below
294
294
  gaugeGroupEl.from_vector(gauge_group_el_vec)
295
295
  return objective_fn(gaugeGroupEl, oob_check)
296
296
 
@@ -309,7 +309,7 @@ def gaugeopt_custom(model, objective_fn, gauge_group=None,
309
309
  assert(_call_jacobian_fn is not None), "Cannot use 'ls' method unless jacobian is available"
310
310
  ralloc = _baseobjs.ResourceAllocation(comm) # FUTURE: plumb up a resource alloc object?
311
311
  test_f = _call_objective_fn(x0)
312
- solnX, converged, msg, _, _, _, _, _ = _opt.custom_leastsq(
312
+ solnX, converged, msg, _, _, _, _ = _opt.simplish_leastsq(
313
313
  _call_objective_fn, _call_jacobian_fn, x0, f_norm2_tol=tol,
314
314
  jac_norm_tol=tol, rel_ftol=tol, rel_xtol=tol,
315
315
  max_iter=maxiter, resource_alloc=ralloc,