34 unsigned int npar = par.size();
35 unsigned int nfcn = 0;
54 std::array<double, 3>
alsb{0., 0., 0.};
55 std::array<double, 3>
flsb{0., 0., 0.};
57 MnPrint print(
"MnFunctionCross");
59 print.
Debug([&](std::ostream &os) {
60 for (
unsigned int i = 0; i < par.size(); ++i)
61 os <<
"Parameter " << par[i] <<
" value " <<
pmid[i] <<
" dir " <<
pdir[i] <<
" function min = " <<
aminsv
62 <<
" contour value aim = (fmin + up) = " <<
aim;
68 for (
unsigned int i = 0; i < par.size(); i++) {
69 unsigned int kex = par[i];
76 if (std::fabs(
zdir) <
fState.Precision().Eps()) {
83 }
else if (
zdir < 0. &&
fState.Parameter(
kex).HasLowerLimit()) {
85 if (std::fabs(
zdir) <
fState.Precision().Eps()) {
100 print.
Warn(
"Parameter is at limit",
pmid[0],
"delta",
pdir[0]);
109 print.
Info([&](std::ostream &os) {
110 os <<
"Run Migrad with fixed parameters:";
111 for (
unsigned i = 0; i <
npar; ++i)
112 os <<
"\n Pos " << par[i] <<
": " <<
fState.Name(par[i]) <<
" = " <<
pmid[i];
115 for (
unsigned int i = 0; i <
npar; i++)
128 print.
Warn(
"New minimum found while scanning parameter", par.front(),
"new value =",
min0.Fval(),
129 "old value =",
fFval);
132 if (
min0.HasReachedCallLimit())
159 print.
Info([&](std::ostream &os) {
160 os <<
"Run Migrad again (2nd) with fixed parameters:";
161 for (
unsigned i = 0; i <
npar; ++i)
162 os <<
"\n Pos " << par[i] <<
": " <<
fState.Name(par[i]) <<
" = " <<
pmid[i] + (
aopt)*
pdir[i];
165 for (
unsigned int i = 0; i <
npar; i++)
175 print.
Debug(
"A new minimum is found: return");
178 if (
min1.HasReachedCallLimit()) {
179 print.
Debug(
"FCN call limit is reached: return");
182 if (!
min1.IsValid()) {
183 print.
Debug(
"Migrad failed: return ");
187 print.
Debug(
"Parameter(s) at limit: return ");
205 for (
unsigned int it = 0; it <
maxlk; it++) {
216 print.
Info([&](std::ostream &os) {
217 os <<
"Run Migrad again (iteration " << it <<
" ) :";
218 for (
unsigned i = 0; i <
npar; ++i)
219 os <<
"\n parameter " << par[i] <<
" (" <<
fState.Name(par[i]) <<
") fixed to "
223 for (
unsigned int i = 0; i <
npar; i++)
232 print.
Debug(
"A new minimum is found: return");
235 if (
min1.HasReachedCallLimit()) {
236 print.
Debug(
"FCN call limit is reached: return");
239 if (!
min1.IsValid()){
240 print.
Debug(
"Migrad failed: return ");
244 print.
Debug(
"Parameter(s) at limit: return ");
270 double fdist = std::min(std::fabs(
aim -
flsb[0]), std::fabs(
aim -
flsb[1]));
273 if (std::fabs(
aopt) > 1.)
276 print.
Info(
"Return: Found good value for aopt = ",
aopt);
280 print.
Info(
"Number of iterations",
ipt,
"larger than max",
maxitr,
": return");
296 print.
Info([&](std::ostream &os) {
297 os <<
"Run Migrad again (3rd) with fixed parameters:";
298 for (
unsigned i = 0; i <
npar; ++i)
299 os <<
"\n Pos " << par[i] <<
": " <<
fState.Name(par[i]) <<
" = " <<
pmid[i] + (
aopt)*
pdir[i];
302 for (
unsigned int i = 0; i <
npar; i++)
311 print.
Debug(
"A new minimum is found: return");
314 if (
min2.HasReachedCallLimit()) {
315 print.
Debug(
"FCN call limit is reached: return");
318 if (!
min2.IsValid()) {
319 print.
Debug(
"Migrad failed: return ");
323 print.
Debug(
"Parameter(s) at limit: return ");
335 unsigned int ibest = 2;
339 for (
unsigned int i = 0; i < 3; i++) {
362 print.
Debug(
"all 3 points are above - invalid result- return");
371 print.
Debug(
"All three points below - look again for positive slope");
381 print.
Debug(
"New straight line using point 1-2; dfda",
dfda);
394 print.
Debug(
"Parabola fit: iteration",
ipt);
412 print.
Debug(
"Parabola fit: x1",
x1,
"x2",
x2,
"s1",
s1,
"s2",
s2);
415 print.
Warn(
"Problem 1");
429 if (std::fabs(
aopt) > 1.)
436 print.
Debug(
"Return: Found best value is within tolerance, aopt",
aopt,
"F=",
flsb[
ibest]);
445 unsigned int ileft = 3;
447 unsigned int iout = 3;
451 for (
unsigned int i = 0; i < 3; i++) {
468 }
else if (
ileft == 3)
508 print.
Info([&](std::ostream &os) {
509 os <<
"Run Migrad again at new point (#iter = " <<
ipt+1 <<
" ):";
510 for (
unsigned i = 0; i <
npar; ++i)
511 os <<
"\n\t - parameter " << par[i] <<
" fixed to " <<
pmid[i] + (
aopt)*
pdir[i];
514 for (
unsigned int i = 0; i <
npar; i++)
523 print.
Debug(
"A new minimum is found: return");
526 if (
min2.HasReachedCallLimit()) {
527 print.
Debug(
"FCN call limit is reached: return");
530 if (!
min2.IsValid()) {
531 print.
Debug(
"Migrad failed: return ");
535 print.
Debug(
"Parameter(s) at limit: return ");
548 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) ...
MnUserParameterState & State()
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...
void SetValue(unsigned int, double)
Namespace for new ROOT classes and functions.