View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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   * Test for {@link CMAESOptimizer}.
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      * Cf. MATH-867
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         // No bounds.
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         // Optimum is near the lower bound.
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         // Optimum is near the upper bound.
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         // System.out.println("resNoBound=" + resNoBound +
462         //                    " resNearLo=" + resNearLo +
463         //                    " resNearHi=" + resNearHi);
464 
465         // The two values currently differ by a substantial amount, indicating that
466         // the bounds definition can prevent reaching the optimum.
467         Assert.assertEquals(resNoBound, resNearLo, 1e-3);
468         Assert.assertEquals(resNoBound, resNearHi, 1e-3);
469     }
470 
471     /**
472      * @param func Function to optimize.
473      * @param startPoint Starting point.
474      * @param inSigma Individual input sigma.
475      * @param boundaries Upper / lower point limit.
476      * @param goal Minimization or maximization.
477      * @param lambda Population size used for offspring.
478      * @param isActive Covariance update mechanism.
479      * @param diagonalOnly Simplified covariance update.
480      * @param stopValue Termination criteria for optimization.
481      * @param fTol Tolerance relative error on the objective function.
482      * @param pointTol Tolerance for checking that the optimum is correct.
483      * @param maxEvaluations Maximum number of evaluations.
484      * @param expected Expected point / value.
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         // test diagonalOnly = 0 - slow but normally fewer feval#
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 }