4
4
FCN ,
5
5
MnContours ,
6
6
MnHesse ,
7
+ MnMachinePrecision ,
7
8
MnMigrad ,
8
9
MnMinos ,
9
10
MnPrint ,
@@ -550,13 +551,7 @@ def migrad(self, ncall=None, iterate=5):
550
551
551
552
self ._last_state = fm .state
552
553
553
- # EDM goal
554
- # - taken from the source code, see VariableMeticBuilder::Minimum and
555
- # ModularFunctionMinimizer::Minimize
556
- # - goal is used to detect convergence but violations by 10x are also accepted;
557
- # see VariableMetricBuilder.cxx:425
558
- edm_goal = 2e-3 * max (self ._tolerance * fm .errordef , migrad .precision .eps2 )
559
-
554
+ edm_goal = self ._migrad_edm_goal ()
560
555
self ._fmin = mutil .FMin (fm , self .nfcn , self .ngrad , edm_goal )
561
556
self ._make_covariance ()
562
557
@@ -605,6 +600,8 @@ def simplex(self, ncall=None):
605
600
606
601
edm_goal = max (self ._tolerance * fm .errordef , simplex .precision .eps2 )
607
602
self ._fmin = mutil .FMin (fm , self .nfcn , self .ngrad , edm_goal )
603
+ self ._covariance = None
604
+ self ._merrors = mutil .MErrors ()
608
605
609
606
return self # return self for method chaining and to autodisplay current state
610
607
@@ -694,11 +691,11 @@ def run(ipar):
694
691
run (0 )
695
692
696
693
edm_goal = self ._tolerance * self ._fcn ._errordef
697
- fm = FunctionMinimum (
698
- self ._fcn , self ._last_state , x [self .npar ], self .strategy , edm_goal
699
- )
694
+ fm = FunctionMinimum (self ._fcn , self ._last_state , self .strategy , edm_goal )
700
695
self ._last_state = fm .state
701
696
self ._fmin = mutil .FMin (fm , self .nfcn , self .ngrad , edm_goal )
697
+ self ._covariance = None
698
+ self ._merrors = mutil .MErrors ()
702
699
703
700
return self # return self for method chaining and to autodisplay current state
704
701
@@ -806,13 +803,16 @@ def minos(self, *parameters, cl=None, ncall=None):
806
803
factor = chi2 (1 ).ppf (cl )
807
804
808
805
if not self ._fmin :
809
- raise RuntimeError (
810
- "MINOS require function to be at the minimum. Run MIGRAD first."
806
+ # create a FunctionMinimum for MnMinos
807
+ fm = FunctionMinimum (
808
+ self ._fcn , self ._last_state , self ._strategy , self ._tolerance
811
809
)
810
+ else :
811
+ fm = self ._fmin ._src
812
812
813
813
ncall = 0 if ncall is None else int (ncall )
814
814
815
- if not self . _fmin .is_valid :
815
+ if not fm .is_valid :
816
816
raise RuntimeError (
817
817
"Function minimum is not valid. Make sure MIGRAD converged."
818
818
)
@@ -833,7 +833,7 @@ def minos(self, *parameters, cl=None, ncall=None):
833
833
pars .append (par )
834
834
835
835
with TemporaryErrordef (self ._fcn , factor ):
836
- minos = MnMinos (self ._fcn , self . _fmin . _src , self .strategy )
836
+ minos = MnMinos (self ._fcn , fm , self .strategy )
837
837
for par in pars :
838
838
me = minos (self ._var2pos [par ], ncall , self ._tolerance )
839
839
self ._merrors [par ] = mutil .MError (
@@ -854,8 +854,9 @@ def minos(self, *parameters, cl=None, ncall=None):
854
854
me .min ,
855
855
)
856
856
857
- self ._fmin ._nfcn = self .nfcn
858
- self ._fmin ._ngrad = self .ngrad
857
+ if self ._fmin :
858
+ self ._fmin ._nfcn = self .nfcn
859
+ self ._fmin ._ngrad = self .ngrad
859
860
860
861
return self # return self for method chaining and to autodisplay current state
861
862
@@ -1353,6 +1354,17 @@ def _make_covariance(self):
1353
1354
else :
1354
1355
self ._covariance = None
1355
1356
1357
+ def _migrad_edm_goal (self ):
1358
+ pr = MnMachinePrecision ()
1359
+ if self .precision is not None :
1360
+ pr .eps = self .precision
1361
+ # EDM goal
1362
+ # - taken from the source code, see VariableMeticBuilder::Minimum and
1363
+ # ModularFunctionMinimizer::Minimize
1364
+ # - goal is used to detect convergence but violations by 10x are also accepted;
1365
+ # see VariableMetricBuilder.cxx:425
1366
+ return 2e-3 * max (self .tol * self .errordef , pr .eps2 )
1367
+
1356
1368
def __repr__ (self ):
1357
1369
s = []
1358
1370
if self .fmin is not None :
0 commit comments