51 "The \"MIGRAD\" sub-command adjusts parameters according to the "
52 "\"MIGRAD\" method taken from MINUIT.") {
54 (
"TOLERANCE",
"The desired tolerance", 1.0
e-6);
56 (
"CALLS",
"Maximum number of calls to the matching functions", 1000.);
72 return new Migrad(name,
this);
78 static const char method[] =
"MIGRAD";
112 if(strategy == 2 || ( strategy > 2 && icovar < 2 )) {
118 for(
int i = 0; i <
n; ++i) {
119 for(
int j = 0; j <
n; ++j)
W(i, j) = 0.0;
120 if(g2(i) == 0.0) g2(i) = 1.0;
121 W(i, i) = 1.0 / g2(i);
130 double edm =
min(0.5 * g * (W * g),
fmin);
139 if(g * g < DBL_EPSILON * fnorm)
break;
151 if(restarts > strategy)
break;
181 edm =
min(0.5 * g * (W * g),
fmin);
189 if(edm >= 0.0 && edm < 1.0
e-4 * tol)
break;
195 if(edm >= 0.0 && yWy > 0.0)
break;
209 for(
int i = 0; i <
n; ++i) {
210 for(
int j = 0; j <
n; ++j) {
211 W(i, j) += s(i) * s(j) / sy - Wy(i) * Wy(j) / yWy;
218 for(
int i = 0; i <
n; ++i) {
219 for(
int j = 0; j <
n; ++j) {
220 W(i, j) += 2.0 * yWy * flnu(i) * flnu(j);
224 if(improv >= n) icovar = 3;
233 if(strategy >= 2 || (strategy == 1 && icovar < 3)) {
236 if(edm > 1.0
e-3 * tol) state =
RESTART;
253 double eps =
sqrt(DBL_EPSILON);
256 Vector<double> xstep(n), x1(x), x2(x), f1(m), f2(m), fu(n), fl(n);
258 for(
int i = 0; i <
n; ++i) {
261 for(
int icycle = 1; icycle <= 10; ++icycle) {
262 x1(i) = x(i) - xstep(i);
263 x2(i) = x(i) + xstep(i);
270 xstep(i) = 0.5 * xstep(i);
274 g(i) = (fu(i) - fl(i)) / (2.0 * xstep(i));
275 g2(i) = (fu(i) - 2.0 *
fmin + fl(i)) / (xstep(i) * xstep(i));
276 if(g2(i) == 0.0) g2(i) = 1.0;
281 x2(i) = x(i) + xstep(i);
282 for(
int j = 0; j < i; ++j) {
283 x2(j) = x(j) + xstep(j);
286 (f * f +
fmin - fu(i) - fu(j)) / (xstep(i) * xstep(j));
288 W(j, i) =
W(i, j) = 0.0;
309 double eps =
sqrt(DBL_EPSILON);
311 for(
int i = 0; i <
n; ++i) {
314 for(
int icycle = 1; icycle <= 10; ++icycle) {
316 x1(i) = x(i) - xstep(i);
317 x2(i) = x(i) + xstep(i);
322 g(i) = (fu - fl) / (2.0 * xstep(i));
323 g2(i) = (fu - 2.0 *
fmin + fl) / (xstep(i) * xstep(i));
324 if(g2(i) == 0.0) g2(i) = 1.0;
328 xstep(i) = 0.5 * xstep(i);
329 x1(i) = x2(i) = x(i);
340 static const double alpha = 2.0;
341 static const double small = 0.05;
342 static const int maxpoints = 12;
346 double lambda_min = 0.0;
347 for(
int i = 0; i <
n; ++i) {
349 double ratio =
std::abs(x(i) / s(i));
350 if(lambda_min == 0.0 || ratio < lambda_min) lambda_min = ratio;
353 if(lambda_min == 0.0) lambda_min = DBL_EPSILON;
354 double lambda_max = lambda_min = lambda_min * DBL_EPSILON;
358 double lambda_val[3], funct_val[3];
361 double lambda_opt = 0.0;
362 double funct_opt =
fmin;
366 double over_all = 1000.0;
367 double under_all = - 100.0;
373 if(lambda <= lambda_min)
break;
376 lambda_val[1] = lambda;
377 funct_val[1] = f * f;
379 if(funct_val[1] < funct_opt) {
380 lambda_opt = lambda_val[1];
381 funct_opt = funct_val[1];
392 lambda_val[2] = 0.5 * lambda;
393 funct_val[2] = f * f;
394 if(funct_val[2] < funct_opt) {
395 lambda_opt = lambda_val[2];
396 funct_opt = funct_val[2];
401 for(
int npts = 2; npts <= maxpoints;) {
404 lambda_max =
max(lambda_max, alpha *
std::abs(lambda_opt));
407 double s21 = lambda_val[1] - lambda_val[0];
408 double s32 = lambda_val[2] - lambda_val[1];
409 double s13 = lambda_val[0] - lambda_val[2];
410 double den = s21 * s32 * s13;
412 (s32 * funct_val[0] + s13 * funct_val[1] + s21 * funct_val[2]) / den;
414 ((lambda_val[2] + lambda_val[1]) * s32 * funct_val[0] +
415 (lambda_val[0] + lambda_val[2]) * s13 * funct_val[1] +
416 (lambda_val[1] + lambda_val[0]) * s21 * funct_val[2]) / den;
419 lambda = (c1 > 2.0 * c2 * lambda_opt) ?
420 (lambda_opt + lambda_max) : (lambda_opt - lambda_max);
422 lambda = c1 / (2.0 * c2);
423 lambda = (lambda > lambda_opt + lambda_max) ?
424 (lambda_opt + lambda_max) : (lambda_opt - lambda_max);
428 if(lambda > over_all) lambda = over_all;
430 if(lambda < under_all) lambda = under_all;
441 double tol9 = small *
max(1.0, lambda);
442 for(
int i = 0; i < 3; ++i) {
443 if(
std::abs(lambda - lambda_val[i]) < tol9)
break;
448 if(++npts > maxpoints ||
454 if(funct_val[1] > funct_val[nvmax]) nvmax = 1;
455 if(funct_val[2] > funct_val[nvmax]) nvmax = 2;
459 if(f3 < funct_val[nvmax])
break;
462 if(lambda > lambda_opt) over_all =
min(over_all, lambda - small);
463 if(lambda < lambda_opt) under_all =
max(under_all, lambda + small);
464 lambda = 0.5 * (lambda + lambda_opt);
471 lambda_val[nvmax] = lambda;
472 funct_val[nvmax] = f3;
478 if(lambda > lambda_opt) over_all =
min(over_all, lambda - small);
479 if(lambda < lambda_opt) under_all =
max(under_all, lambda + small);
497 }
else if(lambda_opt == 0) {
499 }
else if(s * s > DBL_EPSILON * (x * x)) {
509 static const double eps = DBL_EPSILON;
510 static const int itmax = 15;
523 double f = V(0, 0) + V(1, 1);
524 double g =
sqrt(
pow(V(0, 0) - V(1, 1), 2) + 4.0 *
pow(V(1, 0), 2));
525 eigen(0) = (f - g) / 2.0;
526 eigen(1) = (f + g) / 2.0;
533 for(
int i = n; i-- >= 2;) {
535 for(
int j = 0; j < i - 1; ++j) g += A(j, i) * A(j, i);
539 work(i) = A(i, i - 1);
541 double h = g +
pow(A(i, i - 1), 2);
542 work(i) = (A(i, i - 1) >= 0.0) ?
sqrt(h) : (-
sqrt(h));
543 h += A(i, i - 1) * work(i);
544 A(i, i - 1) += work(i);
547 for(
int j = 0; j < i; ++j) {
549 for(
int k = 0; k < i - 1; ++k) g += A(k, i) * A(k, j);
551 f += work(j) * A(i, j);
554 for(
int j = 0; j < i; ++j) {
555 work(j) -= (f / (h + h)) * A(i, j);
556 for(
int k = 0; k <= j; ++k) {
557 A(j, k) -= A(i, j) * work(k) - work(j) * A(i, k);
569 for(
int i = 1; i <
n; ++i) work(i - 1) = work(i);
575 for(
int l = 0; l <
n; ++l) {
578 for(m = 0; m < n - 1; ++m)
if(
std::abs(work(m)) <= b)
break;
581 for(
int iter = 1; iter <= itmax; ++iter) {
582 double p = (eigen(l + 1) - eigen(l)) / (2.0 * work(l));
584 double h = eigen(l) - work(l) / ((p > 0) ? (p + r) : (p - r));
585 for(
int i = l; i <
n; ++i) eigen(i) -= h;
590 for(
int i = m; i-- > l;) {
591 double g = c * work(i);
593 r =
sqrt(work(i) * work(i) + p * p);
597 p = c * eigen(i) - s * g;
598 eigen(i + 1) = h + s * (c * g + s * eigen(i));
607 double p = eigen(l) + f;
608 for(
int i = l; i >= 2; --i) {
609 if(p >= eigen(i - 1)) {
613 eigen(i) = eigen(i - 1);
629 for(
int i = 0; i <
n; ++i) {
631 if(si <= 0.0)
return false;
632 scale(i) = 1.0 /
sqrt(si);
635 for(
int i = 0; i <
n; ++i) {
636 for(
int j = i; j <
n; ++j) A(i, j) *= scale(i) * scale(j);
640 for(
int i = 0; i <
n; ++i) {
641 if(A(i, i) == 0.0)
return false;
643 s(i) = 1.0 / A(i, i);
646 for(
int j = 0; j <
n; ++j) {
649 s(j) = pivot(j) * s(i);
653 s(j) = - pivot(j) * s(i);
658 for(
int j = 0; j <
n; ++j) {
659 for(
int k = j; k <
n; ++k) A(j, k) += pivot(j) * s(k);
664 for(
int i = 0; i <
n; ++i) {
665 for(
int j = i; j <
n; ++j) {
666 A(j, i) = A(i, j) *= scale(i) * scale(j);
676 static const double eps = 1.0e-3;
684 double pmin = eigen(0);
685 double pmax = eigen(0);
687 for(
int i = 0; i <
n; ++i) {
688 if(eigen(i) < pmin) pmin = eigen(i);
689 if(eigen(i) > pmax) pmax = eigen(i);
693 if(pmin <= DBL_EPSILON * pmax) V += eps * pmax - pmin;
void hessenberg(Vector< double > &X, Vector< double > &F, Matrix< double > &V, Vector< double > &G, Vector< double > &G2)
double Round(double value)
Round the double argument.
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual void execute()
Execute the command.
constexpr double e
The value of .
int symmetricEigen(const Matrix< double > &A, Vector< double > &eigen)
MatchState lineSearch(Vector< double > &X, Vector< double > &dX, Vector< double > &F, double tol)
MatchState
The possible states of a matching process.
bool invertSymmetric(Matrix< double > &A)
The base class for all OPAL actions.
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
static Match * block
The block of match data.
int countFunctions() const
Return total number of functions.
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
virtual Migrad * clone(const std::string &name)
Make clone.
void setVariables(const Vector< double > &x)
Set values of matching variables.
constexpr double alpha
The fine structure constant, no dimension.
void print(const char *method, MatchState state)
Print the results of minimisation.
int countVariables() const
Get total number of variables.
void derivatives(Vector< double > &X, Vector< double > &F, Vector< double > &G, Vector< double > &G2)
constexpr double c
The velocity of light in m/s.
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
void forcePositiveDefinite(Matrix< double > &A)
Migrad()
Exemplar constructor.
bool evaluate(const Vector< double > &x, Vector< double > &f)
Evaluate the matching functions.
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Tps< T > sqrt(const Tps< T > &x)
Square root.
T euclidean_norm(const Vector< T > &)
Euclidean norm.
double getReal(const Attribute &attr)
Return real value.
void getVariables(Vector< double > &x) const
Get values of matching variables.
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)