1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv;
19
20 import java.util.Arrays;
21 import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
22 import org.apache.commons.math4.legacy.optim.InitialGuess;
23 import org.apache.commons.math4.legacy.optim.MaxEval;
24 import org.apache.commons.math4.legacy.optim.PointValuePair;
25 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.GoalType;
26 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.ObjectiveFunction;
27 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv.OptimTestUtils.FourExtrema;
28 import org.apache.commons.math4.legacy.core.MathArrays;
29 import org.apache.commons.math4.core.jdkmath.JdkMath;
30 import org.junit.Assert;
31 import org.junit.Test;
32 import org.junit.Ignore;
33
34
35
36
37 public class SimplexOptimizerMultiDirectionalTest {
38 private static final int DIM = 13;
39
40 @Test
41 public void testMath283() {
42 SimplexOptimizer optimizer = new SimplexOptimizer(1e-14, 1e-14);
43 final Gaussian2D function = new Gaussian2D(0, 0, 1);
44 PointValuePair estimate = optimizer.optimize(new MaxEval(1000),
45 new ObjectiveFunction(function),
46 GoalType.MAXIMIZE,
47 new InitialGuess(function.getMaximumPosition()),
48 Simplex.equalSidesAlongAxes(2, 1d),
49 new MultiDirectionalTransform());
50 final double EPSILON = 1e-5;
51 final double expectedMaximum = function.getMaximum();
52 final double actualMaximum = estimate.getValue();
53 Assert.assertEquals(expectedMaximum, actualMaximum, EPSILON);
54
55 final double[] expectedPosition = function.getMaximumPosition();
56 final double[] actualPosition = estimate.getPoint();
57 Assert.assertEquals(expectedPosition[0], actualPosition[0], EPSILON );
58 Assert.assertEquals(expectedPosition[1], actualPosition[1], EPSILON );
59 }
60
61 @Test
62 public void testFourExtremaMinimize1() {
63 final OptimTestUtils.FourExtrema f = new OptimTestUtils.FourExtrema();
64 doTest(f,
65 OptimTestUtils.point(new double[] {-3, 0}, 1e-1),
66 GoalType.MINIMIZE,
67 105,
68 Simplex.alongAxes(OptimTestUtils.point(2, 0.2, 1e-2)),
69 new PointValuePair(new double[] {FourExtrema.xM, FourExtrema.yP}, FourExtrema.valueXmYp),
70 1e-6);
71 }
72 @Test
73 public void testFourExtremaMaximize1() {
74 final OptimTestUtils.FourExtrema f = new OptimTestUtils.FourExtrema();
75 doTest(f,
76 OptimTestUtils.point(new double[] {-3, 0}, 1e-1),
77 GoalType.MAXIMIZE,
78 100,
79 Simplex.alongAxes(OptimTestUtils.point(2, 0.2, 1e-2)),
80 new PointValuePair(new double[] {FourExtrema.xM, FourExtrema.yM}, FourExtrema.valueXmYm),
81 1e-6);
82 }
83 @Test
84 public void testFourExtremaMinimize2() {
85 final OptimTestUtils.FourExtrema f = new OptimTestUtils.FourExtrema();
86 doTest(f,
87 OptimTestUtils.point(new double[] {1, 0}, 1e-1),
88 GoalType.MINIMIZE,
89 100,
90 Simplex.alongAxes(OptimTestUtils.point(2, 0.2, 1e-2)),
91 new PointValuePair(new double[] {FourExtrema.xP, FourExtrema.yM}, FourExtrema.valueXpYm),
92 1e-6);
93 }
94 @Test
95 public void testFourExtremaMaximize2() {
96 final OptimTestUtils.FourExtrema f = new OptimTestUtils.FourExtrema();
97 doTest(f,
98 OptimTestUtils.point(new double[] {1, 0}, 1e-1),
99 GoalType.MAXIMIZE,
100 110,
101 Simplex.alongAxes(OptimTestUtils.point(2, 0.2, 1e-2)),
102 new PointValuePair(new double[] {FourExtrema.xP, FourExtrema.yP}, FourExtrema.valueXpYp),
103 1e-6);
104 }
105
106 @Ignore("See MATH-1552")@Test
107 public void testElliRotated() {
108 doTest(new OptimTestUtils.ElliRotated(),
109 OptimTestUtils.point(DIM, 1.0, 1e-1),
110 GoalType.MINIMIZE,
111 911,
112 new PointValuePair(OptimTestUtils.point(DIM, 0.0), 0.0),
113 1e-9);
114 }
115
116
117
118
119
120
121
122
123
124 private void doTest(MultivariateFunction func,
125 double[] startPoint,
126 GoalType goal,
127 int maxEvaluations,
128 PointValuePair expected,
129 double tol) {
130 doTest(func,
131 startPoint,
132 goal,
133 maxEvaluations,
134 Simplex.equalSidesAlongAxes(startPoint.length, 1),
135 expected,
136 tol);
137 }
138
139
140
141
142
143
144
145
146
147
148 private void doTest(MultivariateFunction func,
149 double[] startPoint,
150 GoalType goal,
151 int maxEvaluations,
152 Simplex simplex,
153 PointValuePair expected,
154 double tol) {
155 final int maxEval = Math.max(maxEvaluations, 12000);
156 final SimplexOptimizer optim = new SimplexOptimizer(1e-13, 1e-14);
157 final PointValuePair result = optim.optimize(new MaxEval(maxEval),
158 new ObjectiveFunction(func),
159 goal,
160 new InitialGuess(startPoint),
161 simplex,
162 new NelderMeadTransform());
163 final String name = func.toString();
164
165 final double[] endPoint = result.getPoint();
166 final double funcValue = result.getValue();
167 Assert.assertEquals(name + ": value at " + Arrays.toString(endPoint),
168 expected.getValue(),
169 funcValue, 1e-2);
170
171 final double dist = MathArrays.distance(expected.getPoint(),
172 endPoint);
173 Assert.assertEquals(name + ": distance to optimum", 0d, dist, tol);
174
175 final int nEval = optim.getEvaluations();
176 Assert.assertTrue(name + ": nEval=" + nEval,
177 nEval < maxEvaluations);
178 }
179
180 private static final class Gaussian2D implements MultivariateFunction {
181 private final double[] maximumPosition;
182 private final double std;
183
184 Gaussian2D(double xOpt, double yOpt, double std) {
185 maximumPosition = new double[] { xOpt, yOpt };
186 this.std = std;
187 }
188
189 public double getMaximum() {
190 return value(maximumPosition);
191 }
192
193 public double[] getMaximumPosition() {
194 return maximumPosition.clone();
195 }
196
197 @Override
198 public double value(double[] point) {
199 final double x = point[0];
200 final double y = point[1];
201 final double twoS2 = 2.0 * std * std;
202 return 1.0 / (twoS2 * JdkMath.PI) * JdkMath.exp(-(x * x + y * y) / twoS2);
203 }
204 }
205 }