Author: erans Date: Mon Nov 15 12:22:47 2010 New Revision: 1035245 URL: http://svn.apache.org/viewvc?rev=1035245&view=rev Log: MATH-441 Implemented proposed solution (rethrow last exception if no optimum were found).
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/BaseMultiStartMultivariateRealOptimizer.java commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/univariate/MultiStartUnivariateRealOptimizer.java commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/univariate/MultiStartUnivariateRealOptimizerTest.java Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/BaseMultiStartMultivariateRealOptimizer.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/BaseMultiStartMultivariateRealOptimizer.java?rev=1035245&r1=1035244&r2=1035245&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/BaseMultiStartMultivariateRealOptimizer.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/BaseMultiStartMultivariateRealOptimizer.java Mon Nov 15 12:22:47 2010 @@ -20,7 +20,7 @@ package org.apache.commons.math.optimiza import java.util.Arrays; import java.util.Comparator; -import org.apache.commons.math.exception.FunctionEvaluationException; +import org.apache.commons.math.exception.MathUserException; import org.apache.commons.math.exception.MathIllegalStateException; import org.apache.commons.math.exception.ConvergenceException; import org.apache.commons.math.analysis.MultivariateRealFunction; @@ -89,13 +89,14 @@ public class BaseMultiStartMultivariateR * descending order if maximizing), followed by and null elements * corresponding to the runs that did not converge. This means all * elements will be null if the {...@link #optimize(MultivariateRealFunction,GoalType,double[]) - * optimize} method did throw a {...@link ConvergenceException}). + * optimize} method did throw a {...@link MathUserException}). * This also means that if the first element is not {...@code null}, it * is the best point found across all starts. * * @return an array containing the optima. * @throws MathIllegalStateException if {...@link - * #optimize(MultivariateRealFunction,GoalType,double[]) optimize} has not been called. + * #optimize(MultivariateRealFunction,GoalType,double[]) optimize} + * has not been called. */ public RealPointValuePair[] getOptima() { if (optima == null) { @@ -135,19 +136,18 @@ public class BaseMultiStartMultivariateR */ public RealPointValuePair optimize(final FUNC f, final GoalType goal, - double[] startPoint) - throws FunctionEvaluationException { + double[] startPoint) { + MathUserException lastException = null; optima = new RealPointValuePair[starts]; + totalEvaluations = 0; // Multi-start loop. for (int i = 0; i < starts; ++i) { - try { optima[i] = optimizer.optimize(f, goal, i == 0 ? startPoint : generator.nextVector()); - } catch (FunctionEvaluationException fee) { - optima[i] = null; - } catch (ConvergenceException oe) { + } catch (MathUserException mue) { + lastException = mue; optima[i] = null; } @@ -159,8 +159,7 @@ public class BaseMultiStartMultivariateR sortPairs(goal); if (optima[0] == null) { - throw new ConvergenceException(LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT, - starts); + throw lastException; } // Return the found point given the best objective function value. Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/univariate/MultiStartUnivariateRealOptimizer.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/univariate/MultiStartUnivariateRealOptimizer.java?rev=1035245&r1=1035244&r2=1035245&view=diff ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/univariate/MultiStartUnivariateRealOptimizer.java (original) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/optimization/univariate/MultiStartUnivariateRealOptimizer.java Mon Nov 15 12:22:47 2010 @@ -20,10 +20,9 @@ package org.apache.commons.math.optimiza import java.util.Arrays; import java.util.Comparator; -import org.apache.commons.math.exception.FunctionEvaluationException; import org.apache.commons.math.analysis.UnivariateRealFunction; +import org.apache.commons.math.exception.MathUserException; import org.apache.commons.math.exception.MathIllegalStateException; -import org.apache.commons.math.exception.ConvergenceException; import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.random.RandomGenerator; import org.apache.commons.math.optimization.GoalType; @@ -121,14 +120,15 @@ public class MultiStartUnivariateRealOpt * descending order if maximizing), followed by {...@code null} elements * corresponding to the runs that did not converge. This means all * elements will be {...@code null} if the {...@link - * #optimize(UnivariateRealFunction,GoalType,double,double) optimize} method did throw a - * {...@link ConvergenceException}). This also means that if the first - * element is not {...@code null}, it is the best point found across all - * starts. + * #optimize(UnivariateRealFunction,GoalType,double,double) optimize} + * method did throw a {...@link MathUserException}). This also means that + * if the first element is not {...@code null}, it is the best point found + * across all starts. * * @return an array containing the optima. * @throws MathIllegalStateException if {...@link - * #optimize(UnivariateRealFunction,GoalType,double,double) optimize} has not been called. + * #optimize(UnivariateRealFunction,GoalType,double,double) optimize} + * has not been called. */ public UnivariateRealPointValuePair[] getOptima() { if (optima == null) { @@ -140,16 +140,15 @@ public class MultiStartUnivariateRealOpt /** {...@inheritdoc} */ public UnivariateRealPointValuePair optimize(final FUNC f, final GoalType goal, - final double min, final double max) - throws FunctionEvaluationException { + final double min, final double max) { return optimize(f, goal, min, max, min + 0.5 * (max - min)); } /** {...@inheritdoc} */ public UnivariateRealPointValuePair optimize(final FUNC f, final GoalType goal, final double min, final double max, - final double startValue) - throws FunctionEvaluationException { + final double startValue) { + MathUserException lastException = null; optima = new UnivariateRealPointValuePair[starts]; totalEvaluations = 0; @@ -158,9 +157,8 @@ public class MultiStartUnivariateRealOpt try { final double s = (i == 0) ? startValue : min + generator.nextDouble() * (max - min); optima[i] = optimizer.optimize(f, goal, min, max, s); - } catch (FunctionEvaluationException fee) { - optima[i] = null; - } catch (ConvergenceException ce) { + } catch (MathUserException mue) { + lastException = mue; optima[i] = null; } @@ -172,8 +170,7 @@ public class MultiStartUnivariateRealOpt sortPairs(goal); if (optima[0] == null) { - throw new ConvergenceException(LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT, - starts); + throw lastException; } // Return the point with the best objective function value. Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/univariate/MultiStartUnivariateRealOptimizerTest.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/univariate/MultiStartUnivariateRealOptimizerTest.java?rev=1035245&r1=1035244&r2=1035245&view=diff ============================================================================== --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/univariate/MultiStartUnivariateRealOptimizerTest.java (original) +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/univariate/MultiStartUnivariateRealOptimizerTest.java Mon Nov 15 12:22:47 2010 @@ -19,7 +19,7 @@ package org.apache.commons.math.optimiza import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import org.apache.commons.math.MathException; +import org.apache.commons.math.exception.MathUserException; import org.apache.commons.math.analysis.QuinticFunction; import org.apache.commons.math.analysis.SinFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; @@ -32,7 +32,7 @@ import org.junit.Test; public class MultiStartUnivariateRealOptimizerTest { @Test - public void testSinMin() throws MathException { + public void testSinMin() { UnivariateRealFunction f = new SinFunction(); UnivariateRealOptimizer underlying = new BrentOptimizer(1e-10, 1e-14); underlying.setMaxEvaluations(300); @@ -53,7 +53,7 @@ public class MultiStartUnivariateRealOpt } @Test - public void testQuinticMin() throws MathException { + public void testQuinticMin() { // The quintic function has zeros at 0, +-0.5 and +-1. // The function has extrema (first derivative is zero) at 0.27195613 and 0.82221643, UnivariateRealFunction f = new QuinticFunction(); @@ -76,4 +76,25 @@ public class MultiStartUnivariateRealOpt assertTrue(optimizer.getEvaluations() >= 50); assertTrue(optimizer.getEvaluations() <= 100); } + + @Test(expected=MathUserException.class) + public void testBadFunction() { + UnivariateRealFunction f = new UnivariateRealFunction() { + public double value(double x) { + if (x < 0) { + throw new MathUserException(); + } + return 0; + } + }; + UnivariateRealOptimizer underlying = new BrentOptimizer(1e-9, 1e-14); + underlying.setMaxEvaluations(300); + JDKRandomGenerator g = new JDKRandomGenerator(); + g.setSeed(4312000053L); + MultiStartUnivariateRealOptimizer<UnivariateRealFunction> optimizer = + new MultiStartUnivariateRealOptimizer<UnivariateRealFunction>(underlying, 5, g); + + UnivariateRealPointValuePair optimum + = optimizer.optimize(f, GoalType.MINIMIZE, -0.3, -0.2); + } }