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};
+
/****************************************************************************/
/****************************************************************************/
-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" }
};
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);
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,
}
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;
}