chiark / gitweb /
use nlopt_stopping in StoGO (currently only for maxevals and maxtime)
[nlopt.git] / util / stop.c
1 #include <math.h>
2 #include "nlopt-util.h"
3
4 /* utility routines to implement the various stopping criteria */
5
6 static int relstop(double old, double new, double reltol, double abstol)
7 {
8      return(fabs(new - old) < abstol 
9             || fabs(new - old) < reltol * (fabs(new) + fabs(old)) * 0.5);
10 }
11
12 int nlopt_stop_ftol(const nlopt_stopping *s, const double f, double oldf)
13 {
14      return (relstop(oldf, f, s->ftol_rel, s->ftol_abs));
15 }
16
17 int nlopt_stop_f(const nlopt_stopping *s, const double f, double oldf)
18 {
19      return (f <= s->fmin_max || nlopt_stop_ftol(s, f, oldf));
20 }
21
22 int nlopt_stop_x(const nlopt_stopping *s, const double *x, const double *oldx)
23 {
24      int i;
25      for (i = 0; i < s->n; ++i)
26           if (relstop(oldx[i], x[i], s->xtol_rel, s->xtol_abs[i]))
27                return 1;
28      return 0;
29 }
30
31 static double sc(double x, double smin, double smax)
32 {
33      return smin + x * (smax - smin);
34 }
35
36 /* some of the algorithms rescale x to a unit hypercube, so we need to
37    scale back before we can compare to the tolerances */
38 int nlopt_stop_xs(const nlopt_stopping *s,
39                   const double *xs, const double *oldxs,
40                   const double *scale_min, const double *scale_max)
41 {
42      int i;
43      for (i = 0; i < s->n; ++i)
44           if (relstop(sc(oldxs[i], scale_min[i], scale_max[i]), 
45                       sc(xs[i], scale_min[i], scale_max[i]),
46                       s->xtol_rel, s->xtol_abs[i]))
47                return 1;
48      return 0;
49 }
50
51 int nlopt_stop_evals(const nlopt_stopping *s)
52 {
53      return (s->maxeval > 0 && s->nevals >= s->maxeval);
54 }
55
56 int nlopt_stop_time(const nlopt_stopping *s)
57 {
58      return (s->maxtime > 0 && nlopt_seconds() - s->start >= s->maxtime);
59 }
60
61 int nlopt_stop_evalstime(const nlopt_stopping *stop)
62 {
63      return nlopt_stop_evals(stop) || nlopt_stop_time(stop);
64 }