chiark / gitweb /
untabify source files, make indenting more uniform with GNU indent -kr --no-tabs...
[nlopt.git] / test / testfuncs.c
1 #include <stdio.h>
2 #include <math.h>
3
4 #include "testfuncs.h"
5 #include "nlopt_config.h"
6
7 #define UNUSED(x) (void) x
8
9 static double sqr(double x)
10 {
11     return x * x;
12 }
13
14 int testfuncs_verbose = 0;
15 int testfuncs_counter = 0;
16
17 static double testfuncs_status(unsigned n, const double *x, double f)
18 {
19     ++testfuncs_counter;
20     if (testfuncs_verbose) {
21         unsigned i;
22         printf("f_%d (%g", testfuncs_counter, x[0]);
23         for (i = 1; i < n; ++i)
24             printf(", %g", x[i]);
25         printf(") = %g\n", f);
26     }
27     return f;
28 }
29
30 #define RETURN(f) return testfuncs_status(n, x, f);
31
32 #define PI2 6.283185307179586   /* 2*pi */
33 #define PI3 9.424777960769379   /* 3*pi */
34 #define PI4 12.5663706143592    /* 4*pi */
35
36 /****************************************************************************/
37 static double rosenbrock_f(unsigned n, const double *x, double *grad, void *data)
38 {
39     double a = x[1] - x[0] * x[0], b = 1 - x[0];
40     UNUSED(data);
41     if (grad) {
42         grad[0] = -400 * a * x[0] - 2 * b;
43         grad[1] = 200 * a;
44     }
45     RETURN(100 * sqr(a) + sqr(b));
46 }
47
48 static const double rosenbrock_lb[2] = { -2, -2 };
49 static const double rosenbrock_ub[2] = { 2, 2 };
50 static const double rosenbrock_xmin[2] = { 1, 1 };
51
52 /****************************************************************************/
53 static double mccormic_f(unsigned n, const double *x, double *grad, void *data)
54 {
55     double a = x[0] + x[1], b = x[0] - x[1];
56     UNUSED(data);
57     if (grad) {
58         grad[0] = cos(a) + 2 * b - 1.5;
59         grad[1] = cos(a) - 2 * b + 2.5;
60     }
61     RETURN(sin(a) + sqr(b) - 1.5 * x[0] + 2.5 * x[1] + 1);
62 }
63
64 static const double mccormic_lb[2] = { -1.5, -3 };
65 static const double mccormic_ub[2] = { 4, 4 };
66 static const double mccormic_xmin[2] = { -0.547197553, -1.54719756 };
67
68 /****************************************************************************/
69 static double boxbetts_f(unsigned n, const double *x, double *grad, void *data)
70 {
71     unsigned i;
72     double f = 0;
73     UNUSED(data);
74     if (grad)
75         grad[0] = grad[1] = grad[2] = 0;
76     for (i = 1; i <= 10; ++i) {
77         double e0 = exp(-0.1 * i * x[0]);
78         double e1 = exp(-0.1 * i * x[1]);
79         double e2 = exp(-0.1 * i) - exp(-1.0 * i);
80         double g = e0 - e1 - e2 * x[2];
81         f += sqr(g);
82         if (grad) {
83             grad[0] += (2 * g) * (-0.1 * i * e0);
84             grad[1] += (2 * g) * (0.1 * i * e1);
85             grad[2] += -(2 * g) * e2;
86         }
87     }
88     RETURN(f);
89 }
90
91 static const double boxbetts_lb[3] = { 0.9, 9, 0.9 };
92 static const double boxbetts_ub[3] = { 1.2, 11.2, 1.2 };
93 static const double boxbetts_xmin[3] = { 1, 10, 1 };
94
95 /****************************************************************************/
96 static double paviani_f(unsigned n, const double *x, double *grad, void *data)
97 {
98     unsigned i;
99     double f = 0, prod = 1;
100     UNUSED(data);
101     if (grad)
102         for (i = 0; i < 10; ++i)
103             grad[i] = 0;
104     for (i = 0; i < 10; ++i) {
105         double ln1 = log(x[i] - 2);
106         double ln2 = log(10 - x[i]);
107         f += sqr(ln1) + sqr(ln2);
108         if (grad)
109             grad[i] += 2 * ln1 / (x[i] - 2) - 2 * ln2 / (10 - x[i]);
110         prod *= x[i];
111     }
112     f -= (prod = pow(prod, 0.2));
113     if (grad)
114         for (i = 0; i < 10; ++i)
115             grad[i] -= 0.2 * prod / x[i];
116     RETURN(f);
117 }
118
119 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 };
120 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 };
121 static const double paviani_xmin[10] = { 9.35026583, 9.35026583, 9.35026583, 9.35026583, 9.35026583, 9.35026583, 9.35026583, 9.35026583, 9.35026583, 9.35026583 };
122
123 /****************************************************************************/
124 static double grosenbrock_f(unsigned n, const double *x, double *grad, void *data)
125 {
126     unsigned i;
127     double f = 0;
128     UNUSED(data);
129     if (grad)
130         grad[0] = 0;
131     for (i = 0; i < 29; ++i) {
132         double a = x[i + 1] - x[i] * x[i], b = 1 - x[i];
133         if (grad) {
134             grad[i] += -400 * a * x[i] - 2 * b;
135             grad[i + 1] = 200 * a;
136         }
137         f += 100 * sqr(a) + sqr(b);
138     }
139     RETURN(f);
140 }
141
142 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 };
143 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 };
144 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 };
145
146 /****************************************************************************/
147 static double goldsteinprice_f(unsigned n, const double *x, double *grad, void *data)
148 {
149     double x0, x1, a1, a12, a2, b1, b12, b2;
150     x0 = x[0];
151     x1 = x[1];
152     a1 = x0 + x1 + 1;
153     a12 = sqr(a1);
154     a2 = 19 - 14 * x0 + 3 * x0 * x0 - 14 * x1 + 6 * x0 * x1 + 3 * x1 * x1;
155     b1 = 2 * x0 - 3 * x1;
156     b12 = sqr(b1);
157     b2 = 18 - 32 * x0 + 12 * x0 * x0 + 48 * x1 - 36 * x0 * x1 + 27 * x1 * x1;
158     UNUSED(data);
159     if (grad) {
160         grad[0] = (1 + a12 * a2) * (2 * b1 * 2 * b2 + b12 * (-32 + 24 * x0 - 36 * x1))
161             + (2 * a1 * a2 + a12 * (-14 + 6 * x0 + 6 * x1)) * (30 + b12 * b2);
162         grad[1] = (1 + a12 * a2) * (2 * b1 * (-3) * b2 + b12 * (48 - 36 * x0 + 54 * x1))
163             + (2 * a1 * a2 + a12 * (-14 + 6 * x0 + 6 * x1)) * (30 + b12 * b2);
164     }
165     RETURN((1 + a12 * a2) * (30 + b12 * b2));
166 }
167
168 static const double goldsteinprice_lb[2] = { -2, -2 };
169 static const double goldsteinprice_ub[2] = { 2, 2 };
170 static const double goldsteinprice_xmin[2] = { 0, -1 };
171
172 /****************************************************************************/
173 static double shekel_f(unsigned n, const double *x, double *grad, void *data)
174 {
175     static const double A[10][4] = { {4, 4, 4, 4},
176     {1, 1, 1, 1},
177     {8, 8, 8, 8},
178     {6, 6, 6, 6},
179     {3, 7, 3, 7},
180     {2, 9, 2, 9},
181     {5, 5, 3, 3},
182     {8, 1, 8, 1},
183     {6, 2, 6, 2},
184     {7, 3.6, 7, 3.6}
185     };
186     static const double c[10] = { .1, .2, .2, .4, .4, .6, .3, .7, .5, .5 };
187     unsigned i;
188     double f = 0;
189     unsigned m = *((unsigned *) data);
190     if (grad)
191         for (i = 0; i < n; ++i)
192             grad[i] = 0;
193     for (i = 0; i < m; ++i) {
194         double fi = 1.0 / (c[i]
195                            + sqr(x[0] - A[i][0])
196                            + sqr(x[1] - A[i][1])
197                            + sqr(x[2] - A[i][2])
198                            + sqr(x[3] - A[i][3]));
199         f -= fi;
200         if (grad) {
201             grad[0] += (2 * fi * fi) * (x[0] - A[i][0]);
202             grad[1] += (2 * fi * fi) * (x[1] - A[i][1]);
203             grad[2] += (2 * fi * fi) * (x[2] - A[i][2]);
204             grad[3] += (2 * fi * fi) * (x[3] - A[i][3]);
205         }
206     }
207     RETURN(f);
208 }
209
210 static unsigned shekel_m[3] = { 5, 7, 10 };
211 static const double shekel_lb[4] = { 0, 0, 0, 0 };
212 static const double shekel_ub[4] = { 10, 10, 10, 10 };
213 static const double shekel0_xmin[4] = { 4.000037154, 4.000133276, 4.000037154, 4.000133276 };
214 static const double shekel1_xmin[4] = { 4.000572917, 4.000689366, 3.999489709, 3.999606158 };
215 static const double shekel2_xmin[4] = { 4.000746531, 4.000592935, 3.999663399, 3.999509801 };
216
217 /****************************************************************************/
218 static double levy_f(unsigned n, const double *x, double *grad, void *data)
219 {
220     unsigned i;
221     double a = x[n - 1] - 1, b = 1 + sqr(sin(PI2 * x[n - 1]));
222     double f = sqr(sin(PI3 * x[0])) + a * b;
223     UNUSED(data);
224     if (grad) {
225         for (i = 0; i < n; ++i)
226             grad[i] = 0;
227         grad[0] = 2 * PI3 * sin(PI3 * x[0]) * cos(PI3 * x[0]);
228         grad[n - 1] += b + a * 2 * PI2 * sin(PI2 * x[n - 1]) * cos(PI2 * x[n - 1]);
229     }
230     for (i = 0; i < n - 1; ++i) {
231         a = x[i] - 1;
232         b = 1 + sqr(sin(PI3 * x[i + 1]));
233         f += sqr(a) * b;
234         if (grad) {
235             grad[i] += 2 * a * b;
236             grad[i + 1] += 2 * PI3 * sqr(a) * sin(PI3 * x[i + 1]) * cos(PI3 * x[i + 1]);
237         }
238     }
239     RETURN(f);
240 }
241
242 static const double levy_lb[7] = { -5, -5, -5, -5, -5, -5, -5 };
243 static const double levy_ub[7] = { 5, 5, 5, 5, 5, 5, 5 };
244 static const double levy_xmin[7] = { 1, 1, 1, 1, 1, 1, -4.75440246 };
245 static const double levy4_lb[4] = { -10, -10, -10, -10 };
246 static const double levy4_ub[4] = { 10, 10, 10, 10 };
247 static const double levy4_xmin[4] = { 1, 1, 1, -9.75235596 };
248
249 /****************************************************************************/
250 static double griewank_f(unsigned n, const double *x, double *grad, void *data)
251 {
252     unsigned i;
253     double f = 1, p = 1;
254     UNUSED(data);
255     for (i = 0; i < n; ++i) {
256         f += sqr(x[i]) * 0.00025;
257         p *= cos(x[i] / sqrt(i + 1.));
258         if (grad)
259             grad[i] = x[i] * 0.0005;
260     }
261     f -= p;
262     if (grad)
263         for (i = 0; i < n; ++i)
264             grad[i] += p * tan(x[i] / sqrt(i + 1.)) / sqrt(i + 1.);
265     RETURN(f);
266 }
267
268 static const double griewank_lb[10] = { -500, -500, -500, -500, -500, -500, -500, -500, -500, -500 };
269 static const double griewank_ub[10] = { 600, 600, 600, 600, 600, 600, 600, 600, 600, 600 };
270 static const double griewank_xmin[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
271
272 /****************************************************************************/
273 static double sixhumpcamel_f(unsigned n, const double *x, double *grad, void *data)
274 {
275     UNUSED(data);
276     if (grad) {
277         grad[0] = 8 * x[0] - 2.1 * 4 * pow(x[0], 3.) + 2 * pow(x[0], 5.) + x[1];
278         grad[1] = x[0] - 8 * x[1] + 16 * pow(x[1], 3.);
279     }
280     RETURN(4 * sqr(x[0]) - 2.1 * pow(x[0], 4.) + pow(x[0], 6.) / 3. + x[0] * x[1] - 4 * sqr(x[1]) + 4 * pow(x[1], 4.));
281 }
282
283 static const double sixhumpcamel_lb[2] = { -5, -5 };
284 static const double sixhumpcamel_ub[2] = { 5, 5 };
285 static const double sixhumpcamel_xmin[2] = { 0.08984201317, -0.7126564032 };
286
287 /****************************************************************************/
288 static double convexcosh_f(unsigned n, const double *x, double *grad, void *data)
289 {
290     unsigned i;
291     double f = 1;
292     UNUSED(data);
293     for (i = 0; i < n; ++i)
294         f *= cosh((x[i] - i) * (i + 1));
295     if (grad)
296         for (i = 0; i < n; ++i)
297             grad[i] = f * tanh((x[i] - i) * (i + 1)) * (i + 1);
298     RETURN(f);
299 }
300
301 static const double convexcosh_lb[10] = { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
302 static const double convexcosh_ub[10] = { 2, 3, 6, 7, 8, 10, 11, 13, 14, 16 };
303 static const double convexcosh_xmin[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
304
305 /****************************************************************************/
306 static double branin_f(unsigned n, const double *x, double *grad, void *data)
307 {
308     double a = 1 - 2 * x[1] + 0.05 * sin(PI4 * x[1]) - x[0];
309     double b = x[1] - 0.5 * sin(PI2 * x[0]);
310     UNUSED(data);
311     if (grad) {
312         grad[0] = -2 * a - cos(PI2 * x[0]) * PI2 * b;
313         grad[1] = 2 * a * (0.05 * PI4 * cos(PI4 * x[1]) - 2) + 2 * b;
314     }
315     RETURN(sqr(a) + sqr(b));
316 }
317
318 static const double branin_lb[2] = { -10, -10 };
319 static const double branin_ub[2] = { 10, 10 };
320 static const double branin_xmin[2] = { 1, 0 };
321
322 /****************************************************************************/
323 static double shubert_f(unsigned n, const double *x, double *grad, void *data)
324 {
325     unsigned i, j;
326     double f = 0;
327     UNUSED(data);
328     for (j = 1; j <= 5; ++j)
329         for (i = 0; i < n; ++i)
330             f -= j * sin((j + 1) * x[i] + j);
331     if (grad) {
332         for (i = 0; i < n; ++i) {
333             grad[i] = 0;
334             for (j = 1; j <= 5; ++j)
335                 grad[i] -= j * (j + 1) * cos((j + 1) * x[i] + j);
336         }
337     }
338     RETURN(f);
339 }
340
341 static const double shubert_lb[2] = { -10, -10 };
342 static const double shubert_ub[2] = { 10, 10 };
343 static const double shubert_xmin[2] = { -6.774576143, -6.774576143 };
344
345 /****************************************************************************/
346 static double hansen_f(unsigned n, const double *x, double *grad, void *data)
347 {
348     unsigned i;
349     double a = 0, b = 0;
350     UNUSED(data);
351     for (i = 1; i <= 5; ++i)
352         a += i * cos((i - 1) * x[0] + i);
353     for (i = 1; i <= 5; ++i)
354         b += i * cos((i + 1) * x[1] + i);
355     if (grad) {
356         grad[0] = 0;
357         for (i = 1; i <= 5; ++i)
358             grad[0] -= i * (i - 1) * sin((i - 1) * x[0] + i);
359         grad[0] *= b;
360         grad[1] = 0;
361         for (i = 1; i <= 5; ++i)
362             grad[1] -= i * (i + 1) * sin((i + 1) * x[1] + i);
363         grad[1] *= a;
364     }
365     RETURN(a * b);
366 }
367
368 static const double hansen_lb[2] = { -10, -10 };
369 static const double hansen_ub[2] = { 10, 10 };
370 static const double hansen_xmin[2] = { -1.306707704, -1.425128429 };
371
372 /****************************************************************************/
373 static double osc1d_f(unsigned n, const double *x, double *grad, void *data)
374 {
375     double y = *x - 1.23456789;
376     UNUSED(data);
377     if (grad)
378         grad[0] = y * 0.02 + sin(y - 2 * sin(3 * y)) * (1 - 6 * cos(3 * y));
379     RETURN(sqr(y * 0.1) - cos(y - 2 * sin(3 * y)));
380 }
381
382 static const double osc1d_lb[1] = { -5 };
383 static const double osc1d_ub[1] = { 5 };
384 static const double osc1d_xmin[1] = { 1.23456789 };
385
386 /****************************************************************************/
387 static double corner4d_f(unsigned n, const double *x, double *grad, void *data)
388 {
389     double u = x[0] + x[1] * x[2] * sin(2 * x[3]);
390     double v = x[0] + 2 * sin(u);
391     UNUSED(data);
392     UNUSED(n);
393     if (grad) {
394         grad[0] = 2 * v * (1 + 2 * cos(u));
395         grad[1] = 2 * v * 2 * cos(u) * x[2] * sin(2 * x[3]) + 0.1;
396         grad[2] = 2 * v * 2 * cos(u) * x[1] * sin(2 * x[3]) + 0.1;
397         grad[3] = 2 * v * 2 * cos(u) * x[1] * x[2] * cos(2 * x[3]) * 2 + 0.1;
398     }
399     RETURN(1 + v * v + 0.1 * (x[1] + x[2] + x[3]));
400 }
401
402 static const double corner4d_lb[4] = { 0, 0, 0, 0 };
403 static const double corner4d_ub[4] = { 1, 1, 1, 1 };
404 static const double corner4d_xmin[4] = { 0, 0, 0, 0 };
405
406 /****************************************************************************/
407 static double side4d_f(unsigned n, const double *x, double *grad, void *data)
408 {
409     double x0, x1, x2, x3, d0, d1, d2, d3;
410     const double w0 = 0.1, w1 = 0.2, w2 = 0.3, w3 = 0.4;
411     UNUSED(data);
412     UNUSED(n);
413     x0 = +0.4977 * x[0] - 0.3153 * x[1] - 0.5066 * x[2] - 0.4391 * x[3];
414     x1 = -0.3153 * x[0] + 0.3248 * x[1] - 0.4382 * x[2] - 0.4096 * x[3];
415     x2 = -0.5066 * x[0] - 0.4382 * x[1] + 0.3807 * x[2] - 0.4543 * x[3];
416     x3 = -0.4391 * x[0] - 0.4096 * x[1] - 0.4543 * x[2] + 0.5667 * x[3];
417
418     d0 = -1. / (x0 * x0 + w0 * w0);
419     d1 = -1. / (x1 * x1 + w1 * w1);
420     d2 = -1. / (x2 * x2 + w2 * w2);
421     d3 = -1. / (x3 * x3 + w3 * w3);
422
423     if (grad) {
424         grad[0] = 2 * (x0 * d0 * d0 * +0.4977 + x1 * d1 * d1 * -0.3153 + x2 * d2 * d2 * -0.5066 + x3 * d3 * d3 * -0.4391);
425         grad[1] = 2 * (x0 * d0 * d0 * -0.3153 + x1 * d1 * d1 * +0.3248 + x2 * d2 * d2 * -0.4382 + x3 * d3 * d3 * -0.4096);
426         grad[2] = 2 * (x0 * d0 * d0 * -0.5066 + x1 * d1 * d1 * -0.4382 + x2 * d2 * d2 * +0.3807 + x3 * d3 * d3 * -0.4543);
427         grad[3] = 2 * (x0 * d0 * d0 * -0.4391 + x1 * d1 * d1 * -0.4096 + x2 * d2 * d2 * -0.4543 + x3 * d3 * d3 * +0.5667);
428     }
429     RETURN(d0 + d1 + d2 + d3);
430 }
431
432 static const double side4d_lb[4] = { 0.1, -1, -1, -1 };
433 static const double side4d_ub[4] = { 1, 1, 1, 1 };
434 static const double side4d_xmin[4] = { 0.1, 0.102971169, 0.0760520641, -0.0497098571 };
435
436 /****************************************************************************/
437 /****************************************************************************/
438
439 const testfunc testfuncs[NTESTFUNCS] = {
440     {rosenbrock_f, NULL, 1, 2,
441      rosenbrock_lb, rosenbrock_ub, rosenbrock_xmin,
442      0.0, "Rosenbrock function"},
443     {mccormic_f, NULL, 1, 2,
444      mccormic_lb, mccormic_ub, mccormic_xmin,
445      -1.91322295, "McCormic function"},
446     {boxbetts_f, NULL, 1, 3,
447      boxbetts_lb, boxbetts_ub, boxbetts_xmin,
448      0.0, "Box and Betts exponential quadratic sum"},
449     {paviani_f, NULL, 1, 10,
450      paviani_lb, paviani_ub, paviani_xmin,
451      -45.7784697, "Paviani function"},
452     {grosenbrock_f, NULL, 1, 30,
453      grosenbrock_lb, grosenbrock_ub, grosenbrock_xmin,
454      0.0, "Generalized Rosenbrock function"},
455     {goldsteinprice_f, NULL, 1, 2,
456      goldsteinprice_lb, goldsteinprice_ub, goldsteinprice_xmin,
457      3.0, "Goldstein and Price function"},
458     {shekel_f, shekel_m + 0, 1, 4,
459      shekel_lb, shekel_ub, shekel0_xmin,
460      -10.15319968, "Shekel m=5 function"},
461     {shekel_f, shekel_m + 1, 1, 4,
462      shekel_lb, shekel_ub, shekel1_xmin,
463      -10.40294057, "Shekel m=7 function"},
464     {shekel_f, shekel_m + 2, 1, 4,
465      shekel_lb, shekel_ub, shekel2_xmin,
466      -10.53640982, "Shekel m=10 function"},
467     {levy_f, NULL, 1, 4,
468      levy4_lb, levy4_ub, levy4_xmin,
469      -21.50235596, "Levy n=4 function"},
470     {levy_f, NULL, 1, 5,
471      levy_lb, levy_ub, levy_xmin + 2,
472      -11.50440302, "Levy n=5 function"},
473     {levy_f, NULL, 1, 6,
474      levy_lb, levy_ub, levy_xmin + 1,
475      -11.50440302, "Levy n=6 function"},
476     {levy_f, NULL, 1, 7,
477      levy_lb, levy_ub, levy_xmin,
478      -11.50440302, "Levy n=7 function"},
479     {griewank_f, NULL, 1, 10,
480      griewank_lb, griewank_ub, griewank_xmin,
481      0.0, "Griewank function"},
482     {sixhumpcamel_f, NULL, 1, 2,
483      sixhumpcamel_lb, sixhumpcamel_ub, sixhumpcamel_xmin,
484      -1.031628453, "Six-hump camel back function"},
485     {convexcosh_f, NULL, 1, 10,
486      convexcosh_lb, convexcosh_ub, convexcosh_xmin,
487      1.0, "Convex product of cosh functions"},
488     {branin_f, NULL, 1, 2,
489      branin_lb, branin_ub, branin_xmin,
490      -.0, "Branin function"},
491     {shubert_f, NULL, 1, 2,
492      shubert_lb, shubert_ub, shubert_xmin,
493      -24.06249888, "Shubert function"},
494     {hansen_f, NULL, 1, 2,
495      hansen_lb, hansen_ub, hansen_xmin,
496      -176.5417931367, "Hansen function"},
497     {osc1d_f, NULL, 1, 1,
498      osc1d_lb, osc1d_ub, osc1d_xmin,
499      -1.0, "1d oscillating function with a single minimum"},
500     {corner4d_f, NULL, 1, 4,
501      corner4d_lb, corner4d_ub, corner4d_xmin,
502      1.0, "4d function with minimum at corner"},
503     {side4d_f, NULL, 1, 4,
504      side4d_lb, side4d_ub, side4d_xmin,
505      -141.285020472, "4d function with minimum at side"}
506 };