ordinary termination tests, set psi = 0.
scratch should contain an array of length >= (n+1)*(n+1) + 2*n,
- used as scratch workspace. */
+ used as scratch workspace.
+
+ On output, *fdiff will contain the difference between the high
+ and low function values of the last simplex. */
nlopt_result nldrmd_minimize_(int n, nlopt_func f, void *f_data,
const double *lb, const double *ub, /* bounds */
double *x, /* in: initial guess, out: minimizer */
double *minf,
const double *xstep, /* initial step sizes */
nlopt_stopping *stop,
- double psi, double *scratch)
+ double psi, double *scratch,
+ double *fdiff)
{
double *pts; /* (n+1) x (n+1) array of n+1 points plus function val [0] */
double *c; /* centroid * n */
rb_tree_init(&t, simplex_compare);
+ *fdiff = HUGE_VAL;
+
/* initialize the simplex based on the starting xstep */
memcpy(pts+1, x, sizeof(double)*n);
pts[0] = *minf;
double fh = high->k[0], *xh = high->k + 1;
double fr;
+ *fdiff = fh - fl;
+
if (init_diam == 0) /* initialize diam. for psi convergence test */
for (i = 0; i < n; ++i) init_diam = fabs(xl[i] - xh[i]);
nlopt_stopping *stop)
{
nlopt_result ret;
- double *scratch;
+ double *scratch, fdiff;
*minf = f(n, x, NULL, f_data);
stop->nevals++;
if (!scratch) return NLOPT_OUT_OF_MEMORY;
ret = nldrmd_minimize_(n, f, f_data, lb, ub, x, minf, xstep, stop,
- 0.0, scratch);
+ 0.0, scratch, &fdiff);
free(scratch);
return ret;
}
double normdx = 0;
int ns, nsubs = 0;
int nevals = stop->nevals;
+ double fdiff, fdiff_max = 0;
memcpy(xprev, x, n * sizeof(double));
fprev = *minf;
++nsubs;
nevals = stop->nevals;
ret = nldrmd_minimize_(ns, subspace_func, &sd, lbs,ubs,xs, minf,
- xsstep, stop, psi, scratch);
+ xsstep, stop, psi, scratch, &fdiff);
+ if (fdiff > fdiff_max) fdiff_max = fdiff;
if (sbplx_verbose)
printf("%d NM iterations for (%d,%d) subspace\n",
stop->nevals - nevals, sd.is, ns);
++nsubs;
nevals = stop->nevals;
ret = nldrmd_minimize_(ns, subspace_func, &sd, lbs,ubs,xs, minf,
- xsstep, stop, psi, scratch);
+ xsstep, stop, psi, scratch, &fdiff);
+ if (fdiff > fdiff_max) fdiff_max = fdiff;
if (sbplx_verbose)
- printf("%d NM iterations for (%d,%d) subspace\n",
+ printf("sbplx: %d NM iterations for (%d,%d) subspace\n",
stop->nevals - nevals, sd.is, ns);
for (i = sd.is; i < n; ++i) x[p[i]] = xs[i-sd.is];
if (ret == NLOPT_FAILURE) { ret=NLOPT_XTOL_REACHED; goto done; }
if (ret != NLOPT_XTOL_REACHED) goto done;
/* termination tests: */
- if (nlopt_stop_ftol(stop, *minf, fprev)) {
+ if (nlopt_stop_ftol(stop, *minf, *minf + fdiff_max)) {
ret = NLOPT_FTOL_REACHED;
goto done;
}
if (scale < omega) scale = omega;
if (scale > 1/omega) scale = 1/omega;
}
+ if (sbplx_verbose)
+ printf("sbplx: stepsize scale factor = %g\n", scale);
for (i = 0; i < n; ++i)
xstep[i] = (dx[i] == 0) ? -(xstep[i] * scale)
: copysign(xstep[i] * scale, dx[i]);