1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.optim.nonlinear.scalar;
18
19 import java.util.function.Function;
20 import java.util.function.DoubleUnaryOperator;
21 import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
22
23
24
25
26
27
28
29
30
31
32 public enum TestFunction {
33
34 SPHERE(dim -> {
35 return x -> {
36 double f = 0;
37 for (int i = 0; i < dim; i++) {
38 f += x[i] * x[i];
39 }
40 return f;
41 };
42 }),
43 CIGAR(dim -> {
44 return x -> {
45 double f = x[0] * x[0];
46 for (int i = 1; i < dim; i++) {
47 f += 1e3 * x[i] * x[i];
48 }
49 return f;
50 };
51 }),
52 TABLET(dim -> {
53 return x -> {
54 double f = 1e3 * x[0] * x[0];
55 for (int i = 1; i < dim; i++) {
56 f += x[i] * x[i];
57 }
58 return f;
59 };
60 }),
61 CIG_TAB(dim -> {
62 final double factor = 1e4;
63 final int last = dim - 1;
64 return x -> {
65 double f = x[0] * x[0] / factor + factor * x[last] * x[last];
66 for (int i = 1; i < last; i++) {
67 f += x[i] * x[i];
68 }
69 return f;
70 };
71 }),
72 TWO_AXES(dim -> {
73 final int halfDim = dim / 2;
74 return x -> {
75 double f = 0;
76 for (int i = 0; i < halfDim; i++) {
77 f += 1e6 * x[i] * x[i];
78 }
79 for (int i = halfDim; i < dim; i++) {
80 f += x[i] * x[i];
81 }
82 return f;
83 };
84 }),
85 ELLI(dim -> {
86 final double M = Math.pow(1e3, 1d / (dim - 1));
87 return x -> {
88 double factor = 1;
89 double f = 0;
90 for (int i = 0; i < dim; i++) {
91 f += factor * x[i] * x[i];
92 factor *= M;
93 }
94 return f;
95 };
96 }),
97 MINUS_ELLI(dim -> {
98 final MultivariateFunction elli = ELLI.withDimension(dim);
99 return x -> {
100 return 1 - elli.value(x);
101 };
102 }),
103
104 SUM_POW(dim -> {
105 return x -> {
106 double f = 0;
107 for (int i = 0; i < dim; i++) {
108 f += Math.pow(Math.abs(x[i]), i + 2);
109 }
110 return f;
111 };
112 }),
113
114 ACKLEY(dim -> {
115 final double A = 20;
116 final double B = 0.2;
117 final double C = 2 * Math.PI;
118 return x -> {
119 double acc1 = 0;
120 double acc2 = 0;
121 for (int i = 0; i < dim; i++) {
122 final double v = x[i];
123 acc1 += v * v;
124 acc2 += Math.cos(C * v);
125 }
126 acc1 = -B * Math.sqrt(acc1 / dim);
127 acc2 /= dim;
128
129 return -A * Math.exp(acc1) - Math.exp(acc2) + A + Math.E;
130 };
131 }),
132
133 RASTRIGIN(dim -> {
134 final double A = 10;
135 final double twopi = 2 * Math.PI;
136 return x -> {
137 double sum = 0;
138 for (int i = 0; i < dim; i++) {
139 final double xi = x[i];
140 sum += xi * xi - A * Math.cos(twopi * xi);
141 }
142 return A * dim + sum;
143 };
144 }),
145
146 SALOMON(dim -> {
147 return x -> {
148 double sum = 0;
149 for (int i = 0; i < dim; i++) {
150 final double xi = x[i];
151 sum += xi * xi;
152 }
153 final double sqrtSum = Math.sqrt(sum);
154 return 1 - Math.cos(2 * Math.PI * sqrtSum) + 0.1 * sqrtSum;
155 };
156 }),
157
158 ROSENBROCK(dim -> {
159 if ((dim & 1) != 0) {
160 throw new IllegalArgumentException("Must be a multiple of 2 (was: " + dim + ")");
161 }
162 final int last = dim / 2;
163 return x -> {
164 double f = 0;
165 for (int i = 1; i <= last; i++) {
166 final int twoI = 2 * i;
167 final int i0 = twoI - 1;
168 final int i1 = twoI;
169 final double x2iM1 = x[i0 - 1];
170 final double x2i = x[i1 - 1];
171 final double t2iM1 = x2i - x2iM1 * x2iM1;
172 final double t2i = 1 - x2iM1;
173 f += 100 * t2iM1 * t2iM1 + t2i * t2i;
174 }
175 return f;
176 };
177 }),
178
179 HAPPY_CAT(dim -> {
180 final double alpha = 0.125;
181 return x -> {
182 double sum = 0;
183 double sumSq = 0;
184 for (int i = 0; i < dim; i++) {
185 final double xi = x[i];
186 sum += xi;
187 sumSq += xi * xi;
188 }
189 return Math.pow(sumSq - dim, 2 * alpha) + (0.5 * sumSq + sum) / dim + 0.5;
190 };
191 }),
192 PARABOLA(dim -> {
193 return x -> {
194 double f = 0;
195 for (int i = 0; i < dim; i++) {
196 final double xi = x[i];
197 f += xi * xi;
198 }
199 return f;
200 };
201 }),
202
203 GRIEWANK(dim -> {
204 final double A = 4000;
205 return x -> {
206 double sum = 0;
207 double prod = 1;
208 for (int i = 0; i < dim; i++) {
209 final double xi = x[i];
210 sum += xi * xi;
211 prod *= Math.cos(xi / Math.sqrt(i + 1));
212 }
213 return sum / A - prod + 1;
214 };
215 }),
216
217 LEVY(dim -> {
218 final int last = dim - 1;
219 final DoubleUnaryOperator w = x -> 1 + 0.25 * (x - 1);
220 return x -> {
221 final double a0 = Math.sin(Math.PI * w.applyAsDouble(x[0]));
222 double sum = a0 * a0;
223 for (int i = 0; i < last; i++) {
224 final double wi = w.applyAsDouble(x[i]);
225 final double wiM1 = wi - 1;
226 final double ai = Math.sin(Math.PI * wi + 1);
227 sum += wiM1 * wiM1 * (1 + 10 * ai * ai);
228 }
229 final double wl = w.applyAsDouble(x[last]);
230 final double wlM1 = wl - 1;
231 final double al = Math.sin(2 * Math.PI * wl);
232 return sum + wlM1 * wlM1 * (1 + al * al);
233 };
234 }),
235
236 SCHWEFEL(dim -> {
237 final double A = 418.9829;
238 return x -> {
239 double sum = 0;
240 for (int i = 0; i < dim; i++) {
241 final double xi = x[i];
242 sum += xi * Math.sin(Math.sqrt(Math.abs(xi)));
243 }
244 return A * dim - sum;
245 };
246 }),
247
248 ZAKHAROV(dim -> {
249 final double A = 0.5;
250 return x -> {
251 double sum1 = 0;
252 double sum2 = 0;
253 for (int i = 0; i < dim; i++) {
254 final double xi = x[i];
255 sum1 += xi * xi;
256 sum2 += A * (i + 1) * xi;
257 }
258 final double sum22 = sum2 * sum2;
259 return sum1 + sum22 + sum22 * sum22;
260 };
261 }),
262
263 PERM(dim -> {
264 final double BETA = 10;
265 return x -> {
266 double sum1 = 0;
267 for (int i = 0; i < dim; i++) {
268 final double iP1 = i + 1;
269 double sum2 = 0;
270 for (int j = 0; j < dim; j++) {
271 final double jP1 = j + 1;
272 final double a = Math.pow(jP1, iP1) + BETA;
273 final double b = Math.pow(x[j] / jP1, iP1) - 1;
274 sum2 += a * b;
275 }
276 sum1 += sum2 * sum2;
277 }
278 return sum1;
279 };
280 }),
281
282 STYBLINSKI_TANG(dim -> {
283 final double A = 0.5;
284 final double B = 16;
285 final double C = 5;
286 return x -> {
287 double sum = 0;
288 for (int i = 0; i < dim; i++) {
289 final double xi = x[i];
290 final double xi2 = xi * xi;
291 final double xi4 = xi2 * xi2;
292 sum += xi4 - B * xi2 + C * xi;
293 }
294 return A * sum;
295 };
296 }),
297
298 POWELL(dim -> {
299 if (dim % 4 != 0) {
300 throw new IllegalArgumentException("Must be a multiple of 4 (was: " + dim + ")");
301 }
302 final int last = dim / 4;
303 return x -> {
304 double sum = 0;
305 for (int i = 1; i <= last; i++) {
306 final int fourI = 4 * i;
307 final int i0 = fourI - 3;
308 final int i1 = fourI - 2;
309 final int i2 = fourI - 1;
310 final int i3 = fourI;
311 final double x4iM3 = x[i0 - 1];
312 final double x4iM2 = x[i1 - 1];
313 final double x4iM1 = x[i2 - 1];
314 final double x4i = x[i3 - 1];
315 final double t4iM3 = x4iM3 + 10 * x4iM2;
316 final double t4iM2 = x4iM1 - x4i;
317 final double t4iM1 = x4iM2 - 2 * x4iM1;
318 final double sqT4iM1 = t4iM1 * t4iM1;
319 final double t4i = x4iM3 - x4i;
320 final double sqT4i = t4i * t4i;
321 sum += t4iM3 * t4iM3 + 5 * t4iM2 * t4iM2 + sqT4iM1 * sqT4iM1 + 10 * sqT4i * sqT4i;
322 }
323 return sum;
324 };
325 });
326
327
328 private final Function<Integer, MultivariateFunction> generator;
329
330
331
332
333 TestFunction(Function<Integer, MultivariateFunction> gen) {
334 generator = gen;
335 }
336
337
338
339
340
341 public MultivariateFunction withDimension(final int dim) {
342 return new MultivariateFunction() {
343
344 private final MultivariateFunction f = generator.apply(dim);
345
346 @Override
347 public double value(double[] x) {
348 if (x.length != dim) {
349 throw new IllegalArgumentException("Dimension mismatch: " + x.length +
350 "(expected: " + dim + ")");
351 }
352 return f.value(x);
353 };
354
355 @Override
356 public String toString() {
357 final StringBuilder sb = new StringBuilder();
358 sb.append("[")
359 .append(TestFunction.this.toString())
360 .append(" dim=")
361 .append(dim)
362 .append("]");
363 return sb.toString();
364 }
365 };
366 }
367 }