sxu = nlopt_new_rescaled(U(n), s, xu);
if (!sxu) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
xu = sxu;
+ nlopt_reorder_bounds(n, sxl, sxu);
- rhobeg = dx[0] / s[0]; /* equals all other dx[i] after rescaling */
+ rhobeg = fabs(dx[0] / s[0]); /* equals all other dx[i] after rescaling */
calfun_data.s = s;
calfun_data.xs = xs;
/* SGJ, 2009: compute rhoend from NLopt stop info */
rhoend = stop->xtol_rel * (rhobeg);
for (j = 0; j < n; ++j)
- if (rhoend < stop->xtol_abs[j] / s[j])
- rhoend = stop->xtol_abs[j] / s[j];
+ if (rhoend < stop->xtol_abs[j] / fabs(s[j]))
+ rhoend = stop->xtol_abs[j] / fabs(s[j]);
/* This subroutine seeks the least value of a function of many variables, */
if (!s.lb) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
s.ub = nlopt_new_rescaled(n, s.scale, ub);
if (!s.ub) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
+ nlopt_reorder_bounds(n, s.lb, s.ub);
s.xtmp = (double *) malloc(sizeof(double) * n);
if (!s.xtmp) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
/* SGJ, 2008: compute rhoend from NLopt stop info */
- rhobeg = dx[0] / s.scale[0];
+ rhobeg = fabs(dx[0] / s.scale[0]);
rhoend = stop->xtol_rel * (rhobeg);
for (j = 0; j < n; ++j)
- if (rhoend < stop->xtol_abs[j] / s.scale[j])
- rhoend = stop->xtol_abs[j] / s.scale[j];
+ if (rhoend < stop->xtol_abs[j] / fabs(s.scale[j]))
+ rhoend = stop->xtol_abs[j] / fabs(s.scale[j]);
/* each equality constraint gives two inequality constraints */
m = nlopt_count_constraints(m, fc) + 2 * nlopt_count_constraints(p, h);
double *nlopt_new_rescaled(unsigned n, const double *s, const double *x);
void nlopt_rescale(unsigned n, const double *s, const double *x, double *xs);
void nlopt_unscale(unsigned n, const double *s, const double *x, double *xs);
+void nlopt_reorder_bounds(unsigned n, double *lb, double *ub);
#ifdef __cplusplus
} /* extern "C" */
nlopt_rescale(n, s, x, xs);
return xs;
}
+
+/* since rescaling can flip the signs of the x components and the bounds,
+ we may have to re-order the bounds in order to ensure that they
+ remain in the correct order */
+void nlopt_reorder_bounds(unsigned n, double *lb, double *ub)
+{
+ unsigned i;
+ for (i = 0; i < n; ++i)
+ if (lb[i] > ub[i]) {
+ double t = lb[i];
+ lb[i] = ub[i];
+ ub[i] = t;
+ }
+}