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) {
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 */
.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
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,
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,
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;
stop.maxeval = opt->maxeval;
stop.maxtime = opt->maxtime;
stop.start = nlopt_seconds();
+ stop.force_stop = &(opt->force_stop);
switch (algorithm) {
case NLOPT_GN_DIRECT:
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;
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;
}
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,
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;
}
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;
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));
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;
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;
/*************************************************************************/
+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)
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;
}
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;}
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;
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;
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) {
/* 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;
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)
#*&!%*@ 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;
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;
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;
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;
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;
}
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;
}
}
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;
}
}
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;
}
}
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;
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;
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 {
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;
}
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))
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;
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;
#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; } \
*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;
*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;
}
++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;
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;
*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;
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);
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,
{
return nlopt_stop_evals(stop) || nlopt_stop_time(stop);
}
+
+int nlopt_stop_forced(const nlopt_stopping *stop)
+{
+ return stop->force_stop && *(stop->force_stop);
+}