MATH-413
Convergence checker passed in the constructor. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1164300 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1ef23c7fb5
commit
681943d4f2
|
@ -63,10 +63,6 @@ import org.apache.commons.math.optimization.MultivariateRealOptimizer;
|
|||
* re-initialized to one with the appropriate dimensions.
|
||||
* </p>
|
||||
* <p>
|
||||
* If {@link #setConvergenceChecker(ConvergenceChecker)} is not called,
|
||||
* a default {@link SimpleScalarValueChecker} is used.
|
||||
* </p>
|
||||
* <p>
|
||||
* Convergence is checked by providing the <em>worst</em> points of
|
||||
* previous and current simplex to the convergence checker, not the best
|
||||
* ones.
|
||||
|
@ -83,10 +79,18 @@ public class SimplexOptimizer
|
|||
private AbstractSimplex simplex;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* Constructor using a default {@link SimpleScalarValueChecker convergence
|
||||
* checker}.
|
||||
*/
|
||||
public SimplexOptimizer() {
|
||||
setConvergenceChecker(new SimpleScalarValueChecker());
|
||||
this(new SimpleScalarValueChecker());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param checker Convergence checker.
|
||||
*/
|
||||
public SimplexOptimizer(ConvergenceChecker<RealPointValuePair> checker) {
|
||||
super(checker);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,7 +98,7 @@ public class SimplexOptimizer
|
|||
* @param abs Absolute threshold.
|
||||
*/
|
||||
public SimplexOptimizer(double rel, double abs) {
|
||||
setConvergenceChecker(new SimpleScalarValueChecker(rel, abs));
|
||||
this(new SimpleScalarValueChecker(rel, abs));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,57 +27,61 @@ import org.junit.Test;
|
|||
|
||||
public class SimplexOptimizerMultiDirectionalTest {
|
||||
@Test
|
||||
public void testMinimizeMaximize() {
|
||||
// the following function has 4 local extrema:
|
||||
final double xM = -3.841947088256863675365;
|
||||
final double yM = -1.391745200270734924416;
|
||||
final double xP = 0.2286682237349059125691;
|
||||
final double yP = -yM;
|
||||
final double valueXmYm = 0.2373295333134216789769; // local maximum
|
||||
final double valueXmYp = -valueXmYm; // local minimum
|
||||
final double valueXpYm = -0.7290400707055187115322; // global minimum
|
||||
final double valueXpYp = -valueXpYm; // global maximum
|
||||
MultivariateRealFunction fourExtrema = new MultivariateRealFunction() {
|
||||
public double value(double[] variables) {
|
||||
final double x = variables[0];
|
||||
final double y = variables[1];
|
||||
return ((x == 0) || (y == 0)) ? 0 :
|
||||
(FastMath.atan(x) * FastMath.atan(x + 2) * FastMath.atan(y) * FastMath.atan(y) / (x * y));
|
||||
}
|
||||
};
|
||||
|
||||
public void testMinimize1() {
|
||||
SimplexOptimizer optimizer = new SimplexOptimizer(1e-11, 1e-30);
|
||||
optimizer.setSimplex(new MultiDirectionalSimplex(new double[] { 0.2, 0.2 }));
|
||||
RealPointValuePair optimum;
|
||||
final FourExtrema fourExtrema = new FourExtrema();
|
||||
|
||||
// minimization
|
||||
optimum = optimizer.optimize(200, fourExtrema, GoalType.MINIMIZE, new double[] { -3, 0 });
|
||||
Assert.assertEquals(xM, optimum.getPoint()[0], 4e-6);
|
||||
Assert.assertEquals(yP, optimum.getPoint()[1], 3e-6);
|
||||
Assert.assertEquals(valueXmYp, optimum.getValue(), 8e-13);
|
||||
final RealPointValuePair optimum
|
||||
= optimizer.optimize(200, fourExtrema, GoalType.MINIMIZE, new double[] { -3, 0 });
|
||||
Assert.assertEquals(fourExtrema.xM, optimum.getPoint()[0], 4e-6);
|
||||
Assert.assertEquals(fourExtrema.yP, optimum.getPoint()[1], 3e-6);
|
||||
Assert.assertEquals(fourExtrema.valueXmYp, optimum.getValue(), 8e-13);
|
||||
Assert.assertTrue(optimizer.getEvaluations() > 120);
|
||||
Assert.assertTrue(optimizer.getEvaluations() < 150);
|
||||
}
|
||||
|
||||
optimum = optimizer.optimize(200, fourExtrema, GoalType.MINIMIZE, new double[] { 1, 0 });
|
||||
Assert.assertEquals(xP, optimum.getPoint()[0], 2e-8);
|
||||
Assert.assertEquals(yM, optimum.getPoint()[1], 3e-6);
|
||||
Assert.assertEquals(valueXpYm, optimum.getValue(), 2e-12);
|
||||
@Test
|
||||
public void testMinimize2() {
|
||||
SimplexOptimizer optimizer = new SimplexOptimizer(1e-11, 1e-30);
|
||||
optimizer.setSimplex(new MultiDirectionalSimplex(new double[] { 0.2, 0.2 }));
|
||||
final FourExtrema fourExtrema = new FourExtrema();
|
||||
|
||||
final RealPointValuePair optimum
|
||||
= optimizer.optimize(200, fourExtrema, GoalType.MINIMIZE, new double[] { 1, 0 });
|
||||
Assert.assertEquals(fourExtrema.xP, optimum.getPoint()[0], 2e-8);
|
||||
Assert.assertEquals(fourExtrema.yM, optimum.getPoint()[1], 3e-6);
|
||||
Assert.assertEquals(fourExtrema.valueXpYm, optimum.getValue(), 2e-12);
|
||||
Assert.assertTrue(optimizer.getEvaluations() > 120);
|
||||
Assert.assertTrue(optimizer.getEvaluations() < 150);
|
||||
}
|
||||
|
||||
// maximization
|
||||
optimum = optimizer.optimize(200, fourExtrema, GoalType.MAXIMIZE, new double[] { -3.0, 0.0 });
|
||||
Assert.assertEquals(xM, optimum.getPoint()[0], 7e-7);
|
||||
Assert.assertEquals(yM, optimum.getPoint()[1], 3e-7);
|
||||
Assert.assertEquals(valueXmYm, optimum.getValue(), 2e-14);
|
||||
@Test
|
||||
public void testMaximize1() {
|
||||
SimplexOptimizer optimizer = new SimplexOptimizer(1e-11, 1e-30);
|
||||
optimizer.setSimplex(new MultiDirectionalSimplex(new double[] { 0.2, 0.2 }));
|
||||
final FourExtrema fourExtrema = new FourExtrema();
|
||||
|
||||
final RealPointValuePair optimum
|
||||
= optimizer.optimize(200, fourExtrema, GoalType.MAXIMIZE, new double[] { -3.0, 0.0 });
|
||||
Assert.assertEquals(fourExtrema.xM, optimum.getPoint()[0], 7e-7);
|
||||
Assert.assertEquals(fourExtrema.yM, optimum.getPoint()[1], 3e-7);
|
||||
Assert.assertEquals(fourExtrema.valueXmYm, optimum.getValue(), 2e-14);
|
||||
Assert.assertTrue(optimizer.getEvaluations() > 120);
|
||||
Assert.assertTrue(optimizer.getEvaluations() < 150);
|
||||
}
|
||||
|
||||
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1e-15, 1e-30));
|
||||
optimum = optimizer.optimize(200, fourExtrema, GoalType.MAXIMIZE, new double[] { 1, 0 });
|
||||
Assert.assertEquals(xP, optimum.getPoint()[0], 2e-8);
|
||||
Assert.assertEquals(yP, optimum.getPoint()[1], 3e-6);
|
||||
Assert.assertEquals(valueXpYp, optimum.getValue(), 2e-12);
|
||||
@Test
|
||||
public void testMaximize2() {
|
||||
SimplexOptimizer optimizer = new SimplexOptimizer(new SimpleScalarValueChecker(1e-15, 1e-30));
|
||||
optimizer.setSimplex(new MultiDirectionalSimplex(new double[] { 0.2, 0.2 }));
|
||||
final FourExtrema fourExtrema = new FourExtrema();
|
||||
|
||||
final RealPointValuePair optimum
|
||||
= optimizer.optimize(200, fourExtrema, GoalType.MAXIMIZE, new double[] { 1, 0 });
|
||||
Assert.assertEquals(fourExtrema.xP, optimum.getPoint()[0], 2e-8);
|
||||
Assert.assertEquals(fourExtrema.yP, optimum.getPoint()[1], 3e-6);
|
||||
Assert.assertEquals(fourExtrema.valueXpYp, optimum.getValue(), 2e-12);
|
||||
Assert.assertTrue(optimizer.getEvaluations() > 180);
|
||||
Assert.assertTrue(optimizer.getEvaluations() < 220);
|
||||
}
|
||||
|
@ -153,6 +157,25 @@ public class SimplexOptimizerMultiDirectionalTest {
|
|||
Assert.assertEquals(expectedPosition[1], actualPosition[1], EPSILON );
|
||||
}
|
||||
|
||||
private static class FourExtrema implements MultivariateRealFunction {
|
||||
// The following function has 4 local extrema.
|
||||
final double xM = -3.841947088256863675365;
|
||||
final double yM = -1.391745200270734924416;
|
||||
final double xP = 0.2286682237349059125691;
|
||||
final double yP = -yM;
|
||||
final double valueXmYm = 0.2373295333134216789769; // Local maximum.
|
||||
final double valueXmYp = -valueXmYm; // Local minimum.
|
||||
final double valueXpYm = -0.7290400707055187115322; // Global minimum.
|
||||
final double valueXpYp = -valueXpYm; // Global maximum.
|
||||
|
||||
public double value(double[] variables) {
|
||||
final double x = variables[0];
|
||||
final double y = variables[1];
|
||||
return (x == 0 || y == 0) ? 0 :
|
||||
FastMath.atan(x) * FastMath.atan(x + 2) * FastMath.atan(y) * FastMath.atan(y) / (x * y);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Gaussian2D implements MultivariateRealFunction {
|
||||
private final double[] maximumPosition;
|
||||
private final double std;
|
||||
|
|
|
@ -26,62 +26,67 @@ import org.apache.commons.math.linear.RealMatrix;
|
|||
import org.apache.commons.math.optimization.GoalType;
|
||||
import org.apache.commons.math.optimization.LeastSquaresConverter;
|
||||
import org.apache.commons.math.optimization.RealPointValuePair;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SimplexOptimizerNelderMeadTest {
|
||||
@Test
|
||||
public void testMinimizeMaximize() {
|
||||
|
||||
// the following function has 4 local extrema:
|
||||
final double xM = -3.841947088256863675365;
|
||||
final double yM = -1.391745200270734924416;
|
||||
final double xP = 0.2286682237349059125691;
|
||||
final double yP = -yM;
|
||||
final double valueXmYm = 0.2373295333134216789769; // local maximum
|
||||
final double valueXmYp = -valueXmYm; // local minimum
|
||||
final double valueXpYm = -0.7290400707055187115322; // global minimum
|
||||
final double valueXpYp = -valueXpYm; // global maximum
|
||||
MultivariateRealFunction fourExtrema = new MultivariateRealFunction() {
|
||||
public double value(double[] variables) {
|
||||
final double x = variables[0];
|
||||
final double y = variables[1];
|
||||
return (x == 0 || y == 0) ? 0 :
|
||||
(Math.atan(x) * Math.atan(x + 2) * Math.atan(y) * Math.atan(y) / (x * y));
|
||||
}
|
||||
};
|
||||
|
||||
public void testMinimize1() {
|
||||
SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
|
||||
optimizer.setSimplex(new NelderMeadSimplex(new double[] { 0.2, 0.2 }));
|
||||
RealPointValuePair optimum;
|
||||
final FourExtrema fourExtrema = new FourExtrema();
|
||||
|
||||
// minimization
|
||||
optimum = optimizer.optimize(100, fourExtrema, GoalType.MINIMIZE, new double[] { -3, 0 });
|
||||
Assert.assertEquals(xM, optimum.getPoint()[0], 2e-7);
|
||||
Assert.assertEquals(yP, optimum.getPoint()[1], 2e-5);
|
||||
Assert.assertEquals(valueXmYp, optimum.getValue(), 6e-12);
|
||||
final RealPointValuePair optimum
|
||||
= optimizer.optimize(100, fourExtrema, GoalType.MINIMIZE, new double[] { -3, 0 });
|
||||
Assert.assertEquals(fourExtrema.xM, optimum.getPoint()[0], 2e-7);
|
||||
Assert.assertEquals(fourExtrema.yP, optimum.getPoint()[1], 2e-5);
|
||||
Assert.assertEquals(fourExtrema.valueXmYp, optimum.getValue(), 6e-12);
|
||||
Assert.assertTrue(optimizer.getEvaluations() > 60);
|
||||
Assert.assertTrue(optimizer.getEvaluations() < 90);
|
||||
}
|
||||
|
||||
optimum = optimizer.optimize(100, fourExtrema, GoalType.MINIMIZE, new double[] { 1, 0 });
|
||||
Assert.assertEquals(xP, optimum.getPoint()[0], 5e-6);
|
||||
Assert.assertEquals(yM, optimum.getPoint()[1], 6e-6);
|
||||
Assert.assertEquals(valueXpYm, optimum.getValue(), 1e-11);
|
||||
@Test
|
||||
public void testMinimize2() {
|
||||
SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
|
||||
optimizer.setSimplex(new NelderMeadSimplex(new double[] { 0.2, 0.2 }));
|
||||
final FourExtrema fourExtrema = new FourExtrema();
|
||||
|
||||
final RealPointValuePair optimum
|
||||
= optimizer.optimize(100, fourExtrema, GoalType.MINIMIZE, new double[] { 1, 0 });
|
||||
Assert.assertEquals(fourExtrema.xP, optimum.getPoint()[0], 5e-6);
|
||||
Assert.assertEquals(fourExtrema.yM, optimum.getPoint()[1], 6e-6);
|
||||
Assert.assertEquals(fourExtrema.valueXpYm, optimum.getValue(), 1e-11);
|
||||
Assert.assertTrue(optimizer.getEvaluations() > 60);
|
||||
Assert.assertTrue(optimizer.getEvaluations() < 90);
|
||||
}
|
||||
|
||||
// maximization
|
||||
optimum = optimizer.optimize(100, fourExtrema, GoalType.MAXIMIZE, new double[] { -3, 0 });
|
||||
Assert.assertEquals(xM, optimum.getPoint()[0], 1e-5);
|
||||
Assert.assertEquals(yM, optimum.getPoint()[1], 3e-6);
|
||||
Assert.assertEquals(valueXmYm, optimum.getValue(), 3e-12);
|
||||
@Test
|
||||
public void testMaximize1() {
|
||||
SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
|
||||
optimizer.setSimplex(new NelderMeadSimplex(new double[] { 0.2, 0.2 }));
|
||||
final FourExtrema fourExtrema = new FourExtrema();
|
||||
|
||||
final RealPointValuePair optimum
|
||||
= optimizer.optimize(100, fourExtrema, GoalType.MAXIMIZE, new double[] { -3, 0 });
|
||||
Assert.assertEquals(fourExtrema.xM, optimum.getPoint()[0], 1e-5);
|
||||
Assert.assertEquals(fourExtrema.yM, optimum.getPoint()[1], 3e-6);
|
||||
Assert.assertEquals(fourExtrema.valueXmYm, optimum.getValue(), 3e-12);
|
||||
Assert.assertTrue(optimizer.getEvaluations() > 60);
|
||||
Assert.assertTrue(optimizer.getEvaluations() < 90);
|
||||
}
|
||||
|
||||
optimum = optimizer.optimize(100, fourExtrema, GoalType.MAXIMIZE, new double[] { 1, 0 });
|
||||
Assert.assertEquals(xP, optimum.getPoint()[0], 4e-6);
|
||||
Assert.assertEquals(yP, optimum.getPoint()[1], 5e-6);
|
||||
Assert.assertEquals(valueXpYp, optimum.getValue(), 7e-12);
|
||||
@Test
|
||||
public void testMaximize2() {
|
||||
SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
|
||||
optimizer.setSimplex(new NelderMeadSimplex(new double[] { 0.2, 0.2 }));
|
||||
final FourExtrema fourExtrema = new FourExtrema();
|
||||
|
||||
final RealPointValuePair optimum
|
||||
= optimizer.optimize(100, fourExtrema, GoalType.MAXIMIZE, new double[] { 1, 0 });
|
||||
Assert.assertEquals(fourExtrema.xP, optimum.getPoint()[0], 4e-6);
|
||||
Assert.assertEquals(fourExtrema.yP, optimum.getPoint()[1], 5e-6);
|
||||
Assert.assertEquals(fourExtrema.valueXpYp, optimum.getValue(), 7e-12);
|
||||
Assert.assertTrue(optimizer.getEvaluations() > 60);
|
||||
Assert.assertTrue(optimizer.getEvaluations() < 90);
|
||||
}
|
||||
|
@ -199,6 +204,25 @@ public class SimplexOptimizerNelderMeadTest {
|
|||
optimizer.optimize(20, powell, GoalType.MINIMIZE, new double[] { 3, -1, 0, 1 });
|
||||
}
|
||||
|
||||
private static class FourExtrema implements MultivariateRealFunction {
|
||||
// The following function has 4 local extrema.
|
||||
final double xM = -3.841947088256863675365;
|
||||
final double yM = -1.391745200270734924416;
|
||||
final double xP = 0.2286682237349059125691;
|
||||
final double yP = -yM;
|
||||
final double valueXmYm = 0.2373295333134216789769; // Local maximum.
|
||||
final double valueXmYp = -valueXmYm; // Local minimum.
|
||||
final double valueXpYm = -0.7290400707055187115322; // Global minimum.
|
||||
final double valueXpYp = -valueXpYm; // Global maximum.
|
||||
|
||||
public double value(double[] variables) {
|
||||
final double x = variables[0];
|
||||
final double y = variables[1];
|
||||
return (x == 0 || y == 0) ? 0 :
|
||||
FastMath.atan(x) * FastMath.atan(x + 2) * FastMath.atan(y) * FastMath.atan(y) / (x * y);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Rosenbrock implements MultivariateRealFunction {
|
||||
private int count;
|
||||
|
||||
|
|
Loading…
Reference in New Issue