* still hold sensible values because they are used to set the line search
* tolerances.
*/
@Test
public void testRelativeToleranceOnScaledValues() {
final MultivariateFunction func = new MultivariateFunction() {
public double value(double[] x) {
final double a = x[0] - 1;
final double b = x[1] - 1;
return a * a * FastMath.sqrt(FastMath.abs(a)) + b * b + 1;
}
};
int dim = 2;
final double[] minPoint = new double[dim];
for (int i = 0; i < dim; i++) {
minPoint[i] = 1;
}
double[] init = new double[dim];
// Initial is far from minimum.
for (int i = 0; i < dim; i++) {
init[i] = minPoint[i] - 20;
}
final double relTol = 1e-10;
final int maxEval = 1000;
// Very small absolute tolerance to rely solely on the relative
// tolerance as a stopping criterion
final PowellOptimizer optim = new PowellOptimizer(relTol, 1e-100);
final PointValuePair funcResult = optim.optimize(new MaxEval(maxEval),
new ObjectiveFunction(func),
GoalType.MINIMIZE,
new InitialGuess(init));
final double funcValue = func.value(funcResult.getPoint());
final int funcEvaluations = optim.getEvaluations();
final double scale = 1e10;
final MultivariateFunction funcScaled = new MultivariateFunction() {
public double value(double[] x) {
return scale * func.value(x);
}
};
final PointValuePair funcScaledResult = optim.optimize(new MaxEval(maxEval),
new ObjectiveFunction(funcScaled),
GoalType.MINIMIZE,
new InitialGuess(init));
final double funcScaledValue = funcScaled.value(funcScaledResult.getPoint());
final int funcScaledEvaluations = optim.getEvaluations();
// Check that both minima provide the same objective funciton values,
// within the relative function tolerance.
Assert.assertEquals(1, funcScaledValue / (scale * funcValue), relTol);