OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Migrad.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: Migrad.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.1.1.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: Migrad
10 // This class encapsulates a minimisation according to the MIGRAD method,
11 // Minimization by a gradient method due to Davidon/Fletcher/Powell.
12 // (Computer Journal 13, 317 (1970).
13 // Algorithm taken from the MINUIT package.
14 //
15 // ------------------------------------------------------------------------
16 //
17 // $Date: 2000/03/27 09:33:44 $
18 // $Author: Andreas Adelmann $
19 //
20 // ------------------------------------------------------------------------
21 
22 #include "Match/Migrad.h"
23 #include "Algebra/Matrix.h"
24 #include "Algebra/Vector.h"
25 #include "Attributes/Attributes.h"
26 #include "Match/Match.h"
27 #include "Utilities/Round.h"
28 #include <algorithm>
29 #include <cmath>
30 #include <cfloat>
31 
32 using std::max;
33 using std::min;
34 
35 
36 // Class Migrad
37 // ------------------------------------------------------------------------
38 
39 // The attributes of class Migrad.
40 namespace {
41  enum {
42  TOLERANCE, // The desired tolerance.
43  CALLS, // The maximum number of calls to the matching functions.
44  SIZE
45  };
46 }
47 
48 
50  Action(SIZE, "MIGRAD",
51  "The \"MIGRAD\" sub-command adjusts parameters according to the "
52  "\"MIGRAD\" method taken from MINUIT.") {
53  itsAttr[TOLERANCE] = Attributes::makeReal
54  ("TOLERANCE", "The desired tolerance", 1.0e-6);
56  ("CALLS", "Maximum number of calls to the matching functions", 1000.);
57 
59 }
60 
61 
62 Migrad::Migrad(const std::string &name, Migrad *parent):
63  Action(name, parent)
64 {}
65 
66 
68 {}
69 
70 
71 Migrad *Migrad::clone(const std::string &name) {
72  return new Migrad(name, this);
73 }
74 
75 
77  // Built-in constants.
78  static const char method[] = "MIGRAD";
79 
80  // fetch command attributes.
81  double tol = max(Attributes::getReal(itsAttr[TOLERANCE]), DBL_EPSILON);
82  int nfcnmax = int(Round(Attributes::getReal(itsAttr[CALLS])));
83 
84  // Working vectors.
85  int n = Match::block->countVariables();
88  double fnorm;
89  MatchState state = START;
90 
91  // Initial function evaluation.
93  if(! Match::block->evaluate(x, f)) {
94  state = FAILED;
95  } else if((fnorm = euclidean_norm(f)) <= tol) {
96  state = CONVERGED;
97  } else {
98  // Initialise algorithm.
99  fmin = f * f;
100  Vector<double> g(n);
101  Vector<double> g2(n);
102  Matrix<double> W(n, n);
103  int restarts = 0;
104  int strategy = 2;
105  int icovar = 0;
106  bool posdef = false;
107  state = START;
108 
109  // Outer loop: start/restart the algorithm.
110  do {
111  // Initialise covariance matrix.
112  if(strategy == 2 || ( strategy > 2 && icovar < 2 )) {
113  hessenberg(x, f, W, g, g2);
114  posdef = false;
115  } else {
116  derivatives(x, f, g, g2);
117  if(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);
122  }
123  }
124 
125  posdef = true;
126  }
127 
128  // Initialize for first iteration.
129  int improv = 0;
130  double edm = min(0.5 * g * (W * g), fmin);
131 
132  // Print after initialization.
133  Match::block->print(method, state);
134 
135  // Inner loop: actual iteration.
136  while(Match::block->getCallCount() < nfcnmax) {
137  // first derivatives all zero?
138  state = CHECK;
139  if(g * g < DBL_EPSILON * fnorm) break;
140 
141  // find step size according to Newton's method.
142  Vector<double> gsave(g);
143  Vector<double> s = - (W * g);
144 
145  // If s * g >= 0 matrix is not positive definite.
146  if(s *g >= 0.0) {
147  if(posdef) {
148  // If already forced positive definite, restart algorithm.
149  restarts++;
150  state = FAILED;
151  if(restarts > strategy) break;
152  state = RESTART;
153  break;
154  } else {
155  // Otherwise force covariance matrix positive definite.
156  invertSymmetric(W);
158  invertSymmetric(W);
159  posdef = true;
160  continue;
161  }
162  }
163 
164  // Search for minimum along predicted line.
165  state = lineSearch(x, s, f, tol);
166  if(state != PROGRESS) break;
167 
168  // find gradient in new point.
169  derivatives(x, f, g, g2);
170  posdef = false;
171 
172  // Inner loop.
173  double sy;
174  double yWy;
175  Vector<double> y;
176  Vector<double> Wy;
177 
178  // Inner loop, try estimating the error.
179  while(true) {
180  // Estimated distance to minimum.
181  edm = min(0.5 * g * (W * g), fmin);
182  y = g - gsave;
183  sy = s * y;
184  Wy = W * y;
185  yWy = Wy * y;
186 
187  // Test for convergence and print-out.
188  state = CONVERGED;
189  if(edm >= 0.0 && edm < 1.0e-4 * tol) break;
190  Match::block->print(method, PROGRESS);
191 
192  // If covariance matrix is not positive definite,
193  // force it positive definite and retry.
194  state = PROGRESS;
195  if(edm >= 0.0 && yWy > 0.0) break;
196  icovar = 0;
197  state = CONVERGED;
198  if(posdef) break;
199  invertSymmetric(W);
201  invertSymmetric(W);
202  posdef = true;
203  }
204 
205  // If iteration has converged, break out of outer loop.
206  if(state == CONVERGED) break;
207 
208  // Update covariance matrix.
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;
212  }
213  }
214 
215  if(sy > yWy) {
216  Vector<double> flnu = s / sy - Wy / yWy;
217 
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);
221  }
222  }
223  improv++;
224  if(improv >= n) icovar = 3;
225  }
226 
227  // End of outer loop.
228  }
229 
230  // End of algorithm, check for special cases.
231  if(state == CHECK) {
232  state = CONVERGED;
233  if(strategy >= 2 || (strategy == 1 && icovar < 3)) {
234  hessenberg(x, f, W, g, g2);
235  posdef = false;
236  if(edm > 1.0e-3 * tol) state = RESTART;
237  }
238  }
239  } while(state == RESTART);
240 
242  }
243 
244  // Common exit point; final print-out.
245  Match::block->print(method, state);
246 }
247 
248 
249 
252  Vector<double> &g2) {
253  double eps = sqrt(DBL_EPSILON);
254  int n = Match::block->countVariables();
255  int m = Match::block->countFunctions();
256  Vector<double> xstep(n), x1(x), x2(x), f1(m), f2(m), fu(n), fl(n);
257 
258  for(int i = 0; i < n; ++i) {
259  xstep(i) = eps * std::max(std::abs(x(i)), 1.0);
260 
261  for(int icycle = 1; icycle <= 10; ++icycle) {
262  x1(i) = x(i) - xstep(i);
263  x2(i) = x(i) + xstep(i);
264 
265  if(Match::block->evaluate(x2, f2) && Match::block->evaluate(x1, f1)) {
266  fl(i) = f1 * f1;
267  fu(i) = f2 * f2;
268  break;
269  } else {
270  xstep(i) = 0.5 * xstep(i);
271  }
272  }
273 
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;
277  W(i, i) = g2(i);
278 
279  // Off-diagonal elements.
280  x1(i) = x(i);
281  x2(i) = x(i) + xstep(i);
282  for(int j = 0; j < i; ++j) {
283  x2(j) = x(j) + xstep(j);
284  if(Match::block->evaluate(x2, f)) {
285  W(j, i) = W(i, j) =
286  (f * f + fmin - fu(i) - fu(j)) / (xstep(i) * xstep(j));
287  } else {
288  W(j, i) = W(i, j) = 0.0;
289  }
290  x2(j) = x(j);
291  }
292  x2(i) = x(i);
293  }
294 
295  // Restore original point.
297 
298  // ensure positive definiteness and invert.
300  invertSymmetric(W);
301 }
302 
303 
305  Vector<double> &g, Vector<double> &g2) {
306  int n = Match::block->countVariables();
307  int m = Match::block->countFunctions();
308  Vector<double> xstep(n), x1(x), x2(x);
309  double eps = sqrt(DBL_EPSILON);
310 
311  for(int i = 0; i < n; ++i) {
312  xstep(i) = eps * std::max(std::abs(x(i)), 1.0);
313 
314  for(int icycle = 1; icycle <= 10; ++icycle) {
315  Vector<double> f1(m), f2(m);
316  x1(i) = x(i) - xstep(i);
317  x2(i) = x(i) + xstep(i);
318 
319  if(Match::block->evaluate(x1, f1) && Match::block->evaluate(x2, f2)) {
320  double fl = f1 * f1;
321  double fu = f2 * f2;
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;
325  break;
326  }
327 
328  xstep(i) = 0.5 * xstep(i);
329  x1(i) = x2(i) = x(i);
330  }
331  }
332 
334 }
335 
336 
338  Vector<double> &f, double tol) {
339  // Built-in constants.
340  static const double alpha = 2.0;
341  static const double small = 0.05;
342  static const int maxpoints = 12;
343  int n = Match::block->countVariables();
344 
345  // find limits for the parameter lambda.
346  double lambda_min = 0.0;
347  for(int i = 0; i < n; ++i) {
348  if(s(i) != 0.0) {
349  double ratio = std::abs(x(i) / s(i));
350  if(lambda_min == 0.0 || ratio < lambda_min) lambda_min = ratio;
351  }
352  }
353  if(lambda_min == 0.0) lambda_min = DBL_EPSILON;
354  double lambda_max = lambda_min = lambda_min * DBL_EPSILON;
355 
356  // Store the initial point x for lambda = 0;
357  // Declare the optimum point (lambda_opt, funct_opt).
358  double lambda_val[3], funct_val[3];
359  lambda_val[0] = 0.0;
360  funct_val[0] = fmin;
361  double lambda_opt = 0.0;
362  double funct_opt = fmin;
363  Vector<double> f_opt(f);
364 
365  // Other parameters.
366  double over_all = 1000.0;
367  double under_all = - 100.0;
368 
369  // find a valid point in direction lambda * s.
370  double lambda = 1.0;
371  while(! Match::block->evaluate(x + lambda * s, f)) {
372  lambda *= 0.5;
373  if(lambda <= lambda_min) break;
374  }
375 
376  lambda_val[1] = lambda;
377  funct_val[1] = f * f;
378 
379  if(funct_val[1] < funct_opt) {
380  lambda_opt = lambda_val[1];
381  funct_opt = funct_val[1];
382  f_opt = f;
383  }
384 
385  // If lambda had to be reduced, use the optimal point.
386  // Then compute function for move by lambda * s / 2.
387  // If this point is acceptable, continue.
388  if(lambda >= 1.0 &&
389  Match::block->evaluate(x + 0.5 * lambda * s, f)) {
390 
391  // Store the second value.
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];
397  f_opt = f;
398  }
399 
400  // Main iteration loop.
401  for(int npts = 2; npts <= maxpoints;) {
402 
403  // Begin iteration.
404  lambda_max = max(lambda_max, alpha * std::abs(lambda_opt));
405 
406  // Quadratic interpolation using three points.
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;
411  double c2 =
412  (s32 * funct_val[0] + s13 * funct_val[1] + s21 * funct_val[2]) / den;
413  double c1 =
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;
417 
418  if(c2 >= 0.0) {
419  lambda = (c1 > 2.0 * c2 * lambda_opt) ?
420  (lambda_opt + lambda_max) : (lambda_opt - lambda_max);
421  } else {
422  lambda = c1 / (2.0 * c2);
423  lambda = (lambda > lambda_opt + lambda_max) ?
424  (lambda_opt + lambda_max) : (lambda_opt - lambda_max);
425  }
426 
427  if(lambda > 0.0) {
428  if(lambda > over_all) lambda = over_all;
429  } else {
430  if(lambda < under_all) lambda = under_all;
431  }
432 
433  // Inner loop: cut interval, if points are no good.
434  bool FAILED;
435  int nvmax = 0;
436  double f3 = 0.0;
437  while(true) {
438 
439  // Reject new point, if it coincides with a previous one.
440  FAILED = true;
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;
444  }
445 
446  // Compute function for interpolated point.
447  // Reject, if too many points computed, or if point is invalid.
448  if(++npts > maxpoints ||
449  ! Match::block->evaluate(x + lambda * s, f)) break;
450  f3 = f * f;
451 
452  // find worst point of previous three.
453  nvmax = 0;
454  if(funct_val[1] > funct_val[nvmax]) nvmax = 1;
455  if(funct_val[2] > funct_val[nvmax]) nvmax = 2;
456 
457  // Accept new point, if it is an improvement.
458  FAILED = false;
459  if(f3 < funct_val[nvmax]) break;
460 
461  // Otherwise cut the interval.
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);
465  } // end of inner loop.
466 
467  // Break out of outer loop, if inner loop FAILED.
468  if(FAILED) break;
469 
470  // Otherwise new point replaces the previous worst point.
471  lambda_val[nvmax] = lambda;
472  funct_val[nvmax] = f3;
473  if(f3 < funct_opt) {
474  lambda_opt = lambda;
475  funct_opt = f3;
476  f_opt = f;
477  } else {
478  if(lambda > lambda_opt) over_all = min(over_all, lambda - small);
479  if(lambda < lambda_opt) under_all = max(under_all, lambda + small);
480  }
481 
482  // End of: for (int npts = 2; ... )
483  }
484 
485  // End of: if (lambda >= 1.0)
486  }
487 
488  // Common exit point: return best point and step used.
489  fmin = funct_opt;
490  s *= lambda_opt;
491  x += s;
492  Match::block->evaluate(x, f);
493 
494  // Return failure indication.
495  if(fmin < tol) {
496  return CONVERGED;
497  } else if(lambda_opt == 0) {
498  return FAILED;
499  } else if(s * s > DBL_EPSILON * (x * x)) {
500  return PROGRESS;
501  } else {
502  return ACCURACY_LIMIT;
503  }
504 }
505 
506 
508  // Built-in constants.
509  static const double eps = DBL_EPSILON;
510  static const int itmax = 15;
511  int n = Match::block->countVariables();
512 
513  // Working vectors.
514  eigen = Vector<double>(n);
515 
516  // Special cases.
517  if(n <= 0) {
518  return 0;
519  } else if(n == 1) {
520  eigen(0) = V(0, 0);
521  return 1;
522  } else if(n == 2) {
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;
527  return 2;
528  }
529 
530  // Dimension is at least 3, reduce to tridiagonal form.
531  Vector<double> work(n);
532  Matrix<double> A(V);
533  for(int i = n; i-- >= 2;) {
534  double g = 0.0;
535  for(int j = 0; j < i - 1; ++j) g += A(j, i) * A(j, i);
536  eigen(i) = A(i, i);
537 
538  if(g == 0.0) {
539  work(i) = A(i, i - 1);
540  } else {
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);
545  double f = 0.0;
546 
547  for(int j = 0; j < i; ++j) {
548  g = 0.0;
549  for(int k = 0; k < i - 1; ++k) g += A(k, i) * A(k, j);
550  work(j) = g / h;
551  f += work(j) * A(i, j);
552  }
553 
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);
558  }
559  }
560  }
561  }
562 
563  work(1) = A(1, 0);
564  work(0) = 0.0;
565  eigen(1) = A(1, 1);
566  eigen(0) = A(0, 0);
567 
568  // Iterate on tridiagonal matrix.
569  for(int i = 1; i < n; ++i) work(i - 1) = work(i);
570 
571  work(n - 1) = 0.0;
572  double f = 0.0;
573  double b = 0.0;
574 
575  for(int l = 0; l < n; ++l) {
576  b = max(eps * (std::abs(eigen(l)) + std::abs(work(l))), b);
577  int m;
578  for(m = 0; m < n - 1; ++m) if(std::abs(work(m)) <= b) break;
579 
580  if(m != l) {
581  for(int iter = 1; iter <= itmax; ++iter) {
582  double p = (eigen(l + 1) - eigen(l)) / (2.0 * work(l));
583  double r = (std::abs(p) > 1.0e10) ? std::abs(p) : sqrt(p * p + 1.0);
584  double h = eigen(l) - work(l) / ((p > 0) ? (p + r) : (p - r));
585  for(int i = l; i < n; ++i) eigen(i) -= h;
586  f += h;
587  p = eigen(m);
588  double c = 1.0;
589  double s = 0.0;
590  for(int i = m; i-- > l;) {
591  double g = c * work(i);
592  h = c * p;
593  r = sqrt(work(i) * work(i) + p * p);
594  work(i + 1) = s * r;
595  s = work(i) / r;
596  c = p / r;
597  p = c * eigen(i) - s * g;
598  eigen(i + 1) = h + s * (c * g + s * eigen(i));
599  }
600  work(l) = s * p;
601  eigen(l) = c * p;
602  if(std::abs(work(l)) <= b) break;
603  }
604  return l;
605  }
606 
607  double p = eigen(l) + f;
608  for(int i = l; i >= 2; --i) {
609  if(p >= eigen(i - 1)) {
610  eigen(0) = p;
611  return n;
612  }
613  eigen(i) = eigen(i - 1);
614  }
615  }
616 
617  return n;
618 }
619 
620 
622  // allocate working space.
623  int n = Match::block->countVariables();
624  Vector<double> scale(n);
625  Vector<double> pivot(n);
626  Vector<double> s(n);
627 
628  // Scale upper triangle.
629  for(int i = 0; i < n; ++i) {
630  double si = A(i, i);
631  if(si <= 0.0) return false;
632  scale(i) = 1.0 / sqrt(si);
633  }
634 
635  for(int i = 0; i < n; ++i) {
636  for(int j = i; j < n; ++j) A(i, j) *= scale(i) * scale(j);
637  }
638 
639  // Invert upper triangle.
640  for(int i = 0; i < n; ++i) {
641  if(A(i, i) == 0.0) return false;
642  pivot(i) = 1.0;
643  s(i) = 1.0 / A(i, i);
644  A(i, i) = 0.0;
645 
646  for(int j = 0; j < n; ++j) {
647  if(j < i) {
648  pivot(j) = A(j, i);
649  s(j) = pivot(j) * s(i);
650  A(j, i) = 0.0;
651  } else if(j > i) {
652  pivot(j) = A(i, j);
653  s(j) = - pivot(j) * s(i);
654  A(i, j) = 0.0;
655  }
656  }
657 
658  for(int j = 0; j < n; ++j) {
659  for(int k = j; k < n; ++k) A(j, k) += pivot(j) * s(k);
660  }
661  }
662 
663  // Rescale upper triangle and symmetrize.
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);
667  }
668  }
669 
670  return true;
671 }
672 
673 
675  // Built-in constant.
676  static const double eps = 1.0e-3;
677 
678  // find eigenvalues.
679  int n = Match::block->countVariables();
680  Vector<double> eigen(n);
681  symmetricEigen(V, eigen);
682 
683  // Enforce positive definiteness.
684  double pmin = eigen(0);
685  double pmax = eigen(0);
686 
687  for(int i = 0; i < n; ++i) {
688  if(eigen(i) < pmin) pmin = eigen(i);
689  if(eigen(i) > pmax) pmax = eigen(i);
690  }
691 
692  pmax = std::max(std::abs(pmax), 1.0);
693  if(pmin <= DBL_EPSILON * pmax) V += eps * pmax - pmin;
694 }
void hessenberg(Vector< double > &X, Vector< double > &F, Matrix< double > &V, Vector< double > &G, Vector< double > &G2)
Definition: Migrad.cpp:250
double Round(double value)
Round the double argument.
Definition: Round.cpp:23
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual void execute()
Execute the command.
Definition: Migrad.cpp:76
constexpr double e
The value of .
Definition: Physics.h:40
int symmetricEigen(const Matrix< double > &A, Vector< double > &eigen)
Definition: Migrad.cpp:507
MatchState lineSearch(Vector< double > &X, Vector< double > &dX, Vector< double > &F, double tol)
Definition: Migrad.cpp:337
MatchState
The possible states of a matching process.
Definition: MatchState.h:29
bool invertSymmetric(Matrix< double > &A)
Definition: Migrad.cpp:621
The base class for all OPAL actions.
Definition: Action.h:30
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:123
static Match * block
The block of match data.
Definition: Match.h:100
int countFunctions() const
Return total number of functions.
Definition: Match.cpp:140
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
Definition: Object.h:214
virtual Migrad * clone(const std::string &name)
Make clone.
Definition: Migrad.cpp:71
void setVariables(const Vector< double > &x)
Set values of matching variables.
Definition: Match.cpp:93
constexpr double alpha
The fine structure constant, no dimension.
Definition: Physics.h:79
void print(const char *method, MatchState state)
Print the results of minimisation.
Definition: Match.cpp:145
int countVariables() const
Get total number of variables.
Definition: Match.cpp:106
The MIGRAD command.
Definition: Migrad.h:40
void derivatives(Vector< double > &X, Vector< double > &F, Vector< double > &G, Vector< double > &G2)
Definition: Migrad.cpp:304
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
virtual ~Migrad()
Definition: Migrad.cpp:67
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Definition: Object.cpp:194
void forcePositiveDefinite(Matrix< double > &A)
Definition: Migrad.cpp:674
Migrad()
Exemplar constructor.
Definition: Migrad.cpp:49
bool evaluate(const Vector< double > &x, Vector< double > &f)
Evaluate the matching functions.
Definition: Match.cpp:117
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition: Vector.h:243
const std::string name
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:217
void getVariables(Vector< double > &x) const
Get values of matching variables.
Definition: Match.cpp:82
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:205
double fmin
Definition: Migrad.h:86
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95