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);
+    }
 }


Reply via email to