chiark / gitweb /
added nlopt_force_stop termination
authorstevenj <stevenj@alum.mit.edu>
Fri, 28 May 2010 16:36:00 +0000 (12:36 -0400)
committerstevenj <stevenj@alum.mit.edu>
Fri, 28 May 2010 16:36:00 +0000 (12:36 -0400)
darcs-hash:20100528163600-c8de0-aa1d026191abea2ffd7870265933673fe18ab890.gz

26 files changed:
api/nlopt-in.hpp
api/nlopt-internal.h
api/nlopt.3
api/nlopt.h
api/optimize.c
api/options.c
auglag/auglag.c
bobyqa/bobyqa.c
cdirect/cdirect.c
cobyla/cobyla.c
cquad/cquad.c
crs/crs.c
isres/isres.c
luksan/plip.c
luksan/plis.c
luksan/pnet.c
luksan/pssubs.c
mlsl/mlsl.c
mma/mma.c
neldermead/nldrmd.c
neldermead/sbplx.c
newuoa/newuoa.c
praxis/praxis.c
subplex/subplex.c
util/nlopt-util.h
util/stop.c

index 5187afb4a32d2ea4bb757dabe8cad9b8dee78cea..a18854443ac6c369c3887578e2761fa13581f59f 100644 (file)
@@ -222,6 +222,9 @@ namespace nlopt {
     NLOPT_GETSET(int, maxeval)
     NLOPT_GETSET(double, maxtime)
 
+    NLOPT_GETSET(int, force_stop)
+    void force_stop() { set_force_stop(1); }
+
     // algorithm-specific parameters:
 
     void set_local_optimizer(const nlopt_opt lo) {
index 80689112f3bb959e089bfe82bd06ff143e5f0d1f..67af6b1366abd7ac6f3856f9d70e1615bfd4f0fe 100644 (file)
@@ -57,6 +57,12 @@ struct nlopt_opt_s {
      int maxeval; /* max # evaluations */
      double maxtime; /* max time (seconds) */
 
+     int force_stop; /* if nonzero, force a halt the next time we
+                       try to evaluate the objective during optimization */
+     /* when local optimization is used, we need a force_stop in the
+       parent object to force a stop in child optimizations */
+     struct nlopt_opt_s *force_stop_child;
+
      /* algorithm-specific parameters */
      nlopt_opt local_opt; /* local optimizer */
      unsigned stochastic_population; /* population size for stochastic algs */
index cec713b4f9bb2f2c2b9e7e061bca0085c1dc4c9b..e5e862ba334cefb0569652eca0c87cbbb608ea54 100644 (file)
@@ -634,6 +634,11 @@ Ran out of memory.
 .TP
 .B NLOPT_ROUNDOFF_LIMITED
 Halted because roundoff errors limited progress.
+.TP
+.B NLOPT_FORCE_STOP
+Halted because the user called \fBnlopt_force_stop\fR(\fIopt\fR) on
+the optimization's \fBnlopt_opt\fR object \fIopt\fR from the user's
+objective function.
 .SH LOCAL OPTIMIZER
 Some of the algorithms, especially MLSL and AUGLAG, use a different
 optimization algorithm as a subroutine, typically for local
index beeaf5329d99f4bc0d78a62224f85dea05d719e6..39cddfd40dc9de6d4c71f3ec0fec8c25243dfcd3 100644 (file)
@@ -135,6 +135,7 @@ typedef enum {
      NLOPT_INVALID_ARGS = -2,
      NLOPT_OUT_OF_MEMORY = -3,
      NLOPT_ROUNDOFF_LIMITED = -4,
+     NLOPT_FORCE_STOP = -5,
      NLOPT_SUCCESS = 1, /* generic success code */
      NLOPT_STOPVAL_REACHED = 2,
      NLOPT_FTOL_REACHED = 3,
@@ -227,6 +228,10 @@ NLOPT_EXTERN int nlopt_get_maxeval(nlopt_opt opt);
 NLOPT_EXTERN nlopt_result nlopt_set_maxtime(nlopt_opt opt, double maxtime);
 NLOPT_EXTERN double nlopt_get_maxtime(nlopt_opt opt);
 
+NLOPT_EXTERN nlopt_result nlopt_force_stop(nlopt_opt opt);
+NLOPT_EXTERN nlopt_result nlopt_set_force_stop(nlopt_opt opt, int val);
+NLOPT_EXTERN int nlopt_get_force_stop(nlopt_opt opt);
+
 /* more algorithm-specific parameters */
 
 NLOPT_EXTERN nlopt_result nlopt_set_local_optimizer(nlopt_opt opt, 
index a684e9a7f5c081428f087d77a2bed63544601527..49595c005d764b988d004b740881e0f58379acf6 100644 (file)
@@ -150,6 +150,10 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
 
      if (!opt || !x || !minf || !opt->f
         || opt->maximize) return NLOPT_INVALID_ARGS;
+
+     /* reset stopping flag */
+     nlopt_set_force_stop(opt, 0);
+     opt->force_stop_child = NULL;
      
      /* copy a few params to local vars for convenience */
      n = opt->n;
@@ -184,6 +188,7 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
      stop.maxeval = opt->maxeval;
      stop.maxtime = opt->maxtime;
      stop.start = nlopt_seconds();
+     stop.force_stop = &(opt->force_stop);
 
      switch (algorithm) {
         case NLOPT_GN_DIRECT:
@@ -267,6 +272,7 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
              if (freedx) { free(opt->dx); opt->dx = NULL; }
              switch (iret) {
                  case -2: return NLOPT_INVALID_ARGS;
+                 case -20: return NLOPT_FORCE_STOP;
                  case -10: return NLOPT_MAXTIME_REACHED;
                  case -1: return NLOPT_MAXEVAL_REACHED;
                  case 0: return NLOPT_XTOL_REACHED;
@@ -378,9 +384,11 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
                   nlopt_set_ftol_rel(local_opt, 1e-15);
                   nlopt_set_xtol_rel(local_opt, 1e-7);
              }
+             opt->force_stop_child = local_opt;
              ret = mlsl_minimize(ni, f, f_data, lb, ub, x, minf, &stop,
                                  local_opt, (int) POP(0),
                                  algorithm >= NLOPT_GN_MLSL_LDS);
+             opt->force_stop_child = NULL;
              if (!opt->local_opt) nlopt_destroy(local_opt);
              return ret;
         }
@@ -476,6 +484,7 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
                   nlopt_set_maxeval(local_opt, nlopt_local_search_maxeval);
                   nlopt_set_initial_step(local_opt, opt->dx);
              }
+             opt->force_stop_child = local_opt;
              ret = auglag_minimize(ni, f, f_data, 
                                    opt->m, opt->fc, 
                                    opt->p, opt->h,
@@ -483,6 +492,7 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
                                    local_opt,
                                    algorithm == NLOPT_LN_AUGLAG_EQ
                                    || algorithm == NLOPT_LD_AUGLAG_EQ);
+             opt->force_stop_child = NULL;
              if (!opt->local_opt) nlopt_destroy(local_opt);
              return ret;
         }
index 83a4da670b4e120a6fca2b0a940e0347634ec9c8..f002a7bb3d5c7ee62d771953cbfc9bf068f1892e 100644 (file)
@@ -69,6 +69,8 @@ nlopt_opt nlopt_create(nlopt_algorithm algorithm, unsigned n)
          opt->xtol_rel = 0; opt->xtol_abs = NULL;
          opt->maxeval = 0;
          opt->maxtime = 0;
+         opt->force_stop = 0;
+         opt->force_stop_child = NULL;
 
          opt->local_opt = NULL;
          opt->stochastic_population = 0;
@@ -105,6 +107,7 @@ nlopt_opt nlopt_copy(const nlopt_opt opt)
          nopt->m_alloc = nopt->p_alloc = 0;
          nopt->local_opt = NULL;
          nopt->dx = NULL;
+         opt->force_stop_child = NULL;
 
          if (opt->n > 0) {
               nopt->lb = (double *) malloc(sizeof(double) * (opt->n));
@@ -157,11 +160,11 @@ oom:
 
 nlopt_result nlopt_set_min_objective(nlopt_opt opt, nlopt_func f, void *f_data)
 {
-     if (opt && f) {
+     if (opt) {
          opt->f = f; opt->f_data = f_data;
          opt->maximize = 0;
          if (nlopt_isinf(opt->stopval) && opt->stopval > 0)
-              opt->stopval = -HUGE_VAL;
+              opt->stopval = -HUGE_VAL; /* switch default from max to min */
          return NLOPT_SUCCESS;
      }
      return NLOPT_INVALID_ARGS;
@@ -169,11 +172,11 @@ nlopt_result nlopt_set_min_objective(nlopt_opt opt, nlopt_func f, void *f_data)
 
 nlopt_result nlopt_set_max_objective(nlopt_opt opt, nlopt_func f, void *f_data)
 {
-     if (opt && f) {
+     if (opt) {
          opt->f = f; opt->f_data = f_data;
          opt->maximize = 1;
          if (nlopt_isinf(opt->stopval) && opt->stopval < 0)
-              opt->stopval = +HUGE_VAL;
+              opt->stopval = +HUGE_VAL; /* switch default from min to max */
          return NLOPT_SUCCESS;
      }
      return NLOPT_INVALID_ARGS;
@@ -379,6 +382,22 @@ GETSET(maxtime, double, maxtime)
 
 /*************************************************************************/
 
+nlopt_result nlopt_set_force_stop(nlopt_opt opt, int force_stop)
+{
+     if (opt) {
+         opt->force_stop = force_stop;
+         if (opt->force_stop_child)
+              return nlopt_set_force_stop(opt->force_stop_child, force_stop);
+         return NLOPT_SUCCESS;
+     }
+     return NLOPT_INVALID_ARGS;
+}
+
+GET(force_stop, int, force_stop)
+nlopt_result nlopt_force_stop(nlopt_opt opt) { nlopt_set_force_stop(opt, 1); }
+
+/*************************************************************************/
+
 GET(algorithm, nlopt_algorithm, algorithm)
 GET(dimension, unsigned, n)
 
@@ -397,6 +416,8 @@ nlopt_result nlopt_set_local_optimizer(nlopt_opt opt,
               nlopt_set_upper_bounds(opt->local_opt, opt->ub);
               nlopt_remove_inequality_constraints(opt->local_opt);
               nlopt_remove_equality_constraints(opt->local_opt);
+              nlopt_set_min_objective(opt->local_opt, NULL, NULL);
+              opt->local_opt->force_stop = 0;
          }
          return NLOPT_SUCCESS;
      }
index c5b65f08d8c0baf0badc5459f3d2a5e486066536..8c85f3955fb055557b2f975bafd24fcdc46c350b 100644 (file)
@@ -215,6 +215,7 @@ nlopt_result auglag_minimize(int n, nlopt_func f, void *f_data,
               if (ret != NLOPT_SUCCESS) break;
          }
 
+         if (nlopt_stop_forced(stop)) {ret = NLOPT_FORCE_STOP; break;}
          if (nlopt_stop_evals(stop)) {ret = NLOPT_MAXEVAL_REACHED; break;}
           if (nlopt_stop_time(stop)) {ret = NLOPT_MAXTIME_REACHED; break;}
 
index 01616211793799016df95ca45bf26ec0cd335e7b..9ca6de7a4eecb853b007a36b64328e8fe09592a6 100644 (file)
@@ -592,7 +592,8 @@ L260:
            goto L340;
        }
 
-       if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
+       if (nlopt_stop_forced(stop)) return NLOPT_FORCE_STOP;
+       else if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
        else if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
 
        ih = 0;
@@ -678,7 +679,8 @@ L260:
        if (f < fval[*kopt]) {
            *kopt = kpt;
        }
-       if (f < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
+       if (nlopt_stop_forced(stop)) return NLOPT_FORCE_STOP;
+       else if (f < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
        else if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
        else if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
 
@@ -1937,7 +1939,8 @@ L50:
        temp = xpt[nf + ipt * xpt_dim1] * xpt[nf + jpt * xpt_dim1];
        hq[ih] = (fbeg - fval[ipt + 1] - fval[jpt + 1] + f) / temp;
     }
-    if (f < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
+    if (nlopt_stop_forced(stop)) return NLOPT_FORCE_STOP;
+    else if (f < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
     else if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
     else if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
     if (nf < *npt) {
@@ -2569,7 +2572,8 @@ L360:
 /* L380: */
     }
 
-    if (nlopt_stop_evals(stop)) rc = NLOPT_MAXEVAL_REACHED;
+    if (nlopt_stop_forced(stop)) rc = NLOPT_FORCE_STOP;
+    else if (nlopt_stop_evals(stop)) rc = NLOPT_MAXEVAL_REACHED;
     else if (nlopt_stop_time(stop)) rc = NLOPT_MAXTIME_REACHED;
     if (rc != NLOPT_SUCCESS) goto L720;
 
index b403e8b457a44cbded274fe9aa3600733c51b462..8ab211c6d7352fa9bd68191e8825655905f35d7a 100644 (file)
@@ -142,7 +142,7 @@ static double function_eval(const double *x, params *p) {
      p->stop->nevals++;
      return f;
 }
-#define FUNCTION_EVAL(fv,x,p,freeonerr) fv = function_eval(x, p); if (p->minf < p->stop->minf_max) { free(freeonerr); return NLOPT_MINF_MAX_REACHED; } else if (nlopt_stop_evals((p)->stop)) { free(freeonerr); return NLOPT_MAXEVAL_REACHED; } else if (nlopt_stop_time((p)->stop)) { free(freeonerr); return NLOPT_MAXTIME_REACHED; }
+#define FUNCTION_EVAL(fv,x,p,freeonerr) fv = function_eval(x, p); if (nlopt_stop_forced((p)->stop)) { free(freeonerr); return NLOPT_FORCE_STOP; } else if (p->minf < p->stop->minf_max) { free(freeonerr); return NLOPT_MINF_MAX_REACHED; } else if (nlopt_stop_evals((p)->stop)) { free(freeonerr); return NLOPT_MAXEVAL_REACHED; } else if (nlopt_stop_time((p)->stop)) { free(freeonerr); return NLOPT_MAXTIME_REACHED; }
 
 #define THIRD (0.3333333333333333333333)
 
index 32a6520eddef36ed0dbd49730ee3f235cb70b858..a285793bc49eb57f701d96811dda3b132dcfcf14 100644 (file)
@@ -499,7 +499,8 @@ static nlopt_result cobylb(int *n, int *m, int *mpp,
      #*&!%*@ Fortran-66 spaghetti code */
 
 L40:
-  if (nlopt_stop_evals(stop)) rc = NLOPT_MAXEVAL_REACHED;
+  if (nlopt_stop_forced(stop)) rc = NLOPT_FORCE_STOP;
+  else if (nlopt_stop_evals(stop)) rc = NLOPT_MAXEVAL_REACHED;
   else if (nlopt_stop_time(stop)) rc = NLOPT_MAXTIME_REACHED;
   if (rc != NLOPT_SUCCESS) goto L600;
 
index ae4e657cba4fcf0ff66b334220108f5c8c30147a..8e3bb698626cdba8d6124bad97c683af456719ca 100644 (file)
@@ -315,7 +315,8 @@ nlopt_result cquad_minimize(int n, nlopt_func f, void *f_data,
               memcpy(x, x0, sizeof(double) * n);
               feasible = 1;
          }
-         if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
+         if (nlopt_stop_forced(stop)) ret = NLOPT_FORCE_STOP;
+         else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
          else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
          else if (*minf < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED;
          if (ret != NLOPT_SUCCESS) goto done;
@@ -341,7 +342,8 @@ nlopt_result cquad_minimize(int n, nlopt_func f, void *f_data,
                         memcpy(x, xcur, sizeof(double) * n);
                         feasible = 1;
                    }
-                   if (nlopt_stop_evals(stop)) 
+                   if (nlopt_stop_forced(stop)) ret = NLOPT_FORCE_STOP;
+                   else if (nlopt_stop_evals(stop)) 
                         ret = NLOPT_MAXEVAL_REACHED;
                    else if (nlopt_stop_time(stop)) 
                         ret = NLOPT_MAXTIME_REACHED;
index 49b3a13aa3cc7d26461643e2ffa5d88e82a4700c..36cbc3e2db03de6ceacf069e7e5acade431f016f 100644 (file)
--- a/crs/crs.c
+++ b/crs/crs.c
@@ -132,6 +132,7 @@ static nlopt_result crs_trial(crs_data *d)
      do {
          d->p[0] = d->f(n, d->p + 1, NULL, d->f_data);
          d->stop->nevals++;
+         if (nlopt_stop_forced(d->stop)) return NLOPT_FORCE_STOP;
          if (d->p[0] < worst->k[0]) break;
          if (nlopt_stop_evals(d->stop)) return NLOPT_MAXEVAL_REACHED;
          if (nlopt_stop_time(d->stop)) return NLOPT_MAXTIME_REACHED;
index 496c7f0a99e4c0ba7419e1b92bd8c6d6447b96f1..53da6157ab7ec114974ebe35a211572f1ef0ed56 100644 (file)
@@ -164,7 +164,8 @@ nlopt_result isres_minimize(int n, nlopt_func f, void *f_data,
                    if (ret != NLOPT_SUCCESS) goto done;
               }
 
-              if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
+              if (nlopt_stop_forced(stop)) ret = NLOPT_FORCE_STOP;
+              else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
               else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
               if (ret != NLOPT_SUCCESS) goto done;
          }
index 7d1e254274759b2ed3b59f5930f44221ec519f5f..975a5b074eb7c5179e367b25f36295ca3b12c4b1 100644 (file)
@@ -516,6 +516,7 @@ nlopt_result luksan_plip(int n, nlopt_func f, void *f_data,
         case 4: return NLOPT_SUCCESS; /* gradient tolerance reached */
         case 6: return NLOPT_SUCCESS;
         case 12: case 13: return NLOPT_MAXEVAL_REACHED;
+        case -999: return NLOPT_FORCE_STOP;
         default: return NLOPT_FAILURE;
      }
 }
index e9ef510b08dc2dd942f3fffab61ae9faad372c0f..d0e4adfc7cdf87e4920276295a996915bd73bc82 100644 (file)
@@ -509,6 +509,7 @@ nlopt_result luksan_plis(int n, nlopt_func f, void *f_data,
         case 4: return NLOPT_SUCCESS; /* gradient tolerance reached */
         case 6: return NLOPT_SUCCESS;
         case 12: case 13: return NLOPT_MAXEVAL_REACHED;
+        case -999: return NLOPT_FORCE_STOP;
         default: return NLOPT_FAILURE;
      }
 }
index c563c96d165e8151f0de8570df9e4649d7e2563b..4f506af4f44a832c6f6434a77968eb6c8f8ee78d 100644 (file)
@@ -659,6 +659,7 @@ nlopt_result luksan_pnet(int n, nlopt_func f, void *f_data,
         case 4: return NLOPT_SUCCESS; /* gradient tolerance reached */
         case 6: return NLOPT_SUCCESS;
         case 12: case 13: return NLOPT_MAXEVAL_REACHED;
+        case -999: return NLOPT_FORCE_STOP;
         default: return NLOPT_FAILURE;
      }
 }
index 2096c198bd963fcee2b525e7caa8ea8ee7a8259e..cf7b1dbcb645d306bf313e029e814d8488103e3f 100644 (file)
@@ -894,6 +894,10 @@ void luksan_pyfut1__(int *n, double *f, double *fo, double *umax,
        d__1 = sqrt((fabs(*f))), d__2 = fabs(*f) / 10.;
        *fo = *f + min(d__1,d__2);
     }
+    if (nlopt_stop_forced(stop)) {
+       *iterm = -999;
+       return;
+    }
     if (*f <= stop->minf_max /* *tolb */) {
        *iterm = 3;
        return;
index 434706ca347a5b7732cf8fe30c1bb49b82d72e88..fa4830175205c052ef1c275f6a85daf7b60155c6 100644 (file)
@@ -333,7 +333,8 @@ nlopt_result mlsl_minimize(int n, nlopt_func f, void *f_data,
      if (!rb_tree_insert(&d.pts, (rb_key) p)) { 
          free(p); ret = NLOPT_OUT_OF_MEMORY; 
      }
-     if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
+     if (nlopt_stop_forced(stop)) ret = NLOPT_FORCE_STOP;
+     else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
      else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
      else if (p->f < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED;
 
@@ -357,7 +358,8 @@ nlopt_result mlsl_minimize(int n, nlopt_func f, void *f_data,
               if (!rb_tree_insert(&d.pts, (rb_key) p)) { 
                    free(p); ret = NLOPT_OUT_OF_MEMORY;
               }
-              if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
+              if (nlopt_stop_forced(stop)) ret = NLOPT_FORCE_STOP;
+              else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
               else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
               else if (p->f < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED;
               else {
@@ -382,6 +384,9 @@ nlopt_result mlsl_minimize(int n, nlopt_func f, void *f_data,
                    double *lm;
                    double t = nlopt_seconds();
 
+                   if (nlopt_stop_forced(stop)) {
+                        ret = NLOPT_FORCE_STOP; break;
+                   }
                    if (nlopt_stop_evals(stop)) {
                          ret = NLOPT_MAXEVAL_REACHED; break;
                    }
@@ -401,6 +406,7 @@ nlopt_result mlsl_minimize(int n, nlopt_func f, void *f_data,
                    if (!rb_tree_insert(&d.lms, lm)) { 
                         free(lm); ret = NLOPT_OUT_OF_MEMORY;
                    }
+                   else if (nlopt_stop_forced(stop)) ret = NLOPT_FORCE_STOP;
                    else if (*lm < stop->minf_max) 
                         ret = NLOPT_MINF_MAX_REACHED;
                    else if (nlopt_stop_evals(stop))
index feba141fda61a74aef79d3e0b115bacc2b1e5b8e..d882ef850fe4a851e26ff90942f4a14d780958f2 100644 (file)
--- a/mma/mma.c
+++ b/mma/mma.c
@@ -235,7 +235,8 @@ nlopt_result mma_minimize(int n, nlopt_func f, void *f_data,
 
      while (1) { /* outer iterations */
          double fprev = fcur;
-         if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
+         if (nlopt_stop_forced(stop)) ret = NLOPT_FORCE_STOP;
+         else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
          else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
          else if (feasible && *minf < stop->minf_max) 
               ret = NLOPT_MINF_MAX_REACHED;
@@ -317,7 +318,8 @@ nlopt_result mma_minimize(int n, nlopt_func f, void *f_data,
                    else if (new_infeasible_constraint) feasible = 0;
 
               }
-              if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
+              if (nlopt_stop_forced(stop)) ret = NLOPT_FORCE_STOP;
+              else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
               else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
               else if (feasible && *minf < stop->minf_max) 
                    ret = NLOPT_MINF_MAX_REACHED;
index f991679c8bb27c8ea9117d7a653613fdd9ec4ed8..4c30751068b7bfbefade604e52b400efba2ab0a1 100644 (file)
@@ -78,6 +78,7 @@ static int reflectpt(int n, double *xnew,
 
 #define CHECK_EVAL(xc,fc)                                                \
  stop->nevals++;                                                         \
+ if (nlopt_stop_forced(stop)) { ret=NLOPT_FORCE_STOP; goto done; }        \
  if ((fc) <= *minf) {                                                    \
    *minf = (fc); memcpy(x, (xc), n * sizeof(double));                    \
    if (*minf < stop->minf_max) { ret=NLOPT_MINF_MAX_REACHED; goto done; } \
@@ -290,6 +291,7 @@ nlopt_result nldrmd_minimize(int n, nlopt_func f, void *f_data,
 
      *minf = f(n, x, NULL, f_data);
      stop->nevals++;
+     if (nlopt_stop_forced(stop)) return NLOPT_FORCE_STOP;
      if (*minf < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
      if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
      if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
index e68bc44f6afefc6169aa36f9e59abf6aa0c2bb62..efe68a43f1f653a428ee599f8a373574ce22de9c 100644 (file)
@@ -79,6 +79,7 @@ nlopt_result sbplx_minimize(int n, nlopt_func f, void *f_data,
 
      *minf = f(n, x, NULL, f_data);
      stop->nevals++;
+     if (nlopt_stop_forced(stop)) return NLOPT_FORCE_STOP;
      if (*minf < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
      if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
      if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
index 233b325bdcf6507a768b4e2453041701b2a73f70..d993813ad1a7eb4887ed24e5707c059f7cb07ae9 100644 (file)
@@ -2099,7 +2099,8 @@ L290:
     }
     ++nf;
 L310:
-    if (nlopt_stop_evals(stop)) rc = NLOPT_MAXEVAL_REACHED;
+    if (nlopt_stop_forced(stop)) rc = NLOPT_FORCE_STOP;
+    else if (nlopt_stop_evals(stop)) rc = NLOPT_MAXEVAL_REACHED;
     else if (nlopt_stop_time(stop)) rc = NLOPT_MAXTIME_REACHED;
     if (rc != NLOPT_SUCCESS) goto L530;
 
index f68e28bc425f8f13e306c5233216bec91d4cc083..c9f1356c5846408edbf89d8fe463455bb0a6406b 100644 (file)
@@ -1241,7 +1241,8 @@ L4:
         q_1->fbest = ret_val;
         memcpy(q_1->xbest, t, n * sizeof(double));
     }
-    if (nlopt_stop_evals(stop)) *ret = NLOPT_MAXEVAL_REACHED;
+    if (nlopt_stop_forced(stop)) *ret = NLOPT_FORCE_STOP;
+    else if (nlopt_stop_evals(stop)) *ret = NLOPT_MAXEVAL_REACHED;
     else if (nlopt_stop_time(stop)) *ret = NLOPT_MAXTIME_REACHED;
     else if (ret_val <= stop->minf_max) *ret = NLOPT_MINF_MAX_REACHED;
     return ret_val;
index 35a5a36f54fc0598ea21025efc17033ea8d40273..5bbe1d66e5b616871a3960360299be3c6dfcbaed 100644 (file)
@@ -1500,7 +1500,9 @@ L40:
        *fx = isubc_1.sfbest;
     }
 L50:
-    if (*fx < stop->minf_max)
+    if (nlopt_stop_forced(stop))
+        *iflag = -20;
+    else if (*fx < stop->minf_max)
         *iflag = 2;
     else if (nlopt_stop_evals(stop))
         *iflag = -1;
index 2c3f6542fc7058257a19c9e3f417f4e54323829d..715e66955cb33c120ce64013fe510e0111bfc102 100644 (file)
@@ -75,6 +75,7 @@ typedef struct {
      const double *xtol_abs;
      int nevals, maxeval;
      double maxtime, start;
+     int *force_stop;
 } nlopt_stopping;
 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);
@@ -88,6 +89,7 @@ extern int nlopt_stop_xs(const nlopt_stopping *stop,
 extern int nlopt_stop_evals(const nlopt_stopping *stop);
 extern int nlopt_stop_time(const nlopt_stopping *stop);
 extern int nlopt_stop_evalstime(const nlopt_stopping *stop);
+extern int nlopt_stop_forced(const nlopt_stopping *stop);
 
 /* for local optimizations, temporarily setting eval/time limits */
 extern nlopt_result nlopt_optimize_limited(nlopt_opt opt, 
index d77683c4463d85ea621e954a9c1609eb78ea9137..eac93dcf94444feb76066efbcfbf69e2ecd9c311 100644 (file)
@@ -95,3 +95,8 @@ int nlopt_stop_evalstime(const nlopt_stopping *stop)
 {
      return nlopt_stop_evals(stop) || nlopt_stop_time(stop);
 }
+
+int nlopt_stop_forced(const nlopt_stopping *stop)
+{
+     return stop->force_stop && *(stop->force_stop);
+}