chiark / gitweb /
added 9 more test functions
[nlopt.git] / test / testopt.cpp
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <math.h>
4
5 #include "config.h"
6
7 #ifdef HAVE_UNISTD_H
8 #  include <unistd.h>
9 #endif
10 #ifdef HAVE_GETOPT_H
11 #  include <getopt.h>
12 #endif
13 #if TIME_WITH_SYS_TIME
14 # include <sys/time.h>
15 # include <time.h>
16 #else
17 # if HAVE_SYS_TIME_H
18 #  include <sys/time.h>
19 # else
20 #  include <time.h>
21 # endif
22 #endif
23
24 #include "nlopt.h"
25 #include "testfuncs.h"
26
27 static double urand(double a, double b)
28 {
29   return a + (rand() * (b - a) / RAND_MAX);
30 }
31
32 static nlopt_algorithm algorithm = NLOPT_GLOBAL_DIRECT;
33 static double ftol_rel = 0, ftol_abs = 0, xtol_rel = 0;
34 static int maxeval = 1000;
35 static double maxtime = 0.0;
36
37 static int test_function(int ifunc)
38 {
39   testfunc func;
40   int i;
41   double *x, fmin, f0;
42   nlopt_result ret;
43   
44   if (ifunc < 0 || ifunc >= NTESTFUNCS) {
45     fprintf(stderr, "testopt: invalid function %d\n", ifunc);
46     return 0;
47   }
48   func = testfuncs[ifunc];
49   if (!func.has_gradient && algorithm >= NLOPT_GLOBAL_STOGO) {
50     fprintf(stderr, 
51             "testopt: A function with gradients is required for %s\n",
52             nlopt_algorithm_name(algorithm));
53     return 0;
54   }
55   x = (double *) malloc(sizeof(double) * func.n * 2);
56   if (!x) { fprintf(stderr, "testopt: Out of memory!\n"); return 0; }
57
58   
59   printf("-----------------------------------------------------------\n");
60   printf("Optimizing %s (%d dims) using %s algorithm\n",
61          func.name, func.n, nlopt_algorithm_name(algorithm));
62   printf("Starting guess x = [");
63   for (i = 0; i < func.n; ++i)
64     printf(" %g", x[i] = urand(func.lb[i], func.ub[i]));
65   printf("]\n");
66   f0 = func.f(func.n, x, x + func.n, func.f_data);
67   printf("Starting function value = %g\n", f0);
68
69   if (testfuncs_verbose && func.has_gradient) {
70     printf("checking gradient:\n");
71     for (i = 0; i < func.n; ++i) {
72       double f;
73       x[i] *= 1 + 1e-6;
74       f = func.f(func.n, x, NULL, func.f_data);
75       x[i] /= 1 + 1e-6;
76       printf("  grad[%d] = %g vs. numerical derivative %g\n",
77              i, x[i + func.n], (f - f0) / (x[i] * 1e-6));
78     }
79   }
80
81   testfuncs_counter = 0;
82   ret = nlopt_minimize(algorithm,
83                        func.n, func.f, func.f_data,
84                        func.lb, func.ub,
85                        x, &fmin,
86                        HUGE_VAL, ftol_rel, ftol_abs, xtol_rel, NULL,
87                        maxeval, maxtime);
88   printf("return code %d from nlopt_minimize\n", ret);
89   if (ret < 0) {
90     fprintf(stderr, "testopt: error in nlopt_minimize\n");
91     return 0;
92   }
93   printf("Found minimum f = %g after %d evaluations.\n", 
94          fmin, testfuncs_counter);
95   printf("Minimum at x = [");
96   for (i = 0; i < func.n; ++i) printf(" %g", x[i]);
97   printf("]\n");
98   printf("vs. global minimum f = %g at x = [", func.fmin);
99   for (i = 0; i < func.n; ++i) printf(" %g", func.xmin[i]);
100   printf("]\n");
101   printf("|f - fmin| = %g, |f - fmin| / |fmin| = %e\n",
102          fabs(fmin - func.fmin), fabs(fmin - func.fmin) / fabs(func.fmin));
103   
104   free(x);
105   return 1;
106 }
107
108 static void usage(FILE *f)
109 {
110   fprintf(f, "Usage: testopt [OPTIONS]\n"
111           "Options:\n"
112           "     -h : print this help\n"
113           "     -v : verbose mode\n"
114           " -r <s> : use random seed <s> for starting guesses\n"
115           " -a <n> : use optimization algorithm <n>\n"
116           " -o <n> : use objective function <n>\n"
117           " -e <n> : use at most <n> evals (default: %d)\n",
118           maxeval);
119 }
120
121 int main(int argc, char **argv)
122 {
123   int c;
124   
125   srand((unsigned) time(NULL));
126   testfuncs_verbose = 0;
127   
128   while ((c = getopt(argc, argv, "hvra:o:e:")) != -1)
129     switch (c) {
130     case 'h':
131       usage(stdout);
132       return EXIT_SUCCESS;
133     case 'v':
134       testfuncs_verbose = 1;
135       break;
136     case 'r':
137       srand((unsigned) atoi(optarg));
138       break;
139     case 'a':
140       c = atoi(optarg);
141       if (c < 0 || c >= NLOPT_NUM_ALGORITHMS) {
142         fprintf(stderr, "testopt: invalid algorithm %d\n", c);
143         return EXIT_FAILURE;
144       }
145       algorithm = (nlopt_algorithm) c;
146       break;
147     case 'o':
148       if (!test_function(atoi(optarg)))
149         return EXIT_FAILURE;
150       break;
151     case 'e':
152       maxeval = atoi(optarg);
153       break;
154     default:
155       fprintf(stderr, "harminv: invalid argument -%c\n", c);
156       usage(stderr);
157       return EXIT_FAILURE;
158     }
159   
160   return EXIT_SUCCESS;
161 }