now pass a 2-dimensional array for the gradient argument, rather
than a flattened 1d array.
+* Improved handling of exceptions and forced stops for constrained
+ optimization, making sure that no constraints are evaluated after
+ the stop.
+
* Return an NLOPT_INVALID_ARGS error if more than n equality constraints
are added in an n-dimensional problem.
unsigned j, k;
L = d->f(n, x, grad, d->f_data);
+ d->stop->nevals++;
+ if (nlopt_stop_forced(d->stop)) return L;
for (ii = i = 0; i < d->p; ++i) {
nlopt_eval_constraint(restmp, gradtmp, d->h + i, n, x);
+ if (nlopt_stop_forced(d->stop)) return L;
for (k = 0; k < d->h[i].m; ++k) {
double h = restmp[k] + lambda[ii++] / rho;
L += 0.5 * rho * h*h;
for (ii = i = 0; i < d->m; ++i) {
nlopt_eval_constraint(restmp, gradtmp, d->fc + i, n, x);
+ if (nlopt_stop_forced(d->stop)) return L;
for (k = 0; k < d->fc[i].m; ++k) {
double fc = restmp[k] + mu[ii++] / rho;
if (fc > 0) {
}
}
}
-
- d->stop->nevals++;
return L;
}
double con2 = 0;
d.stop->nevals++;
fcur = f(n, xcur, NULL, f_data);
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
penalty = 0;
feasible = 1;
for (i = 0; i < d.p; ++i) {
nlopt_eval_constraint(d.restmp, NULL, d.h + i, n, xcur);
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
for (k = 0; k < d.h[i].m; ++k) {
double hi = d.restmp[k];
penalty += fabs(hi);
}
for (i = 0; i < d.m; ++i) {
nlopt_eval_constraint(d.restmp, NULL, d.fc + i, n, xcur);
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
for (k = 0; k < d.fc[i].m; ++k) {
double fci = d.restmp[k];
penalty += fci > 0 ? fci : 0;
d.stop->nevals++;
fcur = f(n, xcur, NULL, f_data);
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
if (auglag_verbose)
printf("auglag: fcur = %g\n", fcur);
feasible = 1;
for (i = ii = 0; i < d.p; ++i) {
nlopt_eval_constraint(d.restmp, NULL, d.h + i, n, xcur);
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
for (k = 0; k < d.h[i].m; ++k) {
double hi = d.restmp[k];
double newlam = d.lambda[ii] + d.rho * hi;
}
for (i = ii = 0; i < d.m; ++i) {
nlopt_eval_constraint(d.restmp, NULL, d.fc + i, n, xcur);
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
for (k = 0; k < d.fc[i].m; ++k) {
double fci = d.restmp[k];
double newmu = d.mu[ii] + d.rho * fci;
if (ICM == 0) return NLOPT_FTOL_REACHED;
} while (1);
+done:
free(xcur);
return ret;
}
double *xtmp;
const double *lb, *ub;
double *con_tol;
+ nlopt_stopping *stop;
} func_wrap_state;
static int func_wrap(int n, int m, double *x, double *f, double *con,
}
*f = s->f(n, xtmp, NULL, s->f_data);
+ if (nlopt_stop_forced(s->stop)) return 1;
i = 0;
for (j = 0; j < s->m_orig; ++j) {
nlopt_eval_constraint(con + i, NULL, s->fc+j, n, xtmp);
+ if (nlopt_stop_forced(s->stop)) return 1;
for (k = 0; k < s->fc[j].m; ++k)
con[i + k] = -con[i + k];
i += s->fc[j].m;
}
for (j = 0; j < s->p; ++j) {
nlopt_eval_constraint(con + i, NULL, s->h+j, n, xtmp);
+ if (nlopt_stop_forced(s->stop)) return 1;
for (k = 0; k < s->h[j].m; ++k)
con[(i + s->h[j].m) + k] = -con[i + k];
i += 2 * s->h[j].m;
if (!nlopt_isinf(ub[j]))
con[i++] = ub[j] - x[j];
}
- if (m != i) return 1; /* ... bug?? */
return 0;
}
s.p = p;
s.h = h;
s.lb = lb; s.ub = ub;
+ s.stop = stop;
s.xtmp = (double *) malloc(sizeof(double) * n);
if (!s.xtmp) return NLOPT_OUT_OF_MEMORY;
if (*iprint >= 1) {
fprintf(stderr, "cobyla: user requested end of minimization.\n");
}
- rc = NLOPT_FAILURE;
+ rc = NLOPT_FORCED_STOP;
goto L600;
}
double gpenalty;
stop->nevals++;
fval[k] = f(n, xs + k*n, NULL, f_data);
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
penalty[k] = 0;
for (c = 0; c < m; ++c) { /* inequality constraints */
nlopt_eval_constraint(results, NULL,
fc + c, n, xs + k*n);
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
for (ires = 0; ires < fc[c].m; ++ires) {
double gval = results[ires];
if (gval > fc[c].tol[ires]) feasible = 0;
for (c = m; c < mp; ++c) { /* equality constraints */
nlopt_eval_constraint(results, NULL,
h + (c-m), n, xs + k*n);
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
for (ires = 0; ires < h[c-m].m; ++ires) {
double hval = results[ires];
if (fabs(hval) > h[c-m].tol[ires]) feasible = 0;
dd.fval = fcur = *minf = f(n, x, dfdx, f_data);
stop->nevals++;
memcpy(xcur, x, sizeof(double) * n);
+ if (nlopt_stop_forced(stop)) { ret = NLOPT_FORCED_STOP; goto done; }
feasible = 1; infeasibility = 0;
for (i = ifc = 0; ifc < mfc; ++ifc) {
nlopt_eval_constraint(fcval + i, dfcdx + i*n,
fc + ifc, n, x);
i += fc[ifc].m;
+ if (nlopt_stop_forced(stop)) { ret = NLOPT_FORCED_STOP; goto done; }
}
for (i = 0; i < m; ++i) {
feasible = feasible && (fcval[i] <= 0 || isnan(fcval[i]));
fcur = f(n, xcur, dfdx_cur, f_data);
stop->nevals++;
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
feasible_cur = 1; infeasibility_cur = 0;
new_infeasible_constraint = 0;
inner_done = dd.gval >= fcur;
nlopt_eval_constraint(fcval_cur + i, dfcdx_cur + i*n,
fc + ifc, n, xcur);
i += fc[ifc].m;
+ if (nlopt_stop_forced(stop)) {
+ ret = NLOPT_FORCED_STOP; goto done; }
}
for (i = ifc = 0; ifc < mfc; ++ifc) {
unsigned i0 = i, inext = i + fc[ifc].m;