chiark / gitweb /
added corner optimization test case, average #evaluations
authorstevenj <stevenj@alum.mit.edu>
Sun, 31 Aug 2008 18:11:21 +0000 (14:11 -0400)
committerstevenj <stevenj@alum.mit.edu>
Sun, 31 Aug 2008 18:11:21 +0000 (14:11 -0400)
darcs-hash:20080831181121-c8de0-84e1ad830abe38d212aca8b8791312d30b105489.gz

test/testfuncs.c
test/testfuncs.h
test/testopt.cpp

index 09f7d554a0283430b31ad577673341f4a88d4ff8..272a16383e54a8eb1387bd44621a4b79e161c187 100644 (file)
@@ -370,6 +370,26 @@ static const double osc1d_lb[1] = {-5};
 static const double osc1d_ub[1] = {5};
 static const double osc1d_xmin[1] = {1.23456789};
 
+/****************************************************************************/
+static double corner4d_f(int n, const double *x, double *grad, void *data)
+{
+     UNUSED(data);
+     UNUSED(n);
+     double u = x[0] + x[1] * x[2] * sin(2 * x[3]);
+     double v = x[0] + 2*sin(u);
+     if (grad) {
+         grad[0] = 2*v * (1 + 2*cos(u));
+         grad[1] = 2*v * 2*cos(u) * x[2] * sin(2*x[3]) + 0.1;
+         grad[2] = 2*v * 2*cos(u) * x[1] * sin(2*x[3]) + 0.1;
+         grad[3] = 2*v * 2*cos(u) * x[1]*x[2] * cos(2*x[3]) * 2 + 0.1;
+     }
+     RETURN(1 + v*v + 0.1*(x[1]+x[2]+x[3]));
+}
+
+static const double corner4d_lb[4] = {0,0,0,0};
+static const double corner4d_ub[4] = {1,1,1,1};
+static const double corner4d_xmin[4] = {0,0,0,0};
+
 /****************************************************************************/
 /****************************************************************************/
 
@@ -433,5 +453,8 @@ const testfunc testfuncs[NTESTFUNCS] = {
        -176.541793, "Hansen function" },
      { osc1d_f, NULL, 1, 1,
        osc1d_lb, osc1d_ub, osc1d_xmin,
-       -1.0, "1d oscillating function with a single minimum" }
+       -1.0, "1d oscillating function with a single minimum" },
+     { corner4d_f, NULL, 1, 4,
+       corner4d_lb, corner4d_ub, corner4d_xmin,
+       1.0, "4d function with minimum at corner" }
 };
index 63ea3da01a921a84bb9726ea19d2119292886eee..b20ea883bcc5c9cd6aabbe32fe2d187792a3cc3b 100644 (file)
@@ -18,7 +18,7 @@ typedef struct {
      const char *name;
 } testfunc;
 
-#define NTESTFUNCS 20
+#define NTESTFUNCS 21
 extern const testfunc testfuncs[NTESTFUNCS];
 
 extern int testfuncs_verbose;
index a58ca00407f0a38bddb57807cdabc5aa8653b4b2..71ac50a516b546b734825d99e0cec60d42b1d9c7 100644 (file)
@@ -46,6 +46,8 @@ static int test_function(int ifunc)
   double *x, minf, minf_max, f0, *xtabs, *lb, *ub;
   nlopt_result ret;
   double start = nlopt_seconds();
+  int total_count = 0;
+  double total_err = 0, max_err = 0;
   
   if (ifunc < 0 || ifunc >= NTESTFUNCS) {
     fprintf(stderr, "testopt: invalid function %d\n", ifunc);
@@ -89,42 +91,43 @@ static int test_function(int ifunc)
     printf("]\n");
   }
 
