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:
Gilles Sadowski 2010-07-28 10:27:02 +00:00
parent c917b3b3fa
commit 7572385a7e
5 changed files with 182 additions and 20 deletions

View File

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

View File

@ -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();
}

View File

@ -236,4 +236,9 @@ public class BrentOptimizer extends AbstractUnivariateRealOptimizer {
}
throw new MaxIterationsExceededException(maximalIterationCount);
}
/** Temporary workaround. */
protected double doOptimize() {
throw new UnsupportedOperationException();
}
}

View File

@ -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>

View File

@ -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");