@@ -619,8 +619,6 @@ def _mock_objective_fn(v):
619
619
620
620
assert gates_metric != "frobeniustt"
621
621
assert spam_metric != "frobeniustt"
622
- assert spam_metric == gates_metric
623
- metric = spam_metric
624
622
# assert spam_metric == gates_metric
625
623
# ^ Erik and Corey said these are rarely used. I've removed support for
626
624
# them in this codepath (non-LS optimizer) in order to make it easier to
@@ -641,73 +639,103 @@ def _objective_fn(gauge_group_el, oob_check):
641
639
spamPenaltyVec = _spam_penalty (mdl , spam_penalty_factor , mdl .basis )
642
640
ret += _np .sum (spamPenaltyVec )
643
641
644
- assert target_model is not None
645
- """
646
- Leakage-aware metric supported, per implementation in mdl.frobeniusdist.
647
- Refer to how mdl.frobeniusdist handles the case when transform_mx_arg
648
- is a tuple in order to understand how the leakage-aware metric is defined.
649
-
650
- Idea: raise an error if mxBasis isn't leakage-friendly.
651
- PROBLEM: if we're deep in the code then we end up needing to be
652
- working in a basis that has the identity matrix as its
653
- first element. The leakage-friendly basis doesn't even
654
- have the identity matrix as an element, let alone the first element
655
-
656
- TODO: dig into function calls below and see where we can
657
- access the mxBasis object. (I'm sure we can.)
658
- Looks like it isn't accessible within ExplicitOpModelCalc objects.
659
- It's most definitely available in ExplicitOpModel.
660
- """
661
- if "frobenius" in metric :
662
- val = mdl .frobeniusdist (target_model , transform_mx_arg , item_weights )
663
- if "squared" in metric :
664
- val = val ** 2
665
- ret += val
666
- return ret
667
-
668
- elif metric == "fidelity" :
669
- # Leakage-aware metric supported for gates, using leaky_entanglement_fidelity.
670
- for opLbl in mdl .operations :
671
- wt = item_weights .get (opLbl , opWeight )
672
- top = target_model .operations [opLbl ].to_dense ()
673
- mop = mdl .operations [opLbl ].to_dense ()
674
- ret += wt * (1.0 - _tools .leaky_entanglement_fidelity (top , mop , mxBasis , n_leak ))** 2
675
- # Leakage-aware metrics NOT available for SPAM
676
- for preplabel , m_prep in mdl .preps .items ():
677
- wt = item_weights .get (preplabel , spamWeight )
678
- rhoMx1 = _tools .vec_to_stdmx (m_prep .to_dense (), mxBasis )
679
- t_prep = target_model .preps [preplabel ]
680
- rhoMx2 = _tools .vec_to_stdmx (t_prep .to_dense (), mxBasis )
681
- ret += wt * (1.0 - _tools .fidelity (rhoMx1 , rhoMx2 ))** 2
682
- for povmlabel in mdl .povms .keys ():
683
- wt = item_weights .get (povmlabel , spamWeight )
684
- fidelity = _tools .povm_fidelity (mdl , target_model , povmlabel )
685
- ret += wt * (1.0 - fidelity )** 2
686
- return ret
687
-
688
- elif metric == "tracedist" :
689
- # Leakage-aware metric supported, using leaky_jtracedist.
690
- for opLbl in mdl .operations :
691
- wt = item_weights .get (opLbl , opWeight )
692
- top = target_model .operations [opLbl ].to_dense ()
693
- mop = mdl .operations [opLbl ].to_dense ()
694
- ret += wt * _tools .leaky_jtracedist (top , mop , mxBasis , n_leak )
695
- # Leakage-aware metrics NOT available for SPAM
696
- for preplabel , m_prep in mdl .preps .items ():
697
- wt = item_weights .get (preplabel , spamWeight )
698
- rhoMx1 = _tools .vec_to_stdmx (m_prep .to_dense (), mxBasis )
699
- t_prep = target_model .preps [preplabel ]
700
- rhoMx2 = _tools .vec_to_stdmx (t_prep .to_dense (), mxBasis )
701
- ret += wt * _tools .tracedist (rhoMx1 , rhoMx2 )
702
- for povmlabel in mdl .povms .keys ():
703
- wt = item_weights .get (povmlabel , spamWeight )
704
- ret += wt * _tools .povm_jtracedist (mdl , target_model , povmlabel )
705
- return ret
642
+ if target_model is not None :
643
+ """
644
+ Leakage-aware metric supported, per implementation in mdl.frobeniusdist.
645
+ Refer to how mdl.frobeniusdist handles the case when transform_mx_arg
646
+ is a tuple in order to understand how the leakage-aware metric is defined.
647
+
648
+ Idea: raise an error if mxBasis isn't leakage-friendly.
649
+ PROBLEM: if we're deep in the code then we end up needing to be
650
+ working in a basis that has the identity matrix as its
651
+ first element. The leakage-friendly basis doesn't even
652
+ have the identity matrix as an element, let alone the first element
653
+
654
+ TODO: dig into function calls below and see where we can
655
+ access the mxBasis object. (I'm sure we can.)
656
+ Looks like it isn't accessible within ExplicitOpModelCalc objects.
657
+ It's most definitely available in ExplicitOpModel.
658
+ """
659
+ if "frobenius" in gates_metric :
660
+ if spam_metric == gates_metric :
661
+ val = mdl .frobeniusdist (target_model , transform_mx_arg , item_weights )
662
+ else :
663
+ wts = item_weights .copy ()
664
+ wts ['spam' ] = 0.0
665
+ for k in wts :
666
+ if k in mdl .preps or k in mdl .povms :
667
+ wts [k ] = 0.0
668
+ val = mdl .frobeniusdist (target_model , transform_mx_arg , wts , n_leak )
669
+ if "squared" in gates_metric :
670
+ val = val ** 2
671
+ ret += val
672
+
673
+ elif gates_metric == "fidelity" :
674
+ # Leakage-aware metric supported, using leaky_entanglement_fidelity.
675
+ for opLbl in mdl .operations :
676
+ wt = item_weights .get (opLbl , opWeight )
677
+ top = target_model .operations [opLbl ].to_dense ()
678
+ mop = mdl .operations [opLbl ].to_dense ()
679
+ ret += wt * (1.0 - _tools .leaky_entanglement_fidelity (top , mop , mxBasis , n_leak ))** 2
680
+
681
+ elif gates_metric == "tracedist" :
682
+ # Leakage-aware metric supported, using leaky_jtracedist.
683
+ for opLbl in mdl .operations :
684
+ wt = item_weights .get (opLbl , opWeight )
685
+ top = target_model .operations [opLbl ].to_dense ()
686
+ mop = mdl .operations [opLbl ].to_dense ()
687
+ ret += wt * _tools .leaky_jtracedist (top , mop , mxBasis , n_leak )
688
+
689
+ else : raise ValueError ("Invalid gates_metric: %s" % gates_metric )
690
+
691
+ if "frobenius" in spam_metric and gates_metric == spam_metric :
692
+ # We already handled SPAM error in this case. Just return.
693
+ return ret
694
+
695
+ elif "frobenius" in spam_metric :
696
+ # Leakage-aware metric supported in principle via implementation in
697
+ # mdl.frobeniusdist (check implementation to see how it handles the
698
+ # case when transform_mx_arg is a tuple).
699
+ wts = item_weights .copy (); wts ['gates' ] = 0.0
700
+ for k in wts :
701
+ if k in mdl .operations or \
702
+ k in mdl .instruments : wts [k ] = 0.0
703
+ val = mdl .frobeniusdist (target_model , transform_mx_arg , wts )
704
+ if "squared" in spam_metric :
705
+ val = val ** 2
706
+ ret += val
707
+
708
+ elif spam_metric == "fidelity" :
709
+ # Leakage-aware metrics NOT available
710
+ for preplabel , m_prep in mdl .preps .items ():
711
+ wt = item_weights .get (preplabel , spamWeight )
712
+ rhoMx1 = _tools .vec_to_stdmx (m_prep .to_dense (), mxBasis )
713
+ t_prep = target_model .preps [preplabel ]
714
+ rhoMx2 = _tools .vec_to_stdmx (t_prep .to_dense (), mxBasis )
715
+ ret += wt * (1.0 - _tools .fidelity (rhoMx1 , rhoMx2 ))** 2
716
+
717
+ for povmlabel in mdl .povms .keys ():
718
+ wt = item_weights .get (povmlabel , spamWeight )
719
+ fidelity = _tools .povm_fidelity (mdl , target_model , povmlabel )
720
+ ret += wt * (1.0 - fidelity )** 2
721
+
722
+ elif spam_metric == "tracedist" :
723
+ # Leakage-aware metrics NOT available.
724
+ for preplabel , m_prep in mdl .preps .items ():
725
+ wt = item_weights .get (preplabel , spamWeight )
726
+ rhoMx1 = _tools .vec_to_stdmx (m_prep .to_dense (), mxBasis )
727
+ t_prep = target_model .preps [preplabel ]
728
+ rhoMx2 = _tools .vec_to_stdmx (t_prep .to_dense (), mxBasis )
729
+ ret += wt * _tools .tracedist (rhoMx1 , rhoMx2 )
730
+
731
+ for povmlabel in mdl .povms .keys ():
732
+ wt = item_weights .get (povmlabel , spamWeight )
733
+ ret += wt * _tools .povm_jtracedist (mdl , target_model , povmlabel )
734
+
735
+ else : raise ValueError ("Invalid spam_metric: %s" % spam_metric )
736
+
737
+ return ret
706
738
707
- else :
708
- raise ValueError ("Invalid metric: %s" % metric )
709
- # end _objective_fn
710
-
711
739
_jacobian_fn = None
712
740
713
741
return _objective_fn , _jacobian_fn
0 commit comments