7 #define UNUSED(x) (void) x
9 static double sqr(double x) { return x * x; }
11 int testfuncs_verbose = 0;
12 int testfuncs_counter = 0;
14 static double testfuncs_status(int n, const double *x, double f)
17 if (testfuncs_verbose) {
19 printf("f_%d (%g", testfuncs_counter, x[0]);
20 for (i = 1; i < n; ++i) printf(", %g", x[i]);
21 printf(") = %g\n", f);
26 #define RETURN(f) return testfuncs_status(n, x, f);
28 #define PI2 6.283185307179586 /* 2*pi */
29 #define PI3 9.424777960769379 /* 3*pi */
30 #define PI4 12.5663706143592 /* 4*pi */
32 /****************************************************************************/
33 static double rosenbrock_f(int n, const double *x, double *grad, void *data)
35 double a = x[1] - x[0] * x[0], b = 1 - x[0];
38 grad[0] = -400 * a * x[0] - 2*b;
41 RETURN(100 * sqr(a) + sqr(b));
44 static const double rosenbrock_lb[2] = {-2, -2};
45 static const double rosenbrock_ub[2] = {2, 2};
46 static const double rosenbrock_xmin[2] = {1, 1};
48 /****************************************************************************/
49 static double mccormic_f(int n, const double *x, double *grad, void *data)
51 double a = x[0] + x[1], b = x[0] - x[1];
54 grad[0] = cos(a) + 2*b - 1.5;
55 grad[1] = cos(a) - 2*b + 2.5;
57 RETURN(sin(a) + sqr(b) - 1.5*x[0] + 2.5*x[1] + 1);
60 static const double mccormic_lb[2] = {-1.5, -3};
61 static const double mccormic_ub[2] = {4, 4};
62 static const double mccormic_xmin[2] = {-0.54719, 1.54719};
64 /****************************************************************************/
65 static double boxbetts_f(int n, const double *x, double *grad, void *data)
71 grad[0] = grad[1] = grad[2] = 0;
72 for (i = 1; i <= 10; ++i) {
73 double e0 = exp(-0.1*i*x[0]);
74 double e1 = exp(-0.1*i*x[1]);
75 double e2 = exp(-0.1*i) - exp((double) -i);
76 double g = e0 - e1 - e2 * x[2];
79 grad[0] += (2 * g) * (-0.1*i*e0);
80 grad[1] += (2 * g) * (0.1*i*e1);
81 grad[2] += -(2 * g) * e2;
87 static const double boxbetts_lb[3] = {0.9,9,0.9};
88 static const double boxbetts_ub[3] = {1.2,11.2,1.2};
89 static const double boxbetts_xmin[3] = {1,10,1};
91 /****************************************************************************/
92 static double paviani_f(int n, const double *x, double *grad, void *data)
95 double f = 0, prod = 1;
97 if (grad) for (i = 0; i < 10; ++i) grad[i] = 0;
98 for (i = 0; i < 10; ++i) {
99 double ln1 = log(x[i] - 2);
100 double ln2 = log(10 - x[i]);
101 f += sqr(ln1) + sqr(ln2);
103 grad[i] += 2 * ln1 / (x[i] - 2) - 2 * ln2 / (10 - x[i]);
106 f -= (prod = pow(prod, 0.2));
108 for (i = 0; i < 10; ++i)
109 grad[i] -= 0.2 * prod / x[i];
113 static const double paviani_lb[10] = {2.001,2.001,2.001,2.001,2.001,2.001,2.001,2.001,2.001,2.001};
114 static const double paviani_ub[10] = {9.999,9.999,9.999,9.999,9.999,9.999,9.999,9.999,9.999,9.999};
115 static const double paviani_xmin[10] = {9.350266,9.350266,9.350266,9.350266,9.350266,9.350266,9.350266,9.350266,9.350266,9.350266};
117 /****************************************************************************/
118 static double grosenbrock_f(int n, const double *x, double *grad, void *data)
123 if (grad) grad[0] = 0;
124 for (i = 0; i < 29; ++i) {
125 double a = x[i+1] - x[i] * x[i], b = 1 - x[i];
127 grad[i] += -400 * a * x[i] - 2*b;
128 grad[i+1] = -200 * a;
130 f += 100 * sqr(a) + sqr(b);
135 static const double grosenbrock_lb[30] = {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30};
136 static const double grosenbrock_ub[30] = {30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30};
137 static const double grosenbrock_xmin[30] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
139 /****************************************************************************/
140 static double goldsteinprice_f(int n, const double *x, double *grad, void *data)
142 double x0, x1, a1, a12, a2, b1, b12, b2;
144 x0 = x[0]; x1 = x[1];
145 a1 = x0+x1+1; a12 = sqr(a1);
146 a2 = 19 - 14*x0 + 3*x0*x0 - 14*x1 + 6*x0*x1 + 3*x1*x1;
147 b1 = 2*x0-3*x1; b12 = sqr(b1);
148 b2 = 18 - 32*x0 + 12*x0*x0 + 48*x1 - 36*x0*x1 + 27*x1*x1;
150 grad[0] = (1 + a12 * a2) * (2 * b1 * 2 * b2
151 + b12 * (-32 + 24*x0 - 36*x1))
152 + (2 * a1 * a2 + a12 * (-14 + 6*x0 + 6*x1)) * (30 + b12 * b2);
153 grad[1] = (1 + a12 * a2) * (2 * b1 * (-3) * b2
154 + b12 * (48 - 36*x0 + 54 * x1))
155 + (2 * a1 * a2 + a12 * (-14 + 6*x0 + 6*x1)) * (30 + b12 * b2);
157 RETURN((1 + a12 * a2) * (30 + b12 * b2));
160 static const double goldsteinprice_lb[2] = {-2, -2};
161 static const double goldsteinprice_ub[2] = {2, 2};
162 static const double goldsteinprice_xmin[2] = {0, -1};
164 /****************************************************************************/
165 static double shekel_f(int n, const double *x, double *grad, void *data)
167 static const double A[10][4] = { {4,4,4,4},
177 static const double c[10] = {.1,.2,.2,.4,.4,.6,.3,.7,.5,.5};
180 if (grad) for (i = 0; i < n; ++i) grad[i] = 0;
181 int m = *((int *) data);
182 for (i = 0; i < m; ++i) {
183 double fi = 1.0 / (c[i]
187 + sqr(x[3]-A[i][3]));
190 grad[0] += (2*fi*fi) * (x[0]-A[i][0]);
191 grad[1] += (2*fi*fi) * (x[1]-A[i][1]);
192 grad[2] += (2*fi*fi) * (x[2]-A[i][2]);
193 grad[3] += (2*fi*fi) * (x[3]-A[i][3]);
199 static int shekel_m[3] = {5,7,10};
200 static const double shekel_lb[4] = {0,0,0,0};
201 static const double shekel_ub[4] = {10,10,10,10};
202 static const double shekel0_xmin[4] = {4.00004,4.00013,4.00004,4.00013};
203 static const double shekel1_xmin[4] = {4.00057,4.00069,3.99949,3.99961};
204 static const double shekel2_xmin[4] = {4.00075,4.00059,3.99966,3.99951};
206 /****************************************************************************/
207 static double levy_f(int n, const double *x, double *grad, void *data)
211 double a = x[n-1] - 1, b = 1 + sqr(sin(PI2*x[n-1]));
212 double f = sqr(sin(PI3*x[0])) + a * b;
214 for (i = 0; i < n; ++i) grad[i] = 0;
215 grad[0] = 2 * PI3 * sin(PI3*x[0]) * cos(PI3*x[0]);
216 grad[n-1] += b + a * 2 * PI2 * sin(PI2*x[n-1]) * cos(PI2*x[n-1]);
218 for (i = 0; i < n-1; ++i) {
220 b = 1 + sqr(sin(PI3*x[i+1]));
223 grad[i] += 2 * a * b;
224 grad[i+1] += 2*PI3 * sqr(a) * sin(PI3*x[i+1])*cos(PI3*x[i+1]);
230 static const double levy_lb[7] = {-5,-5,-5,-5,-5,-5,-5};
231 static const double levy_ub[7] = {5,5,5,5,5,5,5};
232 static const double levy_xmin[7] = {1,1,1,1,1,1,-4.754402};
233 static const double levy4_lb[4] = {-10,-10,-10,-10};
234 static const double levy4_ub[4] = {10,10,10,10};
235 static const double levy4_xmin[4] = {1,1,1,-9.752356};
237 /****************************************************************************/
238 static double griewank_f(int n, const double *x, double *grad, void *data)
243 for (i = 0; i < n; ++i) {
244 f += sqr(x[i]) * 0.00025;
245 p *= cos(x[i] / sqrt(i + 1.));
246 if (grad) grad[i] = x[i] * 0.0005;
250 for (i = 0; i < n; ++i)
251 grad[i] += p * tan(x[i] / sqrt(i + 1.)) / sqrt(i + 1.);
255 static const double griewank_lb[10] = {-500,-500,-500,-500,-500,-500,-500,-500,-500,-500};
256 static const double griewank_ub[10] = {600,600,600,600,600,600,600,600,600,600};
257 static const double griewank_xmin[10] = {0,0,0,0,0,0,0,0,0,0};
259 /****************************************************************************/
260 static double sixhumpcamel_f(int n, const double *x, double *grad, void *data)
264 grad[0] = 8*x[0] - 2.1*4*pow(x[0],3.) + 2*pow(x[0],5.) + x[1];
265 grad[1] = x[0] - 8*x[1] + 16*pow(x[1],3.);
267 RETURN(4*sqr(x[0]) - 2.1 * pow(x[0],4.) + pow(x[0],6.)/3.
268 + x[0]*x[1] - 4*sqr(x[1]) + 4*pow(x[1],4.));
271 static const double sixhumpcamel_lb[2] = {-5,-5};
272 static const double sixhumpcamel_ub[2] = {5,5};
273 static const double sixhumpcamel_xmin[2] = {0.08984, -0.71266};
275 /****************************************************************************/
276 static double convexcosh_f(int n, const double *x, double *grad, void *data)
281 for (i = 0; i < n; ++i)
282 f *= cosh((x[i] - i) * (i+1));
284 for (i = 0; i < n; ++i)
285 grad[i] = f * tanh((x[i] - i) * (i+1)) * (i+1);
289 static const double convexcosh_lb[10] = {-1,0,0,0,0,0,0,0,0,0};
290 static const double convexcosh_ub[10] = {2,3,6,7,8,10,11,13,14,16};
291 static const double convexcosh_xmin[10] = {0,1,2,3,4,5,6,7,8,9};
293 /****************************************************************************/
294 static double branin_f(int n, const double *x, double *grad, void *data)
296 double a = 1 - 2*x[1] + 0.05 * sin(PI4 * x[1]) - x[0];
297 double b = x[1] - 0.5 * sin(PI2 * x[0]);
300 grad[0] = -2*a - cos(PI2 * x[0]) * PI2 * b;
301 grad[1] = 2*a*(0.05 * PI4 * cos(PI4*x[1]) - 2) + 2*b;
303 RETURN(sqr(a) + sqr(b));
306 static const double branin_lb[2] = {-10,-10};
307 static const double branin_ub[2] = {10,10};
308 static const double branin_xmin[2] = {1,0};
310 /****************************************************************************/
311 static double shubert_f(int n, const double *x, double *grad, void *data)
316 for (j = 1; j <= 5; ++j)
317 for (i = 0; i < n; ++i)
318 f -= j * sin((j+1) * x[i] + j);
320 for (i = 0; i < n; ++i) {
322 for (j = 1; j <= 5; ++j)
323 grad[i] -= j * (j+1) * cos((j+1) * x[i] + j);
329 static const double shubert_lb[2] = {-10,-10};
330 static const double shubert_ub[2] = {10,10};
331 static const double shubert_xmin[2] = {-6.774576, -6.774576};
333 /****************************************************************************/
334 static double hansen_f(int n, const double *x, double *grad, void *data)
339 for (i = 1; i <= 5; ++i)
340 a += i * cos((i-1) * x[0] + i);
341 for (i = 1; i <= 5; ++i)
342 b += i * cos((i+1) * x[1] + i);
345 for (i = 1; i <= 5; ++i)
346 grad[0] -= i * (i-1) * sin((i-1) * x[0] + i);
349 for (i = 1; i <= 5; ++i)
350 grad[1] -= i * (i+1) * sin((i+1) * x[1] + i);
356 static const double hansen_lb[2] = {-10,-10};
357 static const double hansen_ub[2] = {10,10};
358 static const double hansen_xmin[2] = {-1.306708,-1.425128};
360 /****************************************************************************/
361 static double osc1d_f(int n, const double *x, double *grad, void *data)
363 double y = *x - 1.23456789;
365 if (grad) grad[0] = y*0.02 - sin(y - 2*sin(3*y)) * (1 - 6*cos(3*y));
366 RETURN(sqr(y*0.1) - cos(y - 2*sin(3*y)));
369 static const double osc1d_lb[1] = {-5};
370 static const double osc1d_ub[1] = {5};
371 static const double osc1d_xmin[1] = {1.23456789};
373 /****************************************************************************/
374 /****************************************************************************/
376 const testfunc testfuncs[NTESTFUNCS] = {
377 { rosenbrock_f, NULL, 1, 2,
378 rosenbrock_lb, rosenbrock_ub, rosenbrock_xmin,
379 0.0, "Rosenbrock function" },
380 { mccormic_f, NULL, 1, 2,
381 mccormic_lb, mccormic_ub, mccormic_xmin,
382 -1.9133, "McCormic function" },
383 { boxbetts_f, NULL, 1, 3,
384 boxbetts_lb, boxbetts_ub, boxbetts_xmin,
385 0.0, "Box and Betts exponential quadratic sum" },
386 { paviani_f, NULL, 1, 10,
387 paviani_lb, paviani_ub, paviani_xmin,
388 -45.778470, "Paviani function" },
389 { grosenbrock_f, NULL, 1, 30,
390 grosenbrock_lb, grosenbrock_ub, grosenbrock_xmin,
391 0.0, "Generalized Rosenbrock function" },
392 { goldsteinprice_f, NULL, 1, 2,
393 goldsteinprice_lb, goldsteinprice_ub, goldsteinprice_xmin,
394 3.0, "Goldstein and Price function" },
395 { shekel_f, shekel_m + 0, 1, 4,
396 shekel_lb, shekel_ub, shekel0_xmin,
397 -10.1532, "Shekel m=5 function" },
398 { shekel_f, shekel_m + 1, 1, 4,
399 shekel_lb, shekel_ub, shekel1_xmin,
400 -10.4029, "Shekel m=7 function" },
401 { shekel_f, shekel_m + 2, 1, 4,
402 shekel_lb, shekel_ub, shekel2_xmin,
403 -10.5364, "Shekel m=10 function" },
404 { levy_f, NULL, 1, 4,
405 levy4_lb, levy4_ub, levy4_xmin,
406 -21.502356, "Levy n=4 function" },
407 { levy_f, NULL, 1, 5,
408 levy_lb, levy_ub, levy_xmin+2,
409 -11.504403, "Levy n=5 function" },
410 { levy_f, NULL, 1, 6,
411 levy_lb, levy_ub, levy_xmin+1,
412 -11.504403, "Levy n=6 function" },
413 { levy_f, NULL, 1, 7,
414 levy_lb, levy_ub, levy_xmin,
415 -11.504403, "Levy n=7 function" },
416 { griewank_f, NULL, 1, 10,
417 griewank_lb, griewank_ub, griewank_xmin,
418 0.0, "Griewank function" },
419 { sixhumpcamel_f, NULL, 1, 2,
420 sixhumpcamel_lb, sixhumpcamel_ub, sixhumpcamel_xmin,
421 -1.03163, "Six-hump camel back function" },
422 { convexcosh_f, NULL, 1, 10,
423 convexcosh_lb, convexcosh_ub, convexcosh_xmin,
424 1.0, "Convex product of cosh functions" },
425 { branin_f, NULL, 1, 2,
426 branin_lb, branin_ub, branin_xmin,
427 -.0, "Branin function" },
428 { shubert_f, NULL, 1, 2,
429 shubert_lb, shubert_ub, shubert_xmin,
430 -24.062499, "Shubert function" },
431 { hansen_f, NULL, 1, 2,
432 hansen_lb, hansen_ub, hansen_xmin,
433 -176.541793, "Hansen function" },
434 { osc1d_f, NULL, 1, 1,
435 osc1d_lb, osc1d_ub, osc1d_xmin,
436 -1.0, "1d oscillating function with a single minimum" }