chiark / gitweb /
support equality constraints in COBYLA (internally, just a pair of inequality constra...
authorstevenj <stevenj@alum.mit.edu>
Thu, 24 Jun 2010 23:29:26 +0000 (19:29 -0400)
committerstevenj <stevenj@alum.mit.edu>
Thu, 24 Jun 2010 23:29:26 +0000 (19:29 -0400)
darcs-hash:20100624232926-c8de0-6baa8f1caf2967dca27635be396fd510701580ab.gz

api/nlopt.3
api/optimize.c
api/options.c
cobyla/cobyla.c
cobyla/cobyla.h

index c3c943ed2273cacff69f19f47b4791b3e888760b..8e13e692d61fe5a07053d4e0753ccd663550dedf 100644 (file)
@@ -200,9 +200,9 @@ constant (so that you don't have to fill an array with a constant value):
 .BI "                                       double " "ub" ); 
 .sp
 .SH NONLINEAR CONSTRAINTS
-Several of the algorithms in NLopt (MMA, COBYLA, and ORIG_DIRECT) also
-support arbitrary nonlinear inequality constraints, and some also
-allow nonlinear equality constraints (ISRES and AUGLAG).  For these
+Several of the algorithms in NLopt (MMA and ORIG_DIRECT) also support
+arbitrary nonlinear inequality constraints, and some also allow
+nonlinear equality constraints (COBYLA, ISRES, and AUGLAG).  For these
 algorithms, you can specify as many nonlinear constraints as you wish
 by calling the following functions multiple times.
 .sp
@@ -450,9 +450,9 @@ Local (L) derivative-free (N) optimization using the COBYLA algorithm
 of Powell (Constrained Optimization BY Linear Approximations).
 The
 .B NLOPT_LN_COBYLA
-algorithm supports both bound-constrained and unconstrained optimization,
-and also supports an arbitrary number (\fIm\fR) of nonlinear constraints
-as described above.
+algorithm supports both bound-constrained and unconstrained
+optimization, and also supports an arbitrary number (\fIm\fR) of
+nonlinear inequality/equality constraints as described above.
 .TP
 .B NLOPT_LN_NEWUOA
 Local (L) derivative-free (N) optimization using a variant of the
index 2c169b173fc6c9278d179e506bd00309674929e8..fe2164fdfc65bc1afad29b8c9dfc988add9e1978 100644 (file)
@@ -423,6 +423,7 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
                   return NLOPT_OUT_OF_MEMORY;
              return cobyla_minimize(ni, f, f_data, 
                                     opt->m, opt->fc,
+                                    opt->p, opt->h,
                                     lb, ub, x, minf, &stop,
                                     step);
         }
index c3ae1b46dc3fd3572e63900fc432caf7acc68840..50a376efab86f8badaca3c8ff8466d052e3d4d57 100644 (file)
@@ -367,7 +367,8 @@ NLOPT_STDCALL nlopt_add_equality_constraint(nlopt_opt opt,
 {
      if (opt && h && tol >= 0) {
          /* equality constraints (h(x) = 0) only via some algorithms */
-         if (!AUGLAG_ALG(opt->algorithm) && opt->algorithm != NLOPT_GN_ISRES)
+         if (!AUGLAG_ALG(opt->algorithm) && opt->algorithm != NLOPT_GN_ISRES
+             && opt->algorithm != NLOPT_LN_COBYLA)
               return NLOPT_INVALID_ARGS;
          return add_constraint(&opt->p, &opt->p_alloc, &opt->h,
                                h, h_data, tol);
index f24c5af4b6e721c4696f3686e2281951c9198286..fe705be0ba312a6dae2947a853c9c24029535778 100644 (file)
@@ -66,6 +66,8 @@ typedef struct {
      void *f_data;
      int m_orig;
      nlopt_constraint *fc;
+     int p;
+     nlopt_constraint *h;
      double *xtmp;
      const double *lb, *ub;
 } func_wrap_state;
@@ -91,6 +93,11 @@ static int func_wrap(int n, int m, double *x, double *f, double *con,
      *f = s->f(n, xtmp, NULL, s->f_data);
      for (i = 0; i < s->m_orig; ++i)
          con[i] = -s->fc[i].f(n, xtmp, NULL, s->fc[i].f_data);
+     for (j = 0; j < s->p; ++j) {
+         double h = s->h[j].f(n, xtmp, NULL, s->h[j].f_data);
+         con[i++] = h;
+         con[i++] = -h;
+     }
      for (j = 0; j < n; ++j) {
          if (!nlopt_isinf(lb[j]))
               con[i++] = x[j] - lb[j];
@@ -154,6 +161,7 @@ extern nlopt_result cobyla(int n, int m, double *x, double *minf, double rhobeg,
 
 nlopt_result cobyla_minimize(int n, nlopt_func f, void *f_data,
                             int m, nlopt_constraint *fc,
+                             int p, nlopt_constraint *h,
                             const double *lb, const double *ub, /* bounds */
                             double *x, /* in: initial guess, out: minimizer */
                             double *minf,
@@ -167,10 +175,15 @@ nlopt_result cobyla_minimize(int n, nlopt_func f, void *f_data,
      s.f = f; s.f_data = f_data;
      s.m_orig = m;
      s.fc = fc; 
+     s.p = p;
+     s.h = h;
      s.lb = lb; s.ub = ub;
      s.xtmp = (double *) malloc(sizeof(double) * n);
      if (!s.xtmp) return NLOPT_OUT_OF_MEMORY;
 
+     /* each equality constraint gives two inequality constraints */
+     m += 2*p;
+
      /* add constraints for lower/upper bounds (if any) */
      for (j = 0; j < n; ++j) {
          if (!nlopt_isinf(lb[j]))
index d1980f88926379b2cab2f9620385643de3c0a582..824c3bde5dca07544ffba43d538270ade8537a53 100644 (file)
@@ -48,6 +48,7 @@ extern "C"
 /* NLopt-style interface function */
 nlopt_result cobyla_minimize(int n, nlopt_func f, void *f_data,
                              int m, nlopt_constraint *fc,
+                             int p, nlopt_constraint *h,
                              const double *lb, const double *ub, /* bounds */
                              double *x, /* in: initial guess, out: minimizer */
                              double *minf,