You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2009/05/27 20:54:49 UTC
svn commit: r779273 - in /commons/proper/math/trunk/src:
java/org/apache/commons/math/ java/org/apache/commons/math/optimization/
java/org/apache/commons/math/optimization/direct/ site/xdoc/
test/org/apache/commons/math/optimization/direct/
Author: luc
Date: Wed May 27 18:54:48 2009
New Revision: 779273
URL: http://svn.apache.org/viewvc?rev=779273&view=rev
Log:
Added a way to limit the number of functions evaluations in optimizers
(the number of iterations could already be limited)
Added:
commons/proper/math/trunk/src/java/org/apache/commons/math/MaxEvaluationsExceededException.java (with props)
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.java
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultivariateRealOptimizer.java
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.java
commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/direct/MultiDirectional.java
commons/proper/math/trunk/src/site/xdoc/changes.xml
commons/proper/math/trunk/src/test/org/apache/commons/math/optimization/direct/NelderMeadTest.java
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/MaxEvaluationsExceededException.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/MaxEvaluationsExceededException.java?rev=779273&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/MaxEvaluationsExceededException.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/MaxEvaluationsExceededException.java Wed May 27 18:54:48 2009
@@ -0,0 +1,67 @@
+/*
+ * 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.math;
+
+import org.apache.commons.math.ConvergenceException;
+
+/**
+ * Error thrown when a numerical computation exceeds its allowed
+ * number of functions evaluations.
+ *
+ * @version $Revision$ $Date$
+ * @since 2.0
+ */
+public class MaxEvaluationsExceededException extends ConvergenceException {
+
+ /** Serializable version identifier. */
+ private static final long serialVersionUID = -5921271447220129118L;
+
+ /** Maximal number of evaluations allowed. */
+ private final int maxEvaluations;
+
+ /**
+ * Constructs an exception with specified formatted detail message.
+ * Message formatting is delegated to {@link java.text.MessageFormat}.
+ * @param maxEvaluations maximal number of evaluations allowed
+ */
+ public MaxEvaluationsExceededException(final int maxEvaluations) {
+ super("Maximal number of evaluations ({0}) exceeded", maxEvaluations);
+ this.maxEvaluations = maxEvaluations;
+ }
+
+ /**
+ * Constructs an exception with specified formatted detail message.
+ * Message formatting is delegated to {@link java.text.MessageFormat}.
+ * @param maxEvaluations the exceeded maximal number of evaluations
+ * @param pattern format specifier
+ * @param arguments format arguments
+ */
+ public MaxEvaluationsExceededException(final int maxEvaluations,
+ final String pattern, final Object ... arguments) {
+ super(pattern, arguments);
+ this.maxEvaluations = maxEvaluations;
+ }
+
+ /** Get the maximal number of evaluations allowed.
+ * @return maximal number of evaluations allowed
+ */
+ public int getMaxEvaluations() {
+ return maxEvaluations;
+ }
+
+}
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/MaxEvaluationsExceededException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/MaxEvaluationsExceededException.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java?rev=779273&r1=779272&r2=779273&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java Wed May 27 18:54:48 2009
@@ -83,6 +83,10 @@
{ "Maximal number of iterations ({0}) exceeded",
"Nombre maximal d''it\u00e9rations ({0}) d\u00e9pass\u00e9" },
+ // org.apache.commons.math.MaxEvaluationsExceededException
+ { "Maximal number of evaluations ({0}) exceeded",
+ "Nombre maximal d''\u00e9valuations ({0}) d\u00e9pass\u00e9" },
+
// org.apache.commons.math.analysis.interpolation.SplineInterpolator
// org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm
// org.apache.commons.math.DimensionMismatchException
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.java?rev=779273&r1=779272&r2=779273&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.java Wed May 27 18:54:48 2009
@@ -51,6 +51,9 @@
/** Maximal number of iterations allowed. */
private int maxIterations;
+ /** Maximal number of evaluations allowed. */
+ private int maxEvaluations;
+
/** Number of iterations already performed for all starts. */
private int totalIterations;
@@ -130,6 +133,16 @@
}
/** {@inheritDoc} */
+ public void setMaxEvaluations(int maxEvaluations) {
+ this.maxEvaluations = maxEvaluations;
+ }
+
+ /** {@inheritDoc} */
+ public int getMaxEvaluations() {
+ return maxEvaluations;
+ }
+
+ /** {@inheritDoc} */
public int getIterations() {
return totalIterations;
}
@@ -164,6 +177,7 @@
try {
optimizer.setMaxIterations(maxIterations - totalIterations);
+ optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
optima[i] = optimizer.optimize(f, goalType,
(i == 0) ? startPoint : generator.nextVector());
} catch (FunctionEvaluationException fee) {
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultivariateRealOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultivariateRealOptimizer.java?rev=779273&r1=779272&r2=779273&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultivariateRealOptimizer.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/MultivariateRealOptimizer.java Wed May 27 18:54:48 2009
@@ -33,10 +33,15 @@
public interface MultivariateRealOptimizer {
/** Set the maximal number of iterations of the algorithm.
- * @param maxIterations maximal number of function calls
+ * @param maxIterations maximal number of algorithm iterations
*/
void setMaxIterations(int maxIterations);
+ /** Set the maximal number of evaluations of the algorithm.
+ * @param maxEvaluations maximal number of function calls
+ */
+ void setMaxEvaluations(int maxEvaluations);
+
/** Get the maximal number of iterations of the algorithm.
* @return maximal number of iterations
*/
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.java?rev=779273&r1=779272&r2=779273&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.java Wed May 27 18:54:48 2009
@@ -23,6 +23,7 @@
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxEvaluationsExceededException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.optimization.GoalType;
@@ -104,6 +105,9 @@
/** Maximal number of iterations allowed. */
private int maxIterations;
+ /** Maximal number of evaluations allowed. */
+ private int maxEvaluations;
+
/** Number of iterations already performed. */
private int iterations;
@@ -118,6 +122,7 @@
protected DirectSearchOptimizer() {
setConvergenceChecker(new SimpleScalarValueChecker());
setMaxIterations(Integer.MAX_VALUE);
+ setMaxEvaluations(Integer.MAX_VALUE);
}
/** Set start configuration for simplex.
@@ -222,6 +227,11 @@
}
/** {@inheritDoc} */
+ public void setMaxEvaluations(int maxEvaluations) {
+ this.maxEvaluations = maxEvaluations;
+ }
+
+ /** {@inheritDoc} */
public int getMaxIterations() {
return maxIterations;
}
@@ -329,10 +339,13 @@
* @return objective function value at the given point
* @exception FunctionEvaluationException if no value can be computed for the parameters
* @exception IllegalArgumentException if the start point dimension is wrong
+ * @exception OptimizationException if the maximal number of evaluations is exceeded
*/
protected double evaluate(final double[] x)
- throws FunctionEvaluationException, IllegalArgumentException {
- evaluations++;
+ throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+ if (++evaluations > maxEvaluations) {
+ throw new OptimizationException(new MaxEvaluationsExceededException(maxEvaluations));
+ }
return f.value(x);
}
@@ -370,9 +383,10 @@
/** Evaluate all the non-evaluated points of the simplex.
* @param comparator comparator to use to sort simplex vertices from best to worst
* @exception FunctionEvaluationException if no value can be computed for the parameters
+ * @exception OptimizationException if the maximal number of evaluations is exceeded
*/
protected void evaluateSimplex(final Comparator<RealPointValuePair> comparator)
- throws FunctionEvaluationException {
+ throws FunctionEvaluationException, OptimizationException {
// evaluate the objective function at all non-evaluated simplex points
for (int i = 0; i < simplex.length; ++i) {
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/direct/MultiDirectional.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/direct/MultiDirectional.java?rev=779273&r1=779272&r2=779273&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/direct/MultiDirectional.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/optimization/direct/MultiDirectional.java Wed May 27 18:54:48 2009
@@ -110,11 +110,12 @@
* @return best point in the transformed simplex
* @exception FunctionEvaluationException if the function cannot be evaluated at
* some point
+ * @exception OptimizationException if the maximal number of evaluations is exceeded
*/
private RealPointValuePair evaluateNewSimplex(final RealPointValuePair[] original,
final double coeff,
final Comparator<RealPointValuePair> comparator)
- throws FunctionEvaluationException {
+ throws FunctionEvaluationException, OptimizationException {
final double[] xSmallest = original[0].getPointRef();
final int n = xSmallest.length;
Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=779273&r1=779272&r2=779273&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Wed May 27 18:54:48 2009
@@ -39,10 +39,14 @@
</properties>
<body>
<release version="2.0" date="TBD" description="TBD">
- <action dev="psteitz" type="add" issue="MATH-267" due=to="Ted Dunning">
+ <action dev="luc" type="add" due-to="Gilles Sadowski">
+ Added a way to limit the number of functions evaluations in optimizers
+ (the number of iterations could already be limited)
+ </action>
+ <action dev="psteitz" type="add" issue="MATH-267" due-to="Ted Dunning">
Added digamma function.
</action>
- <action dev="psteitz" type="add" issue="MATH-136" due=to="John Gant">
+ <action dev="psteitz" type="add" issue="MATH-136" due-to="John Gant">
Added Spearman's rank correlation (SpearmansCorrelation).
</action>
<action dev="psteitz" type="add">
Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/optimization/direct/NelderMeadTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/optimization/direct/NelderMeadTest.java?rev=779273&r1=779272&r2=779273&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/optimization/direct/NelderMeadTest.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/optimization/direct/NelderMeadTest.java Wed May 27 18:54:48 2009
@@ -17,24 +17,27 @@
package org.apache.commons.math.optimization.direct;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MaxEvaluationsExceededException;
+import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.optimization.GoalType;
+import org.apache.commons.math.optimization.OptimizationException;
import org.apache.commons.math.optimization.RealPointValuePair;
import org.apache.commons.math.optimization.SimpleScalarValueChecker;
+import org.junit.Test;
-public class NelderMeadTest
- extends TestCase {
-
- public NelderMeadTest(String name) {
- super(name);
- }
+public class NelderMeadTest {
+ @Test
public void testFunctionEvaluationExceptions() {
MultivariateRealFunction wrong =
new MultivariateRealFunction() {
@@ -71,6 +74,7 @@
}
}
+ @Test
public void testMinimizeMaximize()
throws FunctionEvaluationException, ConvergenceException {
@@ -130,21 +134,11 @@
}
+ @Test
public void testRosenbrock()
throws FunctionEvaluationException, ConvergenceException {
- MultivariateRealFunction rosenbrock =
- new MultivariateRealFunction() {
- private static final long serialVersionUID = -9044950469615237490L;
- public double value(double[] x) throws FunctionEvaluationException {
- ++count;
- double a = x[1] - x[0] * x[0];
- double b = 1.0 - x[0];
- return 100 * a * a + b * b;
- }
- };
-
- count = 0;
+ Rosenbrock rosenbrock = new Rosenbrock();
NelderMead optimizer = new NelderMead();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1, 1.0e-3));
optimizer.setMaxIterations(100);
@@ -154,46 +148,104 @@
RealPointValuePair optimum =
optimizer.optimize(rosenbrock, GoalType.MINIMIZE, new double[] { -1.2, 1.0 });
- assertEquals(count, optimizer.getEvaluations());
+ assertEquals(rosenbrock.getCount(), optimizer.getEvaluations());
assertTrue(optimizer.getEvaluations() > 40);
assertTrue(optimizer.getEvaluations() < 50);
assertTrue(optimum.getValue() < 8.0e-4);
}
+ @Test
public void testPowell()
throws FunctionEvaluationException, ConvergenceException {
- MultivariateRealFunction powell =
- new MultivariateRealFunction() {
- private static final long serialVersionUID = -832162886102041840L;
- public double value(double[] x) throws FunctionEvaluationException {
- ++count;
- double a = x[0] + 10 * x[1];
- double b = x[2] - x[3];
- double c = x[1] - 2 * x[2];
- double d = x[0] - x[3];
- return a * a + 5 * b * b + c * c * c * c + 10 * d * d * d * d;
- }
- };
-
- count = 0;
+ Powell powell = new Powell();
NelderMead optimizer = new NelderMead();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-3));
optimizer.setMaxIterations(200);
RealPointValuePair optimum =
optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 });
- assertEquals(count, optimizer.getEvaluations());
+ assertEquals(powell.getCount(), optimizer.getEvaluations());
assertTrue(optimizer.getEvaluations() > 110);
assertTrue(optimizer.getEvaluations() < 130);
assertTrue(optimum.getValue() < 2.0e-3);
}
- public static Test suite() {
- return new TestSuite(NelderMeadTest.class);
+ @Test(expected = MaxIterationsExceededException.class)
+ public void testMaxIterations() throws MathException {
+ try {
+ Powell powell = new Powell();
+ NelderMead optimizer = new NelderMead();
+ optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-3));
+ optimizer.setMaxIterations(20);
+ optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 });
+ } catch (OptimizationException oe) {
+ if (oe.getCause() instanceof ConvergenceException) {
+ throw (ConvergenceException) oe.getCause();
+ }
+ throw oe;
+ }
}
- private int count;
+ @Test(expected = MaxEvaluationsExceededException.class)
+ public void testMaxEvaluations() throws MathException {
+ try {
+ Powell powell = new Powell();
+ NelderMead optimizer = new NelderMead();
+ optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-3));
+ optimizer.setMaxEvaluations(20);
+ optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 });
+ } catch (OptimizationException oe) {
+ if (oe.getCause() instanceof ConvergenceException) {
+ throw (ConvergenceException) oe.getCause();
+ }
+ throw oe;
+ }
+ }
+
+ private class Rosenbrock implements MultivariateRealFunction {
+
+ private int count;
+
+ public Rosenbrock() {
+ count = 0;
+ }
+
+ public double value(double[] x) throws FunctionEvaluationException {
+ ++count;
+ double a = x[1] - x[0] * x[0];
+ double b = 1.0 - x[0];
+ return 100 * a * a + b * b;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ }
+
+ private class Powell implements MultivariateRealFunction {
+
+ private int count;
+
+ public Powell() {
+ count = 0;
+ }
+
+ public double value(double[] x) throws FunctionEvaluationException {
+ ++count;
+ double a = x[0] + 10 * x[1];
+ double b = x[2] - x[3];
+ double c = x[1] - 2 * x[2];
+ double d = x[0] - x[3];
+ return a * a + 5 * b * b + c * c * c * c + 10 * d * d * d * d;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ }
}