chiark / gitweb /
add set_max_objective to automate the sign flip for maximization
authorstevenj <stevenj@alum.mit.edu>
Mon, 5 Apr 2010 07:16:50 +0000 (03:16 -0400)
committerstevenj <stevenj@alum.mit.edu>
Mon, 5 Apr 2010 07:16:50 +0000 (03:16 -0400)
darcs-hash:20100405071650-c8de0-c7d3b05da048406f5004a4c9c46dccd6d2a41100.gz

api/nlopt-in.hpp
api/nlopt-internal.h
api/nlopt.h
api/optimize.c
api/options.c
auglag/auglag.c
mma/mma.c

index dd76746d3f1be0704874127b9bbff86ad376f0e9..a4d91440ed5d7b3a979168c92dfacc2f0defd1b5 100644 (file)
@@ -130,6 +130,13 @@ namespace nlopt {
     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:
 
index 336f77efe84c2b6a8015dd83b07ef694555dde48..80689112f3bb959e089bfe82bd06ff143e5f0d1f 100644 (file)
@@ -38,6 +38,7 @@ struct nlopt_opt_s {
      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) */
 
@@ -50,7 +51,7 @@ struct nlopt_opt_s {
      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 */
index 7f34090f706f6dcc794a9f42a5cd1f4f57735fb0..8c5819a8d42f7c6ca116cbb809015189b6caa9d4 100644 (file)
@@ -135,7 +135,7 @@ typedef enum {
      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,
@@ -144,6 +144,7 @@ typedef enum {
      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);
@@ -173,6 +174,8 @@ NLOPT_EXTERN nlopt_result nlopt_optimize(nlopt_opt opt, double *x,
 
 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);
@@ -204,7 +207,7 @@ NLOPT_EXTERN nlopt_result nlopt_add_equality_constraint(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);
index b1448f27e40b42c877ef6672c4147774e5584860..6c70bd6d5d5d622744730b96480d371cff9e8d95 100644 (file)
@@ -69,8 +69,6 @@ typedef struct {
      const double *lb, *ub;
 } nlopt_data;
 
-#include "praxis.h"
-
 static double f_bound(int n, const double *x, void *data_)
 {
      int i;
@@ -142,7 +140,8 @@ static int finite_domain(unsigned n, const double *lb, const double *ub)
                          (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;
@@ -152,8 +151,9 @@ nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *minf)
      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 */
@@ -162,7 +162,7 @@ nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *minf)
      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;
      }
 
@@ -183,7 +183,7 @@ nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *minf)
               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;
@@ -512,6 +512,55 @@ nlopt_result nlopt_optimize(nlopt_opt opt, double *x, double *minf)
 
 /*********************************************************************/
 
+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)
 {
index af50c4dab0994f44a576b7c49942e9b27960ed27..038256efe39e23d641d6ee91d97ca8bb20e462ba 100644 (file)
@@ -56,6 +56,7 @@ nlopt_opt nlopt_create(nlopt_algorithm algorithm, unsigned n)
          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;
@@ -63,7 +64,7 @@ nlopt_opt nlopt_create(nlopt_algorithm algorithm, unsigned n)
          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;
@@ -158,6 +159,21 @@ nlopt_result nlopt_set_min_objective(nlopt_opt opt, nlopt_func f, void *f_data)
 {
      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;
@@ -323,7 +339,7 @@ nlopt_result nlopt_add_equality_constraint(nlopt_opt opt,
 
 #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)
index 808d20eed2bc85e05ba57c922ab49dbfe91150dc..c5b65f08d8c0baf0badc5459f3d2a5e486066536 100644 (file)
@@ -91,6 +91,7 @@ nlopt_result auglag_minimize(int n, nlopt_func f, void *f_data,
      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) {
index 3451b4971fe44ade1f3fa75d973ed3cc14f37619..feba141fda61a74aef79d3e0b115bacc2b1e5b8e 100644 (file)
--- a/mma/mma.c
+++ b/mma/mma.c
@@ -231,6 +231,7 @@ nlopt_result mma_minimize(int n, nlopt_func f, void *f_data,
      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;