MATH-1362: Use "IntegerSequence.Incrementor".

This commit is contained in:
Gilles Sadowski 2019-12-24 12:32:15 +01:00
parent aa46bcc64b
commit 22da2300b8
9 changed files with 67 additions and 48 deletions

View File

@ -31,7 +31,7 @@ import org.apache.commons.math4.linear.RealVector;
import org.apache.commons.math4.linear.SingularMatrixException;
import org.apache.commons.math4.linear.SingularValueDecomposition;
import org.apache.commons.math4.optim.ConvergenceChecker;
import org.apache.commons.math4.util.Incrementor;
import org.apache.commons.math4.util.IntegerSequence;
import org.apache.commons.math4.util.Pair;
/**
@ -207,8 +207,8 @@ public class GaussNewtonOptimizer implements LeastSquaresOptimizer {
@Override
public Optimum optimize(final LeastSquaresProblem lsp) {
//create local evaluation and iteration counts
final Incrementor evaluationCounter = lsp.getEvaluationCounter();
final Incrementor iterationCounter = lsp.getIterationCounter();
final IntegerSequence.Incrementor evaluationCounter = lsp.getEvaluationCounter();
final IntegerSequence.Incrementor iterationCounter = lsp.getIterationCounter();
final ConvergenceChecker<Evaluation> checker
= lsp.getConvergenceChecker();
@ -222,12 +222,12 @@ public class GaussNewtonOptimizer implements LeastSquaresOptimizer {
// iterate until convergence is reached
Evaluation current = null;
while (true) {
iterationCounter.incrementCount();
iterationCounter.increment();
// evaluate the objective function and its jacobian
Evaluation previous = current;
// Value of the objective function at "currentPoint".
evaluationCounter.incrementCount();
evaluationCounter.increment();
current = lsp.evaluate(currentPoint);
final RealVector currentResiduals = current.getResiduals();
final RealMatrix weightedJacobian = current.getJacobian();

View File

@ -18,7 +18,7 @@ package org.apache.commons.math4.fitting.leastsquares;
import org.apache.commons.math4.linear.RealVector;
import org.apache.commons.math4.optim.ConvergenceChecker;
import org.apache.commons.math4.util.Incrementor;
import org.apache.commons.math4.util.IntegerSequence;
/**
* An adapter that delegates to another implementation of {@link LeastSquaresProblem}.
@ -66,13 +66,13 @@ public class LeastSquaresAdapter implements LeastSquaresProblem {
/** {@inheritDoc} */
@Override
public Incrementor getEvaluationCounter() {
public IntegerSequence.Incrementor getEvaluationCounter() {
return problem.getEvaluationCounter();
}
/** {@inheritDoc} */
@Override
public Incrementor getIterationCounter() {
public IntegerSequence.Incrementor getIterationCounter() {
return problem.getIterationCounter();
}

View File

@ -31,7 +31,7 @@ import org.apache.commons.math4.optim.AbstractOptimizationProblem;
import org.apache.commons.math4.optim.ConvergenceChecker;
import org.apache.commons.math4.optim.PointVectorValuePair;
import org.apache.commons.math4.util.FastMath;
import org.apache.commons.math4.util.Incrementor;
import org.apache.commons.math4.util.IntegerSequence;
import org.apache.commons.math4.util.Pair;
/**
@ -224,13 +224,13 @@ public class LeastSquaresFactory {
* @return a least squares problem that tracks evaluations
*/
public static LeastSquaresProblem countEvaluations(final LeastSquaresProblem problem,
final Incrementor counter) {
final IntegerSequence.Incrementor counter) {
return new LeastSquaresAdapter(problem) {
/** {@inheritDoc} */
@Override
public Evaluation evaluate(final RealVector point) {
counter.incrementCount();
counter.increment();
return super.evaluate(point);
}

View File

@ -25,7 +25,7 @@ import org.apache.commons.math4.linear.ArrayRealVector;
import org.apache.commons.math4.linear.RealMatrix;
import org.apache.commons.math4.optim.ConvergenceChecker;
import org.apache.commons.math4.util.FastMath;
import org.apache.commons.math4.util.Incrementor;
import org.apache.commons.math4.util.IntegerSequence;
import org.apache.commons.numbers.core.Precision;
@ -299,8 +299,8 @@ public class LevenbergMarquardtOptimizer implements LeastSquaresOptimizer {
final int nR = problem.getObservationSize(); // Number of observed data.
final int nC = problem.getParameterSize(); // Number of parameters.
// Counters.
final Incrementor iterationCounter = problem.getIterationCounter();
final Incrementor evaluationCounter = problem.getEvaluationCounter();
final IntegerSequence.Incrementor iterationCounter = problem.getIterationCounter();
final IntegerSequence.Incrementor evaluationCounter = problem.getEvaluationCounter();
// Convergence criterion.
final ConvergenceChecker<Evaluation> checker = problem.getConvergenceChecker();
@ -324,7 +324,7 @@ public class LevenbergMarquardtOptimizer implements LeastSquaresOptimizer {
// Evaluate the function at the starting point and calculate its norm.
evaluationCounter.incrementCount();
evaluationCounter.increment();
//value will be reassigned in the loop
Evaluation current = problem.evaluate(problem.getStart());
double[] currentResiduals = current.getResiduals().toArray();
@ -334,7 +334,7 @@ public class LevenbergMarquardtOptimizer implements LeastSquaresOptimizer {
// Outer loop.
boolean firstIteration = true;
while (true) {
iterationCounter.incrementCount();
iterationCounter.increment();
final Evaluation previous = current;
@ -443,7 +443,7 @@ public class LevenbergMarquardtOptimizer implements LeastSquaresOptimizer {
}
// Evaluate the function at x + p and calculate its norm.
evaluationCounter.incrementCount();
evaluationCounter.increment();
current = problem.evaluate(new ArrayRealVector(currentPoint));
currentResiduals = current.getResiduals().toArray();
currentCost = current.getCost();

View File

@ -18,7 +18,7 @@ package org.apache.commons.math4.optim;
import org.apache.commons.math4.exception.TooManyEvaluationsException;
import org.apache.commons.math4.exception.TooManyIterationsException;
import org.apache.commons.math4.util.Incrementor;
import org.apache.commons.math4.util.IntegerSequence;
/**
* Base class for implementing optimization problems. It contains the boiler-plate code
@ -60,14 +60,18 @@ public abstract class AbstractOptimizationProblem<PAIR>
/** {@inheritDoc} */
@Override
public Incrementor getEvaluationCounter() {
return new Incrementor(this.maxEvaluations, MAX_EVAL_CALLBACK);
public IntegerSequence.Incrementor getEvaluationCounter() {
return IntegerSequence.Incrementor.create()
.withMaximalCount(maxEvaluations)
.withCallback(MAX_EVAL_CALLBACK);
}
/** {@inheritDoc} */
@Override
public Incrementor getIterationCounter() {
return new Incrementor(this.maxIterations, MAX_ITER_CALLBACK);
public IntegerSequence.Incrementor getIterationCounter() {
return IntegerSequence.Incrementor.create()
.withMaximalCount(maxIterations)
.withCallback(MAX_ITER_CALLBACK);
}
/** {@inheritDoc} */
@ -78,7 +82,7 @@ public abstract class AbstractOptimizationProblem<PAIR>
/** Defines the action to perform when reaching the maximum number of evaluations. */
private static class MaxEvalCallback
implements Incrementor.MaxCountExceededCallback {
implements IntegerSequence.Incrementor.MaxCountExceededCallback {
/**
* {@inheritDoc}
*
@ -92,7 +96,7 @@ public abstract class AbstractOptimizationProblem<PAIR>
/** Defines the action to perform when reaching the maximum number of evaluations. */
private static class MaxIterCallback
implements Incrementor.MaxCountExceededCallback {
implements IntegerSequence.Incrementor.MaxCountExceededCallback {
/**
* {@inheritDoc}
*

View File

@ -18,7 +18,7 @@ package org.apache.commons.math4.optim;
import org.apache.commons.math4.exception.TooManyEvaluationsException;
import org.apache.commons.math4.exception.TooManyIterationsException;
import org.apache.commons.math4.util.Incrementor;
import org.apache.commons.math4.util.IntegerSequence;
/**
* Base class for implementing optimizers.
@ -33,12 +33,21 @@ import org.apache.commons.math4.util.Incrementor;
* @since 3.1
*/
public abstract class BaseOptimizer<PAIR> {
/** Evaluations counter. */
protected final Incrementor evaluations;
/** Iterations counter. */
protected final Incrementor iterations;
/** Callback to use for the evaluation counter. */
private static final MaxEvalCallback MAX_EVAL_CALLBACK = new MaxEvalCallback();
/** Callback to use for the iteration counter. */
private static final MaxIterCallback MAX_ITER_CALLBACK = new MaxIterCallback();
/** Convergence checker. */
private final ConvergenceChecker<PAIR> checker;
/** Maximum number of evaluations. */
private int maxEvaluations;
/** Maximum number of iterations. */
private int maxIterations;
/** Evaluations counter. */
private IntegerSequence.Incrementor evaluations;
/** Iterations counter. */
private IntegerSequence.Incrementor iterations;
/**
* @param checker Convergence checker.
@ -56,9 +65,8 @@ public abstract class BaseOptimizer<PAIR> {
int maxEval,
int maxIter) {
this.checker = checker;
evaluations = new Incrementor(maxEval, new MaxEvalCallback());
iterations = new Incrementor(maxIter, new MaxIterCallback());
this.maxEvaluations = maxEval;
this.maxIterations = maxIter;
}
/**
@ -145,10 +153,8 @@ public abstract class BaseOptimizer<PAIR> {
TooManyIterationsException {
// Parse options.
parseOptimizationData(optData);
// Reset counters.
evaluations.resetCount();
iterations.resetCount();
resetCounters();
// Perform optimization.
return doOptimize();
}
@ -166,8 +172,7 @@ public abstract class BaseOptimizer<PAIR> {
throws TooManyEvaluationsException,
TooManyIterationsException {
// Reset counters.
evaluations.resetCount();
iterations.resetCount();
resetCounters();
// Perform optimization.
return doOptimize();
}
@ -188,7 +193,7 @@ public abstract class BaseOptimizer<PAIR> {
*/
protected void incrementEvaluationCount()
throws TooManyEvaluationsException {
evaluations.incrementCount();
evaluations.increment();
}
/**
@ -199,7 +204,7 @@ public abstract class BaseOptimizer<PAIR> {
*/
protected void incrementIterationCount()
throws TooManyIterationsException {
iterations.incrementCount();
iterations.increment();
}
/**
@ -218,22 +223,32 @@ public abstract class BaseOptimizer<PAIR> {
// not provided in the argument list.
for (OptimizationData data : optData) {
if (data instanceof MaxEval) {
evaluations.setMaximalCount(((MaxEval) data).getMaxEval());
maxEvaluations = ((MaxEval) data).getMaxEval();
continue;
}
if (data instanceof MaxIter) {
iterations.setMaximalCount(((MaxIter) data).getMaxIter());
maxIterations = ((MaxIter) data).getMaxIter();
continue;
}
}
}
/** Reset counters. */
private void resetCounters() {
evaluations = IntegerSequence.Incrementor.create()
.withMaximalCount(maxEvaluations)
.withCallback(MAX_EVAL_CALLBACK);
iterations = IntegerSequence.Incrementor.create()
.withMaximalCount(maxIterations)
.withCallback(MAX_ITER_CALLBACK);
}
/**
* Defines the action to perform when reaching the maximum number
* of evaluations.
*/
private static class MaxEvalCallback
implements Incrementor.MaxCountExceededCallback {
implements IntegerSequence.Incrementor.MaxCountExceededCallback {
/**
* {@inheritDoc}
* @throws TooManyEvaluationsException
@ -249,7 +264,7 @@ public abstract class BaseOptimizer<PAIR> {
* of evaluations.
*/
private static class MaxIterCallback
implements Incrementor.MaxCountExceededCallback {
implements IntegerSequence.Incrementor.MaxCountExceededCallback {
/**
* {@inheritDoc}
* @throws TooManyIterationsException

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math4.optim;
import org.apache.commons.math4.util.Incrementor;
import org.apache.commons.math4.util.IntegerSequence;
/**
* Common settings for all optimization problems. Includes divergence and convergence
@ -34,7 +34,7 @@ public interface OptimizationProblem<PAIR> {
*
* @return a counter for the evaluations.
*/
Incrementor getEvaluationCounter();
IntegerSequence.Incrementor getEvaluationCounter();
/**
* Get a independent Incrementor that counts up to the maximum number of iterations
@ -42,7 +42,7 @@ public interface OptimizationProblem<PAIR> {
*
* @return a counter for the evaluations.
*/
Incrementor getIterationCounter();
IntegerSequence.Incrementor getIterationCounter();
/**
* Gets the convergence checker.

View File

@ -779,7 +779,7 @@ public class SimplexSolverTest {
Assert.assertFalse(callback.isSolutionOptimal());
try {
solver.optimize(new MaxIter(3), f, new LinearConstraintSet(constraints),
solver.optimize(new MaxIter(4), f, new LinearConstraintSet(constraints),
GoalType.MAXIMIZE, new NonNegativeConstraint(true), callback);
Assert.fail("expected TooManyIterationsException");
} catch (TooManyIterationsException ex) {

View File

@ -228,7 +228,7 @@ public final class BrentOptimizerTest {
};
UnivariateOptimizer optimizer = new BrentOptimizer(1e-10, 1e-8);
final double result = optimizer.optimize(new MaxEval(1483),
final double result = optimizer.optimize(new MaxEval(1484),
new UnivariateObjectiveFunction(f),
GoalType.MINIMIZE,
new SearchInterval(Double.MIN_VALUE,