@@ -179,7 +179,7 @@ def do_lgst(dataset, prepStrs, effectStrs, targetModel, opLabels=None, opLabelAl
179
179
if svdTruncateTo is None or svdTruncateTo == targetModel .dim : #use target sslbls and basis
180
180
lgstModel = _objs .ExplicitOpModel (targetModel .state_space_labels , targetModel .basis )
181
181
else : # construct a default basis for the requested dimension
182
- dumb_basis = _objs .Basis ( 'gm' ,[ 1 ]* svdTruncateTo ) # - just act on diagonal density mx
182
+ dumb_basis = _objs .DirectSumBasis ( [ _objs . BuiltinBasis ( 'gm' ,1 ) ]* svdTruncateTo ) # - just act on diagonal density mx
183
183
lgstModel = _objs .ExplicitOpModel ([('L%d' % i ,) for i in range (svdTruncateTo )], dumb_basis )
184
184
185
185
for opLabel in opLabelsToEstimate :
@@ -2437,6 +2437,7 @@ def _objective_func(vectorGS):
2437
2437
v = _np .where ( probs < min_p , v + S * (probs - min_p ) + S2 * (probs - min_p )** 2 , v ) #quadratic extrapolation of logl at min_p for probabilities < min_p
2438
2438
v = _np .where ( minusCntVecMx == 0 , totalCntVec * _np .where (probs >= a , probs , (- 1.0 / (3 * a ** 2 ))* probs ** 3 + probs ** 2 / a + a / 3.0 ), v )
2439
2439
#special handling for f == 0 terms using quadratic rounding of function with minimum: max(0,(a-p)^2)/(2a) + p
2440
+ #assert( _np.all(v >= 0) ), "LogL term is < 0! (This is usually caused by using a large #samples without reducing minProbClip)"
2440
2441
v = _np .sqrt ( v )
2441
2442
v .shape = [KM ] #reshape ensuring no copy is needed
2442
2443
if cptp_penalty_factor != 0 :
@@ -2534,6 +2535,7 @@ def _objective_func(vectorGS):
2534
2535
v = _np .maximum (v ,0 ) #remove small negative elements due to roundoff error (above expression *cannot* really be negative)
2535
2536
v = _np .where ( probs < min_p , v + S * (probs - min_p ) + S2 * (probs - min_p )** 2 , v ) #quadratic extrapolation of logl at min_p for probabilities < min_p
2536
2537
v = _np .where ( minusCntVecMx == 0 , 0.0 , v )
2538
+ #assert( _np.all(v >= 0) ), "LogL term is < 0! (This is usually caused by using a large #samples without reducing minProbClip)"
2537
2539
v = _np .sqrt ( v )
2538
2540
assert (v .shape == (KM ,)) #reshape ensuring no copy is needed
2539
2541
@@ -2687,7 +2689,7 @@ def do_iterative_mlgst(dataset, startModel, circuitSetsToUseInEstimation,
2687
2689
verbosity = 0 , check = False , circuitWeightsDict = None ,
2688
2690
opLabelAliases = None , memLimit = None ,
2689
2691
profiler = None , comm = None , distributeMethod = "deriv" ,
2690
- alwaysPerformMLE = False , evaltree_cache = None ):
2692
+ alwaysPerformMLE = False , onlyPerformMLE = False , evaltree_cache = None ):
2691
2693
"""
2692
2694
Performs Iterative Maximum Likelihood Estimation Gate Set Tomography on the dataset.
2693
2695
@@ -2806,6 +2808,10 @@ def do_iterative_mlgst(dataset, startModel, circuitSetsToUseInEstimation,
2806
2808
not just the final one. When False, chi2 minimization is used for all
2807
2809
except the final iteration (for improved numerical stability).
2808
2810
2811
+ onlyPerformMLE : bool, optional
2812
+ When True, `alwaysPerformMLE` must also be true, and in this case only
2813
+ a ML optimization is performed for each iteration.
2814
+
2809
2815
evaltree_cache : dict, optional
2810
2816
An empty dictionary which gets filled with the *final* computed EvalTree
2811
2817
(and supporting info) used in this computation.
@@ -2823,6 +2829,9 @@ def do_iterative_mlgst(dataset, startModel, circuitSetsToUseInEstimation,
2823
2829
of the i-th iteration.
2824
2830
"""
2825
2831
2832
+ if onlyPerformMLE :
2833
+ assert (alwaysPerformMLE ), "Must set `alwaysPerformMLE` to True whenever `onlyPerformMLE` is True."
2834
+
2826
2835
printer = _objs .VerbosityPrinter .build_printer (verbosity , comm )
2827
2836
if profiler is None : profiler = _dummy_profiler
2828
2837
@@ -2864,12 +2873,13 @@ def do_iterative_mlgst(dataset, startModel, circuitSetsToUseInEstimation,
2864
2873
num_fd = fditer if (i == 0 ) else 0
2865
2874
2866
2875
evt_cache = {} # get the eval tree that's created so we can reuse it
2867
- _ , mleModel = do_mc2gst (dataset , mleModel , stringsToEstimate ,
2868
- maxiter , maxfev , num_fd , tol , cptp_penalty_factor ,
2869
- spam_penalty_factor , minProbClip , probClipInterval ,
2870
- useFreqWeightedChiSq , 0 ,printer - 1 , check ,
2871
- check , circuitWeights , opLabelAliases ,
2872
- memLimit , comm , distributeMethod , profiler , evt_cache )
2876
+ if not onlyPerformMLE :
2877
+ _ , mleModel = do_mc2gst (dataset , mleModel , stringsToEstimate ,
2878
+ maxiter , maxfev , num_fd , tol , cptp_penalty_factor ,
2879
+ spam_penalty_factor , minProbClip , probClipInterval ,
2880
+ useFreqWeightedChiSq , 0 ,printer - 1 , check ,
2881
+ check , circuitWeights , opLabelAliases ,
2882
+ memLimit , comm , distributeMethod , profiler , evt_cache )
2873
2883
2874
2884
if alwaysPerformMLE :
2875
2885
_ , mleModel = do_mlgst (dataset , mleModel , stringsToEstimate ,
@@ -3054,7 +3064,7 @@ def _spam_penalty_jac_fill(spamPenaltyVecGradToFill, mdl, prefactor, opBasis):
3054
3064
Helper function - jacobian of CPTP penalty (sum of tracenorms of gates)
3055
3065
Returns a (real) array of shape ( _spam_penalty_size(mdl), nParams).
3056
3066
"""
3057
- BMxs = opBasis .get_composite_matrices () #shape [mdl.dim, dmDim, dmDim]
3067
+ BMxs = opBasis .elements #shape [mdl.dim, dmDim, dmDim]
3058
3068
ddenMxdV = dEMxdV = BMxs .conjugate () # b/c denMx = sum( spamvec[i] * Bmx[i] ) and "V" == spamvec
3059
3069
#NOTE: conjugate() above is because ddenMxdV and dEMxdV will get *elementwise*
3060
3070
# multiplied (einsum below) by another complex matrix (sgndm or sgnE) and summed
0 commit comments