+  for (iter = 0; iter < iterations; ++iter) {
+    double val;
+    testfuncs_counter = 0;
 
-  printf("Starting guess x = [");
-  for (i = 0; i < func.n; ++i) {
-    if (center_start)
-      x[i] = (ub[i] + lb[i]) * 0.5;
-    else if (xinit_tol < 0) { /* random starting point near center of box */
-      double dx = (ub[i] - lb[i]) * 0.25;
-      double xm = 0.5 * (ub[i] + lb[i]);
-      x[i] = nlopt_urand(xm - dx, xm + dx);
-    }
-    else {
-      x[i] = nlopt_urand(-xinit_tol, xinit_tol)
-       + (1 + nlopt_urand(-xinit_tol, xinit_tol)) * func.xmin[i];
-      if (x[i] > ub[i]) x[i] = ub[i];
-      else if (x[i] < lb[i]) x[i] = lb[i];
-    }
-    printf(" %g", x[i]);
-  }
-  printf("]\n");
-  f0 = func.f(func.n, x, x + func.n, func.f_data);
-  printf("Starting function value = %g\n", f0);
-
-  if (testfuncs_verbose && func.has_gradient) {
-    printf("checking gradient:\n");
+    printf("Starting guess x = [");
     for (i = 0; i < func.n; ++i) {
-      double f;
-      x[i] *= 1 + 1e-6;
-      f = func.f(func.n, x, NULL, func.f_data);
-      x[i] /= 1 + 1e-6;
-      printf("  grad[%d] = %g vs. numerical derivative %g\n",
-            i, x[i + func.n], (f - f0) / (x[i] * 1e-6));
+      if (center_start)
+       x[i] = (ub[i] + lb[i]) * 0.5;
+      else if (xinit_tol < 0) { /* random starting point near center of box */
+       double dx = (ub[i] - lb[i]) * 0.25;
+       double xm = 0.5 * (ub[i] + lb[i]);
+       x[i] = nlopt_urand(xm - dx, xm + dx);
+      }
+      else {
+       x[i] = nlopt_urand(-xinit_tol, xinit_tol)
+         + (1 + nlopt_urand(-xinit_tol, xinit_tol)) * func.xmin[i];
+       if (x[i] > ub[i]) x[i] = ub[i];
+       else if (x[i] < lb[i]) x[i] = lb[i];
+      }
+      printf(" %g", x[i]);
     }
-  }
-
-  for (iter = 0; iter < iterations; ++iter) {
-    testfuncs_counter = 0;
+    printf("]\n");
+    f0 = func.f(func.n, x, x + func.n, func.f_data);
+    printf("Starting function value = %g\n", f0);
+    
+    if (iter > 0 && testfuncs_verbose && func.has_gradient) {
+      printf("checking gradient:\n");
+      for (i = 0; i < func.n; ++i) {
+       double f;
+       x[i] *= 1 + 1e-6;
+       f = func.f(func.n, x, NULL, func.f_data);
+       x[i] /= 1 + 1e-6;
+       printf("  grad[%d] = %g vs. numerical derivative %g\n",
+              i, x[i + func.n], (f - f0) / (x[i] * 1e-6));
+      }
+    }
+    
     ret = nlopt_minimize(algorithm,
                         func.n, func.f, func.f_data,
                         lb, ub,
@@ -139,16 +142,28 @@ static int test_function(int ifunc)
     }
     printf("Found minimum f = %g after %d evaluations.\n", 
           minf, testfuncs_counter);
+    total_count += testfuncs_counter;
     printf("Minimum at x = [");
     for (i = 0; i < func.n; ++i) printf(" %g", x[i]);
     printf("]\n");
     printf("|f - minf| = %g, |f - minf| / |minf| = %e\n",
           fabs(minf - func.minf), fabs(minf - func.minf) / fabs(func.minf));
+    total_err += fabs(minf - func.minf);
+    if (fabs(minf - func.minf) > max_err)
+      max_err = fabs(minf - func.minf);
+    printf("vs. global minimum f = %g at x = [", func.minf);
+    for (i = 0; i < func.n; ++i) printf(" %g", func.xmin[i]);
+    printf("]\n");
+
+    val = func.f(func.n, x, NULL, func.f_data);
+    if (val != minf) {
+      fprintf(stderr, "Mismatch %g between returned minf=%g and f(x) = %g\n", 
+             minf - val, minf, val);
+      return 0;
+    }
   }
-  printf("vs. global minimum f = %g at x = [", func.minf);
-  for (i = 0; i < func.n; ++i) printf(" %g", func.xmin[i]);
-  printf("]\n");
-  
+  printf("average #evaluations = %g\naverage |f-minf| = %g, max |f-minf| = %g\n", total_count * 1.0 / iterations, total_err / iterations, max_err);
+
   free(x);
   return 1;
 }