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.SingularMatrixException;
import org.apache.commons.math4.linear.SingularValueDecomposition; import org.apache.commons.math4.linear.SingularValueDecomposition;
import org.apache.commons.math4.optim.ConvergenceChecker; 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; import org.apache.commons.math4.util.Pair;
/** /**
@ -207,8 +207,8 @@ public class GaussNewtonOptimizer implements LeastSquaresOptimizer {
@Override @Override
public Optimum optimize(final LeastSquaresProblem lsp) { public Optimum optimize(final LeastSquaresProblem lsp) {
//create local evaluation and iteration counts //create local evaluation and iteration counts
final Incrementor evaluationCounter = lsp.getEvaluationCounter(); final IntegerSequence.Incrementor evaluationCounter = lsp.getEvaluationCounter();
final Incrementor iterationCounter = lsp.getIterationCounter(); final IntegerSequence.Incrementor iterationCounter = lsp.getIterationCounter();
final ConvergenceChecker<Evaluation> checker final ConvergenceChecker<Evaluation> checker
= lsp.getConvergenceChecker(); = lsp.getConvergenceChecker();
@ -222,12 +222,12 @@ public class GaussNewtonOptimizer implements LeastSquaresOptimizer {
// iterate until convergence is reached // iterate until convergence is reached
Evaluation current = null; Evaluation current = null;
while (true) { while (true) {
iterationCounter.incrementCount(); iterationCounter.increment();
// evaluate the objective function and its jacobian // evaluate the objective function and its jacobian
Evaluation previous = current; Evaluation previous = current;
// Value of the objective function at "currentPoint". // Value of the objective function at "currentPoint".
evaluationCounter.incrementCount(); evaluationCounter.increment();
current = lsp.evaluate(currentPoint); current = lsp.evaluate(currentPoint);
final RealVector currentResiduals = current.getResiduals(); final RealVector currentResiduals = current.getResiduals();
final RealMatrix weightedJacobian = current.getJacobian(); 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.linear.RealVector;
import org.apache.commons.math4.optim.ConvergenceChecker; 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}. * An adapter that delegates to another implementation of {@link LeastSquaresProblem}.
@ -66,13 +66,13 @@ public class LeastSquaresAdapter implements LeastSquaresProblem {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public Incrementor getEvaluationCounter() { public IntegerSequence.Incrementor getEvaluationCounter() {
return problem.getEvaluationCounter(); return problem.getEvaluationCounter();
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public Incrementor getIterationCounter() { public IntegerSequence.Incrementor getIterationCounter() {
return problem.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.ConvergenceChecker;
import org.apache.commons.math4.optim.PointVectorValuePair; import org.apache.commons.math4.optim.PointVectorValuePair;
import org.apache.commons.math4.util.FastMath; 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; import org.apache.commons.math4.util.Pair;
/** /**
@ -224,13 +224,13 @@ public class LeastSquaresFactory {
* @return a least squares problem that tracks evaluations * @return a least squares problem that tracks evaluations
*/ */
public static LeastSquaresProblem countEvaluations(final LeastSquaresProblem problem, public static LeastSquaresProblem countEvaluations(final LeastSquaresProblem problem,
final Incrementor counter) { final IntegerSequence.Incrementor counter) {
return new LeastSquaresAdapter(problem) { return new LeastSquaresAdapter(problem) {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public Evaluation evaluate(final RealVector point) { public Evaluation evaluate(final RealVector point) {
counter.incrementCount(); counter.increment();
return super.evaluate(point); 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.linear.RealMatrix;
import org.apache.commons.math4.optim.ConvergenceChecker; import org.apache.commons.math4.optim.ConvergenceChecker;
import org.apache.commons.math4.util.FastMath; 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; 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 nR = problem.getObservationSize(); // Number of observed data.
final int nC = problem.getParameterSize(); // Number of parameters. final int nC = problem.getParameterSize(); // Number of parameters.
// Counters. // Counters.
final Incrementor iterationCounter = problem.getIterationCounter(); final IntegerSequence.Incrementor iterationCounter = problem.getIterationCounter();
final Incrementor evaluationCounter = problem.getEvaluationCounter(); final IntegerSequence.Incrementor evaluationCounter = problem.getEvaluationCounter();
// Convergence criterion. // Convergence criterion.
final ConvergenceChecker<Evaluation> checker = problem.getConvergenceChecker(); 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. // Evaluate the function at the starting point and calculate its norm.
evaluationCounter.incrementCount(); evaluationCounter.increment();
//value will be reassigned in the loop //value will be reassigned in the loop
Evaluation current = problem.evaluate(problem.getStart()); Evaluation current = problem.evaluate(problem.getStart());
double[] currentResiduals = current.getResiduals().toArray(); double[] currentResiduals = current.getResiduals().toArray();
@ -334,7 +334,7 @@ public class LevenbergMarquardtOptimizer implements LeastSquaresOptimizer {
// Outer loop. // Outer loop.
boolean firstIteration = true; boolean firstIteration = true;
while (true) { while (true) {
iterationCounter.incrementCount(); iterationCounter.increment();
final Evaluation previous = current; final Evaluation previous = current;
@ -443,7 +443,7 @@ public class LevenbergMarquardtOptimizer implements LeastSquaresOptimizer {
} }
// Evaluate the function at x + p and calculate its norm. // Evaluate the function at x + p and calculate its norm.
evaluationCounter.incrementCount(); evaluationCounter.increment();
current = problem.evaluate(new ArrayRealVector(currentPoint)); current = problem.evaluate(new ArrayRealVector(currentPoint));
currentResiduals = current.getResiduals().toArray(); currentResiduals = current.getResiduals().toArray();
currentCost = current.getCost(); 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.TooManyEvaluationsException;
import org.apache.commons.math4.exception.TooManyIterationsException; 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 * Base class for implementing optimization problems. It contains the boiler-plate code
@ -60,14 +60,18 @@ public abstract class AbstractOptimizationProblem<PAIR>
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public Incrementor getEvaluationCounter() { public IntegerSequence.Incrementor getEvaluationCounter() {
return new Incrementor(this.maxEvaluations, MAX_EVAL_CALLBACK); return IntegerSequence.Incrementor.create()
.withMaximalCount(maxEvaluations)
.withCallback(MAX_EVAL_CALLBACK);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public Incrementor getIterationCounter() { public IntegerSequence.Incrementor getIterationCounter() {
return new Incrementor(this.maxIterations, MAX_ITER_CALLBACK); return IntegerSequence.Incrementor.create()
.withMaximalCount(maxIterations)
.withCallback(MAX_ITER_CALLBACK);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@ -78,7 +82,7 @@ public abstract class AbstractOptimizationProblem<PAIR>
/** Defines the action to perform when reaching the maximum number of evaluations. */ /** Defines the action to perform when reaching the maximum number of evaluations. */
private static class MaxEvalCallback private static class MaxEvalCallback
implements Incrementor.MaxCountExceededCallback { implements IntegerSequence.Incrementor.MaxCountExceededCallback {
/** /**
* {@inheritDoc} * {@inheritDoc}
* *
@ -92,7 +96,7 @@ public abstract class AbstractOptimizationProblem<PAIR>
/** Defines the action to perform when reaching the maximum number of evaluations. */ /** Defines the action to perform when reaching the maximum number of evaluations. */
private static class MaxIterCallback private static class MaxIterCallback
implements Incrementor.MaxCountExceededCallback { implements IntegerSequence.Incrementor.MaxCountExceededCallback {
/** /**
* {@inheritDoc} * {@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.TooManyEvaluationsException;
import org.apache.commons.math4.exception.TooManyIterationsException; 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. * Base class for implementing optimizers.
@ -33,12 +33,21 @@ import org.apache.commons.math4.util.Incrementor;
* @since 3.1 * @since 3.1
*/ */
public abstract class BaseOptimizer<PAIR> { public abstract class BaseOptimizer<PAIR> {
/** Evaluations counter. */ /** Callback to use for the evaluation counter. */
protected final Incrementor evaluations; private static final MaxEvalCallback MAX_EVAL_CALLBACK = new MaxEvalCallback();
/** Iterations counter. */ /** Callback to use for the iteration counter. */
protected final Incrementor iterations; private static final MaxIterCallback MAX_ITER_CALLBACK = new MaxIterCallback();
/** Convergence checker. */ /** Convergence checker. */
private final ConvergenceChecker<PAIR> 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. * @param checker Convergence checker.
@ -56,9 +65,8 @@ public abstract class BaseOptimizer<PAIR> {
int maxEval, int maxEval,
int maxIter) { int maxIter) {
this.checker = checker; this.checker = checker;
this.maxEvaluations = maxEval;
evaluations = new Incrementor(maxEval, new MaxEvalCallback()); this.maxIterations = maxIter;
iterations = new Incrementor(maxIter, new MaxIterCallback());
} }
/** /**
@ -145,10 +153,8 @@ public abstract class BaseOptimizer<PAIR> {
TooManyIterationsException { TooManyIterationsException {
// Parse options. // Parse options.
parseOptimizationData(optData); parseOptimizationData(optData);
// Reset counters. // Reset counters.
evaluations.resetCount(); resetCounters();
iterations.resetCount();
// Perform optimization. // Perform optimization.
return doOptimize(); return doOptimize();
} }
@ -166,8 +172,7 @@ public abstract class BaseOptimizer<PAIR> {
throws TooManyEvaluationsException, throws TooManyEvaluationsException,
TooManyIterationsException { TooManyIterationsException {
// Reset counters. // Reset counters.
evaluations.resetCount(); resetCounters();
iterations.resetCount();
// Perform optimization. // Perform optimization.
return doOptimize(); return doOptimize();
} }
@ -188,7 +193,7 @@ public abstract class BaseOptimizer<PAIR> {
*/ */
protected void incrementEvaluationCount() protected void incrementEvaluationCount()
throws TooManyEvaluationsException { throws TooManyEvaluationsException {
evaluations.incrementCount(); evaluations.increment();
} }
/** /**
@ -199,7 +204,7 @@ public abstract class BaseOptimizer<PAIR> {
*/ */
protected void incrementIterationCount() protected void incrementIterationCount()
throws TooManyIterationsException { throws TooManyIterationsException {
iterations.incrementCount(); iterations.increment();
} }
/** /**
@ -218,22 +223,32 @@ public abstract class BaseOptimizer<PAIR> {
// not provided in the argument list. // not provided in the argument list.
for (OptimizationData data : optData) { for (OptimizationData data : optData) {
if (data instanceof MaxEval) { if (data instanceof MaxEval) {
evaluations.setMaximalCount(((MaxEval) data).getMaxEval()); maxEvaluations = ((MaxEval) data).getMaxEval();
continue; continue;
} }
if (data instanceof MaxIter) { if (data instanceof MaxIter) {
iterations.setMaximalCount(((MaxIter) data).getMaxIter()); maxIterations = ((MaxIter) data).getMaxIter();
continue; 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 * Defines the action to perform when reaching the maximum number
* of evaluations. * of evaluations.
*/ */
private static class MaxEvalCallback private static class MaxEvalCallback
implements Incrementor.MaxCountExceededCallback { implements IntegerSequence.Incrementor.MaxCountExceededCallback {
/** /**
* {@inheritDoc} * {@inheritDoc}
* @throws TooManyEvaluationsException * @throws TooManyEvaluationsException
@ -249,7 +264,7 @@ public abstract class BaseOptimizer<PAIR> {
* of evaluations. * of evaluations.
*/ */
private static class MaxIterCallback private static class MaxIterCallback
implements Incrementor.MaxCountExceededCallback { implements IntegerSequence.Incrementor.MaxCountExceededCallback {
/** /**
* {@inheritDoc} * {@inheritDoc}
* @throws TooManyIterationsException * @throws TooManyIterationsException

View File

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

View File

@ -779,7 +779,7 @@ public class SimplexSolverTest {
Assert.assertFalse(callback.isSolutionOptimal()); Assert.assertFalse(callback.isSolutionOptimal());
try { 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); GoalType.MAXIMIZE, new NonNegativeConstraint(true), callback);
Assert.fail("expected TooManyIterationsException"); Assert.fail("expected TooManyIterationsException");
} catch (TooManyIterationsException ex) { } catch (TooManyIterationsException ex) {

View File

@ -228,7 +228,7 @@ public final class BrentOptimizerTest {
}; };
UnivariateOptimizer optimizer = new BrentOptimizer(1e-10, 1e-8); 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), new UnivariateObjectiveFunction(f),
GoalType.MINIMIZE, GoalType.MINIMIZE,
new SearchInterval(Double.MIN_VALUE, new SearchInterval(Double.MIN_VALUE,