You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2012/12/12 15:11:04 UTC
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...
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