MATH-397. Modified "AbstractUnivariateRealOptimizer" so that its usage is
more similar to what is done in package "optimization.general". Deprecated many methods as a consequence of the new layout. New utility methods in "ConvergingAlgorithmImpl". Temporary workaround in "BrentOptimizer" (requirement from base class) to avoid committing two issues at the same time... git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@980013 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c917b3b3fa
commit
7572385a7e
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.apache.commons.math;
|
||||
|
||||
|
||||
/**
|
||||
* Provide a default implementation for several functions useful to generic
|
||||
* converging algorithms.
|
||||
|
@ -25,7 +24,7 @@ package org.apache.commons.math;
|
|||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm{
|
||||
public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm {
|
||||
|
||||
/** Maximum absolute error. */
|
||||
protected double absoluteAccuracy;
|
||||
|
@ -45,7 +44,6 @@ public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm{
|
|||
/** Default maximum number of iterations. */
|
||||
protected int defaultMaximalIterationCount;
|
||||
|
||||
// Mainly for test framework.
|
||||
/** The last iteration count. */
|
||||
protected int iterationCount;
|
||||
|
||||
|
@ -56,6 +54,8 @@ public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm{
|
|||
* @param defaultMaximalIterationCount maximum number of iterations
|
||||
* @throws IllegalArgumentException if f is null or the
|
||||
* defaultAbsoluteAccuracy is not valid
|
||||
* @deprecated in 2.2. Derived classes should use the "setter" methods
|
||||
* in order to assign meaningful values to all the instances variables.
|
||||
*/
|
||||
protected ConvergingAlgorithmImpl(final int defaultMaximalIterationCount,
|
||||
final double defaultAbsoluteAccuracy) {
|
||||
|
@ -68,6 +68,15 @@ public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm{
|
|||
this.iterationCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*
|
||||
* @since 2.2
|
||||
* @deprecated in 2.2 (to be removed as soon as the single non-default one
|
||||
* has been removed).
|
||||
*/
|
||||
protected ConvergingAlgorithmImpl() {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getIterationCount() {
|
||||
return iterationCount;
|
||||
|
@ -118,4 +127,26 @@ public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm{
|
|||
relativeAccuracy = defaultRelativeAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the iterations counter to 0.
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
protected void resetIterationsCounter() {
|
||||
iterationCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the iterations counter by 1.
|
||||
*
|
||||
* @throws OptimizationException if the maximal number
|
||||
* of iterations is exceeded.
|
||||
* @since 2.2
|
||||
*/
|
||||
protected void incrementIterationsCounter()
|
||||
throws ConvergenceException {
|
||||
if (++iterationCount > maximalIterationCount) {
|
||||
throw new ConvergenceException(new MaxIterationsExceededException(maximalIterationCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@ package org.apache.commons.math.optimization.univariate;
|
|||
|
||||
import org.apache.commons.math.ConvergingAlgorithmImpl;
|
||||
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.exception.NotStrictlyPositiveException;
|
||||
import org.apache.commons.math.exception.NoDataException;
|
||||
import org.apache.commons.math.analysis.UnivariateRealFunction;
|
||||
import org.apache.commons.math.optimization.UnivariateRealOptimizer;
|
||||
import org.apache.commons.math.util.LocalizedFormats;
|
||||
import org.apache.commons.math.optimization.GoalType;
|
||||
|
||||
/**
|
||||
* Provide a default implementation for several functions useful to generic
|
||||
|
@ -34,21 +36,26 @@ import org.apache.commons.math.util.LocalizedFormats;
|
|||
*/
|
||||
public abstract class AbstractUnivariateRealOptimizer
|
||||
extends ConvergingAlgorithmImpl implements UnivariateRealOptimizer {
|
||||
|
||||
/** Indicates where a root has been computed. */
|
||||
protected boolean resultComputed;
|
||||
|
||||
private boolean resultComputed;
|
||||
/** The last computed root. */
|
||||
protected double result;
|
||||
|
||||
private double result;
|
||||
/** Value of the function at the last computed result. */
|
||||
protected double functionValue;
|
||||
|
||||
private double functionValue;
|
||||
/** Maximal number of evaluations allowed. */
|
||||
private int maxEvaluations;
|
||||
|
||||
/** Number of evaluations already performed. */
|
||||
private int evaluations;
|
||||
/** Optimization type */
|
||||
private GoalType goal;
|
||||
/** Lower end of search interval. */
|
||||
private double min;
|
||||
/** Higher end of search interval. */
|
||||
private double max;
|
||||
/** Initial guess . */
|
||||
private double startValue;
|
||||
/** Function to optimize. */
|
||||
private UnivariateRealFunction function;
|
||||
|
||||
/**
|
||||
* Construct a solver with given iteration count and accuracy.
|
||||
|
@ -57,6 +64,9 @@ public abstract class AbstractUnivariateRealOptimizer
|
|||
* @param defaultMaximalIterationCount maximum number of iterations
|
||||
* @throws IllegalArgumentException if f is null or the
|
||||
* defaultAbsoluteAccuracy is not valid
|
||||
* @deprecated in 2.2. Please use the "setter" methods to assign meaningful
|
||||
* values to the maximum numbers of iterations and evaluations, and to the
|
||||
* absolute and relative accuracy thresholds.
|
||||
*/
|
||||
protected AbstractUnivariateRealOptimizer(final int defaultMaximalIterationCount,
|
||||
final double defaultAbsoluteAccuracy) {
|
||||
|
@ -65,24 +75,41 @@ public abstract class AbstractUnivariateRealOptimizer
|
|||
setMaxEvaluations(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/** Check if a result has been computed.
|
||||
* @exception IllegalStateException if no result has been computed
|
||||
/**
|
||||
* Default constructor.
|
||||
* To be removed once the single non-default one has been removed.
|
||||
*/
|
||||
protected void checkResultComputed() throws IllegalStateException {
|
||||
protected AbstractUnivariateRealOptimizer() {}
|
||||
|
||||
/**
|
||||
* Check whether a result has been computed.
|
||||
* @throws NoDataException if no result has been computed
|
||||
* @deprecated in 2.2 (no alternative).
|
||||
*/
|
||||
protected void checkResultComputed() {
|
||||
if (!resultComputed) {
|
||||
throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_RESULT_AVAILABLE);
|
||||
throw new NoDataException();
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getResult() {
|
||||
checkResultComputed();
|
||||
if (!resultComputed) {
|
||||
throw new NoDataException();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getFunctionValue() {
|
||||
checkResultComputed();
|
||||
if (functionValue == Double.NaN) {
|
||||
final double opt = getResult();
|
||||
try {
|
||||
functionValue = function.value(opt);
|
||||
} catch (FunctionEvaluationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return functionValue;
|
||||
}
|
||||
|
||||
|
@ -92,6 +119,7 @@ public abstract class AbstractUnivariateRealOptimizer
|
|||
* @param x the result to set
|
||||
* @param fx the result to set
|
||||
* @param iterationCount the iteration count to set
|
||||
* @deprecated in 2.2 (no alternative).
|
||||
*/
|
||||
protected final void setResult(final double x, final double fx,
|
||||
final int iterationCount) {
|
||||
|
@ -103,6 +131,7 @@ public abstract class AbstractUnivariateRealOptimizer
|
|||
|
||||
/**
|
||||
* Convenience function for implementations.
|
||||
* @deprecated in 2.2 (no alternative).
|
||||
*/
|
||||
protected final void clearResult() {
|
||||
this.resultComputed = false;
|
||||
|
@ -123,6 +152,31 @@ public abstract class AbstractUnivariateRealOptimizer
|
|||
return evaluations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the optimization type.
|
||||
*/
|
||||
public GoalType getGoalType() {
|
||||
return goal;
|
||||
}
|
||||
/**
|
||||
* @return the lower of the search interval.
|
||||
*/
|
||||
public double getMin() {
|
||||
return min;
|
||||
}
|
||||
/**
|
||||
* @return the higher of the search interval.
|
||||
*/
|
||||
public double getMax() {
|
||||
return max;
|
||||
}
|
||||
/**
|
||||
* @return the initial guess.
|
||||
*/
|
||||
public double getStartValue() {
|
||||
return startValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the objective function value.
|
||||
* @param f objective function
|
||||
|
@ -130,6 +184,8 @@ public abstract class AbstractUnivariateRealOptimizer
|
|||
* @return objective function value at specified point
|
||||
* @exception FunctionEvaluationException if the function cannot be evaluated
|
||||
* or the maximal number of iterations is exceeded
|
||||
* @deprecated in 2.2. Use this {@link #computeObjectiveValue(double)
|
||||
* replacement} instead.
|
||||
*/
|
||||
protected double computeObjectiveValue(final UnivariateRealFunction f,
|
||||
final double point)
|
||||
|
@ -141,4 +197,68 @@ public abstract class AbstractUnivariateRealOptimizer
|
|||
return f.value(point);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the objective function value.
|
||||
*
|
||||
* @param point Point at which the objective function must be evaluated.
|
||||
* @return the objective function value at specified point.
|
||||
* @exception FunctionEvaluationException if the function cannot be evaluated
|
||||
* or the maximal number of iterations is exceeded.
|
||||
*/
|
||||
protected double computeObjectiveValue(double point)
|
||||
throws FunctionEvaluationException {
|
||||
if (++evaluations > maxEvaluations) {
|
||||
resultComputed = false;
|
||||
throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations),
|
||||
point);
|
||||
}
|
||||
return function.value(point);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double optimize(UnivariateRealFunction function, GoalType goal,
|
||||
double min, double max, double startValue)
|
||||
throws MaxIterationsExceededException, FunctionEvaluationException {
|
||||
// Initialize.
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.startValue = startValue;
|
||||
this.goal = goal;
|
||||
this.function = function;
|
||||
|
||||
// Reset.
|
||||
functionValue = Double.NaN;
|
||||
evaluations = 0;
|
||||
resetIterationsCounter();
|
||||
|
||||
// Perform computation.
|
||||
result = doOptimize();
|
||||
resultComputed = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value at the optimum.
|
||||
*
|
||||
* @param functionValue Value of the objective function at the optimum.
|
||||
*/
|
||||
protected void setFunctionValue(double functionValue) {
|
||||
this.functionValue = functionValue;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double optimize(UnivariateRealFunction f, GoalType goal,
|
||||
double min, double max)
|
||||
throws MaxIterationsExceededException, FunctionEvaluationException {
|
||||
return optimize(f, goal, min, max, min + 0.5 * (max - min));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for implementing actual optimization algorithms in derived
|
||||
* classes.
|
||||
*
|
||||
* @return the optimum.
|
||||
*/
|
||||
protected abstract double doOptimize();
|
||||
}
|
||||
|
|
|
@ -236,4 +236,9 @@ public class BrentOptimizer extends AbstractUnivariateRealOptimizer {
|
|||
}
|
||||
throw new MaxIterationsExceededException(maximalIterationCount);
|
||||
}
|
||||
|
||||
/** Temporary workaround. */
|
||||
protected double doOptimize() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,11 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
If the output is not quite correct, check for invisible trailing spaces!
|
||||
-->
|
||||
<release version="2.2" date="TBD" description="TBD">
|
||||
<action dev="erans" type="update" issue="MATH-397">
|
||||
Modified "AbstractUnivariateRealOptimizer" to make it more similar to
|
||||
"BaseAbstractScalarOptimizer".
|
||||
Added utility methods in "ConvergingAlgorithmImpl".
|
||||
</action>
|
||||
<action dev="erans" type="fix" issue="MATH-395">
|
||||
Fixed several bugs in "BrentOptimizer".
|
||||
</action>
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.junit.Assert.fail;
|
|||
import org.apache.commons.math.FunctionEvaluationException;
|
||||
import org.apache.commons.math.MathException;
|
||||
import org.apache.commons.math.MaxIterationsExceededException;
|
||||
import org.apache.commons.math.exception.NoDataException;
|
||||
import org.apache.commons.math.analysis.QuinticFunction;
|
||||
import org.apache.commons.math.analysis.SinFunction;
|
||||
import org.apache.commons.math.analysis.UnivariateRealFunction;
|
||||
|
@ -44,7 +45,7 @@ public final class BrentOptimizerTest {
|
|||
try {
|
||||
minimizer.getResult();
|
||||
fail("an exception should have been thrown");
|
||||
} catch (IllegalStateException ise) {
|
||||
} catch (NoDataException ise) {
|
||||
// expected
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
|
|
Loading…
Reference in New Issue