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.noderiv;
18
19 import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
20 import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
21 import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException;
22 import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException;
23 import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
24 import org.apache.commons.math4.legacy.exception.OutOfRangeException;
25 import org.apache.commons.math4.legacy.optim.InitialGuess;
26 import org.apache.commons.math4.legacy.optim.MaxEval;
27 import org.apache.commons.math4.legacy.optim.PointValuePair;
28 import org.apache.commons.math4.legacy.optim.SimpleBounds;
29 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.GoalType;
30 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.PopulationSize;
31 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.Sigma;
32 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.ObjectiveFunction;
33 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.TestFunction;
34 import org.apache.commons.rng.simple.RandomSource;
35 import org.apache.commons.math4.core.jdkmath.JdkMath;
36 import org.junit.Assert;
37 import org.junit.Test;
38
39
40
41
42 public class CMAESOptimizerTest {
43
44 static final int DIM = 13;
45 static final int LAMBDA = 4 + (int)(3.*JdkMath.log(DIM));
46
47 @Test(expected = NumberIsTooLargeException.class)
48 public void testInitOutofbounds1() {
49 final int dim = 12;
50 double[] startPoint = OptimTestUtils.point(dim, 3);
51 double[] insigma = OptimTestUtils.point(dim, 0.3);
52 double[][] boundaries = boundaries(dim, -1, 2);
53 PointValuePair expected =
54 new PointValuePair(OptimTestUtils.point(dim, 1.0), 0.0);
55 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
56 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
57 1e-13, 1e-6, 100000, expected);
58 }
59 @Test(expected = NumberIsTooSmallException.class)
60 public void testInitOutofbounds2() {
61 final int dim = 12;
62 double[] startPoint = OptimTestUtils.point(dim, -2);
63 double[] insigma = OptimTestUtils.point(dim, 0.3);
64 double[][] boundaries = boundaries(dim, -1, 2);
65 PointValuePair expected =
66 new PointValuePair(OptimTestUtils.point(dim, 1.0), 0.0);
67 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
68 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
69 1e-13, 1e-6, 100000, expected);
70 }
71
72 @Test(expected = DimensionMismatchException.class)
73 public void testBoundariesDimensionMismatch() {
74 final int dim = 12;
75 double[] startPoint = OptimTestUtils.point(dim, 0.5);
76 double[] insigma = OptimTestUtils.point(dim, 0.3);
77 double[][] boundaries = boundaries(dim + 1,-1,2);
78 PointValuePair expected =
79 new PointValuePair(OptimTestUtils.point(dim, 1.0), 0.0);
80 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
81 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
82 1e-13, 1e-6, 100000, expected);
83 }
84
85 @Test(expected = NotStrictlyPositiveException.class)
86 public void testInputSigmaNegative() {
87 final int dim = 12;
88 double[] startPoint = OptimTestUtils.point(dim, 0.5);
89 double[] insigma = OptimTestUtils.point(dim, -0.5);
90 double[][] boundaries = null;
91 PointValuePair expected =
92 new PointValuePair(OptimTestUtils.point(dim, 1.0), 0.0);
93 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
94 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
95 1e-13, 1e-6, 100000, expected);
96 }
97
98 @Test(expected = OutOfRangeException.class)
99 public void testInputSigmaOutOfRange() {
100 final int dim = 12;
101 double[] startPoint = OptimTestUtils.point(dim, 0.5);
102 double[] insigma = OptimTestUtils.point(dim, 1.1);
103 double[][] boundaries = boundaries(dim, -0.5,0.5);
104 PointValuePair expected =
105 new PointValuePair(OptimTestUtils.point(dim, 1.0), 0.0);
106 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
107 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
108 1e-13, 1e-6, 100000, expected);
109 }
110
111 @Test(expected = DimensionMismatchException.class)
112 public void testInputSigmaDimensionMismatch() {
113 final int dim = 12;
114 double[] startPoint = OptimTestUtils.point(dim, 0.5);
115 double[] insigma = OptimTestUtils.point(dim + 1, 0.5);
116 double[][] boundaries = null;
117 PointValuePair expected =
118 new PointValuePair(OptimTestUtils.point(dim, 1.0), 0.0);
119 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
120 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
121 1e-13, 1e-6, 100000, expected);
122 }
123
124 @Test
125 public void testRosen() {
126 final int dim = 12;
127 double[] startPoint = OptimTestUtils.point(dim, 0.1);
128 double[] insigma = OptimTestUtils.point(dim, 0.1);
129 double[][] boundaries = null;
130 PointValuePair expected =
131 new PointValuePair(OptimTestUtils.point(dim, 1.0), 0.0);
132 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
133 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
134 1e-13, 1e-6, 100000, expected);
135 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
136 GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
137 1e-13, 1e-6, 100000, expected);
138 }
139
140 @Test
141 public void testMaximize() {
142 double[] startPoint = OptimTestUtils.point(DIM,1.0);
143 double[] insigma = OptimTestUtils.point(DIM,0.1);
144 double[][] boundaries = null;
145 PointValuePair expected =
146 new PointValuePair(OptimTestUtils.point(DIM,0.0),1.0);
147 doTest(TestFunction.MINUS_ELLI.withDimension(DIM), startPoint, insigma, boundaries,
148 GoalType.MAXIMIZE, LAMBDA, true, 0, 1.0-1e-13,
149 2e-10, 5e-6, 100000, expected);
150 doTest(TestFunction.MINUS_ELLI.withDimension(DIM), startPoint, insigma, boundaries,
151 GoalType.MAXIMIZE, LAMBDA, false, 0, 1.0-1e-13,
152 2e-10, 5e-6, 100000, expected);
153 boundaries = boundaries(DIM,-0.3,0.3);
154 startPoint = OptimTestUtils.point(DIM,0.1);
155 doTest(TestFunction.MINUS_ELLI.withDimension(DIM), startPoint, insigma, boundaries,
156 GoalType.MAXIMIZE, LAMBDA, true, 0, 1.0-1e-13,
157 2e-10, 5e-6, 100000, expected);
158 }
159
160 @Test
161 public void testMath1466() {
162 final CMAESOptimizer optimizer
163 = new CMAESOptimizer(30000, Double.NEGATIVE_INFINITY, true, 10,
164 0, RandomSource.MT_64.create(), false, null);
165 final MultivariateFunction fitnessFunction = new MultivariateFunction() {
166 @Override
167 public double value(double[] x) {
168 return x[0] * x[0] - 100;
169 }
170 };
171
172 final double[] start = { 100 };
173 final double[] sigma = { 1e-1 };
174 final double[] result = optimizer.optimize(new MaxEval(10000),
175 new ObjectiveFunction(fitnessFunction),
176 SimpleBounds.unbounded(1),
177 GoalType.MINIMIZE,
178 new PopulationSize(5),
179 new Sigma(sigma),
180 new InitialGuess(start)).getPoint();
181 Assert.assertEquals(0, result[0], 1e-7);
182 }
183
184 @Test
185 public void testEllipse() {
186 double[] startPoint = OptimTestUtils.point(DIM,1.0);
187 double[] insigma = OptimTestUtils.point(DIM,0.1);
188 double[][] boundaries = null;
189 PointValuePair expected =
190 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
191 doTest(TestFunction.ELLI.withDimension(DIM), startPoint, insigma, boundaries,
192 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
193 1e-13, 1e-6, 100000, expected);
194 doTest(TestFunction.ELLI.withDimension(DIM), startPoint, insigma, boundaries,
195 GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
196 1e-13, 1e-6, 100000, expected);
197 }
198
199 @Test
200 public void testElliRotated() {
201 double[] startPoint = OptimTestUtils.point(DIM,1.0);
202 double[] insigma = OptimTestUtils.point(DIM,0.1);
203 double[][] boundaries = null;
204 PointValuePair expected =
205 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
206 doTest(new OptimTestUtils.ElliRotated(), startPoint, insigma, boundaries,
207 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
208 1e-13, 1e-6, 100000, expected);
209 doTest(new OptimTestUtils.ElliRotated(), startPoint, insigma, boundaries,
210 GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
211 1e-13, 1e-6, 100000, expected);
212 }
213
214 @Test
215 public void testCigar() {
216 double[] startPoint = OptimTestUtils.point(DIM,1.0);
217 double[] insigma = OptimTestUtils.point(DIM,0.1);
218 double[][] boundaries = null;
219 PointValuePair expected =
220 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
221 doTest(TestFunction.CIGAR.withDimension(DIM), startPoint, insigma, boundaries,
222 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
223 1e-13, 1e-6, 200000, expected);
224 doTest(TestFunction.CIGAR.withDimension(DIM), startPoint, insigma, boundaries,
225 GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
226 1e-13, 1e-6, 100000, expected);
227 }
228
229 @Test
230 public void testCigarWithBoundaries() {
231 double[] startPoint = OptimTestUtils.point(DIM,1.0);
232 double[] insigma = OptimTestUtils.point(DIM,0.1);
233 double[][] boundaries = boundaries(DIM, -1e100, Double.POSITIVE_INFINITY);
234 PointValuePair expected =
235 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
236 doTest(TestFunction.CIGAR.withDimension(DIM), startPoint, insigma, boundaries,
237 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
238 1e-13, 1e-6, 200000, expected);
239 doTest(TestFunction.CIGAR.withDimension(DIM), startPoint, insigma, boundaries,
240 GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
241 1e-13, 1e-6, 100000, expected);
242 }
243
244 @Test
245 public void testTwoAxes() {
246 double[] startPoint = OptimTestUtils.point(DIM,1.0);
247 double[] insigma = OptimTestUtils.point(DIM,0.1);
248 double[][] boundaries = null;
249 PointValuePair expected =
250 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
251 doTest(TestFunction.TWO_AXES.withDimension(DIM), startPoint, insigma, boundaries,
252 GoalType.MINIMIZE, 2*LAMBDA, true, 0, 1e-13,
253 1e-13, 1e-6, 200000, expected);
254 doTest(TestFunction.TWO_AXES.withDimension(DIM), startPoint, insigma, boundaries,
255 GoalType.MINIMIZE, 2*LAMBDA, false, 0, 1e-13,
256 1e-8, 1e-3, 200000, expected);
257 }
258
259 @Test
260 public void testCigTab() {
261 double[] startPoint = OptimTestUtils.point(DIM,1.0);
262 double[] insigma = OptimTestUtils.point(DIM,0.3);
263 double[][] boundaries = null;
264 PointValuePair expected =
265 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
266 doTest(TestFunction.CIG_TAB.withDimension(DIM), startPoint, insigma, boundaries,
267 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
268 1e-13, 5e-5, 100000, expected);
269 doTest(TestFunction.CIG_TAB.withDimension(DIM), startPoint, insigma, boundaries,
270 GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
271 1e-13, 5e-5, 100000, expected);
272 }
273
274 @Test
275 public void testSphere() {
276 double[] startPoint = OptimTestUtils.point(DIM,1.0);
277 double[] insigma = OptimTestUtils.point(DIM,0.1);
278 double[][] boundaries = null;
279 PointValuePair expected =
280 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
281 doTest(TestFunction.SPHERE.withDimension(DIM), startPoint, insigma, boundaries,
282 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
283 1e-13, 1e-6, 100000, expected);
284 doTest(TestFunction.SPHERE.withDimension(DIM), startPoint, insigma, boundaries,
285 GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
286 1e-13, 1e-6, 100000, expected);
287 }
288
289 @Test
290 public void testTablet() {
291 double[] startPoint = OptimTestUtils.point(DIM,1.0);
292 double[] insigma = OptimTestUtils.point(DIM,0.1);
293 double[][] boundaries = null;
294 PointValuePair expected =
295 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
296 doTest(TestFunction.TABLET.withDimension(DIM), startPoint, insigma, boundaries,
297 GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
298 1e-13, 1e-6, 100000, expected);
299 doTest(TestFunction.TABLET.withDimension(DIM), startPoint, insigma, boundaries,
300 GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
301 1e-13, 1e-6, 100000, expected);
302 }
303
304 @Test
305 public void testSumPow() {
306 double[] startPoint = OptimTestUtils.point(DIM,1.0);
307 double[] insigma = OptimTestUtils.point(DIM,0.1);
308 double[][] boundaries = null;
309 PointValuePair expected =
310 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
311 doTest(TestFunction.SUM_POW.withDimension(DIM), startPoint, insigma, boundaries,
312 GoalType.MINIMIZE, 10, true, 0, 1e-13,
313 1e-8, 1.5e-1, 100000, expected);
314 doTest(TestFunction.SUM_POW.withDimension(DIM), startPoint, insigma, boundaries,
315 GoalType.MINIMIZE, 10, false, 0, 1e-13,
316 1e-8, 2e-1, 100000, expected);
317 }
318
319 @Test
320 public void testAckley() {
321 double[] startPoint = OptimTestUtils.point(DIM,1.0);
322 double[] insigma = OptimTestUtils.point(DIM,1.0);
323 double[][] boundaries = null;
324 PointValuePair expected =
325 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
326 doTest(TestFunction.ACKLEY.withDimension(DIM), startPoint, insigma, boundaries,
327 GoalType.MINIMIZE, 2*LAMBDA, true, 0, 1e-13,
328 1e-9, 1e-5, 100000, expected);
329 doTest(TestFunction.ACKLEY.withDimension(DIM), startPoint, insigma, boundaries,
330 GoalType.MINIMIZE, 2*LAMBDA, false, 0, 1e-13,
331 1e-9, 1e-5, 100000, expected);
332 }
333
334 @Test
335 public void testRastrigin() {
336 double[] startPoint = OptimTestUtils.point(DIM,0.1);
337 double[] insigma = OptimTestUtils.point(DIM,0.1);
338 double[][] boundaries = null;
339 PointValuePair expected =
340 new PointValuePair(OptimTestUtils.point(DIM,0.0),0.0);
341 doTest(TestFunction.RASTRIGIN.withDimension(DIM), startPoint, insigma, boundaries,
342 GoalType.MINIMIZE, (int)(200*JdkMath.sqrt(DIM)), true, 0, 1e-13,
343 1e-13, 1e-6, 200000, expected);
344 doTest(TestFunction.RASTRIGIN.withDimension(DIM), startPoint, insigma, boundaries,
345 GoalType.MINIMIZE, (int)(200*JdkMath.sqrt(DIM)), false, 0, 1e-13,
346 1e-13, 1e-6, 200000, expected);
347 }
348
349 @Test
350 public void testConstrainedRosen() {
351 final int dim = 12;
352 double[] startPoint = OptimTestUtils.point(dim, 0.1);
353 double[] insigma = OptimTestUtils.point(dim, 0.1);
354 double[][] boundaries = boundaries(dim, -1, 2);
355 PointValuePair expected =
356 new PointValuePair(OptimTestUtils.point(dim, 1.0), 0.0);
357 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
358 GoalType.MINIMIZE, 2*LAMBDA, true, 0, 1e-13,
359 1e-13, 1e-6, 100000, expected);
360 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
361 GoalType.MINIMIZE, 2*LAMBDA, false, 0, 1e-13,
362 1e-13, 1e-6, 100000, expected);
363 }
364
365 @Test
366 public void testDiagonalRosen() {
367 final int dim = 12;
368 double[] startPoint = OptimTestUtils.point(dim, 0.1);
369 double[] insigma = OptimTestUtils.point(dim, 0.1);
370 double[][] boundaries = null;
371 PointValuePair expected =
372 new PointValuePair(OptimTestUtils.point(dim, 1.0), 0.0);
373 doTest(TestFunction.ROSENBROCK.withDimension(dim), startPoint, insigma, boundaries,
374 GoalType.MINIMIZE, LAMBDA, false, 1, 1e-13,
375 1e-10, 1e-4, 1000000, expected);
376 }
377
378 @Test
379 public void testMath864() {
380 final CMAESOptimizer optimizer
381 = new CMAESOptimizer(30000, 0, true, 10,
382 0, RandomSource.MT_64.create(), false, null);
383 final MultivariateFunction fitnessFunction = new MultivariateFunction() {
384 @Override
385 public double value(double[] parameters) {
386 final double target = 1;
387 final double error = target - parameters[0];
388 return error * error;
389 }
390 };
391
392 final double[] start = { 0 };
393 final double[] lower = { -1e6 };
394 final double[] upper = { 1.5 };
395 final double[] sigma = { 1e-1 };
396 final double[] result = optimizer.optimize(new MaxEval(10000),
397 new ObjectiveFunction(fitnessFunction),
398 GoalType.MINIMIZE,
399 new PopulationSize(5),
400 new Sigma(sigma),
401 new InitialGuess(start),
402 new SimpleBounds(lower, upper)).getPoint();
403 Assert.assertTrue("Out of bounds (" + result[0] + " > " + upper[0] + ")",
404 result[0] <= upper[0]);
405 }
406
407
408
409
410 @Test
411 public void testFitAccuracyDependsOnBoundary() {
412 final CMAESOptimizer optimizer
413 = new CMAESOptimizer(30000, 0, true, 10,
414 0, RandomSource.MT_64.create(), false, null);
415 final MultivariateFunction fitnessFunction = new MultivariateFunction() {
416 @Override
417 public double value(double[] parameters) {
418 final double target = 11.1;
419 final double error = target - parameters[0];
420 return error * error;
421 }
422 };
423
424 final double[] start = { 1 };
425
426
427 PointValuePair result = optimizer.optimize(new MaxEval(100000),
428 new ObjectiveFunction(fitnessFunction),
429 GoalType.MINIMIZE,
430 SimpleBounds.unbounded(1),
431 new PopulationSize(5),
432 new Sigma(new double[] { 1e-1 }),
433 new InitialGuess(start));
434 final double resNoBound = result.getPoint()[0];
435
436
437 final double[] lower = { -20 };
438 final double[] upper = { 5e16 };
439 final double[] sigma = { 10 };
440 result = optimizer.optimize(new MaxEval(100000),
441 new ObjectiveFunction(fitnessFunction),
442 GoalType.MINIMIZE,
443 new PopulationSize(5),
444 new Sigma(sigma),
445 new InitialGuess(start),
446 new SimpleBounds(lower, upper));
447 final double resNearLo = result.getPoint()[0];
448
449
450 lower[0] = -5e16;
451 upper[0] = 20;
452 result = optimizer.optimize(new MaxEval(100000),
453 new ObjectiveFunction(fitnessFunction),
454 GoalType.MINIMIZE,
455 new PopulationSize(5),
456 new Sigma(sigma),
457 new InitialGuess(start),
458 new SimpleBounds(lower, upper));
459 final double resNearHi = result.getPoint()[0];
460
461
462
463
464
465
466
467 Assert.assertEquals(resNoBound, resNearLo, 1e-3);
468 Assert.assertEquals(resNoBound, resNearHi, 1e-3);
469 }
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486 private void doTest(MultivariateFunction func,
487 double[] startPoint,
488 double[] inSigma,
489 double[][] boundaries,
490 GoalType goal,
491 int lambda,
492 boolean isActive,
493 int diagonalOnly,
494 double stopValue,
495 double fTol,
496 double pointTol,
497 int maxEvaluations,
498 PointValuePair expected) {
499 int dim = startPoint.length;
500
501 CMAESOptimizer optim = new CMAESOptimizer(30000, stopValue, isActive, diagonalOnly,
502 0, RandomSource.MT_64.create(), false, null);
503 PointValuePair result = boundaries == null ?
504 optim.optimize(new MaxEval(maxEvaluations),
505 new ObjectiveFunction(func),
506 goal,
507 new InitialGuess(startPoint),
508 SimpleBounds.unbounded(dim),
509 new Sigma(inSigma),
510 new PopulationSize(lambda)) :
511 optim.optimize(new MaxEval(maxEvaluations),
512 new ObjectiveFunction(func),
513 goal,
514 new SimpleBounds(boundaries[0],
515 boundaries[1]),
516 new InitialGuess(startPoint),
517 new Sigma(inSigma),
518 new PopulationSize(lambda));
519
520 Assert.assertEquals("Delta: " + fTol, expected.getValue(), result.getValue(), fTol);
521 for (int i = 0; i < dim; i++) {
522 Assert.assertEquals("Delta: " + pointTol, expected.getPoint()[i], result.getPoint()[i], pointTol);
523 }
524
525 Assert.assertTrue(optim.getIterations() > 0);
526 }
527
528 private static double[][] boundaries(int dim,
529 double lower, double upper) {
530 double[][] boundaries = new double[2][dim];
531 for (int i = 0; i < dim; i++) {
532 boundaries[0][i] = lower;
533 }
534 for (int i = 0; i < dim; i++) {
535 boundaries[1][i] = upper;
536 }
537 return boundaries;
538 }
539 }