1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.hipparchus.optim.nonlinear.scalar.noderiv;
24
25
26 import org.hipparchus.analysis.MultivariateFunction;
27 import org.hipparchus.analysis.MultivariateVectorFunction;
28 import org.hipparchus.exception.MathIllegalStateException;
29 import org.hipparchus.exception.MathRuntimeException;
30 import org.hipparchus.linear.Array2DRowRealMatrix;
31 import org.hipparchus.linear.RealMatrix;
32 import org.hipparchus.optim.InitialGuess;
33 import org.hipparchus.optim.MaxEval;
34 import org.hipparchus.optim.PointValuePair;
35 import org.hipparchus.optim.SimpleBounds;
36 import org.hipparchus.optim.nonlinear.scalar.GoalType;
37 import org.hipparchus.optim.nonlinear.scalar.LeastSquaresConverter;
38 import org.hipparchus.optim.nonlinear.scalar.ObjectiveFunction;
39 import org.hipparchus.util.FastMath;
40 import org.junit.Assert;
41 import org.junit.Test;
42
43 public class SimplexOptimizerNelderMeadTest {
44 @Test(expected=MathRuntimeException.class)
45 public void testBoundsUnsupported() {
46 SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
47 final FourExtrema fourExtrema = new FourExtrema();
48
49 optimizer.optimize(new MaxEval(100),
50 new ObjectiveFunction(fourExtrema),
51 GoalType.MINIMIZE,
52 new InitialGuess(new double[] { -3, 0 }),
53 new NelderMeadSimplex(new double[] { 0.2, 0.2 }),
54 new SimpleBounds(new double[] { -5, -1 },
55 new double[] { 5, 1 }));
56 }
57
58 @Test
59 public void testMinimize1() {
60 SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
61 final FourExtrema fourExtrema = new FourExtrema();
62
63 final PointValuePair optimum
64 = optimizer.optimize(new MaxEval(100),
65 new ObjectiveFunction(fourExtrema),
66 GoalType.MINIMIZE,
67 new InitialGuess(new double[] { -3, 0 }),
68 new NelderMeadSimplex(new double[] { 0.2, 0.2 }));
69 Assert.assertEquals(fourExtrema.xM, optimum.getPoint()[0], 2e-7);
70 Assert.assertEquals(fourExtrema.yP, optimum.getPoint()[1], 2e-5);
71 Assert.assertEquals(fourExtrema.valueXmYp, optimum.getValue(), 6e-12);
72 Assert.assertTrue(optimizer.getEvaluations() > 60);
73 Assert.assertTrue(optimizer.getEvaluations() < 90);
74
75
76 Assert.assertTrue(optimizer.getIterations() > 0);
77 }
78
79 @Test
80 public void testMinimize2() {
81 SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
82 final FourExtrema fourExtrema = new FourExtrema();
83
84 final PointValuePair optimum
85 = optimizer.optimize(new MaxEval(100),
86 new ObjectiveFunction(fourExtrema),
87 GoalType.MINIMIZE,
88 new InitialGuess(new double[] { 1, 0 }),
89 new NelderMeadSimplex(new double[] { 0.2, 0.2 }));
90 Assert.assertEquals(fourExtrema.xP, optimum.getPoint()[0], 5e-6);
91 Assert.assertEquals(fourExtrema.yM, optimum.getPoint()[1], 6e-6);
92 Assert.assertEquals(fourExtrema.valueXpYm, optimum.getValue(), 1e-11);
93 Assert.assertTrue(optimizer.getEvaluations() > 60);
94 Assert.assertTrue(optimizer.getEvaluations() < 90);
95
96
97 Assert.assertTrue(optimizer.getIterations() > 0);
98 }
99
100 @Test
101 public void testMaximize1() {
102 SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
103 final FourExtrema fourExtrema = new FourExtrema();
104
105 final PointValuePair optimum
106 = optimizer.optimize(new MaxEval(100),
107 new ObjectiveFunction(fourExtrema),
108 GoalType.MAXIMIZE,
109 new InitialGuess(new double[] { -3, 0 }),
110 new NelderMeadSimplex(new double[] { 0.2, 0.2 }));
111 Assert.assertEquals(fourExtrema.xM, optimum.getPoint()[0], 1e-5);
112 Assert.assertEquals(fourExtrema.yM, optimum.getPoint()[1], 3e-6);
113 Assert.assertEquals(fourExtrema.valueXmYm, optimum.getValue(), 3e-12);
114 Assert.assertTrue(optimizer.getEvaluations() > 60);
115 Assert.assertTrue(optimizer.getEvaluations() < 90);
116
117
118 Assert.assertTrue(optimizer.getIterations() > 0);
119 }
120
121 @Test
122 public void testMaximize2() {
123 SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
124 final FourExtrema fourExtrema = new FourExtrema();
125
126 final PointValuePair optimum
127 = optimizer.optimize(new MaxEval(100),
128 new ObjectiveFunction(fourExtrema),
129 GoalType.MAXIMIZE,
130 new InitialGuess(new double[] { 1, 0 }),
131 new NelderMeadSimplex(new double[] { 0.2, 0.2 }));
132 Assert.assertEquals(fourExtrema.xP, optimum.getPoint()[0], 4e-6);
133 Assert.assertEquals(fourExtrema.yP, optimum.getPoint()[1], 5e-6);
134 Assert.assertEquals(fourExtrema.valueXpYp, optimum.getValue(), 7e-12);
135 Assert.assertTrue(optimizer.getEvaluations() > 60);
136 Assert.assertTrue(optimizer.getEvaluations() < 90);
137
138
139 Assert.assertTrue(optimizer.getIterations() > 0);
140 }
141
142 @Test
143 public void testRosenbrock() {
144
145 Rosenbrock rosenbrock = new Rosenbrock();
146 SimplexOptimizer optimizer = new SimplexOptimizer(-1, 1e-3);
147 PointValuePair optimum
148 = optimizer.optimize(new MaxEval(100),
149 new ObjectiveFunction(rosenbrock),
150 GoalType.MINIMIZE,
151 new InitialGuess(new double[] { -1.2, 1 }),
152 new NelderMeadSimplex(new double[][] {
153 { -1.2, 1 },
154 { 0.9, 1.2 },
155 { 3.5, -2.3 } }));
156
157 Assert.assertEquals(rosenbrock.getCount(), optimizer.getEvaluations());
158 Assert.assertTrue(optimizer.getEvaluations() > 40);
159 Assert.assertTrue(optimizer.getEvaluations() < 50);
160 Assert.assertTrue(optimum.getValue() < 8e-4);
161 }
162
163 @Test
164 public void testPowell() {
165 Powell powell = new Powell();
166 SimplexOptimizer optimizer = new SimplexOptimizer(-1, 1e-3);
167 PointValuePair optimum =
168 optimizer.optimize(new MaxEval(200),
169 new ObjectiveFunction(powell),
170 GoalType.MINIMIZE,
171 new InitialGuess(new double[] { 3, -1, 0, 1 }),
172 new NelderMeadSimplex(4));
173 Assert.assertEquals(powell.getCount(), optimizer.getEvaluations());
174 Assert.assertTrue(optimizer.getEvaluations() > 110);
175 Assert.assertTrue(optimizer.getEvaluations() < 130);
176 Assert.assertTrue(optimum.getValue() < 2e-3);
177 }
178
179 @Test
180 public void testLeastSquares1() {
181 final RealMatrix factors
182 = new Array2DRowRealMatrix(new double[][] {
183 { 1, 0 },
184 { 0, 1 }
185 }, false);
186 LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorFunction() {
187 public double[] value(double[] variables) {
188 return factors.operate(variables);
189 }
190 }, new double[] { 2.0, -3.0 });
191 SimplexOptimizer optimizer = new SimplexOptimizer(-1, 1e-6);
192 PointValuePair optimum =
193 optimizer.optimize(new MaxEval(200),
194 new ObjectiveFunction(ls),
195 GoalType.MINIMIZE,
196 new InitialGuess(new double[] { 10, 10 }),
197 new NelderMeadSimplex(2));
198 Assert.assertEquals( 2, optimum.getPointRef()[0], 3e-5);
199 Assert.assertEquals(-3, optimum.getPointRef()[1], 4e-4);
200 Assert.assertTrue(optimizer.getEvaluations() > 60);
201 Assert.assertTrue(optimizer.getEvaluations() < 80);
202 Assert.assertTrue(optimum.getValue() < 1.0e-6);
203 }
204
205 @Test
206 public void testLeastSquares2() {
207 final RealMatrix factors
208 = new Array2DRowRealMatrix(new double[][] {
209 { 1, 0 },
210 { 0, 1 }
211 }, false);
212 LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorFunction() {
213 public double[] value(double[] variables) {
214 return factors.operate(variables);
215 }
216 }, new double[] { 2, -3 }, new double[] { 10, 0.1 });
217 SimplexOptimizer optimizer = new SimplexOptimizer(-1, 1e-6);
218 PointValuePair optimum =
219 optimizer.optimize(new MaxEval(200),
220 new ObjectiveFunction(ls),
221 GoalType.MINIMIZE,
222 new InitialGuess(new double[] { 10, 10 }),
223 new NelderMeadSimplex(2));
224 Assert.assertEquals( 2, optimum.getPointRef()[0], 5e-5);
225 Assert.assertEquals(-3, optimum.getPointRef()[1], 8e-4);
226 Assert.assertTrue(optimizer.getEvaluations() > 60);
227 Assert.assertTrue(optimizer.getEvaluations() < 80);
228 Assert.assertTrue(optimum.getValue() < 1e-6);
229 }
230
231 @Test
232 public void testLeastSquares3() {
233 final RealMatrix factors =
234 new Array2DRowRealMatrix(new double[][] {
235 { 1, 0 },
236 { 0, 1 }
237 }, false);
238 LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorFunction() {
239 public double[] value(double[] variables) {
240 return factors.operate(variables);
241 }
242 }, new double[] { 2, -3 }, new Array2DRowRealMatrix(new double [][] {
243 { 1, 1.2 }, { 1.2, 2 }
244 }));
245 SimplexOptimizer optimizer = new SimplexOptimizer(-1, 1e-6);
246 PointValuePair optimum
247 = optimizer.optimize(new MaxEval(200),
248 new ObjectiveFunction(ls),
249 GoalType.MINIMIZE,
250 new InitialGuess(new double[] { 10, 10 }),
251 new NelderMeadSimplex(2));
252 Assert.assertEquals( 2, optimum.getPointRef()[0], 2e-3);
253 Assert.assertEquals(-3, optimum.getPointRef()[1], 8e-4);
254 Assert.assertTrue(optimizer.getEvaluations() > 60);
255 Assert.assertTrue(optimizer.getEvaluations() < 80);
256 Assert.assertTrue(optimum.getValue() < 1e-6);
257 }
258
259 @Test(expected=MathIllegalStateException.class)
260 public void testMaxIterations() {
261 Powell powell = new Powell();
262 SimplexOptimizer optimizer = new SimplexOptimizer(-1, 1e-3);
263 optimizer.optimize(new MaxEval(20),
264 new ObjectiveFunction(powell),
265 GoalType.MINIMIZE,
266 new InitialGuess(new double[] { 3, -1, 0, 1 }),
267 new NelderMeadSimplex(4));
268 }
269
270 private static class FourExtrema implements MultivariateFunction {
271
272 final double xM = -3.841947088256863675365;
273 final double yM = -1.391745200270734924416;
274 final double xP = 0.2286682237349059125691;
275 final double yP = -yM;
276 final double valueXmYm = 0.2373295333134216789769;
277 final double valueXmYp = -valueXmYm;
278 final double valueXpYm = -0.7290400707055187115322;
279 final double valueXpYp = -valueXpYm;
280
281 public double value(double[] variables) {
282 final double x = variables[0];
283 final double y = variables[1];
284 return (x == 0 || y == 0) ? 0 :
285 FastMath.atan(x) * FastMath.atan(x + 2) * FastMath.atan(y) * FastMath.atan(y) / (x * y);
286 }
287 }
288
289 private static class Rosenbrock implements MultivariateFunction {
290 private int count;
291
292 public Rosenbrock() {
293 count = 0;
294 }
295
296 public double value(double[] x) {
297 ++count;
298 double a = x[1] - x[0] * x[0];
299 double b = 1.0 - x[0];
300 return 100 * a * a + b * b;
301 }
302
303 public int getCount() {
304 return count;
305 }
306 }
307
308 private static class Powell implements MultivariateFunction {
309 private int count;
310
311 public Powell() {
312 count = 0;
313 }
314
315 public double value(double[] x) {
316 ++count;
317 double a = x[0] + 10 * x[1];
318 double b = x[2] - x[3];
319 double c = x[1] - 2 * x[2];
320 double d = x[0] - x[3];
321 return a * a + 5 * b * b + c * c * c * c + 10 * d * d * d * d;
322 }
323
324 public int getCount() {
325 return count;
326 }
327 }
328 }