36 unsigned int npar = par.size();
37 unsigned int nfcn = 0;
56 std::array<double, 3>
alsb{0., 0., 0.};
57 std::array<double, 3>
flsb{0., 0., 0.};
59 MnPrint print(
"MnFunctionCross");
61 print.
Debug([&](std::ostream &os) {
62 for (
unsigned int i = 0; i < par.size(); ++i)
63 os <<
"Parameter " << par[i] <<
" value " <<
pmid[i] <<
" dir " <<
pdir[i] <<
" function min = " <<
aminsv
64 <<
" contour value aim = (fmin + up) = " <<
aim;
70 for (
unsigned int i = 0; i < par.size(); i++) {
71 unsigned int kex = par[i];
78 if (std::fabs(
zdir) <
fState.Precision().Eps()) {
85 }
else if (
zdir < 0. &&
fState.Parameter(
kex).HasLowerLimit()) {
87 if (std::fabs(
zdir) <
fState.Precision().Eps()) {
102 print.
Warn(
"Parameter is at limit",
pmid[0],
"delta",
pdir[0]);
111 print.
Info([&](std::ostream &os) {
112 os <<
"Run Migrad with fixed parameters:";
113 for (
unsigned i = 0; i <
npar; ++i)
114 os <<
"\n Pos " << par[i] <<
": " <<
fState.Name(par[i]) <<
" = " <<
pmid[i];
117 for (
unsigned int i = 0; i <
npar; i++)
130 print.
Warn(
"New minimum found while scanning parameter", par.front(),
"new value =",
min0.Fval(),
131 "old value =",
fFval);
134 if (
min0.HasReachedCallLimit())
161 print.
Info([&](std::ostream &os) {
162 os <<
"Run Migrad again (2nd) with fixed parameters:";
163 for (
unsigned i = 0; i <
npar; ++i)
164 os <<
"\n Pos " << par[i] <<
": " <<
fState.Name(par[i]) <<
" = " <<
pmid[i] + (
aopt)*
pdir[i];
167 for (
unsigned int i = 0; i <
npar; i++)
177 print.
Debug(
"A new minimum is found: return");
180 if (
min1.HasReachedCallLimit()) {
181 print.
Debug(
"FCN call limit is reached: return");
184 if (!
min1.IsValid()) {
185 print.
Debug(
"Migrad failed: return ");
189 print.
Debug(
"Parameter(s) at limit: return ");
207 for (
unsigned int it = 0; it <
maxlk; it++) {
218 print.
Info([&](std::ostream &os) {
219 os <<
"Run Migrad again (iteration " << it <<
" ) :";
220 for (
unsigned i = 0; i <
npar; ++i)
221 os <<
"\n parameter " << par[i] <<
" (" <<
fState.Name(par[i]) <<
") fixed to "
225 for (
unsigned int i = 0; i <
npar; i++)
234 print.
Debug(
"A new minimum is found: return");
237 if (
min1.HasReachedCallLimit()) {
238 print.
Debug(
"FCN call limit is reached: return");
241 if (!
min1.IsValid()){
242 print.
Debug(
"Migrad failed: return ");
246 print.
Debug(
"Parameter(s) at limit: return ");
272 double fdist = std::min(std::fabs(
aim -
flsb[0]), std::fabs(
aim -
flsb[1]));
275 if (std::fabs(
aopt) > 1.)
278 print.
Info(
"Return: Found good value for aopt = ",
aopt);
282 print.
Info(
"Number of iterations",
ipt,
"larger than max",
maxitr,
": return");
298 print.
Info([&](std::ostream &os) {
299 os <<
"Run Migrad again (3rd) with fixed parameters:";
300 for (
unsigned i = 0; i <
npar; ++i)
301 os <<
"\n Pos " << par[i] <<
": " <<
fState.Name(par[i]) <<
" = " <<
pmid[i] + (
aopt)*
pdir[i];
304 for (
unsigned int i = 0; i <
npar; i++)
313 print.
Debug(
"A new minimum is found: return");
316 if (
min2.HasReachedCallLimit()) {
317 print.
Debug(
"FCN call limit is reached: return");
320 if (!
min2.IsValid()) {
321 print.
Debug(
"Migrad failed: return ");
325 print.
Debug(
"Parameter(s) at limit: return ");
337 unsigned int ibest = 2;
341 for (
unsigned int i = 0; i < 3; i++) {
364 print.
Debug(
"all 3 points are above - invalid result- return");
373 print.
Debug(
"All three points below - look again for positive slope");
383 print.
Debug(
"New straight line using point 1-2; dfda",
dfda);
397 print.
Debug(
"Parabola fit: iteration",
ipt);
415 print.
Debug(
"Parabola fit: x1",
x1,
"x2",
x2,
"s1",
s1,
"s2",
s2);
418 print.
Warn(
"Problem 1");
432 if (std::fabs(
aopt) > 1.)
439 print.
Debug(
"Return: Found best value is within tolerance, aopt",
aopt,
"F=",
flsb[
ibest]);
448 unsigned int ileft = 3;
450 unsigned int iout = 3;
454 for (
unsigned int i = 0; i < 3; i++) {
471 }
else if (
ileft == 3)
511 print.
Info([&](std::ostream &os) {
512 os <<
"Run Migrad again at new point (#iter = " <<
ipt+1 <<
" ):";
513 for (
unsigned i = 0; i <
npar; ++i)
514 os <<
"\n\t - parameter " << par[i] <<
" fixed to " <<
pmid[i] + (
aopt)*
pdir[i];
517 for (
unsigned int i = 0; i <
npar; i++)
526 print.
Debug(
"A new minimum is found: return");
529 if (
min2.HasReachedCallLimit()) {
530 print.
Debug(
"FCN call limit is reached: return");
533 if (!
min2.IsValid()) {
534 print.
Debug(
"Migrad failed: return ");
538 print.
Debug(
"Parameter(s) at limit: return ");
551 print.
Debug(
"Best point is not found: return invalid result after many trial",
ipt);
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
class holding the full result of the minimization; both internal and external (MnUserParameterState) ...
void SetValue(unsigned int, double)
MnCross operator()(std::span< const unsigned int >, std::span< const double >, std::span< const double >, double, unsigned int) const
const MnUserParameterState & fState
const MnStrategy & fStrategy
Sets the relative floating point (double) arithmetic precision.
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.
void Debug(const Ts &... args)
void Info(const Ts &... args)
void Warn(const Ts &... args)
API class for defining four levels of strategies: low (0), medium (1), high (2), very high (>=3); act...
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...