From: stevenj Date: Tue, 9 Feb 2010 22:47:41 +0000 (-0500) Subject: use NLopt stop criteria in Luksan code: in particular, absolute tolerances were missi... X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=883c76b6e1dfdd817fead5dbd3f9a45529ac1b0e;p=nlopt.git use NLopt stop criteria in Luksan code: in particular, absolute tolerances were missing (thanks to Greg Nicholas for the bug report) darcs-hash:20100209224741-c8de0-3df6ca15549dfe15027bc582948587adbcaa3b29.gz --- diff --git a/TODO b/TODO index ff8e01c..1ec38fc 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,3 @@ -Modify luksan code (e.g. luksan/plis.c) to use full NLopt stopping -criteria, and in particular the absolute tolerances and maxtime. - Python interface. SLSQP routine from scipy. diff --git a/luksan/luksan.h b/luksan/luksan.h index 94ce69e..9e37557 100644 --- a/luksan/luksan.h +++ b/luksan/luksan.h @@ -98,10 +98,10 @@ void luksan_pulvp3__(int *n, int *m, double *xm, void luksan_pyadc0__(int *nf, int *n, double *x, int *ix, double *xl, double *xu, int *inew); void luksan_pyfut1__(int *n, double *f, double * - fo, double *umax, double *gmax, double *dmax__, - double *tolx, double *tolf, double *tolb, double * - tolg, int *kd, int *nit, int *kit, int *mit, int * - nfv, int *mfv, int *nfg, int *mfg, int *ntesx, + fo, double *umax, double *gmax, + int xstop, const nlopt_stopping *stop, + double *tolg, int *kd, int *nit, int *kit, int *mit, + int *nfg, int *mfg, int *ntesx, int *mtesx, int *ntesf, int *mtesf, int *ites, int *ires1, int *ires2, int *irest, int *iters, int *iterm); diff --git a/luksan/plip.c b/luksan/plip.c index c6109ac..7d1e254 100644 --- a/luksan/plip.c +++ b/luksan/plip.c @@ -141,6 +141,7 @@ static void plip_(int *nf, int *nb, double *x, int * double eps8, eps9; int meta, mred, nred, iold; double maxf, dmax__; + int xstop = 0; int inew; double told; int ites; @@ -282,8 +283,8 @@ static void plip_(int *nf, int *nb, double *x, int * ++stat_1->nfg; L11120: luksan_pytrcg__(nf, nf, &ix[1], &gf[1], &umax, gmax, &kbf, &iold); - luksan_pyfut1__(nf, f, &fo, &umax, gmax, &dmax__, tolx, tolf, tolb, tolg, - &kd, &stat_1->nit, &kit, mit, &stop->nevals, mfv, &stat_1->nfg, &mfg, + luksan_pyfut1__(nf, f, &fo, &umax, gmax, xstop, stop, tolg, + &kd, &stat_1->nit, &kit, mit, &stat_1->nfg, &mfg, &ntesx, &mtesx, &ntesf, &mtesf, &ites, &ires1, &ires2, &irest, & iters, iterm); if (*iterm != 0) { @@ -399,6 +400,7 @@ L11174: luksan_mxuneg__(nf, &go[1], &s[1], &ix[1], &kbf); luksan_pytrcd__(nf, &x[1], &ix[1], &xo[1], &gf[1], &go[1], &r__, f, &fo, & p, &po, &dmax__, &kbf, &kd, &ld, &iters); + xstop = nlopt_stop_dx(stop, &x[1], &xo[1]); luksan_mxucop__(nf, &gf[1], &so[1], &ix[1], &kbf); if (nn < *mf) { luksan_pulsp3__(nf, &nn, mf, &xm[1], &gr[1], &xo[1], &go[1], &r__, & diff --git a/luksan/plis.c b/luksan/plis.c index 3c6b71a..e9ef510 100644 --- a/luksan/plis.c +++ b/luksan/plis.c @@ -132,6 +132,7 @@ static void plis_(int *nf, int *nb, double *x, int * double eps8, eps9; int mred, iold, nred; double maxf, dmax__; + int xstop = 0; int inew; double told; int ites; @@ -264,8 +265,8 @@ static void plis_(int *nf, int *nb, double *x, int * ++stat_1->nfg; L11120: luksan_pytrcg__(nf, nf, &ix[1], &gf[1], &umax, gmax, &kbf, &iold); - luksan_pyfut1__(nf, f, &fo, &umax, gmax, &dmax__, tolx, tolf, tolb, tolg, - &kd, &stat_1->nit, &kit, mit, &stop->nevals, mfv, &stat_1->nfg, &mfg, + luksan_pyfut1__(nf, f, &fo, &umax, gmax, xstop, stop, tolg, + &kd, &stat_1->nit, &kit, mit, &stat_1->nfg, &mfg, &ntesx, &mtesx, &ntesf, &mtesf, &ites, &ires1, &ires2, &irest, & iters, iterm); if (*iterm != 0) { @@ -405,6 +406,7 @@ L11174: } luksan_pytrcd__(nf, &x[1], &ix[1], &xo[1], &gf[1], &go[1], &r__, f, &fo, & p, &po, &dmax__, &kbf, &kd, &ld, &iters); + xstop = nlopt_stop_dx(stop, &x[1], &xo[1]); L11175: if (kbf > 0) { luksan_mxvine__(nf, &ix[1]); diff --git a/luksan/pnet.c b/luksan/pnet.c index 012dc6e..c563c96 100644 --- a/luksan/pnet.c +++ b/luksan/pnet.c @@ -160,6 +160,7 @@ static void pnet_(int *nf, int *nb, double *x, int * double rho1, rho2, eps8, eps9; int mred, iold, nred; double maxf, dmax__; + int xstop = 0; int inew; double told; int ites; @@ -304,8 +305,8 @@ static void pnet_(int *nf, int *nb, double *x, int * L11020: luksan_pytrcg__(nf, nf, &ix[1], &gf[1], &umax, gmax, &kbf, &iold); luksan_mxvcop__(nf, &gf[1], &gn[1]); - luksan_pyfut1__(nf, f, &fo, &umax, gmax, &dmax__, tolx, tolf, tolb, tolg, - &kd, &stat_1->nit, &kit, mit, &stop->nevals, mfv, &stat_1->nfg, mfg, & + luksan_pyfut1__(nf, f, &fo, &umax, gmax, xstop, stop, tolg, + &kd, &stat_1->nit, &kit, mit, &stat_1->nfg, mfg, & ntesx, &mtesx, &ntesf, &mtesf, &ites, &ires1, &ires2, &irest, & iters, iterm); if (*iterm != 0) { @@ -540,6 +541,7 @@ L11064: } luksan_pytrcd__(nf, &x[1], &ix[1], &xo[1], &gf[1], &go[1], &r__, f, &fo, & p, &po, &dmax__, &kbf, &kd, &ld, &iters); + xstop = nlopt_stop_dx(stop, &x[1], &xo[1]); if (*mos2 > 1) { /* Computing MIN */ i__1 = mx + 1; diff --git a/luksan/pssubs.c b/luksan/pssubs.c index c6ae5b4..2096c19 100644 --- a/luksan/pssubs.c +++ b/luksan/pssubs.c @@ -866,11 +866,11 @@ void luksan_pyadc0__(int *nf, int *n, double *x, * ITERATIONS. ITERM=12-TERMINATION AFTER MAXIMUM NUMBER OF * COMPUTED FUNCTION VALUES. */ -void luksan_pyfut1__(int *n, double *f, double * - fo, double *umax, double *gmax, double *dmax__, - double *tolx, double *tolf, double *tolb, double * - tolg, int *kd, int *nit, int *kit, int *mit, int * - nfv, int *mfv, int *nfg, int *mfg, int *ntesx, +void luksan_pyfut1__(int *n, double *f, double *fo, double *umax, + double *gmax, int xstop, /* double *dmax__, */ + const nlopt_stopping *stop, + double *tolg, int *kd, int *nit, int *kit, int *mit, + int *nfg, int *mfg, int *ntesx, int *mtesx, int *ntesf, int *mtesf, int *ites, int *ires1, int *ires2, int *irest, int *iters, int *iterm) @@ -880,9 +880,6 @@ void luksan_pyfut1__(int *n, double *f, double * /* Builtin functions */ - /* Local variables */ - double temp; - if (*iterm < 0) { return; } @@ -897,7 +894,7 @@ void luksan_pyfut1__(int *n, double *f, double * d__1 = sqrt((fabs(*f))), d__2 = fabs(*f) / 10.; *fo = *f + min(d__1,d__2); } - if (*f <= *tolb) { + if (*f <= stop->minf_max /* *tolb */) { *iterm = 3; return; } @@ -911,7 +908,7 @@ void luksan_pyfut1__(int *n, double *f, double * *ntesx = 0; *ntesf = 0; } - if (*dmax__ <= *tolx) { + if (xstop) /* (*dmax__ <= *tolx) */ { *iterm = 1; ++(*ntesx); if (*ntesx >= *mtesx) { @@ -920,10 +917,7 @@ void luksan_pyfut1__(int *n, double *f, double * } else { *ntesx = 0; } -/* Computing MAX */ - d__2 = fabs(*f); - temp = (d__1 = *fo - *f, fabs(d__1)) / max(d__2,1.); - if (temp <= *tolf) { + if (nlopt_stop_ftol(stop, *f, *fo)) { *iterm = 2; ++(*ntesf); if (*ntesf >= *mtesf) { @@ -937,7 +931,7 @@ L1: *iterm = 11; return; } - if (*nfv >= *mfv) { + if (nlopt_stop_evals(stop)) /* (*nfv >= *mfv) */ { *iterm = 12; return; } diff --git a/util/nlopt-util.h b/util/nlopt-util.h index 861914d..a6b9744 100644 --- a/util/nlopt-util.h +++ b/util/nlopt-util.h @@ -79,6 +79,8 @@ extern int nlopt_stop_f(const nlopt_stopping *stop, double f, double oldf); extern int nlopt_stop_ftol(const nlopt_stopping *stop, double f, double oldf); extern int nlopt_stop_x(const nlopt_stopping *stop, const double *x, const double *oldx); +extern int nlopt_stop_dx(const nlopt_stopping *stop, + const double *x, const double *dx); extern int nlopt_stop_xs(const nlopt_stopping *stop, const double *xs, const double *oldxs, const double *scale_min, const double *scale_max); diff --git a/util/stop.c b/util/stop.c index 534b76c..17ddbf5 100644 --- a/util/stop.c +++ b/util/stop.c @@ -52,6 +52,15 @@ int nlopt_stop_x(const nlopt_stopping *s, const double *x, const double *oldx) return 1; } +int nlopt_stop_dx(const nlopt_stopping *s, const double *x, const double *dx) +{ + int i; + for (i = 0; i < s->n; ++i) + if (!relstop(x[i] - dx[i], x[i], s->xtol_rel, s->xtol_abs[i])) + return 0; + return 1; +} + static double sc(double x, double smin, double smax) { return smin + x * (smax - smin);