void set_min_objective(func *f) {
set_min_objective(myfunc, f);
}
+ void set_max_objective(nlopt_func f, void *f_data) {
+ nlopt_result ret = nlopt_set_max_objective(o, f, f_data);
+ mythrow(ret);
+ }
+ void set_max_objective(func *f) {
+ set_max_objective(myfunc, f);
+ }
// Nonlinear constraints:
unsigned n; /* the dimension of the problem (immutable) */
nlopt_func f; void *f_data; /* objective function to minimize */
+ int maximize; /* nonzero if we are maximizing, not minimizing */
double *lb, *ub; /* lower and upper bounds (length n) */
nlopt_constraint *h; /* equality constraints, length p_alloc */
/* stopping criteria */
- double minf_max; /* stop when f < minf_max */
+ double stopval; /* stop when f reaches stopval or better */
double ftol_rel, ftol_abs; /* relative/absolute f tolerances */
double xtol_rel, *xtol_abs; /* rel/abs x tolerances */
int maxeval; /* max # evaluations */
NLOPT_INVALID_ARGS = -2,
NLOPT_OUT_OF_MEMORY = -3,
NLOPT_ROUNDOFF_LIMITED = -4,
-
+ NLOPT_STOPVAL_REACHED = 2,
NLOPT_SUCCESS = 1, /* generic success code */
NLOPT_MINF_MAX_REACHED = 2,
NLOPT_FTOL_REACHED = 3,
NLOPT_MAXTIME_REACHED = 6
} nlopt_result;
+#define NLOPT_MINF_MAX_REACHED NLOPT_STOPVAL_REACHED
NLOPT_EXTERN void nlopt_srand(unsigned long seed);
NLOPT_EXTERN void nlopt_srand_time(void);
NLOPT_EXTERN nlopt_result nlopt_set_min_objective(nlopt_opt opt, nlopt_func f,
void *f_data);
+NLOPT_EXTERN nlopt_result nlopt_set_max_objective(nlopt_opt opt, nlopt_func f,
+ void *f_data);
NLOPT_EXTERN nlopt_algorithm nlopt_get_algorithm(const nlopt_opt opt);
NLOPT_EXTERN unsigned nlopt_get_dimension(const nlopt_opt opt);
/* stopping criteria: */
-NLOPT_EXTERN nlopt_result nlopt_set_stopval(nlopt_opt opt, double minf_max);
+NLOPT_EXTERN nlopt_result nlopt_set_stopval(nlopt_opt opt, double stopval);
NLOPT_EXTERN double nlopt_get_stopval(const nlopt_opt opt);
NLOPT_EXTERN nlopt_result nlopt_set_ftol_rel(nlopt_opt opt, double tol);
const double *lb, *ub;
} nlopt_data;
-#include "praxis.h"
-
static double f_bound(int n, const double *x, void *data_)
{
int i;
(nlopt_stochastic_population > 0 ? \
nlopt_stochastic_population : (defaultpop)))
-nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *minf)
+/* unlike nlopt_optimize() below, only handles minimization case */
+static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
{
const double *lb, *ub;
nlopt_algorithm algorithm;
nlopt_data d;
nlopt_stopping stop;
- if (!opt || !x || !minf || !opt->f) return NLOPT_INVALID_ARGS;
-
+ if (!opt || !x || !minf || !opt->f
+ || opt->maximize) return NLOPT_INVALID_ARGS;
+
/* copy a few params to local vars for convenience */
n = opt->n;
ni = (int) n; /* most of the subroutines take "int" arg */
f = opt->f; f_data = opt->f_data;
if (n == 0) { /* trivial case: no degrees of freedom */
- *minf = f(n, x, NULL, f_data);
+ *minf = opt->f(n, x, NULL, opt->f_data);
return NLOPT_SUCCESS;
}
return NLOPT_INVALID_ARGS;
stop.n = n;
- stop.minf_max = opt->minf_max;
+ stop.minf_max = opt->stopval;
stop.ftol_rel = opt->ftol_rel;
stop.ftol_abs = opt->ftol_abs;
stop.xtol_rel = opt->xtol_rel;
/*********************************************************************/
+typedef struct {
+ nlopt_func f;
+ void *f_data;
+} f_max_data;
+
+/* wrapper for maximizing: just flip the sign of f and grad */
+static double f_max(unsigned n, const double *x, double *grad, void *data)
+{
+ f_max_data *d = (f_max_data *) data;
+ double val = d->f(n, x, grad, d->f_data);
+ if (grad) {
+ unsigned i;
+ for (i = 0; i < n; ++i)
+ grad[i] = -grad[i];
+ }
+ return -val;
+}
+
+nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *opt_f)
+{
+ nlopt_func f; void *f_data;
+ f_max_data fmd;
+ int maximize;
+ nlopt_result ret;
+
+ if (!opt || !opt_f || !opt->f) return NLOPT_INVALID_ARGS;
+ f = opt->f; f_data = opt->f_data;
+
+ /* for maximizing, just minimize the f_max wrapper, which
+ flips the sign of everything */
+ if ((maximize = opt->maximize)) {
+ fmd.f = f; fmd.f_data = f_data;
+ opt->f = f_max; opt->f_data = &fmd;
+ opt->stopval = -opt->stopval;
+ }
+
+ ret = nlopt_optimize_(opt, x, opt_f);
+
+ if (maximize) { /* restore original signs */
+ opt->stopval = -opt->stopval;
+ opt->f = f; opt->f_data = f_data;
+ *opt_f = -*opt_f;
+ }
+
+ return ret;
+}
+
+/*********************************************************************/
+
nlopt_result nlopt_optimize_limited(nlopt_opt opt, double *x, double *minf,
int maxeval, double maxtime)
{
opt->algorithm = algorithm;
opt->n = n;
opt->f = NULL; opt->f_data = NULL;
+ opt->maximize = 0;
opt->lb = opt->ub = NULL;
opt->m = opt->m_alloc = 0;
opt->p = opt->p_alloc = 0;
opt->h = NULL;
- opt->minf_max = -HUGE_VAL;
+ opt->stopval = -HUGE_VAL;
opt->ftol_rel = opt->ftol_abs = 0;
opt->xtol_rel = 0; opt->xtol_abs = NULL;
opt->maxeval = 0;
{
if (opt && f) {
opt->f = f; opt->f_data = f_data;
+ opt->maximize = 0;
+ if (nlopt_isinf(opt->stopval) && opt->stopval > 0)
+ opt->stopval = -HUGE_VAL;
+ 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) {
+ opt->f = f; opt->f_data = f_data;
+ opt->maximize = 1;
+ if (nlopt_isinf(opt->stopval) && opt->stopval < 0)
+ opt->stopval = +HUGE_VAL;
return NLOPT_SUCCESS;
}
return NLOPT_INVALID_ARGS;
#define GETSET(param, T, arg) GET(param, T, arg) SET(param, T, arg)
-GETSET(stopval, double, minf_max)
+GETSET(stopval, double, stopval)
GETSET(ftol_rel, double, ftol_rel)
GETSET(ftol_abs, double, ftol_abs)
ret = nlopt_set_min_objective(sub_opt, auglag, &d); if (ret<0) return ret;
ret = nlopt_set_lower_bounds(sub_opt, lb); if (ret<0) return ret;
ret = nlopt_set_upper_bounds(sub_opt, ub); if (ret<0) return ret;
+ ret = nlopt_set_stopval(sub_opt, stop->minf_max); if (ret<0) return ret;
ret = nlopt_remove_inequality_constraints(sub_opt); if (ret<0) return ret;
ret = nlopt_remove_equality_constraints(sub_opt); if (ret<0) return ret;
for (i = 0; i < m; ++i) {
nlopt_set_min_objective(dual_opt, dual_func, &dd);
nlopt_set_lower_bounds(dual_opt, dual_lb);
nlopt_set_upper_bounds(dual_opt, dual_ub);
+ nlopt_set_stopval(dual_opt, -HUGE_VAL);
while (1) { /* outer iterations */
double fprev = fcur;