MATH-1092

Added parameter in "LineSearch" and "NonLinearConjugateGradientOptimizer".


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1573316 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gilles Sadowski 2014-03-02 14:54:37 +00:00
parent e2dc384d7b
commit b95cfc9b57
5 changed files with 63 additions and 28 deletions

View File

@ -54,6 +54,11 @@ public class LineSearch {
* Automatic bracketing. * Automatic bracketing.
*/ */
private final BracketFinder bracket = new BracketFinder(); private final BracketFinder bracket = new BracketFinder();
/**
* Extent of the initial interval used to find an interval that
* brackets the optimum.
*/
private final double initialBracketingRange;
/** /**
* Optimizer on behalf of which the line search must be performed. * Optimizer on behalf of which the line search must be performed.
*/ */
@ -70,23 +75,33 @@ public class LineSearch {
* @param optimizer Optimizer on behalf of which the line search * @param optimizer Optimizer on behalf of which the line search
* be performed. * be performed.
* Its {@link MultivariateOptimizer#computeObjectiveValue(double[]) * Its {@link MultivariateOptimizer#computeObjectiveValue(double[])
* computeObjectiveValue} method will be called by this class's * computeObjectiveValue} method will be called by the
* {@link #search(double[],double[]) search} method. * {@link #search(double[],double[]) search} method.
* @param relativeTolerance Relative threshold. * @param relativeTolerance Search will stop when the function relative
* @param absoluteTolerance Absolute threshold. * difference between successive iterations is smaller than this value.
* @param absoluteTolerance Search will stop when the function absolute
* difference between successive iterations is smaller than this value.
* @param initialBracketingRange Extent of the initial interval used to
* find an interval that brackets the optimum.
* If the optimized function varies a lot in the vicinity of the optimum,
* it may be necessary to provide a value lower than the distance between
* successive local minima.
*/ */
public LineSearch(MultivariateOptimizer optimizer, public LineSearch(MultivariateOptimizer optimizer,
double relativeTolerance, double relativeTolerance,
double absoluteTolerance) { double absoluteTolerance,
double initialBracketingRange) {
mainOptimizer = optimizer; mainOptimizer = optimizer;
lineOptimizer = new BrentOptimizer(REL_TOL_UNUSED, lineOptimizer = new BrentOptimizer(REL_TOL_UNUSED,
ABS_TOL_UNUSED, ABS_TOL_UNUSED,
new SimpleUnivariateValueChecker(relativeTolerance, new SimpleUnivariateValueChecker(relativeTolerance,
absoluteTolerance)); absoluteTolerance));
this.initialBracketingRange = initialBracketingRange;
} }
/** /**
* Find the minimum of the function {@code f(p + alpha * d)}. * Finds the number {@code alpha} that optimizes
* {@code f(startPoint + alpha * direction)}.
* *
* @param startPoint Starting point. * @param startPoint Starting point.
* @param direction Search direction. * @param direction Search direction.
@ -109,7 +124,7 @@ public class LineSearch {
}; };
final GoalType goal = mainOptimizer.getGoalType(); final GoalType goal = mainOptimizer.getGoalType();
bracket.search(f, goal, 0, 1); bracket.search(f, goal, 0, initialBracketingRange);
// Passing "MAX_VALUE" as a dummy value because it is the enclosing // Passing "MAX_VALUE" as a dummy value because it is the enclosing
// class that counts the number of evaluations (and will eventually // class that counts the number of evaluations (and will eventually
// generate the exception). // generate the exception).

View File

@ -86,7 +86,9 @@ public class NonLinearConjugateGradientOptimizer
* search. * search.
* *
* @since 3.1 * @since 3.1
* @deprecated As of v3.3, class is not used anymore. * @deprecated As of v3.3, this class is not used anymore.
* This setting is replaced by the {@code initialBracketingRange}
* argument to the new constructors.
*/ */
@Deprecated @Deprecated
public static class BracketingStep implements OptimizationData { public static class BracketingStep implements OptimizationData {
@ -125,6 +127,7 @@ public class NonLinearConjugateGradientOptimizer
checker, checker,
1e-8, 1e-8,
1e-8, 1e-8,
1e-8,
new IdentityPreconditioner()); new IdentityPreconditioner());
} }
@ -137,7 +140,7 @@ public class NonLinearConjugateGradientOptimizer
* @param checker Convergence checker. * @param checker Convergence checker.
* @param lineSearchSolver Solver to use during line search. * @param lineSearchSolver Solver to use during line search.
* @deprecated as of 3.3. Please use * @deprecated as of 3.3. Please use
* {@link #NonLinearConjugateGradientOptimizer(Formula,ConvergenceChecker,double,double)} instead. * {@link #NonLinearConjugateGradientOptimizer(Formula,ConvergenceChecker,double,double,double)} instead.
*/ */
@Deprecated @Deprecated
public NonLinearConjugateGradientOptimizer(final Formula updateFormula, public NonLinearConjugateGradientOptimizer(final Formula updateFormula,
@ -158,17 +161,23 @@ public class NonLinearConjugateGradientOptimizer
* @param checker Convergence checker. * @param checker Convergence checker.
* @param relativeTolerance Relative threshold for line search. * @param relativeTolerance Relative threshold for line search.
* @param absoluteTolerance Absolute threshold for line search. * @param absoluteTolerance Absolute threshold for line search.
* @param initialBracketingRange Extent of the initial interval used to
* find an interval that brackets the optimum in order to perform the
* line search.
* *
* @see LineSearch#LineSearch(MultivariateOptimizer,double,double) * @see LineSearch#LineSearch(MultivariateOptimizer,double,double,double)
* @since 3.3
*/ */
public NonLinearConjugateGradientOptimizer(final Formula updateFormula, public NonLinearConjugateGradientOptimizer(final Formula updateFormula,
ConvergenceChecker<PointValuePair> checker, ConvergenceChecker<PointValuePair> checker,
double relativeTolerance, double relativeTolerance,
double absoluteTolerance) { double absoluteTolerance,
double initialBracketingRange) {
this(updateFormula, this(updateFormula,
checker, checker,
relativeTolerance, relativeTolerance,
absoluteTolerance, absoluteTolerance,
initialBracketingRange,
new IdentityPreconditioner()); new IdentityPreconditioner());
} }
@ -180,7 +189,7 @@ public class NonLinearConjugateGradientOptimizer
* @param lineSearchSolver Solver to use during line search. * @param lineSearchSolver Solver to use during line search.
* @param preconditioner Preconditioner. * @param preconditioner Preconditioner.
* @deprecated as of 3.3. Please use * @deprecated as of 3.3. Please use
* {@link #NonLinearConjugateGradientOptimizer(Formula,ConvergenceChecker,double,double,Preconditioner)} instead. * {@link #NonLinearConjugateGradientOptimizer(Formula,ConvergenceChecker,double,double,double,Preconditioner)} instead.
*/ */
@Deprecated @Deprecated
public NonLinearConjugateGradientOptimizer(final Formula updateFormula, public NonLinearConjugateGradientOptimizer(final Formula updateFormula,
@ -191,6 +200,7 @@ public class NonLinearConjugateGradientOptimizer
checker, checker,
lineSearchSolver.getRelativeAccuracy(), lineSearchSolver.getRelativeAccuracy(),
lineSearchSolver.getAbsoluteAccuracy(), lineSearchSolver.getAbsoluteAccuracy(),
lineSearchSolver.getAbsoluteAccuracy(),
preconditioner); preconditioner);
} }
@ -202,13 +212,18 @@ public class NonLinearConjugateGradientOptimizer
* @param preconditioner Preconditioner. * @param preconditioner Preconditioner.
* @param relativeTolerance Relative threshold for line search. * @param relativeTolerance Relative threshold for line search.
* @param absoluteTolerance Absolute threshold for line search. * @param absoluteTolerance Absolute threshold for line search.
* @param initialBracketingRange Extent of the initial interval used to
* find an interval that brackets the optimum in order to perform the
* line search.
* *
* @see LineSearch#LineSearch(MultivariateOptimizer,double,double) * @see LineSearch#LineSearch(MultivariateOptimizer,double,double,double)
* @since 3.3
*/ */
public NonLinearConjugateGradientOptimizer(final Formula updateFormula, public NonLinearConjugateGradientOptimizer(final Formula updateFormula,
ConvergenceChecker<PointValuePair> checker, ConvergenceChecker<PointValuePair> checker,
double relativeTolerance, double relativeTolerance,
double absoluteTolerance, double absoluteTolerance,
double initialBracketingRange,
final Preconditioner preconditioner) { final Preconditioner preconditioner) {
super(checker); super(checker);
@ -216,7 +231,8 @@ public class NonLinearConjugateGradientOptimizer
this.preconditioner = preconditioner; this.preconditioner = preconditioner;
line = new LineSearch(this, line = new LineSearch(this,
relativeTolerance, relativeTolerance,
absoluteTolerance); absoluteTolerance,
initialBracketingRange);
} }
/** /**

View File

@ -127,7 +127,8 @@ public class PowellOptimizer
// Create the line search optimizer. // Create the line search optimizer.
line = new LineSearch(this, line = new LineSearch(this,
lineRel, lineRel,
lineAbs); lineAbs,
1d);
} }
/** /**

View File

@ -110,7 +110,10 @@ public class BracketFinder {
* @throws TooManyEvaluationsException if the maximum number of evaluations * @throws TooManyEvaluationsException if the maximum number of evaluations
* is exceeded. * is exceeded.
*/ */
public void search(UnivariateFunction func, GoalType goal, double xA, double xB) { public void search(UnivariateFunction func,
GoalType goal,
double xA,
double xB) {
evaluations.resetCount(); evaluations.resetCount();
final boolean isMinim = goal == GoalType.MINIMIZE; final boolean isMinim = goal == GoalType.MINIMIZE;

View File

@ -105,7 +105,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6), new SimpleValueChecker(1e-6, 1e-6),
1e-3, 1e-3); 1e-3, 1e-3, 1);
optimizer.optimize(new MaxEval(100), optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),
problem.getObjectiveFunctionGradient(), problem.getObjectiveFunctionGradient(),
@ -122,7 +122,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6), new SimpleValueChecker(1e-6, 1e-6),
1e-3, 1e-3); 1e-3, 1e-3, 1);
PointValuePair optimum PointValuePair optimum
= optimizer.optimize(new MaxEval(100), = optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),
@ -145,7 +145,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6), new SimpleValueChecker(1e-6, 1e-6),
1e-3, 1e-3); 1e-3, 1e-3, 1);
PointValuePair optimum PointValuePair optimum
= optimizer.optimize(new MaxEval(100), = optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),
@ -171,7 +171,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6), new SimpleValueChecker(1e-6, 1e-6),
1e-3, 1e-3); 1e-3, 1e-3, 1);
PointValuePair optimum PointValuePair optimum
= optimizer.optimize(new MaxEval(100), = optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),
@ -193,7 +193,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6), new SimpleValueChecker(1e-6, 1e-6),
1e-3, 1e-3); 1e-3, 1e-3, 1);
PointValuePair optimum PointValuePair optimum
= optimizer.optimize(new MaxEval(100), = optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),
@ -235,7 +235,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-13, 1e-13), new SimpleValueChecker(1e-13, 1e-13),
1e-7, 1e-7, 1e-7, 1e-7, 1,
preconditioner); preconditioner);
PointValuePair optimum PointValuePair optimum
@ -267,7 +267,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6), new SimpleValueChecker(1e-6, 1e-6),
1e-3, 1e-3); 1e-3, 1e-3, 1);
PointValuePair optimum PointValuePair optimum
= optimizer.optimize(new MaxEval(100), = optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),
@ -288,7 +288,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-13, 1e-13), new SimpleValueChecker(1e-13, 1e-13),
1e-15, 1e-15); 1e-15, 1e-15, 1);
PointValuePair optimum1 PointValuePair optimum1
= optimizer.optimize(new MaxEval(200), = optimizer.optimize(new MaxEval(200),
problem1.getObjectiveFunction(), problem1.getObjectiveFunction(),
@ -333,7 +333,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6), new SimpleValueChecker(1e-6, 1e-6),
1e-3, 1e-3); 1e-3, 1e-3, 1);
PointValuePair optimum PointValuePair optimum
= optimizer.optimize(new MaxEval(100), = optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),
@ -356,7 +356,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6), new SimpleValueChecker(1e-6, 1e-6),
1e-3, 1e-3); 1e-3, 1e-3, 1);
PointValuePair optimum PointValuePair optimum
= optimizer.optimize(new MaxEval(100), = optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),
@ -377,7 +377,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6), new SimpleValueChecker(1e-6, 1e-6),
1e-3, 1e-3); 1e-3, 1e-3, 1);
PointValuePair optimum PointValuePair optimum
= optimizer.optimize(new MaxEval(100), = optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),
@ -400,7 +400,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6), new SimpleValueChecker(1e-6, 1e-6),
1e-3, 1e-3); 1e-3, 1e-3, 1);
PointValuePair optimum PointValuePair optimum
= optimizer.optimize(new MaxEval(100), = optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),
@ -422,7 +422,7 @@ public class NonLinearConjugateGradientOptimizerTest {
NonLinearConjugateGradientOptimizer optimizer NonLinearConjugateGradientOptimizer optimizer
= new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE, = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
new SimpleValueChecker(1e-30, 1e-30), new SimpleValueChecker(1e-30, 1e-30),
1e-15, 1e-13); 1e-15, 1e-13, 1);
PointValuePair optimum PointValuePair optimum
= optimizer.optimize(new MaxEval(100), = optimizer.optimize(new MaxEval(100),
problem.getObjectiveFunction(), problem.getObjectiveFunction(),