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/10/19 16:20:16 UTC
svn commit: r1400108 - in /commons/proper/math/trunk/src:
main/java/org/apache/commons/math3/optimization/direct/CMAESOptimizer.java
test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java
Author: erans
Date: Fri Oct 19 14:20:16 2012
New Revision: 1400108
URL: http://svn.apache.org/viewvc?rev=1400108&view=rev
Log:
MATH-868
MATH-879
"lambda" and "inputSigma" should be passed to "optimize" as arguments of
type "OptimizationData". Deprecated constructors. Updated unit tests.
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/CMAESOptimizer.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/CMAESOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/CMAESOptimizer.java?rev=1400108&r1=1400107&r2=1400108&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/CMAESOptimizer.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/optimization/direct/CMAESOptimizer.java Fri Oct 19 14:20:16 2012
@@ -24,6 +24,7 @@ import java.util.List;
import org.apache.commons.math3.analysis.MultivariateFunction;
import org.apache.commons.math3.exception.DimensionMismatchException;
import org.apache.commons.math3.exception.NotPositiveException;
+import org.apache.commons.math3.exception.NotStrictlyPositiveException;
import org.apache.commons.math3.exception.OutOfRangeException;
import org.apache.commons.math3.exception.TooManyEvaluationsException;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
@@ -225,6 +226,10 @@ public class CMAESOptimizer
/**
* Default constructor, uses default parameters
+ *
+ * @deprecated As of version 3.1: Parameter {@code lambda} must be
+ * passed with the call to {@link #optimize(int,MultivariateFunction,GoalType,OptimizationData[])
+ * optimize} (whereas in the current code it is set to an undocumented value).
*/
public CMAESOptimizer() {
this(0);
@@ -232,9 +237,12 @@ public class CMAESOptimizer
/**
* @param lambda Population size.
+ * @deprecated As of version 3.1: Parameter {@code lambda} must be
+ * passed with the call to {@link #optimize(int,MultivariateFunction,GoalType,OptimizationData[])
+ * optimize} (whereas in the current code it is set to an undocumented value)..
*/
public CMAESOptimizer(int lambda) {
- this(lambda, DEFAULT_MAXITERATIONS, DEFAULT_STOPFITNESS,
+ this(lambda, null, DEFAULT_MAXITERATIONS, DEFAULT_STOPFITNESS,
DEFAULT_ISACTIVECMA, DEFAULT_DIAGONALONLY,
DEFAULT_CHECKFEASABLECOUNT, DEFAULT_RANDOMGENERATOR,
false, null);
@@ -244,7 +252,7 @@ public class CMAESOptimizer
* @param lambda Population size.
* @param inputSigma Initial standard deviations to sample new points
* around the initial guess.
- * @deprecated As of version 3.1: Parameter {@code inputSigma} must be
+ * @deprecated As of version 3.1: Parameters {@code lambda} and {@code inputSigma} must be
* passed with the call to {@link #optimize(int,MultivariateFunction,GoalType,OptimizationData[])
* optimize}.
*/
@@ -296,7 +304,7 @@ public class CMAESOptimizer
* @param random Random generator.
* @param generateStatistics Whether statistic data is collected.
* @param checker Convergence checker.
- * @deprecated As of version 3.1: Parameter {@code inputSigma} must be
+ * @deprecated As of version 3.1: Parameters {@code lambda} and {@code inputSigma} must be
* passed with the call to {@link #optimize(int,MultivariateFunction,GoalType,OptimizationData[])
* optimize}.
*/
@@ -319,7 +327,6 @@ public class CMAESOptimizer
}
/**
- * @param lambda Population size.
* @param maxIterations Maximal number of iterations.
* @param stopFitness Whether to stop if objective function value is smaller than
* {@code stopFitness}.
@@ -331,9 +338,10 @@ public class CMAESOptimizer
* @param random Random generator.
* @param generateStatistics Whether statistic data is collected.
* @param checker Convergence checker.
+ *
+ * @since 3.1
*/
- public CMAESOptimizer(int lambda,
- int maxIterations,
+ public CMAESOptimizer(int maxIterations,
double stopFitness,
boolean isActiveCMA,
int diagonalOnly,
@@ -342,7 +350,6 @@ public class CMAESOptimizer
boolean generateStatistics,
ConvergenceChecker<PointValuePair> checker) {
super(checker);
- this.lambda = lambda;
this.maxIterations = maxIterations;
this.stopFitness = stopFitness;
this.isActiveCMA = isActiveCMA;
@@ -397,8 +404,17 @@ public class CMAESOptimizer
/**
* @param s Sigma values.
+ * @throws NotPositiveException if any of the array entries is smaller
+ * than zero.
*/
- public Sigma(double[] s) {
+ public Sigma(double[] s)
+ throws NotPositiveException {
+ for (int i = 0; i < s.length; i++) {
+ if (s[i] < 0) {
+ throw new NotPositiveException(s[i]);
+ }
+ }
+
sigma = s.clone();
}
@@ -411,6 +427,40 @@ public class CMAESOptimizer
}
/**
+ * Population size.
+ * The number of offspring is the primary strategy parameter.
+ * In the absence of better clues, a good default could be an
+ * integer close to {@code 4 + 3 ln(n)}, where {@code n} is the
+ * number of optimized parameters.
+ * Increasing the population size improves global search properties
+ * at the expense of speed (which in general decreases at most
+ * linearly with increasing population size).
+ */
+ public static class PopulationSize implements OptimizationData {
+ /** Population size. */
+ private final int lambda;
+
+ /**
+ * @param size Population size.
+ * @throws NotStrictlyPositiveException if {@code size <= 0}.
+ */
+ public PopulationSize(int size)
+ throws NotStrictlyPositiveException {
+ if (size <= 0) {
+ throw new NotStrictlyPositiveException(size);
+ }
+ lambda = size;
+ }
+
+ /**
+ * @return the population size.
+ */
+ public int getPopulationSize() {
+ return lambda;
+ }
+ }
+
+ /**
* Optimize an objective function.
*
* @param maxEval Allowed number of evaluations of the objective function.
@@ -420,6 +470,7 @@ public class CMAESOptimizer
* <ul>
* <li>{@link org.apache.commons.math3.optimization.InitialGuess InitialGuess}</li>
* <li>{@link Sigma}</li>
+ * <li>{@link PopulationSize}</li>
* </ul>
* @return the point/value pair giving the optimal value for objective
* function.
@@ -593,6 +644,7 @@ public class CMAESOptimizer
* @param optData Optimization data. The following data will be looked for:
* <ul>
* <li>{@link Sigma}</li>
+ * <li>{@link PopulationSize}</li>
* </ul>
*/
private void parseOptimizationData(OptimizationData... optData) {
@@ -603,6 +655,10 @@ public class CMAESOptimizer
inputSigma = ((Sigma) data).getSigma();
continue;
}
+ if (data instanceof PopulationSize) {
+ lambda = ((PopulationSize) data).getPopulationSize();
+ continue;
+ }
}
}
@@ -620,6 +676,7 @@ public class CMAESOptimizer
}
for (int i = 0; i < init.length; i++) {
if (inputSigma[i] < 0) {
+ // XXX Remove this block in 4.0 (check performed in "Sigma" class).
throw new NotPositiveException(inputSigma[i]);
}
if (inputSigma[i] > uB[i] - lB[i]) {
@@ -636,11 +693,15 @@ public class CMAESOptimizer
*/
private void initializeCMA(double[] guess) {
if (lambda <= 0) {
+ // XXX Line below to replace the current one in 4.0 (MATH-879).
+ // throw new NotStrictlyPositiveException(lambda);
lambda = 4 + (int) (3 * Math.log(dimension));
}
// initialize sigma
final double[][] sigmaArray = new double[guess.length][1];
for (int i = 0; i < guess.length; i++) {
+ // XXX Line below to replace the current one in 4.0 (MATH-868).
+ // sigmaArray[i][0] = inputSigma[i];
sigmaArray[i][0] = inputSigma == null ? 0.3 : inputSigma[i];
}
final RealMatrix insigma = new Array2DRowRealMatrix(sigmaArray, false);
Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java?rev=1400108&r1=1400107&r2=1400108&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/optimization/direct/CMAESOptimizerTest.java Fri Oct 19 14:20:16 2012
@@ -52,7 +52,7 @@ public class CMAESOptimizerTest {
@Test(expected = NumberIsTooLargeException.class)
public void testInitOutofbounds1() {
double[] startPoint = point(DIM,3);
- double[] insigma = null;
+ double[] insigma = point(DIM, 0.3);
double[][] boundaries = boundaries(DIM,-1,2);
PointValuePair expected =
new PointValuePair(point(DIM,1.0),0.0);
@@ -63,7 +63,7 @@ public class CMAESOptimizerTest {
@Test(expected = NumberIsTooSmallException.class)
public void testInitOutofbounds2() {
double[] startPoint = point(DIM, -2);
- double[] insigma = null;
+ double[] insigma = point(DIM, 0.3);
double[][] boundaries = boundaries(DIM,-1,2);
PointValuePair expected =
new PointValuePair(point(DIM,1.0),0.0);
@@ -75,7 +75,7 @@ public class CMAESOptimizerTest {
@Test(expected = DimensionMismatchException.class)
public void testBoundariesDimensionMismatch() {
double[] startPoint = point(DIM,0.5);
- double[] insigma = null;
+ double[] insigma = point(DIM, 0.3);
double[][] boundaries = boundaries(DIM+1,-1,2);
PointValuePair expected =
new PointValuePair(point(DIM,1.0),0.0);
@@ -111,7 +111,7 @@ public class CMAESOptimizerTest {
@Test(expected = DimensionMismatchException.class)
public void testInputSigmaDimensionMismatch() {
double[] startPoint = point(DIM,0.5);
- double[] insigma = point(DIM+1,-0.5);
+ double[] insigma = point(DIM + 1, 0.5);
double[][] boundaries = null;
PointValuePair expected =
new PointValuePair(point(DIM,1.0),0.0);
@@ -459,17 +459,20 @@ public class CMAESOptimizerTest {
PointValuePair expected) {
int dim = startPoint.length;
// test diagonalOnly = 0 - slow but normally fewer feval#
- CMAESOptimizer optim = new CMAESOptimizer(lambda, inSigma, 30000,
- stopValue, isActive, diagonalOnly,
- 0, new MersenneTwister(), false);
+ CMAESOptimizer optim = new CMAESOptimizer(30000, stopValue, isActive, diagonalOnly,
+ 0, new MersenneTwister(), false, null);
final double[] lB = boundaries == null ? null : boundaries[0];
final double[] uB = boundaries == null ? null : boundaries[1];
PointValuePair result = boundaries == null ?
optim.optimize(maxEvaluations, func, goal,
- new InitialGuess(startPoint)) :
+ new InitialGuess(startPoint),
+ new CMAESOptimizer.Sigma(inSigma),
+ new CMAESOptimizer.PopulationSize(lambda)) :
optim.optimize(maxEvaluations, func, goal,
new InitialGuess(startPoint),
- new SimpleBounds(lB, uB));
+ new SimpleBounds(lB, uB),
+ 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++) {