50 MinimumSeed MnSeedGenerator::operator()(
const MnFcn& fcn,
const GradientCalculator& gc,
const MnUserParameterState& st,
const MnStrategy& stra)
const {
54 unsigned int n = st.VariableParameters();
55 const MnMachinePrecision& prec = st.Precision();
58 std::cout <<
"MnSeedGenerator: operator() - var par = " << n <<
" mnfcn pointer " << &fcn << std::endl;
61 int printLevel = MnPrint::Level();
64 MnAlgebraicVector x(n);
65 for(
unsigned int i = 0; i < n; i++) x(i) = st.IntParameters()[i];
66 double fcnmin = fcn(x);
69 std::cout <<
"MnSeedGenerator: for initial parameters FCN = ";
70 MnPrint::PrintFcn(std::cout,fcnmin);
73 MinimumParameters pa(x, fcnmin);
74 FunctionGradient dgrad = gc(pa);
75 MnAlgebraicSymMatrix mat(n);
77 if(st.HasCovariance()) {
78 for(
unsigned int i = 0; i < n; i++)
79 for(
unsigned int j = i; j < n; j++) mat(i,j) = st.IntCovariance()(i,j);
82 for(
unsigned int i = 0; i < n; i++)
83 mat(i,i) = (fabs(dgrad.G2()(i)) > prec.Eps2() ? 1./dgrad.G2()(i) : 1.);
85 MinimumError err(mat, dcovar);
87 double edm = VariableMetricEDMEstimator().Estimate(dgrad, err);
88 MinimumState state(pa, err, dgrad, edm, fcn.NumOfCalls());
91 MnPrint::PrintState(std::cout, state,
"MnSeedGenerator: Initial state: ");
94 NegativeG2LineSearch ng2ls;
95 if(ng2ls.HasNegativeG2(dgrad, prec)) {
97 std::cout <<
"MnSeedGenerator: Negative G2 Found: " << std::endl;
98 std::cout << x << std::endl;
99 std::cout << dgrad.Grad() << std::endl;
100 std::cout << dgrad.G2() << std::endl;
102 state = ng2ls(fcn, state, gc, prec);
105 MnPrint::PrintState(std::cout, state,
"MnSeedGenerator: Negative G2 found - new state: ");
111 if(stra.Strategy() == 2 && !st.HasCovariance()) {
114 std::cout <<
"MnSeedGenerator: calling MnHesse " << std::endl;
116 MinimumState tmp = MnHesse(stra)(fcn, state, st.Trafo());
119 MnPrint::PrintState(std::cout, tmp,
"MnSeedGenerator: run Hesse - new state: ");
122 return MinimumSeed(tmp, st.Trafo());
125 return MinimumSeed(state, st.Trafo());
129 MinimumSeed MnSeedGenerator::operator()(
const MnFcn& fcn,
const AnalyticalGradientCalculator& gc,
const MnUserParameterState& st,
const MnStrategy& stra)
const {
131 unsigned int n = st.VariableParameters();
132 const MnMachinePrecision& prec = st.Precision();
135 MnAlgebraicVector x(n);
136 for(
unsigned int i = 0; i < n; i++) x(i) = st.IntParameters()[i];
137 double fcnmin = fcn(x);
138 MinimumParameters pa(x, fcnmin);
140 InitialGradientCalculator igc(fcn, st.Trafo(), stra);
141 FunctionGradient tmp = igc(pa);
142 FunctionGradient grd = gc(pa);
143 FunctionGradient dgrad(grd.Grad(), tmp.G2(), tmp.Gstep());
145 if(gc.CheckGradient()) {
147 HessianGradientCalculator hgc(fcn, st.Trafo(), MnStrategy(2));
148 std::pair<FunctionGradient, MnAlgebraicVector> hgrd = hgc.DeltaGradient(pa, dgrad);
149 for(
unsigned int i = 0; i < n; i++) {
150 if(fabs(hgrd.first.Grad()(i) - grd.Grad()(i)) > hgrd.second(i)) {
152 MN_INFO_MSG(
"MnSeedGenerator:gradient discrepancy of external Parameter too large");
153 int externalParameterIndex = st.Trafo().ExtOfInt(i);
154 const char * parameter_name = st.Trafo().Name(externalParameterIndex);
155 MN_INFO_VAL(parameter_name);
156 MN_INFO_VAL(externalParameterIndex);
157 MN_INFO_VAL2(
"internal",i);
164 MN_ERROR_MSG(
"Minuit does not accept user specified Gradient. To force acceptance, override 'virtual bool CheckGradient() const' of FCNGradientBase.h in the derived class.");
170 MnAlgebraicSymMatrix mat(n);
172 if(st.HasCovariance()) {
173 for(
unsigned int i = 0; i < n; i++)
174 for(
unsigned int j = i; j < n; j++) mat(i,j) = st.IntCovariance()(i,j);
177 for(
unsigned int i = 0; i < n; i++)
178 mat(i,i) = (fabs(dgrad.G2()(i)) > prec.Eps2() ? 1./dgrad.G2()(i) : 1.);
180 MinimumError err(mat, dcovar);
181 double edm = VariableMetricEDMEstimator().Estimate(dgrad, err);
182 MinimumState state(pa, err, dgrad, edm, fcn.NumOfCalls());
184 NegativeG2LineSearch ng2ls;
185 if(ng2ls.HasNegativeG2(dgrad, prec)) {
186 Numerical2PGradientCalculator ngc(fcn, st.Trafo(), stra);
187 state = ng2ls(fcn, state, ngc, prec);
190 if(stra.Strategy() == 2 && !st.HasCovariance()) {
192 MinimumState tmpState = MnHesse(stra)(fcn, state, st.Trafo());
193 return MinimumSeed(tmpState, st.Trafo());
196 return MinimumSeed(state, st.Trafo());