MATH-441
Implemented proposed solution (rethrow last exception if no optimum were found). git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1035245 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
65e95d0224
commit
0d52bf6394
|
@ -20,7 +20,7 @@ package org.apache.commons.math.optimization;
|
|||
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 BaseMultiStartMultivariateRealOptimizer<FUNC extends MultivariateRe
|
|||
* 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 BaseMultiStartMultivariateRealOptimizer<FUNC extends MultivariateRe
|
|||
*/
|
||||
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 BaseMultiStartMultivariateRealOptimizer<FUNC extends MultivariateRe
|
|||
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.
|
||||
|
|
|
@ -20,10 +20,9 @@ package org.apache.commons.math.optimization.univariate;
|
|||
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 MultiStartUnivariateRealOptimizer<FUNC extends UnivariateRealFuncti
|
|||
* 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 MultiStartUnivariateRealOptimizer<FUNC extends UnivariateRealFuncti
|
|||
/** {@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 MultiStartUnivariateRealOptimizer<FUNC extends UnivariateRealFuncti
|
|||
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 MultiStartUnivariateRealOptimizer<FUNC extends UnivariateRealFuncti
|
|||
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.
|
||||
|
|
|
@ -19,7 +19,7 @@ package org.apache.commons.math.optimization.univariate;
|
|||
|
||||
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 MultiStartUnivariateRealOptimizerTest {
|
|||
}
|
||||
|
||||
@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 MultiStartUnivariateRealOptimizerTest {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue