From: stevenj Date: Thu, 15 Jul 2010 19:34:06 +0000 (-0400) Subject: support forced stops in ORIG_DIRECT X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=fa723f78d788996a6e06ea19ff659d7b72c1f1e8;p=nlopt.git support forced stops in ORIG_DIRECT darcs-hash:20100715193406-c8de0-57853932f731ace7580a80e8fdb66cbb6f753cb6.gz --- diff --git a/api/optimize.c b/api/optimize.c index ef9402a..e52216d 100644 --- a/api/optimize.c +++ b/api/optimize.c @@ -229,6 +229,7 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf) dret = direct_optimize(f_direct, opt, ni, lb, ub, x, minf, stop.maxeval, -1, 0.0, 0.0, pow(stop.xtol_rel, (double) n), -1.0, + stop.force_stop, stop.minf_max, 0.0, NULL, algorithm == NLOPT_GN_ORIG_DIRECT @@ -254,6 +255,8 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf) return NLOPT_XTOL_REACHED; case DIRECT_OUT_OF_MEMORY: return NLOPT_OUT_OF_MEMORY; + case DIRECT_FORCED_STOP: + return NLOPT_FORCED_STOP; } break; } diff --git a/direct/DIRect.c b/direct/DIRect.c index 3e675e8..1bd4bbf 100644 --- a/direct/DIRect.c +++ b/direct/DIRect.c @@ -44,7 +44,7 @@ /* | Lipschitz continues. However, DIRECT has proven to be effective on | */ /* | more complex problems than these. | */ /* +-----------------------------------------------------------------------+ */ -/* Subroutine */ void direct_direct_(fp fcn, doublereal *x, integer *n, doublereal *eps, doublereal epsabs, integer *maxf, integer *maxt, doublereal *minf, doublereal *l, +/* Subroutine */ void direct_direct_(fp fcn, doublereal *x, integer *n, doublereal *eps, doublereal epsabs, integer *maxf, integer *maxt, int *force_stop, doublereal *minf, doublereal *l, doublereal *u, integer *algmethod, integer *ierror, FILE *logfile, doublereal *fglobal, doublereal *fglper, doublereal *volper, doublereal *sigmaper, void *fcn_data) @@ -405,7 +405,8 @@ direct_dirinit_(f, fcn, c__, length, &actdeep, point, anchor, &ifree, logfile, arrayi, &maxi, list2, w, &x[1], &l[1], &u[1], minf, &minpos, thirds, levels, &MAXFUNC, &MAXDEEP, n, n, & - fmax, &ifeasiblef, &iinfesiblef, ierror, fcn_data, jones); + fmax, &ifeasiblef, &iinfesiblef, ierror, fcn_data, jones, + force_stop); /* +-----------------------------------------------------------------------+ */ /* | Added error checking. | */ /* +-----------------------------------------------------------------------+ */ @@ -420,6 +421,7 @@ fprintf(logfile, "WARNING: Error occured in routine DIRsamplef..\n"); goto cleanup; } + if (*ierror == -102) goto L100; } numfunc = maxi + 1 + maxi; actmaxdeep = 1; @@ -544,7 +546,11 @@ logfile, f, &ifree, &maxi, point, fcn, &x[ 1], &l[1], minf, &minpos, &u[1], n, &MAXFUNC, & MAXDEEP, &oops, &fmax, &ifeasiblef, &iinfesiblef, - fcn_data); + fcn_data, force_stop); + if (force_stop && *force_stop) { + *ierror = -102; + goto L100; + } if (oops > 0) { if (logfile) fprintf(logfile, "WARNING: Error occured in routine DIRsamplef.\n"); diff --git a/direct/DIRserial.c b/direct/DIRserial.c index 0f7eec8..03dd91d 100644 --- a/direct/DIRserial.c +++ b/direct/DIRserial.c @@ -20,7 +20,7 @@ integer *point, fp fcn, doublereal *x, doublereal *l, doublereal * minf, integer *minpos, doublereal *u, integer *n, integer *maxfunc, const integer *maxdeep, integer *oops, doublereal *fmax, integer * - ifeasiblef, integer *iinfesiblef, void *fcn_data) + ifeasiblef, integer *iinfesiblef, void *fcn_data, int *force_stop) { /* System generated locals */ integer length_dim1, length_offset, c_dim1, c_offset, i__1, i__2; @@ -80,8 +80,13 @@ /* +-----------------------------------------------------------------------+ */ /* | Call the function. | */ /* +-----------------------------------------------------------------------+ */ - direct_dirinfcn_(fcn, &x[1], &l[1], &u[1], n, &f[(pos << 1) + 1], - &kret, fcn_data); + if (force_stop && *force_stop) /* skip eval after forced stop */ + f[(pos << 1) + 1] = *fmax; + else + direct_dirinfcn_(fcn, &x[1], &l[1], &u[1], n, &f[(pos << 1) + 1], + &kret, fcn_data); + if (force_stop && *force_stop) + kret = -1; /* mark as invalid point */ /* +-----------------------------------------------------------------------+ */ /* | Remember IF an infeasible point has been found. | */ /* +-----------------------------------------------------------------------+ */ @@ -128,7 +133,7 @@ /* | Iterate over all evaluated points and see, IF the minimal | */ /* | value of the function has changed. IF this has happEND, | */ /* | store the minimal value and its position in the array. | */ -/* | Attention: Only valied values are checked!! | */ +/* | Attention: Only valid values are checked!! | */ /* +-----------------------------------------------------------------------+ */ i__1 = *maxi + *maxi; for (j = 1; j <= i__1; ++j) { diff --git a/direct/DIRsubrout.c b/direct/DIRsubrout.c index 4ff5e5d..79b094a 100644 --- a/direct/DIRsubrout.c +++ b/direct/DIRsubrout.c @@ -1148,7 +1148,7 @@ L50: doublereal *thirds, doublereal *levels, integer *maxfunc, const integer * maxdeep, integer *n, integer *maxor, doublereal *fmax, integer * ifeasiblef, integer *iinfeasible, integer *ierror, void *fcndata, - integer jones) + integer jones, int *force_stop) { /* System generated locals */ integer c_dim1, c_offset, length_dim1, length_offset, list2_dim1, @@ -1242,6 +1242,10 @@ L50: /* L20: */ } direct_dirinfcn_(fcn, &x[1], &l[1], &u[1], n, &f[3], &help, fcndata); + if (force_stop && *force_stop) { + *ierror = -102; + return; + } f[4] = (doublereal) help; *iinfeasible = help; *fmax = f[3]; @@ -1282,7 +1286,12 @@ L50: direct_dirsamplef_(&c__[c_offset], &arrayi[1], &delta, &c__1, &new__, &length[ length_offset], logfile, &f[3], free, maxi, &point[ 1], fcn, &x[1], &l[1], minf, minpos, &u[1], n, maxfunc, - maxdeep, &oops, fmax, ifeasiblef, iinfeasible, fcndata); + maxdeep, &oops, fmax, ifeasiblef, iinfeasible, fcndata, + force_stop); + if (force_stop && *force_stop) { + *ierror = -102; + return; + } /* +-----------------------------------------------------------------------+ */ /* | JG 01/23/01 Added error checking. | */ /* +-----------------------------------------------------------------------+ */ diff --git a/direct/direct-internal.h b/direct/direct-internal.h index 996ca10..ed3e4df 100644 --- a/direct/direct-internal.h +++ b/direct/direct-internal.h @@ -40,7 +40,7 @@ extern void direct_dirinit_( doublereal *thirds, doublereal *levels, integer *maxfunc, const integer * maxdeep, integer *n, integer *maxor, doublereal *fmax, integer * ifeasiblef, integer *iinfeasible, integer *ierror, void *fcndata, - integer jones); + integer jones, int *force_stop); extern void direct_dirinitlist_( integer *anchor, integer *free, integer * point, doublereal *f, integer *maxfunc, const integer *maxdeep); @@ -103,12 +103,12 @@ extern void direct_dirsamplef_( integer *point, fp fcn, doublereal *x, doublereal *l, doublereal * minf, integer *minpos, doublereal *u, integer *n, integer *maxfunc, const integer *maxdeep, integer *oops, doublereal *fmax, integer * - ifeasiblef, integer *iinfesiblef, void *fcn_data); + ifeasiblef, integer *iinfesiblef, void *fcn_data, int *force_stop); /* DIRect.c */ extern void direct_direct_( fp fcn, doublereal *x, integer *n, doublereal *eps, doublereal epsabs, - integer *maxf, integer *maxt, doublereal *minf, doublereal *l, + integer *maxf, integer *maxt, int *force_stop, doublereal *minf, doublereal *l, doublereal *u, integer *algmethod, integer *ierror, FILE *logfile, doublereal *fglobal, doublereal *fglper, doublereal *volper, doublereal *sigmaper, void *fcn_data); diff --git a/direct/direct.h b/direct/direct.h index f357843..cd6a124 100644 --- a/direct/direct.h +++ b/direct/direct.h @@ -30,7 +30,8 @@ typedef enum { DIRECT_SIGMATOL = 5, DIRECT_OUT_OF_MEMORY = -100, - DIRECT_INVALID_ARGS = -101 + DIRECT_INVALID_ARGS = -101, + DIRECT_FORCED_STOP = -102 } direct_return_code; #define DIRECT_UNKNOWN_FGLOBAL (-HUGE_VAL) @@ -46,6 +47,7 @@ extern direct_return_code direct_optimize( int max_feval, int max_iter, double magic_eps, double magic_eps_abs, double volume_reltol, double sigma_reltol, + int *force_stop, double fglobal, double fglobal_reltol, diff --git a/direct/direct_wrap.c b/direct/direct_wrap.c index 6e857cd..330743d 100644 --- a/direct/direct_wrap.c +++ b/direct/direct_wrap.c @@ -50,6 +50,7 @@ direct_return_code direct_optimize( int max_feval, int max_iter, double magic_eps, double magic_eps_abs, double volume_reltol, double sigma_reltol, + int *force_stop, double fglobal, double fglobal_reltol, @@ -85,7 +86,7 @@ direct_return_code direct_optimize( } direct_direct_(f, x, &dimension, &magic_eps, magic_eps_abs, - &max_feval, &max_iter, + &max_feval, &max_iter, force_stop, minf, l, u, &algmethod, diff --git a/test/testopt.cpp b/test/testopt.cpp index 307fddf..1079935 100644 --- a/test/testopt.cpp +++ b/test/testopt.cpp @@ -207,7 +207,8 @@ static int test_function(int ifunc) maxeval, maxtime); printf("finished after %g seconds.\n", nlopt_seconds() - start); printf("return code %d from nlopt_minimize\n", ret); - if (ret < 0 && ret != NLOPT_ROUNDOFF_LIMITED) { + if (ret < 0 && ret != NLOPT_ROUNDOFF_LIMITED + && ret != NLOPT_FORCED_STOP) { fprintf(stderr, "testopt: error in nlopt_minimize\n"); free(x); return 0; @@ -236,6 +237,7 @@ static int test_function(int ifunc) if (val != minf) { fprintf(stderr, "Mismatch %g between returned minf=%g and f(x) = %g\n", minf - val, minf, val); + free(x); return 0; } }