chiark / gitweb /
check bounds in testopt, fix bug in NEWUOA_BOUNDS that allowed it to go outside of...
authorstevenj <stevenj@alum.mit.edu>
Mon, 1 Sep 2008 06:36:05 +0000 (02:36 -0400)
committerstevenj <stevenj@alum.mit.edu>
Mon, 1 Sep 2008 06:36:05 +0000 (02:36 -0400)
darcs-hash:20080901063605-c8de0-466debf023ac975267a65a9f125ada08c771fb49.gz

newuoa/newuoa.c
test/testopt.cpp

index 883f30ff92642ddcea460a6f4c93aff476746b8e..8842c3c6d5514174c706b686f3992e9d98032946 100644 (file)
@@ -1744,6 +1744,12 @@ L50:
 /* L60: */
        x[j] = xpt[nf + j * xpt_dim1] + xbase[j];
     }
+    if (lb && ub) { /* SGJ, 2008: make sure we are within bounds */
+        for (j = 1; j <= i__1; ++j) {
+             if (x[j] < lb[j-1]) x[j] = lb[j-1];
+             else if (x[j] > ub[j-1]) x[j] = ub[j-1];
+        }
+    }
     goto L310;
 L70:
     fval[nf] = f;
index 71ac50a516b546b734825d99e0cec60d42b1d9c7..66a74d82b1478106a3f97e398e37fbb7161f1d9b 100644 (file)
@@ -39,6 +39,24 @@ static void listfuncs(FILE *f)
     fprintf(f, "  %2d: %s (%d dims)\n", i, testfuncs[i].name, testfuncs[i].n);
 }
 
+typedef struct {
+  const double *lb, *ub;
+  nlopt_func f;
+  void *f_data;
+} bounds_wrap_data;
+
+static double bounds_wrap_func(int n, const double *x, double *grad, void *d_)
+{
+  bounds_wrap_data *d = (bounds_wrap_data *) d_;
+  int i;
+  for (i = 0; i < n; ++i)
+    if (x[i] < d->lb[i] || x[i] > d->ub[i])
+      break;
+  if (i < n)
+    fprintf(stderr, "WARNING: bounds violated by x[%d] = %g\n", i, x[i]);
+  return d->f(n, x, grad, d->f_data);
+}
+
 static int test_function(int ifunc)
 {
   testfunc func;
@@ -48,6 +66,7 @@ static int test_function(int ifunc)
   double start = nlopt_seconds();
   int total_count = 0;
   double total_err = 0, max_err = 0;
+  bounds_wrap_data bw;
   
   if (ifunc < 0 || ifunc >= NTESTFUNCS) {
     fprintf(stderr, "testopt: invalid function %d\n", ifunc);
@@ -61,6 +80,10 @@ static int test_function(int ifunc)
   lb = x + func.n * 3;
   ub = lb + func.n;
   xtabs = x + func.n * 2;
+  bw.lb = lb;
+  bw.ub = ub;
+  bw.f = func.f;
+  bw.f_data = func.f_data;
 
   for (i = 0; i < func.n; ++i) xtabs[i] = xtol_abs;
   minf_max = minf_max_delta > (-HUGE_VAL) ? minf_max_delta + func.minf : (-HUGE_VAL);
@@ -129,7 +152,7 @@ static int test_function(int ifunc)
     }
     
     ret = nlopt_minimize(algorithm,
-                        func.n, func.f, func.f_data,
+                        func.n, bounds_wrap_func, &bw,
                         lb, ub,
                         x, &minf,
                         minf_max, ftol_rel, ftol_abs, xtol_rel, xtabs,