31 const std::vector<double>& pdir,
double tlr,
unsigned int maxcalls)
const {
39 unsigned int npar = par.size();
40 unsigned int nfcn = 0;
43 double mgr_tlr = 0.5 * tlr;
52 unsigned int maxitr = 15;
54 double aminsv =
fFval;
55 double aim = aminsv + up;
59 std::vector<double> alsb(3, 0.), flsb(3, 0.);
67 for (
unsigned int i = 0; i < par.size(); ++i)
68 std::cout <<
"MnFunctionCross for parameter " << par[i] <<
" value " << pmid[i] <<
" dir " << pdir[i]
69 <<
" function min = " << aminsv <<
" contur value aim = (fmin + up) = " << aim << std::endl;
76 for(
unsigned int i = 0; i < par.size(); i++) {
77 unsigned int kex = par[i];
79 double zmid = pmid[i];
80 double zdir = pdir[i];
89 aulim = std::min(aulim, (zlim-zmid)/zdir);
98 aulim = std::min(aulim, (zlim-zmid)/zdir);
104 std::cout<<
"Largest allowed aulim "<< aulim << std::endl;
109 if (limset && npar == 1) {
111 std::cout <<
"MnFunctionCross: parameter is at limit " << pmid[0] <<
" delta "
112 << pdir[0] << std::endl;
116 if (aulim < aopt + tla)
121 if (printLevel > 2) {
122 std::cout <<
"MnFunctionCross: Run Migrad fixing parameters :";
123 if (npar > 1) std::cout << std::endl;
125 for (
unsigned int i = 0; i < npar; i++) {
129 if (printLevel > 2) {
130 std::cout <<
"\t" <<
fState.
Name(par[i]) <<
" #" << par[i] <<
" to " << pmid[i] << std::endl;
138 if (printLevel > 2) {
146 if (printLevel > 1) {
147 std::cout <<
"MnFunctionCross: A new minimum is found when scanning parameter " << par.front() <<
" new value = "
148 << min0.
Fval() <<
" old value : " <<
fFval << std::endl;
155 if(limset ==
true && min0.
Fval() < aim)
160 flsb[0] = min0.
Fval();
161 flsb[0] = std::max(flsb[0], aminsv + 0.1*up);
162 aopt =
sqrt(up/(flsb[0]-aminsv)) - 1.;
165 if(aopt > 1.) aopt = 1.;
166 if(aopt < -0.5) aopt = -0.5;
173 std::cout <<
"MnFunctionCross: flsb[0] = " << flsb[0] <<
" aopt = " << aopt << std::endl;
176 if (printLevel > 2) {
177 std::cout <<
"MnFunctionCross: Run Migrad again (#2) : ";
178 if (npar > 1) std::cout << std::endl;
180 for (
unsigned int i = 0; i < npar; i++) {
181 migrad.
SetValue(par[i], pmid[i] + (aopt)*pdir[i]);
182 if (printLevel > 2) {
183 std::cout <<
"\t - parameter " << i <<
" fixed to " << pmid[i] + (aopt)*pdir[i] << std::endl;
190 if (printLevel > 2) {
200 if(limset ==
true && min1.
Fval() < aim)
205 flsb[1] = min1.
Fval();
206 double dfda = (flsb[1] - flsb[0])/(alsb[1] - alsb[0]);
209 std::cout <<
"aopt = " << aopt <<
" min1Val = " << flsb[1] <<
" dfda = " << dfda << std::endl;
217 std::cout <<
"MnFunctionCross: dfda < 0 - iterate from " << ipt <<
" to max of " << maxitr << std::endl;
221 unsigned int maxlk = maxitr - ipt;
222 for(
unsigned int it = 0; it < maxlk; it++) {
226 aopt = alsb[0] + 0.2*(it+1);
232 if (printLevel > 2) {
233 std::cout <<
"MnFunctionCross: Run Migrad again (iteration " << it <<
" ) : ";
234 if (npar > 1) std::cout << std::endl;
236 for(
unsigned int i = 0; i < npar; i++) {
237 migrad.
SetValue(par[i], pmid[i] + (aopt)*pdir[i]);
238 if (printLevel > 2) {
239 std::cout <<
"\t - parameter " << i <<
" fixed to " << pmid[i] + (aopt)*pdir[i] << std::endl;
242 min1 = migrad(maxcalls, mgr_tlr);
245 if (printLevel > 2) {
255 if(limset ==
true && min1.
Fval() < aim)
259 flsb[1] = min1.
Fval();
260 dfda = (flsb[1] - flsb[0])/(alsb[1] - alsb[0]);
264 std::cout <<
"aopt = " << aopt <<
" min1Val = " << flsb[1] <<
" dfda = " << dfda << std::endl;
276 aopt = alsb[1] + (aim-flsb[1])/dfda;
279 std::cout <<
"MnFunctionCross: dfda > 0 : aopt = " << aopt << std::endl;
282 double fdist = std::min(
fabs(aim - flsb[0]),
fabs(aim - flsb[1]));
283 double adist = std::min(
fabs(aopt - alsb[0]),
fabs(aopt - alsb[1]));
285 if(
fabs(aopt) > 1.) tla = tlr*
fabs(aopt);
286 if(adist < tla && fdist < tlf)
return MnCross(aopt, min1.
UserState(), nfcn);
288 double bmin = std::min(alsb[0], alsb[1]) - 1.;
289 if(aopt < bmin) aopt = bmin;
290 double bmax = std::max(alsb[0], alsb[1]) + 1.;
291 if(aopt > bmax) aopt = bmax;
299 if (printLevel > 2) {
300 std::cout <<
"MnFunctionCross: Run Migrad again (#3) : ";
301 if (npar > 1) std::cout << std::endl;
303 for(
unsigned int i = 0; i < npar; i++) {
304 migrad.
SetValue(par[i], pmid[i] + (aopt)*pdir[i]);
305 if (printLevel > 2) {
306 std::cout <<
"\t : parameter " << i <<
" fixed to " << pmid[i] + (aopt)*pdir[i] << std::endl;
312 if (printLevel > 2) {
322 if(limset ==
true && min2.
Fval() < aim)
327 flsb[2] = min2.
Fval();
331 double ecarmn =
fabs(flsb[2] - aim);
333 unsigned int ibest = 2;
334 unsigned int iworst = 0;
335 unsigned int noless = 0;
337 for(
unsigned int i = 0; i < 3; i++) {
338 double ecart =
fabs(flsb[i] - aim);
347 if(flsb[i] < aim) noless++;
351 std::cout <<
"MnFunctionCross: have three points : nless < aim = " << noless <<
" ibest = " << ibest <<
" iworst = " << iworst << std::endl;
357 if(noless == 1 || noless == 2)
goto L500;
362 if(noless == 3 && ibest != 2) {
366 std::cout <<
"MnFunctionCross: all three points below - look again fir positive slope " << std::endl;
373 flsb[iworst] = flsb[2];
374 alsb[iworst] = alsb[2];
375 dfda = (flsb[1] - flsb[0])/(alsb[1] - alsb[0]);
377 std::cout <<
"MnFunctionCross: new straight line using point 1-2 - dfda = " << dfda << std::endl;
391 std::cout <<
"MnFunctionCross: parabola fit: iteration " << ipt << std::endl;
394 double coeff1 = parbol.
C();
395 double coeff2 = parbol.
B();
396 double coeff3 = parbol.
A();
397 double determ = coeff2*coeff2 - 4.*coeff3*(coeff1 - aim);
400 std::cout <<
"MnFunctionCross: parabola fit: a = " << coeff3 <<
" b = "
401 << coeff2 <<
" c = " << coeff1 <<
" determ = " << determ << std::endl;
405 double rt =
sqrt(determ);
406 double x1 = (-coeff2 + rt)/(2.*coeff3);
407 double x2 = (-coeff2 - rt)/(2.*coeff3);
408 double s1 = coeff2 + 2.*
x1*coeff3;
409 double s2 = coeff2 + 2.*
x2*coeff3;
412 std::cout <<
"MnFunctionCross: parabola fit: x1 = " <<
x1 <<
" x2 = "
413 <<
x2 <<
" s1 = " <<
s1 <<
" s2 = " << s2 << std::endl;
427 std::cout <<
"MnFunctionCross: parabola fit: aopt = " << aopt <<
" slope = "
428 << slope << std::endl;
433 if(
fabs(aopt) > 1.) tla = tlr*
fabs(aopt);
436 std::cout <<
"MnFunctionCross: Delta(aopt) = " <<
fabs(aopt - alsb[ibest]) <<
" tla = "
437 << tla <<
"Delta(F) = " <<
fabs(flsb[ibest] - aim) <<
" tlf = " << tlf << std::endl;
441 if(
fabs(aopt - alsb[ibest]) < tla &&
fabs(flsb[ibest] - aim) < tlf)
449 unsigned int ileft = 3;
450 unsigned int iright = 3;
451 unsigned int iout = 3;
454 ecarmn =
fabs(aim-flsb[0]);
455 for(
unsigned int i = 0; i < 3; i++) {
456 double ecart =
fabs(flsb[i] - aim);
461 if(ecart > ecarmx) ecarmx = ecart;
463 if(iright == 3) iright = i;
464 else if(flsb[i] > flsb[iright]) iout = i;
469 }
else if(ileft == 3) ileft = i;
470 else if(flsb[i] < flsb[ileft]) iout = i;
478 std::cout <<
"MnFunctionCross: ileft = " << ileft <<
" iright = "
479 << iright <<
" iout = " << iout <<
" ibest = " << ibest << std::endl;
484 if(ecarmx > 10.*
fabs(flsb[iout] - aim))
485 aopt = 0.5*(aopt + 0.5*(alsb[iright] + alsb[ileft]));
488 double smalla = 0.1*tla;
489 if(slope*smalla > tlf) smalla = tlf/slope;
490 double aleft = alsb[ileft] + smalla;
491 double aright = alsb[iright] - smalla;
494 if(aopt < aleft) aopt = aleft;
495 if(aopt > aright) aopt = aright;
496 if(aleft > aright) aopt = 0.5*(aleft + aright);
506 if (printLevel > 2) {
507 std::cout <<
"MnFunctionCross: Run Migrad again at new point (#iter = " << ipt <<
" ): ";
508 if (npar > 1) std::cout << std::endl;
510 for(
unsigned int i = 0; i < npar; i++) {
511 migrad.
SetValue(par[i], pmid[i] + (aopt)*pdir[i]);
512 if (printLevel > 2) {
513 std::cout <<
"\t : parameter " << i <<
" fixed to " << pmid[i] + (aopt)*pdir[i] << std::endl;
516 min2 = migrad(maxcalls, mgr_tlr);
519 if (printLevel > 2) {
529 if(limset ==
true && min2.
Fval() < aim)
535 flsb[iout] = min2.
Fval();
537 }
while(ipt < maxitr);
static const double x2[5]
static const double x1[5]
virtual double Up() const =0
Error definition of the function.
class holding the full result of the minimization; both internal and external (MnUserParameterState) ...
bool HasReachedCallLimit() const
const MnUserParameterState & UserState() const
const MinimumState & State() const
double LowerLimit() const
double UpperLimit() const
bool HasLowerLimit() const
bool HasUpperLimit() const
void SetValue(unsigned int, double)
const MnUserParameterState & fState
const MnStrategy & fStrategy
MnCross operator()(const std::vector< unsigned int > &, const std::vector< double > &, const std::vector< double > &, double, unsigned int) const
Sets the relative floating point (double) arithmetic precision.
double Eps() const
eps returns the smallest possible number so that 1.+eps > 1.
API class for minimization using Variable Metric technology ("MIGRAD"); allows for user interaction: ...
This class defines a parabola of the form a*x*x + b*x + c.
double B() const
Accessor to the coefficient of the linear term.
double C() const
Accessor to the coefficient of the constant term.
double A() const
Accessor to the coefficient of the quadratic term.
static void PrintState(std::ostream &os, const MinimumState &state, const char *msg, int iter=-1)
API class for defining three levels of strategies: low (0), medium (1), high (>=2); acts on: Migrad (...
unsigned int Strategy() const
const MnMachinePrecision & Precision() const
const MnUserParameters & Parameters() const
const MinuitParameter & Parameter(unsigned int i) const
const char * Name(unsigned int) const
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...