commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From er...@apache.org
Subject svn commit: r1420684 [11/15] - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/exception/ main/java/org/apache/commons/math3/exception/util/ main/java/org/apache/commons/math3/fitting/ main/java/org/apache/commons/math3/optim/ mai...
Date Wed, 12 Dec 2012 14:11:04 GMT
Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizerTest.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizerTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizerTest.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,447 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.optim.nonlinear.scalar.gradient;
+
+import java.io.Serializable;
+
+import org.apache.commons.math3.analysis.DifferentiableMultivariateFunction;
+import org.apache.commons.math3.analysis.MultivariateFunction;
+import org.apache.commons.math3.analysis.MultivariateVectorFunction;
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
+import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableFunction;
+import org.apache.commons.math3.analysis.solvers.BrentSolver;
+import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.exception.MathIllegalArgumentException;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
+import org.apache.commons.math3.linear.BlockRealMatrix;
+import org.apache.commons.math3.linear.RealMatrix;
+import org.apache.commons.math3.optim.GoalType;
+import org.apache.commons.math3.optim.PointValuePair;
+import org.apache.commons.math3.optim.SimpleValueChecker;
+import org.apache.commons.math3.optim.InitialGuess;
+import org.apache.commons.math3.optim.MaxEval;
+import org.apache.commons.math3.optim.ObjectiveFunction;
+import org.apache.commons.math3.optim.nonlinear.scalar.ObjectiveFunctionGradient;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * <p>Some of the unit tests are re-implementations of the MINPACK <a
+ * href="http://www.netlib.org/minpack/ex/file17">file17</a> and <a
+ * href="http://www.netlib.org/minpack/ex/file22">file22</a> test files.
+ * The redistribution policy for MINPACK is available <a
+ * href="http://www.netlib.org/minpack/disclaimer">here</a>, for
+ * convenience, it is reproduced below.</p>
+ *
+ * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
+ * <tr><td>
+ *    Minpack Copyright Notice (1999) University of Chicago.
+ *    All rights reserved
+ * </td></tr>
+ * <tr><td>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * <ol>
+ *  <li>Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.</li>
+ * <li>Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.</li>
+ * <li>The end-user documentation included with the redistribution, if any,
+ *     must include the following acknowledgment:
+ *     <code>This product includes software developed by the University of
+ *           Chicago, as Operator of Argonne National Laboratory.</code>
+ *     Alternately, this acknowledgment may appear in the software itself,
+ *     if and wherever such third-party acknowledgments normally appear.</li>
+ * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"
+ *     WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE
+ *     UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND
+ *     THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR
+ *     IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
+ *     OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY
+ *     OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
+ *     USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF
+ *     THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)
+ *     DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION
+ *     UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL
+ *     BE CORRECTED.</strong></li>
+ * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT
+ *     HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF
+ *     ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,
+ *     INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF
+ *     ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF
+ *     PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER
+ *     SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
+ *     (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
+ *     EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
+ *     POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li>
+ * <ol></td></tr>
+ * </table>
+ *
+ * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests)
+ * @author Burton S. Garbow (original fortran minpack tests)
+ * @author Kenneth E. Hillstrom (original fortran minpack tests)
+ * @author Jorge J. More (original fortran minpack tests)
+ * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation)
+ */
+public class NonLinearConjugateGradientOptimizerTest {
+    @Test
+    public void testTrivial() {
+        LinearProblem problem
+            = new LinearProblem(new double[][] { { 2 } }, new double[] { 3 });
+        NonLinearConjugateGradientOptimizer optimizer
+            = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                      new SimpleValueChecker(1e-6, 1e-6));
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 0 }));
+        Assert.assertEquals(1.5, optimum.getPoint()[0], 1.0e-10);
+        Assert.assertEquals(0.0, optimum.getValue(), 1.0e-10);
+    }
+
+    @Test
+    public void testColumnsPermutation() {
+        LinearProblem problem
+            = new LinearProblem(new double[][] { { 1.0, -1.0 }, { 0.0, 2.0 }, { 1.0, -2.0 } },
+                                new double[] { 4.0, 6.0, 1.0 });
+
+        NonLinearConjugateGradientOptimizer optimizer
+            = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                      new SimpleValueChecker(1e-6, 1e-6));
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 0, 0 }));
+        Assert.assertEquals(7.0, optimum.getPoint()[0], 1.0e-10);
+        Assert.assertEquals(3.0, optimum.getPoint()[1], 1.0e-10);
+        Assert.assertEquals(0.0, optimum.getValue(), 1.0e-10);
+
+    }
+
+    @Test
+    public void testNoDependency() {
+        LinearProblem problem = new LinearProblem(new double[][] {
+                { 2, 0, 0, 0, 0, 0 },
+                { 0, 2, 0, 0, 0, 0 },
+                { 0, 0, 2, 0, 0, 0 },
+                { 0, 0, 0, 2, 0, 0 },
+                { 0, 0, 0, 0, 2, 0 },
+                { 0, 0, 0, 0, 0, 2 }
+        }, new double[] { 0.0, 1.1, 2.2, 3.3, 4.4, 5.5 });
+        NonLinearConjugateGradientOptimizer optimizer
+            = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                      new SimpleValueChecker(1e-6, 1e-6));
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 0, 0, 0, 0, 0, 0 }));
+        for (int i = 0; i < problem.target.length; ++i) {
+            Assert.assertEquals(0.55 * i, optimum.getPoint()[i], 1.0e-10);
+        }
+    }
+
+    @Test
+    public void testOneSet() {
+        LinearProblem problem = new LinearProblem(new double[][] {
+                {  1,  0, 0 },
+                { -1,  1, 0 },
+                {  0, -1, 1 }
+        }, new double[] { 1, 1, 1});
+        NonLinearConjugateGradientOptimizer optimizer
+            = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                      new SimpleValueChecker(1e-6, 1e-6));
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 0, 0, 0 }));
+        Assert.assertEquals(1.0, optimum.getPoint()[0], 1.0e-10);
+        Assert.assertEquals(2.0, optimum.getPoint()[1], 1.0e-10);
+        Assert.assertEquals(3.0, optimum.getPoint()[2], 1.0e-10);
+
+    }
+
+    @Test
+    public void testTwoSets() {
+        final double epsilon = 1.0e-7;
+        LinearProblem problem = new LinearProblem(new double[][] {
+                {  2,  1,   0,  4,       0, 0 },
+                { -4, -2,   3, -7,       0, 0 },
+                {  4,  1,  -2,  8,       0, 0 },
+                {  0, -3, -12, -1,       0, 0 },
+                {  0,  0,   0,  0, epsilon, 1 },
+                {  0,  0,   0,  0,       1, 1 }
+        }, new double[] { 2, -9, 2, 2, 1 + epsilon * epsilon, 2});
+
+        final Preconditioner preconditioner
+            = new Preconditioner() {
+                    public double[] precondition(double[] point, double[] r) {
+                        double[] d = r.clone();
+                        d[0] /=  72.0;
+                        d[1] /=  30.0;
+                        d[2] /= 314.0;
+                        d[3] /= 260.0;
+                        d[4] /= 2 * (1 + epsilon * epsilon);
+                        d[5] /= 4.0;
+                        return d;
+                    }
+                };
+
+        NonLinearConjugateGradientOptimizer optimizer
+           = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                     new SimpleValueChecker(1e-13, 1e-13),
+                                                     new BrentSolver(),
+                                                     preconditioner);
+
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 0, 0, 0, 0, 0, 0 }));
+        Assert.assertEquals( 3.0, optimum.getPoint()[0], 1.0e-10);
+        Assert.assertEquals( 4.0, optimum.getPoint()[1], 1.0e-10);
+        Assert.assertEquals(-1.0, optimum.getPoint()[2], 1.0e-10);
+        Assert.assertEquals(-2.0, optimum.getPoint()[3], 1.0e-10);
+        Assert.assertEquals( 1.0 + epsilon, optimum.getPoint()[4], 1.0e-10);
+        Assert.assertEquals( 1.0 - epsilon, optimum.getPoint()[5], 1.0e-10);
+
+    }
+
+    @Test
+    public void testNonInversible() {
+        LinearProblem problem = new LinearProblem(new double[][] {
+                {  1, 2, -3 },
+                {  2, 1,  3 },
+                { -3, 0, -9 }
+        }, new double[] { 1, 1, 1 });
+        NonLinearConjugateGradientOptimizer optimizer
+            = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                      new SimpleValueChecker(1e-6, 1e-6));
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 0, 0, 0 }));
+        Assert.assertTrue(optimum.getValue() > 0.5);
+    }
+
+    @Test
+    public void testIllConditioned() {
+        LinearProblem problem1 = new LinearProblem(new double[][] {
+                { 10.0, 7.0,  8.0,  7.0 },
+                {  7.0, 5.0,  6.0,  5.0 },
+                {  8.0, 6.0, 10.0,  9.0 },
+                {  7.0, 5.0,  9.0, 10.0 }
+        }, new double[] { 32, 23, 33, 31 });
+        NonLinearConjugateGradientOptimizer optimizer
+            = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                      new SimpleValueChecker(1e-13, 1e-13),
+                                                      new BrentSolver(1e-15, 1e-15));
+        PointValuePair optimum1
+            = optimizer.optimize(new MaxEval(200),
+                                 problem1.getObjectiveFunction(),
+                                 problem1.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 0, 1, 2, 3 }));
+        Assert.assertEquals(1.0, optimum1.getPoint()[0], 1.0e-4);
+        Assert.assertEquals(1.0, optimum1.getPoint()[1], 1.0e-4);
+        Assert.assertEquals(1.0, optimum1.getPoint()[2], 1.0e-4);
+        Assert.assertEquals(1.0, optimum1.getPoint()[3], 1.0e-4);
+
+        LinearProblem problem2 = new LinearProblem(new double[][] {
+                { 10.00, 7.00, 8.10, 7.20 },
+                {  7.08, 5.04, 6.00, 5.00 },
+                {  8.00, 5.98, 9.89, 9.00 },
+                {  6.99, 4.99, 9.00, 9.98 }
+        }, new double[] { 32, 23, 33, 31 });
+        PointValuePair optimum2
+            = optimizer.optimize(new MaxEval(200),
+                                 problem2.getObjectiveFunction(),
+                                 problem2.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 0, 1, 2, 3 }));
+        Assert.assertEquals(-81.0, optimum2.getPoint()[0], 1.0e-1);
+        Assert.assertEquals(137.0, optimum2.getPoint()[1], 1.0e-1);
+        Assert.assertEquals(-34.0, optimum2.getPoint()[2], 1.0e-1);
+        Assert.assertEquals( 22.0, optimum2.getPoint()[3], 1.0e-1);
+
+    }
+
+    @Test
+    public void testMoreEstimatedParametersSimple() {
+        LinearProblem problem = new LinearProblem(new double[][] {
+                { 3.0, 2.0,  0.0, 0.0 },
+                { 0.0, 1.0, -1.0, 1.0 },
+                { 2.0, 0.0,  1.0, 0.0 }
+        }, new double[] { 7.0, 3.0, 5.0 });
+
+        NonLinearConjugateGradientOptimizer optimizer
+            = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                      new SimpleValueChecker(1e-6, 1e-6));
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 7, 6, 5, 4 }));
+        Assert.assertEquals(0, optimum.getValue(), 1.0e-10);
+
+    }
+
+    @Test
+    public void testMoreEstimatedParametersUnsorted() {
+        LinearProblem problem = new LinearProblem(new double[][] {
+                 { 1.0, 1.0,  0.0,  0.0, 0.0,  0.0 },
+                 { 0.0, 0.0,  1.0,  1.0, 1.0,  0.0 },
+                 { 0.0, 0.0,  0.0,  0.0, 1.0, -1.0 },
+                 { 0.0, 0.0, -1.0,  1.0, 0.0,  1.0 },
+                 { 0.0, 0.0,  0.0, -1.0, 1.0,  0.0 }
+        }, new double[] { 3.0, 12.0, -1.0, 7.0, 1.0 });
+        NonLinearConjugateGradientOptimizer optimizer
+           = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                     new SimpleValueChecker(1e-6, 1e-6));
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 2, 2, 2, 2, 2, 2 }));
+        Assert.assertEquals(0, optimum.getValue(), 1.0e-10);
+    }
+
+    @Test
+    public void testRedundantEquations() {
+        LinearProblem problem = new LinearProblem(new double[][] {
+                { 1.0,  1.0 },
+                { 1.0, -1.0 },
+                { 1.0,  3.0 }
+        }, new double[] { 3.0, 1.0, 5.0 });
+
+        NonLinearConjugateGradientOptimizer optimizer
+            = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                      new SimpleValueChecker(1e-6, 1e-6));
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 1, 1 }));
+        Assert.assertEquals(2.0, optimum.getPoint()[0], 1.0e-8);
+        Assert.assertEquals(1.0, optimum.getPoint()[1], 1.0e-8);
+
+    }
+
+    @Test
+    public void testInconsistentEquations() {
+        LinearProblem problem = new LinearProblem(new double[][] {
+                { 1.0,  1.0 },
+                { 1.0, -1.0 },
+                { 1.0,  3.0 }
+        }, new double[] { 3.0, 1.0, 4.0 });
+
+        NonLinearConjugateGradientOptimizer optimizer
+            = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                      new SimpleValueChecker(1e-6, 1e-6));
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 1, 1 }));
+        Assert.assertTrue(optimum.getValue() > 0.1);
+
+    }
+
+    @Test
+    public void testCircleFitting() {
+        CircleScalar problem = new CircleScalar();
+        problem.addPoint( 30.0,  68.0);
+        problem.addPoint( 50.0,  -6.0);
+        problem.addPoint(110.0, -20.0);
+        problem.addPoint( 35.0,  15.0);
+        problem.addPoint( 45.0,  97.0);
+        NonLinearConjugateGradientOptimizer optimizer
+           = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
+                                                     new SimpleValueChecker(1e-30, 1e-30),
+                                                     new BrentSolver(1e-15, 1e-13));
+        PointValuePair optimum
+            = optimizer.optimize(new MaxEval(100),
+                                 problem.getObjectiveFunction(),
+                                 problem.getObjectiveFunctionGradient(),
+                                 GoalType.MINIMIZE,
+                                 new InitialGuess(new double[] { 98.680, 47.345 }));
+        Vector2D center = new Vector2D(optimum.getPointRef()[0], optimum.getPointRef()[1]);
+        Assert.assertEquals(69.960161753, problem.getRadius(center), 1.0e-8);
+        Assert.assertEquals(96.075902096, center.getX(), 1.0e-8);
+        Assert.assertEquals(48.135167894, center.getY(), 1.0e-8);
+    }
+
+    private static class LinearProblem {
+        final RealMatrix factors;
+        final double[] target;
+
+        public LinearProblem(double[][] factors,
+                             double[] target) {
+            this.factors = new BlockRealMatrix(factors);
+            this.target  = target;
+        }
+
+        public ObjectiveFunction getObjectiveFunction() {
+            return new ObjectiveFunction(new MultivariateFunction() {
+                    public double value(double[] point) {
+                        double[] y = factors.operate(point);
+                        double sum = 0;
+                        for (int i = 0; i < y.length; ++i) {
+                            double ri = y[i] - target[i];
+                            sum += ri * ri;
+                        }
+                        return sum;
+                    }
+                });
+        }
+
+        public ObjectiveFunctionGradient getObjectiveFunctionGradient() {
+            return new ObjectiveFunctionGradient(new MultivariateVectorFunction() {
+                    public double[] value(double[] point) {
+                        double[] r = factors.operate(point);
+                        for (int i = 0; i < r.length; ++i) {
+                            r[i] -= target[i];
+                        }
+                        double[] p = factors.transpose().operate(r);
+                        for (int i = 0; i < p.length; ++i) {
+                            p[i] *= 2;
+                        }
+                        return p;
+                    }
+                });
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/BOBYQAOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/BOBYQAOptimizerTest.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/BOBYQAOptimizerTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/BOBYQAOptimizerTest.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,627 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.optim.nonlinear.scalar.noderiv;
+
+import java.util.Arrays;
+import java.util.Random;
+import org.apache.commons.math3.analysis.MultivariateFunction;
+import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.exception.TooManyEvaluationsException;
+import org.apache.commons.math3.exception.NumberIsTooLargeException;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
+import org.apache.commons.math3.optim.MaxEval;
+import org.apache.commons.math3.optim.ObjectiveFunction;
+import org.apache.commons.math3.optim.GoalType;
+import org.apache.commons.math3.optim.PointValuePair;
+import org.apache.commons.math3.optim.InitialGuess;
+import org.apache.commons.math3.optim.SimpleBounds;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for {@link BOBYQAOptimizer}.
+ */
+public class BOBYQAOptimizerTest {
+
+    static final int DIM = 13;
+   
+    @Test(expected=NumberIsTooLargeException.class)
+    public void testInitOutOfBounds() {
+        double[] startPoint = point(DIM, 3);
+        double[][] boundaries = boundaries(DIM, -1, 2);
+        doTest(new Rosen(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-13, 1e-6, 2000, null);
+    }
+    
+    @Test(expected=DimensionMismatchException.class)
+    public void testBoundariesDimensionMismatch() {
+        double[] startPoint = point(DIM, 0.5);
+        double[][] boundaries = boundaries(DIM + 1, -1, 2);
+        doTest(new Rosen(), startPoint, boundaries,
+               GoalType.MINIMIZE, 
+               1e-13, 1e-6, 2000, null);
+    }
+
+    @Test(expected=NumberIsTooSmallException.class)
+    public void testProblemDimensionTooSmall() {
+        double[] startPoint = point(1, 0.5);
+        doTest(new Rosen(), startPoint, null,
+               GoalType.MINIMIZE,
+               1e-13, 1e-6, 2000, null);
+    }
+
+    @Test(expected=TooManyEvaluationsException.class)
+    public void testMaxEvaluations() {
+        final int lowMaxEval = 2;
+        double[] startPoint = point(DIM, 0.1);
+        double[][] boundaries = null;
+        doTest(new Rosen(), startPoint, boundaries,
+               GoalType.MINIMIZE, 
+               1e-13, 1e-6, lowMaxEval, null);
+     }
+
+    @Test
+    public void testRosen() {
+        double[] startPoint = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected = new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-13, 1e-6, 2000, expected);
+     }
+
+    @Test
+    public void testMaximize() {
+        double[] startPoint = point(DIM,1.0);
+        double[][] boundaries = null;
+        PointValuePair expected = new PointValuePair(point(DIM,0.0),1.0);
+        doTest(new MinusElli(), startPoint, boundaries,
+                GoalType.MAXIMIZE, 
+                2e-10, 5e-6, 1000, expected);
+        boundaries = boundaries(DIM,-0.3,0.3); 
+        startPoint = point(DIM,0.1);
+        doTest(new MinusElli(), startPoint, boundaries,
+                GoalType.MAXIMIZE, 
+                2e-10, 5e-6, 1000, expected);
+    }
+
+    @Test
+    public void testEllipse() {
+        double[] startPoint = point(DIM,1.0);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Elli(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-13, 1e-6, 1000, expected);
+     }
+
+    @Test
+    public void testElliRotated() {
+        double[] startPoint = point(DIM,1.0);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new ElliRotated(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-12, 1e-6, 10000, expected);
+    }
+
+    @Test
+    public void testCigar() {
+        double[] startPoint = point(DIM,1.0);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Cigar(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-13, 1e-6, 100, expected);
+    }
+
+    @Test
+    public void testTwoAxes() {
+        double[] startPoint = point(DIM,1.0);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new TwoAxes(), startPoint, boundaries,
+                GoalType.MINIMIZE, 2*
+                1e-13, 1e-6, 100, expected);
+     }
+
+    @Test
+    public void testCigTab() {
+        double[] startPoint = point(DIM,1.0);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new CigTab(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-13, 5e-5, 100, expected);
+     }
+
+    @Test
+    public void testSphere() {
+        double[] startPoint = point(DIM,1.0);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Sphere(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-13, 1e-6, 100, expected);
+    }
+
+    @Test
+    public void testTablet() {
+        double[] startPoint = point(DIM,1.0); 
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Tablet(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-13, 1e-6, 100, expected);
+    }
+
+    @Test
+    public void testDiffPow() {
+        double[] startPoint = point(DIM/2,1.0);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM/2,0.0),0.0);
+        doTest(new DiffPow(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-8, 1e-1, 12000, expected);
+    }
+
+    @Test
+    public void testSsDiffPow() {
+        double[] startPoint = point(DIM/2,1.0);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM/2,0.0),0.0);
+        doTest(new SsDiffPow(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-2, 1.3e-1, 50000, expected);
+    }
+
+    @Test
+    public void testAckley() {
+        double[] startPoint = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Ackley(), startPoint, boundaries,
+                GoalType.MINIMIZE,
+                1e-8, 1e-5, 1000, expected);
+    }
+
+    @Test
+    public void testRastrigin() {
+        double[] startPoint = point(DIM,1.0);
+
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Rastrigin(), startPoint, boundaries,
+                GoalType.MINIMIZE, 
+                1e-13, 1e-6, 1000, expected);
+    }
+
+    @Test
+    public void testConstrainedRosen() {
+        double[] startPoint = point(DIM,0.1);
+
+        double[][] boundaries = boundaries(DIM,-1,2);
+        PointValuePair expected =
+            new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, boundaries,
+                GoalType.MINIMIZE,
+                1e-13, 1e-6, 2000, expected);
+    }
+
+    // See MATH-728
+    @Test
+    public void testConstrainedRosenWithMoreInterpolationPoints() {
+        final double[] startPoint = point(DIM, 0.1);
+        final double[][] boundaries = boundaries(DIM, -1, 2);
+        final PointValuePair expected = new PointValuePair(point(DIM, 1.0), 0.0);
+
+        // This should have been 78 because in the code the hard limit is
+        // said to be
+        //   ((DIM + 1) * (DIM + 2)) / 2 - (2 * DIM + 1)
+        // i.e. 78 in this case, but the test fails for 48, 59, 62, 63, 64,
+        // 65, 66, ...
+        final int maxAdditionalPoints = 47;
+
+        for (int num = 1; num <= maxAdditionalPoints; num++) {
+            doTest(new Rosen(), startPoint, boundaries,
+                   GoalType.MINIMIZE,
+                   1e-12, 1e-6, 2000,
+                   num,
+                   expected,
+                   "num=" + num);
+        }
+    }
+
+    /**
+     * @param func Function to optimize.
+     * @param startPoint Starting point.
+     * @param boundaries Upper / lower point limit.
+     * @param goal Minimization or maximization.
+     * @param fTol Tolerance relative error on the objective function.
+     * @param pointTol Tolerance for checking that the optimum is correct.
+     * @param maxEvaluations Maximum number of evaluations.
+     * @param expected Expected point / value.
+     */
+    private void doTest(MultivariateFunction func,
+                        double[] startPoint,
+                        double[][] boundaries,
+                        GoalType goal,
+                        double fTol,
+                        double pointTol,
+                        int maxEvaluations,
+                        PointValuePair expected) {
+        doTest(func,
+               startPoint,
+               boundaries,
+               goal,
+               fTol,
+               pointTol,
+               maxEvaluations,
+               0,
+               expected,
+               "");
+    }
+
+    /**
+     * @param func Function to optimize.
+     * @param startPoint Starting point.
+     * @param boundaries Upper / lower point limit.
+     * @param goal Minimization or maximization.
+     * @param fTol Tolerance relative error on the objective function.
+     * @param pointTol Tolerance for checking that the optimum is correct.
+     * @param maxEvaluations Maximum number of evaluations.
+     * @param additionalInterpolationPoints Number of interpolation to used
+     * in addition to the default (2 * dim + 1).
+     * @param expected Expected point / value.
+     */
+    private void doTest(MultivariateFunction func,
+                        double[] startPoint,
+                        double[][] boundaries,
+                        GoalType goal,
+                        double fTol,
+                        double pointTol,
+                        int maxEvaluations,
+                        int additionalInterpolationPoints,
+                        PointValuePair expected,
+                        String assertMsg) {
+
+//         System.out.println(func.getClass().getName() + " BEGIN"); // XXX
+
+        int dim = startPoint.length;
+        final int numIterpolationPoints = 2 * dim + 1 + additionalInterpolationPoints;
+        BOBYQAOptimizer optim = new BOBYQAOptimizer(numIterpolationPoints);
+        PointValuePair result = boundaries == null ?
+            optim.optimize(new MaxEval(maxEvaluations),
+                           new ObjectiveFunction(func),
+                           goal,
+                           SimpleBounds.unbounded(dim),
+                           new InitialGuess(startPoint)) :
+            optim.optimize(new MaxEval(maxEvaluations),
+                           new ObjectiveFunction(func),
+                           goal,
+                           new InitialGuess(startPoint),
+                           new SimpleBounds(boundaries[0],
+                                            boundaries[1]));
+//        System.out.println(func.getClass().getName() + " = " 
+//              + optim.getEvaluations() + " f(");
+//        for (double x: result.getPoint())  System.out.print(x + " ");
+//        System.out.println(") = " +  result.getValue());
+        Assert.assertEquals(assertMsg, expected.getValue(), result.getValue(), fTol);
+        for (int i = 0; i < dim; i++) {
+            Assert.assertEquals(expected.getPoint()[i],
+                                result.getPoint()[i], pointTol);
+        }
+
+//         System.out.println(func.getClass().getName() + " END"); // XXX
+    }
+
+    private static double[] point(int n, double value) {
+        double[] ds = new double[n];
+        Arrays.fill(ds, value);
+        return ds;
+    }
+
+    private static double[][] boundaries(int dim,
+            double lower, double upper) {
+        double[][] boundaries = new double[2][dim];
+        for (int i = 0; i < dim; i++)
+            boundaries[0][i] = lower;
+        for (int i = 0; i < dim; i++)
+            boundaries[1][i] = upper;
+        return boundaries;
+    }
+
+    private static class Sphere implements MultivariateFunction {
+
+        public double value(double[] x) {
+            double f = 0;
+            for (int i = 0; i < x.length; ++i)
+                f += x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class Cigar implements MultivariateFunction {
+        private double factor;
+
+        Cigar() {
+            this(1e3);
+        }
+
+        Cigar(double axisratio) {
+            factor = axisratio * axisratio;
+        }
+
+        public double value(double[] x) {
+            double f = x[0] * x[0];
+            for (int i = 1; i < x.length; ++i)
+                f += factor * x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class Tablet implements MultivariateFunction {
+        private double factor;
+
+        Tablet() {
+            this(1e3);
+        }
+
+        Tablet(double axisratio) {
+            factor = axisratio * axisratio;
+        }
+
+        public double value(double[] x) {
+            double f = factor * x[0] * x[0];
+            for (int i = 1; i < x.length; ++i)
+                f += x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class CigTab implements MultivariateFunction {
+        private double factor;
+
+        CigTab() {
+            this(1e4);
+        }
+
+        CigTab(double axisratio) {
+            factor = axisratio;
+        }
+
+        public double value(double[] x) {
+            int end = x.length - 1;
+            double f = x[0] * x[0] / factor + factor * x[end] * x[end];
+            for (int i = 1; i < end; ++i)
+                f += x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class TwoAxes implements MultivariateFunction {
+
+        private double factor;
+
+        TwoAxes() {
+            this(1e6);
+        }
+
+        TwoAxes(double axisratio) {
+            factor = axisratio * axisratio;
+        }
+
+        public double value(double[] x) {
+            double f = 0;
+            for (int i = 0; i < x.length; ++i)
+                f += (i < x.length / 2 ? factor : 1) * x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class ElliRotated implements MultivariateFunction {
+        private Basis B = new Basis();
+        private double factor;
+
+        ElliRotated() {
+            this(1e3);
+        }
+
+        ElliRotated(double axisratio) {
+            factor = axisratio * axisratio;
+        }
+
+        public double value(double[] x) {
+            double f = 0;
+            x = B.Rotate(x);
+            for (int i = 0; i < x.length; ++i)
+                f += Math.pow(factor, i / (x.length - 1.)) * x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class Elli implements MultivariateFunction {
+
+        private double factor;
+
+        Elli() {
+            this(1e3);
+        }
+
+        Elli(double axisratio) {
+            factor = axisratio * axisratio;
+        }
+
+        public double value(double[] x) {
+            double f = 0;
+            for (int i = 0; i < x.length; ++i)
+                f += Math.pow(factor, i / (x.length - 1.)) * x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class MinusElli implements MultivariateFunction {
+        private final Elli elli = new Elli();
+        public double value(double[] x) {
+            return 1.0 - elli.value(x);
+        }
+    }
+
+    private static class DiffPow implements MultivariateFunction {
+//        private int fcount = 0;
+        public double value(double[] x) {
+            double f = 0;
+            for (int i = 0; i < x.length; ++i)
+                f += Math.pow(Math.abs(x[i]), 2. + 10 * (double) i
+                        / (x.length - 1.));
+//            System.out.print("" + (fcount++) + ") ");
+//            for (int i = 0; i < x.length; i++)
+//                System.out.print(x[i] +  " ");
+//            System.out.println(" = " + f);
+            return f;
+        }
+    }
+
+    private static class SsDiffPow implements MultivariateFunction {
+
+        public double value(double[] x) {
+            double f = Math.pow(new DiffPow().value(x), 0.25);
+            return f;
+        }
+    }
+
+    private static class Rosen implements MultivariateFunction {
+
+        public double value(double[] x) {
+            double f = 0;
+            for (int i = 0; i < x.length - 1; ++i)
+                f += 1e2 * (x[i] * x[i] - x[i + 1]) * (x[i] * x[i] - x[i + 1])
+                + (x[i] - 1.) * (x[i] - 1.);
+            return f;
+        }
+    }
+
+    private static class Ackley implements MultivariateFunction {
+        private double axisratio;
+
+        Ackley(double axra) {
+            axisratio = axra;
+        }
+
+        public Ackley() {
+            this(1);
+        }
+
+        public double value(double[] x) {
+            double f = 0;
+            double res2 = 0;
+            double fac = 0;
+            for (int i = 0; i < x.length; ++i) {
+                fac = Math.pow(axisratio, (i - 1.) / (x.length - 1.));
+                f += fac * fac * x[i] * x[i];
+                res2 += Math.cos(2. * Math.PI * fac * x[i]);
+            }
+            f = (20. - 20. * Math.exp(-0.2 * Math.sqrt(f / x.length))
+                    + Math.exp(1.) - Math.exp(res2 / x.length));
+            return f;
+        }
+    }
+
+    private static class Rastrigin implements MultivariateFunction {
+
+        private double axisratio;
+        private double amplitude;
+
+        Rastrigin() {
+            this(1, 10);
+        }
+
+        Rastrigin(double axisratio, double amplitude) {
+            this.axisratio = axisratio;
+            this.amplitude = amplitude;
+        }
+
+        public double value(double[] x) {
+            double f = 0;
+            double fac;
+            for (int i = 0; i < x.length; ++i) {
+                fac = Math.pow(axisratio, (i - 1.) / (x.length - 1.));
+                if (i == 0 && x[i] < 0)
+                    fac *= 1.;
+                f += fac * fac * x[i] * x[i] + amplitude
+                * (1. - Math.cos(2. * Math.PI * fac * x[i]));
+            }
+            return f;
+        }
+    }
+
+    private static class Basis {
+        double[][] basis;
+        Random rand = new Random(2); // use not always the same basis
+
+        double[] Rotate(double[] x) {
+            GenBasis(x.length);
+            double[] y = new double[x.length];
+            for (int i = 0; i < x.length; ++i) {
+                y[i] = 0;
+                for (int j = 0; j < x.length; ++j)
+                    y[i] += basis[i][j] * x[j];
+            }
+            return y;
+        }
+
+        void GenBasis(int DIM) {
+            if (basis != null ? basis.length == DIM : false)
+                return;
+
+            double sp;
+            int i, j, k;
+
+            /* generate orthogonal basis */
+            basis = new double[DIM][DIM];
+            for (i = 0; i < DIM; ++i) {
+                /* sample components gaussian */
+                for (j = 0; j < DIM; ++j)
+                    basis[i][j] = rand.nextGaussian();
+                /* substract projection of previous vectors */
+                for (j = i - 1; j >= 0; --j) {
+                    for (sp = 0., k = 0; k < DIM; ++k)
+                        sp += basis[i][k] * basis[j][k]; /* scalar product */
+                    for (k = 0; k < DIM; ++k)
+                        basis[i][k] -= sp * basis[j][k]; /* substract */
+                }
+                /* normalize */
+                for (sp = 0., k = 0; k < DIM; ++k)
+                    sp += basis[i][k] * basis[i][k]; /* squared norm */
+                for (k = 0; k < DIM; ++k)
+                    basis[i][k] /= Math.sqrt(sp);
+            }
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/BOBYQAOptimizerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/CMAESOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/CMAESOptimizerTest.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/CMAESOptimizerTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/CMAESOptimizerTest.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,794 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.optim.nonlinear.scalar.noderiv;
+
+import java.util.Arrays;
+import java.util.Random;
+import org.apache.commons.math3.Retry;
+import org.apache.commons.math3.RetryRunner;
+import org.apache.commons.math3.analysis.MultivariateFunction;
+import org.apache.commons.math3.exception.NumberIsTooLargeException;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
+import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.exception.MathUnsupportedOperationException;
+import org.apache.commons.math3.exception.MathIllegalStateException;
+import org.apache.commons.math3.exception.NotPositiveException;
+import org.apache.commons.math3.exception.OutOfRangeException;
+import org.apache.commons.math3.optim.GoalType;
+import org.apache.commons.math3.optim.PointValuePair;
+import org.apache.commons.math3.optim.InitialGuess;
+import org.apache.commons.math3.optim.SimpleBounds;
+import org.apache.commons.math3.optim.ObjectiveFunction;
+import org.apache.commons.math3.optim.MaxEval;
+import org.apache.commons.math3.random.MersenneTwister;
+import org.apache.commons.math3.util.FastMath;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.Ignore;
+import org.junit.runner.RunWith;
+
+/**
+ * Test for {@link CMAESOptimizer}.
+ */
+@RunWith(RetryRunner.class)
+public class CMAESOptimizerTest {
+
+    static final int DIM = 13;
+    static final int LAMBDA = 4 + (int)(3.*Math.log(DIM));
+   
+    @Test(expected = NumberIsTooLargeException.class)
+    public void testInitOutofbounds1() {
+        double[] startPoint = point(DIM,3);
+        double[] insigma = point(DIM, 0.3);
+        double[][] boundaries = boundaries(DIM,-1,2);
+        PointValuePair expected =
+            new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+    @Test(expected = NumberIsTooSmallException.class)
+    public void testInitOutofbounds2() {
+        double[] startPoint = point(DIM, -2);
+        double[] insigma = point(DIM, 0.3);
+        double[][] boundaries = boundaries(DIM,-1,2);
+        PointValuePair expected =
+            new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+    
+    @Test(expected = DimensionMismatchException.class)
+    public void testBoundariesDimensionMismatch() {
+        double[] startPoint = point(DIM,0.5);
+        double[] insigma = point(DIM, 0.3);
+        double[][] boundaries = boundaries(DIM+1,-1,2);
+        PointValuePair expected =
+            new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test(expected = NotPositiveException.class)
+    public void testInputSigmaNegative() {
+        double[] startPoint = point(DIM,0.5);
+        double[] insigma = point(DIM,-0.5);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test(expected = OutOfRangeException.class)
+    public void testInputSigmaOutOfRange() {
+        double[] startPoint = point(DIM,0.5);
+        double[] insigma = point(DIM, 1.1);
+        double[][] boundaries = boundaries(DIM,-0.5,0.5);
+        PointValuePair expected =
+            new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test(expected = DimensionMismatchException.class)
+    public void testInputSigmaDimensionMismatch() {
+        double[] startPoint = point(DIM,0.5);
+        double[] insigma = point(DIM + 1, 0.5);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+    
+    @Test
+    @Retry(3)
+    public void testRosen() {
+        double[] startPoint = point(DIM,0.1);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test
+    @Retry(3)
+    public void testMaximize() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),1.0);
+        doTest(new MinusElli(), startPoint, insigma, boundaries,
+                GoalType.MAXIMIZE, LAMBDA, true, 0, 1.0-1e-13,
+                2e-10, 5e-6, 100000, expected);
+        doTest(new MinusElli(), startPoint, insigma, boundaries,
+                GoalType.MAXIMIZE, LAMBDA, false, 0, 1.0-1e-13,
+                2e-10, 5e-6, 100000, expected);
+        boundaries = boundaries(DIM,-0.3,0.3); 
+        startPoint = point(DIM,0.1);
+        doTest(new MinusElli(), startPoint, insigma, boundaries,
+                GoalType.MAXIMIZE, LAMBDA, true, 0, 1.0-1e-13,
+                2e-10, 5e-6, 100000, expected);
+    }
+
+    @Test
+    public void testEllipse() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Elli(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+        doTest(new Elli(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test
+    public void testElliRotated() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new ElliRotated(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+        doTest(new ElliRotated(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test
+    public void testCigar() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Cigar(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 200000, expected);
+        doTest(new Cigar(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test
+    public void testCigarWithBoundaries() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = boundaries(DIM, -1e100, Double.POSITIVE_INFINITY);
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Cigar(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 200000, expected);
+        doTest(new Cigar(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test
+    public void testTwoAxes() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new TwoAxes(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, 2*LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 200000, expected);
+        doTest(new TwoAxes(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, 2*LAMBDA, false, 0, 1e-13,
+                1e-8, 1e-3, 200000, expected);
+    }
+
+    @Test
+    public void testCigTab() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.3);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new CigTab(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 5e-5, 100000, expected);
+        doTest(new CigTab(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
+                1e-13, 5e-5, 100000, expected);
+    }
+
+    @Test
+    public void testSphere() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Sphere(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+        doTest(new Sphere(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test
+    public void testTablet() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Tablet(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+        doTest(new Tablet(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, false, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test
+    public void testDiffPow() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new DiffPow(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, 10, true, 0, 1e-13,
+                1e-8, 1e-1, 100000, expected);
+        doTest(new DiffPow(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, 10, false, 0, 1e-13,
+                1e-8, 2e-1, 100000, expected);
+    }
+
+    @Test
+    public void testSsDiffPow() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new SsDiffPow(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, 10, true, 0, 1e-13,
+                1e-4, 1e-1, 200000, expected);
+        doTest(new SsDiffPow(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, 10, false, 0, 1e-13,
+                1e-4, 1e-1, 200000, expected);
+    }
+
+    @Test
+    public void testAckley() {
+        double[] startPoint = point(DIM,1.0);
+        double[] insigma = point(DIM,1.0);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Ackley(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, 2*LAMBDA, true, 0, 1e-13,
+                1e-9, 1e-5, 100000, expected);
+        doTest(new Ackley(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, 2*LAMBDA, false, 0, 1e-13,
+                1e-9, 1e-5, 100000, expected);
+    }
+
+    @Test
+    public void testRastrigin() {
+        double[] startPoint = point(DIM,0.1);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,0.0),0.0);
+        doTest(new Rastrigin(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, (int)(200*Math.sqrt(DIM)), true, 0, 1e-13,
+                1e-13, 1e-6, 200000, expected);
+        doTest(new Rastrigin(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, (int)(200*Math.sqrt(DIM)), false, 0, 1e-13,
+                1e-13, 1e-6, 200000, expected);
+    }
+
+    @Test
+    public void testConstrainedRosen() {
+        double[] startPoint = point(DIM, 0.1);
+        double[] insigma = point(DIM, 0.1);
+        double[][] boundaries = boundaries(DIM, -1, 2);
+        PointValuePair expected =
+            new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, 2*LAMBDA, true, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, 2*LAMBDA, false, 0, 1e-13,
+                1e-13, 1e-6, 100000, expected);
+    }
+
+    @Test
+    public void testDiagonalRosen() {
+        double[] startPoint = point(DIM,0.1);
+        double[] insigma = point(DIM,0.1);
+        double[][] boundaries = null;
+        PointValuePair expected =
+            new PointValuePair(point(DIM,1.0),0.0);
+        doTest(new Rosen(), startPoint, insigma, boundaries,
+                GoalType.MINIMIZE, LAMBDA, false, 1, 1e-13,
+                1e-10, 1e-4, 1000000, expected);
+     }
+
+    @Test
+    public void testMath864() {
+        final CMAESOptimizer optimizer
+            = new CMAESOptimizer(30000, 0, true, 10,
+                                 0, new MersenneTwister(), false, null);
+        final MultivariateFunction fitnessFunction = new MultivariateFunction() {
+                public double value(double[] parameters) {
+                    final double target = 1;
+                    final double error = target - parameters[0];
+                    return error * error;
+                }
+            };
+
+        final double[] start = { 0 };
+        final double[] lower = { -1e6 };
+        final double[] upper = { 1.5 };
+        final double[] sigma = { 1e-1 };
+        final double[] result = optimizer.optimize(new MaxEval(10000),
+                                                   new ObjectiveFunction(fitnessFunction),
+                                                   GoalType.MINIMIZE,
+                                                   new CMAESOptimizer.PopulationSize(5),
+                                                   new CMAESOptimizer.Sigma(sigma),
+                                                   new InitialGuess(start),
+                                                   new SimpleBounds(lower, upper)).getPoint();
+        Assert.assertTrue("Out of bounds (" + result[0] + " > " + upper[0] + ")",
+                          result[0] <= upper[0]);
+    }
+
+    /**
+     * Cf. MATH-867
+     */
+    @Test
+    public void testFitAccuracyDependsOnBoundary() {
+        final CMAESOptimizer optimizer
+            = new CMAESOptimizer(30000, 0, true, 10,
+                                 0, new MersenneTwister(), false, null);
+        final MultivariateFunction fitnessFunction = new MultivariateFunction() {
+                public double value(double[] parameters) {
+                    final double target = 11.1;
+                    final double error = target - parameters[0];
+                    return error * error;
+                }
+            };
+
+        final double[] start = { 1 };
+ 
+        // No bounds.
+        PointValuePair result = optimizer.optimize(new MaxEval(100000),
+                                                   new ObjectiveFunction(fitnessFunction),
+                                                   GoalType.MINIMIZE,
+                                                   SimpleBounds.unbounded(1),
+                                                   new CMAESOptimizer.PopulationSize(5),
+                                                   new CMAESOptimizer.Sigma(new double[] { 1e-1 }),
+                                                   new InitialGuess(start));
+        final double resNoBound = result.getPoint()[0];
+
+        // Optimum is near the lower bound.
+        final double[] lower = { -20 };
+        final double[] upper = { 5e16 };
+        final double[] sigma = { 10 };
+        result = optimizer.optimize(new MaxEval(100000),
+                                    new ObjectiveFunction(fitnessFunction),
+                                    GoalType.MINIMIZE,
+                                    new CMAESOptimizer.PopulationSize(5),
+                                    new CMAESOptimizer.Sigma(sigma),
+                                    new InitialGuess(start),
+                                    new SimpleBounds(lower, upper));
+        final double resNearLo = result.getPoint()[0];
+
+        // Optimum is near the upper bound.
+        lower[0] = -5e16;
+        upper[0] = 20;
+        result = optimizer.optimize(new MaxEval(100000),
+                                    new ObjectiveFunction(fitnessFunction),
+                                    GoalType.MINIMIZE,
+                                    new CMAESOptimizer.PopulationSize(5),
+                                    new CMAESOptimizer.Sigma(sigma),
+                                    new InitialGuess(start),
+                                    new SimpleBounds(lower, upper));
+        final double resNearHi = result.getPoint()[0];
+
+        // System.out.println("resNoBound=" + resNoBound +
+        //                    " resNearLo=" + resNearLo +
+        //                    " resNearHi=" + resNearHi);
+
+        // The two values currently differ by a substantial amount, indicating that
+        // the bounds definition can prevent reaching the optimum.
+        Assert.assertEquals(resNoBound, resNearLo, 1e-3);
+        Assert.assertEquals(resNoBound, resNearHi, 1e-3);
+    }
+ 
+    /**
+     * @param func Function to optimize.
+     * @param startPoint Starting point.
+     * @param inSigma Individual input sigma.
+     * @param boundaries Upper / lower point limit.
+     * @param goal Minimization or maximization.
+     * @param lambda Population size used for offspring.
+     * @param isActive Covariance update mechanism.
+     * @param diagonalOnly Simplified covariance update.
+     * @param stopValue Termination criteria for optimization.
+     * @param fTol Tolerance relative error on the objective function.
+     * @param pointTol Tolerance for checking that the optimum is correct.
+     * @param maxEvaluations Maximum number of evaluations.
+     * @param expected Expected point / value.
+     */
+    private void doTest(MultivariateFunction func,
+                        double[] startPoint,
+                        double[] inSigma,
+                        double[][] boundaries,
+                        GoalType goal,
+                        int lambda,
+                        boolean isActive,
+                        int diagonalOnly, 
+                        double stopValue,
+                        double fTol,
+                        double pointTol,
+                        int maxEvaluations,
+                        PointValuePair expected) {
+        int dim = startPoint.length;
+        // test diagonalOnly = 0 - slow but normally fewer feval#
+        CMAESOptimizer optim = new CMAESOptimizer(30000, stopValue, isActive, diagonalOnly,
+                                                  0, new MersenneTwister(), false, null);
+        PointValuePair result = boundaries == null ?
+            optim.optimize(new MaxEval(maxEvaluations),
+                           new ObjectiveFunction(func),
+                           goal,
+                           new InitialGuess(startPoint),
+                           SimpleBounds.unbounded(dim),
+                           new CMAESOptimizer.Sigma(inSigma),
+                           new CMAESOptimizer.PopulationSize(lambda)) :
+            optim.optimize(new MaxEval(maxEvaluations),
+                           new ObjectiveFunction(func),
+                           goal,
+                           new SimpleBounds(boundaries[0],
+                                            boundaries[1]),
+                           new InitialGuess(startPoint),
+                           new CMAESOptimizer.Sigma(inSigma),
+                           new CMAESOptimizer.PopulationSize(lambda));
+
+        // System.out.println("sol=" + Arrays.toString(result.getPoint()));
+        Assert.assertEquals(expected.getValue(), result.getValue(), fTol);
+        for (int i = 0; i < dim; i++) {
+            Assert.assertEquals(expected.getPoint()[i], result.getPoint()[i], pointTol);
+        }
+    }
+
+    private static double[] point(int n, double value) {
+        double[] ds = new double[n];
+        Arrays.fill(ds, value);
+        return ds;
+    }
+
+    private static double[][] boundaries(int dim,
+            double lower, double upper) {
+        double[][] boundaries = new double[2][dim];
+        for (int i = 0; i < dim; i++)
+            boundaries[0][i] = lower;
+        for (int i = 0; i < dim; i++)
+            boundaries[1][i] = upper;
+        return boundaries;
+    }
+
+    private static class Sphere implements MultivariateFunction {
+
+        public double value(double[] x) {
+            double f = 0;
+            for (int i = 0; i < x.length; ++i)
+                f += x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class Cigar implements MultivariateFunction {
+        private double factor;
+
+        Cigar() {
+            this(1e3);
+        }
+
+        Cigar(double axisratio) {
+            factor = axisratio * axisratio;
+        }
+
+        public double value(double[] x) {
+            double f = x[0] * x[0];
+            for (int i = 1; i < x.length; ++i)
+                f += factor * x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class Tablet implements MultivariateFunction {
+        private double factor;
+
+        Tablet() {
+            this(1e3);
+        }
+
+        Tablet(double axisratio) {
+            factor = axisratio * axisratio;
+        }
+
+        public double value(double[] x) {
+            double f = factor * x[0] * x[0];
+            for (int i = 1; i < x.length; ++i)
+                f += x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class CigTab implements MultivariateFunction {
+        private double factor;
+
+        CigTab() {
+            this(1e4);
+        }
+
+        CigTab(double axisratio) {
+            factor = axisratio;
+        }
+
+        public double value(double[] x) {
+            int end = x.length - 1;
+            double f = x[0] * x[0] / factor + factor * x[end] * x[end];
+            for (int i = 1; i < end; ++i)
+                f += x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class TwoAxes implements MultivariateFunction {
+
+        private double factor;
+
+        TwoAxes() {
+            this(1e6);
+        }
+
+        TwoAxes(double axisratio) {
+            factor = axisratio * axisratio;
+        }
+
+        public double value(double[] x) {
+            double f = 0;
+            for (int i = 0; i < x.length; ++i)
+                f += (i < x.length / 2 ? factor : 1) * x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class ElliRotated implements MultivariateFunction {
+        private Basis B = new Basis();
+        private double factor;
+
+        ElliRotated() {
+            this(1e3);
+        }
+
+        ElliRotated(double axisratio) {
+            factor = axisratio * axisratio;
+        }
+
+        public double value(double[] x) {
+            double f = 0;
+            x = B.Rotate(x);
+            for (int i = 0; i < x.length; ++i)
+                f += Math.pow(factor, i / (x.length - 1.)) * x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class Elli implements MultivariateFunction {
+
+        private double factor;
+
+        Elli() {
+            this(1e3);
+        }
+
+        Elli(double axisratio) {
+            factor = axisratio * axisratio;
+        }
+
+        public double value(double[] x) {
+            double f = 0;
+            for (int i = 0; i < x.length; ++i)
+                f += Math.pow(factor, i / (x.length - 1.)) * x[i] * x[i];
+            return f;
+        }
+    }
+
+    private static class MinusElli implements MultivariateFunction {
+
+        public double value(double[] x) {
+            return 1.0-(new Elli().value(x));
+        }
+    }
+
+    private static class DiffPow implements MultivariateFunction {
+
+        public double value(double[] x) {
+            double f = 0;
+            for (int i = 0; i < x.length; ++i)
+                f += Math.pow(Math.abs(x[i]), 2. + 10 * (double) i
+                        / (x.length - 1.));
+            return f;
+        }
+    }
+
+    private static class SsDiffPow implements MultivariateFunction {
+
+        public double value(double[] x) {
+            double f = Math.pow(new DiffPow().value(x), 0.25);
+            return f;
+        }
+    }
+
+    private static class Rosen implements MultivariateFunction {
+
+        public double value(double[] x) {
+            double f = 0;
+            for (int i = 0; i < x.length - 1; ++i)
+                f += 1e2 * (x[i] * x[i] - x[i + 1]) * (x[i] * x[i] - x[i + 1])
+                + (x[i] - 1.) * (x[i] - 1.);
+            return f;
+        }
+    }
+
+    private static class Ackley implements MultivariateFunction {
+        private double axisratio;
+
+        Ackley(double axra) {
+            axisratio = axra;
+        }
+
+        public Ackley() {
+            this(1);
+        }
+
+        public double value(double[] x) {
+            double f = 0;
+            double res2 = 0;
+            double fac = 0;
+            for (int i = 0; i < x.length; ++i) {
+                fac = Math.pow(axisratio, (i - 1.) / (x.length - 1.));
+                f += fac * fac * x[i] * x[i];
+                res2 += Math.cos(2. * Math.PI * fac * x[i]);
+            }
+            f = (20. - 20. * Math.exp(-0.2 * Math.sqrt(f / x.length))
+                    + Math.exp(1.) - Math.exp(res2 / x.length));
+            return f;
+        }
+    }
+
+    private static class Rastrigin implements MultivariateFunction {
+
+        private double axisratio;
+        private double amplitude;
+
+        Rastrigin() {
+            this(1, 10);
+        }
+
+        Rastrigin(double axisratio, double amplitude) {
+            this.axisratio = axisratio;
+            this.amplitude = amplitude;
+        }
+
+        public double value(double[] x) {
+            double f = 0;
+            double fac;
+            for (int i = 0; i < x.length; ++i) {
+                fac = Math.pow(axisratio, (i - 1.) / (x.length - 1.));
+                if (i == 0 && x[i] < 0)
+                    fac *= 1.;
+                f += fac * fac * x[i] * x[i] + amplitude
+                * (1. - Math.cos(2. * Math.PI * fac * x[i]));
+            }
+            return f;
+        }
+    }
+
+    private static class Basis {
+        double[][] basis;
+        Random rand = new Random(2); // use not always the same basis
+
+        double[] Rotate(double[] x) {
+            GenBasis(x.length);
+            double[] y = new double[x.length];
+            for (int i = 0; i < x.length; ++i) {
+                y[i] = 0;
+                for (int j = 0; j < x.length; ++j)
+                    y[i] += basis[i][j] * x[j];
+            }
+            return y;
+        }
+
+        void GenBasis(int DIM) {
+            if (basis != null ? basis.length == DIM : false)
+                return;
+
+            double sp;
+            int i, j, k;
+
+            /* generate orthogonal basis */
+            basis = new double[DIM][DIM];
+            for (i = 0; i < DIM; ++i) {
+                /* sample components gaussian */
+                for (j = 0; j < DIM; ++j)
+                    basis[i][j] = rand.nextGaussian();
+                /* substract projection of previous vectors */
+                for (j = i - 1; j >= 0; --j) {
+                    for (sp = 0., k = 0; k < DIM; ++k)
+                        sp += basis[i][k] * basis[j][k]; /* scalar product */
+                    for (k = 0; k < DIM; ++k)
+                        basis[i][k] -= sp * basis[j][k]; /* substract */
+                }
+                /* normalize */
+                for (sp = 0., k = 0; k < DIM; ++k)
+                    sp += basis[i][k] * basis[i][k]; /* squared norm */
+                for (k = 0; k < DIM; ++k)
+                    basis[i][k] /= Math.sqrt(sp);
+            }
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/CMAESOptimizerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/PowellOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/PowellOptimizerTest.java?rev=1420684&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/PowellOptimizerTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/PowellOptimizerTest.java Wed Dec 12 14:10:38 2012
@@ -0,0 +1,251 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.optim.nonlinear.scalar.noderiv;
+
+import org.apache.commons.math3.analysis.MultivariateFunction;
+import org.apache.commons.math3.analysis.SumSincFunction;
+import org.apache.commons.math3.optim.GoalType;
+import org.apache.commons.math3.optim.PointValuePair;
+import org.apache.commons.math3.optim.InitialGuess;
+import org.apache.commons.math3.optim.MaxEval;
+import org.apache.commons.math3.optim.ObjectiveFunction;
+import org.apache.commons.math3.util.FastMath;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for {@link PowellOptimizer}.
+ */
+public class PowellOptimizerTest {
+
+    @Test
+    public void testSumSinc() {
+        final MultivariateFunction func = new SumSincFunction(-1);
+
+        int dim = 2;
+        final double[] minPoint = new double[dim];
+        for (int i = 0; i < dim; i++) {
+            minPoint[i] = 0;
+        }
+
+        double[] init = new double[dim];
+
+        // Initial is minimum.
+        for (int i = 0; i < dim; i++) {
+            init[i] = minPoint[i];
+        }
+        doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-9, 1e-9);
+
+        // Initial is far from minimum.
+        for (int i = 0; i < dim; i++) {
+            init[i] = minPoint[i] + 3;
+        }
+        doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-9, 1e-5);
+        // More stringent line search tolerance enhances the precision
+        // of the result.
+        doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-9, 1e-9, 1e-7);
+    }
+
+    @Test
+    public void testQuadratic() {
+        final MultivariateFunction func = new MultivariateFunction() {
+                public double value(double[] x) {
+                    final double a = x[0] - 1;
+                    final double b = x[1] - 1;
+                    return a * a + b * b + 1;
+                }
+            };
+
+        int dim = 2;
+        final double[] minPoint = new double[dim];
+        for (int i = 0; i < dim; i++) {
+            minPoint[i] = 1;
+        }
+
+        double[] init = new double[dim];
+
+        // Initial is minimum.
+        for (int i = 0; i < dim; i++) {
+            init[i] = minPoint[i];
+        }
+        doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-9, 1e-8);
+
+        // Initial is far from minimum.
+        for (int i = 0; i < dim; i++) {
+            init[i] = minPoint[i] - 20;
+        }
+        doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-9, 1e-8);
+    }
+
+    @Test
+    public void testMaximizeQuadratic() {
+        final MultivariateFunction func = new MultivariateFunction() {
+                public double value(double[] x) {
+                    final double a = x[0] - 1;
+                    final double b = x[1] - 1;
+                    return -a * a - b * b + 1;
+                }
+            };
+
+        int dim = 2;
+        final double[] maxPoint = new double[dim];
+        for (int i = 0; i < dim; i++) {
+            maxPoint[i] = 1;
+        }
+
+        double[] init = new double[dim];
+
+        // Initial is minimum.
+        for (int i = 0; i < dim; i++) {
+            init[i] = maxPoint[i];
+        }
+        doTest(func, maxPoint, init,  GoalType.MAXIMIZE, 1e-9, 1e-8);
+
+        // Initial is far from minimum.
+        for (int i = 0; i < dim; i++) {
+            init[i] = maxPoint[i] - 20;
+        }
+        doTest(func, maxPoint, init, GoalType.MAXIMIZE, 1e-9, 1e-8);
+    }
+
+    /**
+     * Ensure that we do not increase the number of function evaluations when
+     * the function values are scaled up.
+     * Note that the tolerances parameters passed to the constructor must
+     * still hold sensible values because they are used to set the line search
+     * tolerances.
+     */
+    @Test
+    public void testRelativeToleranceOnScaledValues() {
+        final MultivariateFunction func = new MultivariateFunction() {
+                public double value(double[] x) {
+                    final double a = x[0] - 1;
+                    final double b = x[1] - 1;
+                    return a * a * FastMath.sqrt(FastMath.abs(a)) + b * b + 1;
+                }
+            };
+
+        int dim = 2;
+        final double[] minPoint = new double[dim];
+        for (int i = 0; i < dim; i++) {
+            minPoint[i] = 1;
+        }
+
+        double[] init = new double[dim];
+        // Initial is far from minimum.
+        for (int i = 0; i < dim; i++) {
+            init[i] = minPoint[i] - 20;
+        }
+
+        final double relTol = 1e-10;
+
+        final int maxEval = 1000;
+        // Very small absolute tolerance to rely solely on the relative
+        // tolerance as a stopping criterion
+        final PowellOptimizer optim = new PowellOptimizer(relTol, 1e-100);
+
+        final PointValuePair funcResult = optim.optimize(new MaxEval(maxEval),
+                                                         new ObjectiveFunction(func),
+                                                         GoalType.MINIMIZE,
+                                                         new InitialGuess(init));
+        final double funcValue = func.value(funcResult.getPoint());
+        final int funcEvaluations = optim.getEvaluations();
+
+        final double scale = 1e10;
+        final MultivariateFunction funcScaled = new MultivariateFunction() {
+                public double value(double[] x) {
+                    return scale * func.value(x);
+                }
+            };
+
+        final PointValuePair funcScaledResult = optim.optimize(new MaxEval(maxEval),
+                                                               new ObjectiveFunction(funcScaled),
+                                                               GoalType.MINIMIZE,
+                                                               new InitialGuess(init));
+        final double funcScaledValue = funcScaled.value(funcScaledResult.getPoint());
+        final int funcScaledEvaluations = optim.getEvaluations();
+
+        // Check that both minima provide the same objective funciton values,
+        // within the relative function tolerance.
+        Assert.assertEquals(1, funcScaledValue / (scale * funcValue), relTol);
+
+        // Check that the numbers of evaluations are the same.
+        Assert.assertEquals(funcEvaluations, funcScaledEvaluations);
+    }
+
+    /**
+     * @param func Function to optimize.
+     * @param optimum Expected optimum.
+     * @param init Starting point.
+     * @param goal Minimization or maximization.
+     * @param fTol Tolerance (relative error on the objective function) for
+     * "Powell" algorithm.
+     * @param pointTol Tolerance for checking that the optimum is correct.
+     */
+    private void doTest(MultivariateFunction func,
+                        double[] optimum,
+                        double[] init,
+                        GoalType goal,
+                        double fTol,
+                        double pointTol) {
+        final PowellOptimizer optim = new PowellOptimizer(fTol, Math.ulp(1d));
+
+        final PointValuePair result = optim.optimize(new MaxEval(1000),
+                                                     new ObjectiveFunction(func),
+                                                     goal,
+                                                     new InitialGuess(init));
+        final double[] point = result.getPoint();
+
+        for (int i = 0, dim = optimum.length; i < dim; i++) {
+            Assert.assertEquals("found[" + i + "]=" + point[i] + " value=" + result.getValue(),
+                                optimum[i], point[i], pointTol);
+        }
+    }
+
+    /**
+     * @param func Function to optimize.
+     * @param optimum Expected optimum.
+     * @param init Starting point.
+     * @param goal Minimization or maximization.
+     * @param fTol Tolerance (relative error on the objective function) for
+     * "Powell" algorithm.
+     * @param fLineTol Tolerance (relative error on the objective function)
+     * for the internal line search algorithm.
+     * @param pointTol Tolerance for checking that the optimum is correct.
+     */
+    private void doTest(MultivariateFunction func,
+                        double[] optimum,
+                        double[] init,
+                        GoalType goal,
+                        double fTol,
+                        double fLineTol,
+                        double pointTol) {
+        final PowellOptimizer optim = new PowellOptimizer(fTol, Math.ulp(1d),
+                                                          fLineTol, Math.ulp(1d));
+
+        final PointValuePair result = optim.optimize(new MaxEval(1000),
+                                                     new ObjectiveFunction(func),
+                                                     goal,
+                                                     new InitialGuess(init));
+        final double[] point = result.getPoint();
+
+        for (int i = 0, dim = optimum.length; i < dim; i++) {
+            Assert.assertEquals("found[" + i + "]=" + point[i] + " value=" + result.getValue(),
+                                optimum[i], point[i], pointTol);
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optim/nonlinear/scalar/noderiv/PowellOptimizerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message