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.analysis.MultivariateVectorFunction;
23 import org.apache.commons.math4.legacy.linear.Array2DRowRealMatrix;
24 import org.apache.commons.math4.legacy.linear.RealMatrix;
25 import org.apache.commons.math4.legacy.optim.InitialGuess;
26 import org.apache.commons.math4.legacy.optim.MaxEval;
27 import org.apache.commons.math4.legacy.optim.PointValuePair;
28 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.GoalType;
29 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.LeastSquaresConverter;
30 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.ObjectiveFunction;
31 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv.OptimTestUtils.FourExtrema;
32 import org.apache.commons.math4.legacy.core.MathArrays;
33 import org.junit.Assert;
34 import org.junit.Test;
35 import org.junit.Ignore;
36
37
38
39
40 public class SimplexOptimizerNelderMeadTest {
41 private static final int DIM = 13;
42
43 @Test
44 public void testLeastSquares1() {
45 final RealMatrix factors
46 = new Array2DRowRealMatrix(new double[][] {
47 { 1, 0 },
48 { 0, 1 }
49 }, false);
50 LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorFunction() {
51 @Override
52 public double[] value(double[] variables) {
53 return factors.operate(variables);
54 }
55 }, new double[] { 2.0, -3.0 });
56 SimplexOptimizer optimizer = new SimplexOptimizer(-1, 1e-6);
57 PointValuePair optimum =
58 optimizer.optimize(new MaxEval(200),
59 new ObjectiveFunction(ls),
60 GoalType.MINIMIZE,
61 new InitialGuess(new double[] { 10, 10 }),
62 Simplex.equalSidesAlongAxes(2, 1d),
63 new NelderMeadTransform());
64 Assert.assertEquals( 2, optimum.getPointRef()[0], 1e-3);
65 Assert.assertEquals(-3, optimum.getPointRef()[1], 4e-4);
66 final int nEval = optimizer.getEvaluations();
67 Assert.assertTrue("nEval=" + nEval, nEval > 60);
68 Assert.assertTrue("nEval=" + nEval, nEval < 80);
69 Assert.assertTrue(optimum.getValue() < 1.0e-6);
70 }
71
72 @Test
73 public void testLeastSquares2() {
74 final RealMatrix factors
75 = new Array2DRowRealMatrix(new double[][] {
76 { 1, 0 },
77 { 0, 1 }
78 }, false);
79 LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorFunction() {
80 @Override
81 public double[] value(double[] variables) {
82 return factors.operate(variables);
83 }
84 }, new double[] { 2, -3 }, new double[] { 10, 0.1 });
85 SimplexOptimizer optimizer = new SimplexOptimizer(-1, 1e-6);
86 PointValuePair optimum =
87 optimizer.optimize(new MaxEval(200),
88 new ObjectiveFunction(ls),
89 GoalType.MINIMIZE,
90 new InitialGuess(new double[] { 10, 10 }),
91 Simplex.equalSidesAlongAxes(2, 1d),
92 new NelderMeadTransform());
93 Assert.assertEquals( 2, optimum.getPointRef()[0], 1e-4);
94 Assert.assertEquals(-3, optimum.getPointRef()[1], 8e-4);
95 final int nEval = optimizer.getEvaluations();
96 Assert.assertTrue("nEval=" + nEval, nEval > 70);
97 Assert.assertTrue("nEval=" + nEval, nEval < 85);
98 Assert.assertTrue(optimum.getValue() < 1e-6);
99 }
100
101 @Test
102 public void testLeastSquares3() {
103 final RealMatrix factors =
104 new Array2DRowRealMatrix(new double[][] {
105 { 1, 0 },
106 { 0, 1 }
107 }, false);
108 LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorFunction() {
109 @Override
110 public double[] value(double[] variables) {
111 return factors.operate(variables);
112 }
113 }, new double[] { 2, -3 }, new Array2DRowRealMatrix(new double [][] {
114 { 1, 1.2 }, { 1.2, 2 }
115 }));
116 SimplexOptimizer optimizer = new SimplexOptimizer(-1, 1e-6);
117 PointValuePair optimum
118 = optimizer.optimize(new MaxEval(200),
119 new ObjectiveFunction(ls),
120 GoalType.MINIMIZE,
121 new InitialGuess(new double[] { 10, 10 }),
122 Simplex.equalSidesAlongAxes(2, 1d),
123 new NelderMeadTransform());
124 Assert.assertEquals( 2, optimum.getPointRef()[0], 1e-2);
125 Assert.assertEquals(-3, optimum.getPointRef()[1], 1e-2);
126 final int nEval = optimizer.getEvaluations();
127 Assert.assertTrue("nEval=" + nEval, nEval > 60);
128 Assert.assertTrue("nEval=" + nEval, nEval < 80);
129 Assert.assertTrue(optimum.getValue() < 1e-6);
130 }
131
132 @Test
133 public void testFourExtremaMinimize1() {
134 final OptimTestUtils.FourExtrema f = new OptimTestUtils.FourExtrema();
135 doTest(f,
136 OptimTestUtils.point(new double[] {-3, 0}, 1e-1),
137 GoalType.MINIMIZE,
138 105,
139 Simplex.alongAxes(OptimTestUtils.point(2, 0.2, 1e-2)),
140 new PointValuePair(new double[] {FourExtrema.xM, FourExtrema.yP}, FourExtrema.valueXmYp),
141 1e-6);
142 }
143 @Test
144 public void testFourExtremaMaximize1() {
145 final OptimTestUtils.FourExtrema f = new OptimTestUtils.FourExtrema();
146 doTest(f,
147 OptimTestUtils.point(new double[] {-3, 0}, 1e-1),
148 GoalType.MAXIMIZE,
149 100,
150 Simplex.alongAxes(OptimTestUtils.point(2, 0.2, 1e-2)),
151 new PointValuePair(new double[] {FourExtrema.xM, FourExtrema.yM}, FourExtrema.valueXmYm),
152 1e-6);
153 }
154 @Test
155 public void testFourExtremaMinimize2() {
156 final OptimTestUtils.FourExtrema f = new OptimTestUtils.FourExtrema();
157 doTest(f,
158 OptimTestUtils.point(new double[] {1, 0}, 1e-1),
159 GoalType.MINIMIZE,
160 100,
161 Simplex.alongAxes(OptimTestUtils.point(2, 0.2, 1e-2)),
162 new PointValuePair(new double[] {FourExtrema.xP, FourExtrema.yM}, FourExtrema.valueXpYm),
163 1e-6);
164 }
165 @Test
166 public void testFourExtremaMaximize2() {
167 final OptimTestUtils.FourExtrema f = new OptimTestUtils.FourExtrema();
168 doTest(f,
169 OptimTestUtils.point(new double[] {1, 0}, 1e-1),
170 GoalType.MAXIMIZE,
171 110,
172 Simplex.alongAxes(OptimTestUtils.point(2, 0.2, 1e-2)),
173 new PointValuePair(new double[] {FourExtrema.xP, FourExtrema.yP}, FourExtrema.valueXpYp),
174 1e-6);
175 }
176
177 @Ignore("See MATH-1552")@Test
178 public void testElliRotated() {
179 doTest(new OptimTestUtils.ElliRotated(),
180 OptimTestUtils.point(DIM, 1.0, 1e-1),
181 GoalType.MINIMIZE,
182 7467,
183 new PointValuePair(OptimTestUtils.point(DIM, 0.0), 0.0),
184 1e-14);
185 }
186
187
188
189
190
191
192
193
194
195 private void doTest(MultivariateFunction func,
196 double[] startPoint,
197 GoalType goal,
198 int maxEvaluations,
199 PointValuePair expected,
200 double tol) {
201 doTest(func,
202 startPoint,
203 goal,
204 maxEvaluations,
205 Simplex.equalSidesAlongAxes(startPoint.length, 1d),
206 expected,
207 tol);
208 }
209
210
211
212
213
214
215
216
217
218
219 private void doTest(MultivariateFunction func,
220 double[] startPoint,
221 GoalType goal,
222 int maxEvaluations,
223 Simplex simplex,
224 PointValuePair expected,
225 double tol) {
226 final String name = func.toString();
227
228 final int maxEval = Math.max(maxEvaluations, 12000);
229 final SimplexOptimizer optim = new SimplexOptimizer(1e-13, 1e-14);
230 final PointValuePair result = optim.optimize(new MaxEval(maxEval),
231 new ObjectiveFunction(func),
232 goal,
233 new InitialGuess(startPoint),
234 simplex,
235 new NelderMeadTransform());
236
237 final double[] endPoint = result.getPoint();
238 final double funcValue = result.getValue();
239 Assert.assertEquals(name + ": value at " + Arrays.toString(endPoint),
240 expected.getValue(),
241 funcValue, 1e-2);
242
243 final double dist = MathArrays.distance(expected.getPoint(),
244 endPoint);
245 Assert.assertEquals(name + ": distance to optimum", 0d, dist, tol);
246
247 final int nEval = optim.getEvaluations();
248 Assert.assertTrue(name + ": nEval=" + nEval + " < " + maxEvaluations,
249 nEval < maxEvaluations);
250 }
251 }