1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv;
18
19 import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
20 import org.apache.commons.math4.legacy.analysis.SumSincFunction;
21 import org.apache.commons.math4.legacy.exception.MathUnsupportedOperationException;
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.SimpleBounds;
26 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.GoalType;
27 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.ObjectiveFunction;
28 import org.apache.commons.math4.core.jdkmath.JdkMath;
29 import org.junit.Assert;
30 import org.junit.Test;
31
32
33
34
35 public class PowellOptimizerTest {
36 @Test(expected=MathUnsupportedOperationException.class)
37 public void testBoundsUnsupported() {
38 final MultivariateFunction func = new SumSincFunction(-1);
39 final PowellOptimizer optim = new PowellOptimizer(1e-8, 1e-5,
40 1e-4, 1e-4);
41
42 optim.optimize(new MaxEval(100),
43 new ObjectiveFunction(func),
44 GoalType.MINIMIZE,
45 new InitialGuess(new double[] { -3, 0 }),
46 new SimpleBounds(new double[] { -5, -1 },
47 new double[] { 5, 1 }));
48 }
49
50 @Test
51 public void testSumSinc() {
52 final MultivariateFunction func = new SumSincFunction(-1);
53
54 int dim = 2;
55 final double[] minPoint = new double[dim];
56 for (int i = 0; i < dim; i++) {
57 minPoint[i] = 0;
58 }
59
60 double[] init = new double[dim];
61
62
63 for (int i = 0; i < dim; i++) {
64 init[i] = minPoint[i];
65 }
66 doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-9, 1e-9);
67
68
69 for (int i = 0; i < dim; i++) {
70 init[i] = minPoint[i] + 3;
71 }
72 doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-9, 1e-5);
73
74
75 doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-9, 1e-9, 1e-7);
76 }
77
78 @Test
79 public void testQuadratic() {
80 final MultivariateFunction func = new MultivariateFunction() {
81 @Override
82 public double value(double[] x) {
83 final double a = x[0] - 1;
84 final double b = x[1] - 1;
85 return a * a + b * b + 1;
86 }
87 };
88
89 int dim = 2;
90 final double[] minPoint = new double[dim];
91 for (int i = 0; i < dim; i++) {
92 minPoint[i] = 1;
93 }
94
95 double[] init = new double[dim];
96
97
98 for (int i = 0; i < dim; i++) {
99 init[i] = minPoint[i];
100 }
101 doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-9, 1e-8);
102
103
104 for (int i = 0; i < dim; i++) {
105 init[i] = minPoint[i] - 20;
106 }
107 doTest(func, minPoint, init, GoalType.MINIMIZE, 1e-9, 1e-8);
108 }
109
110 @Test
111 public void testMaximizeQuadratic() {
112 final MultivariateFunction func = new MultivariateFunction() {
113 @Override
114 public double value(double[] x) {
115 final double a = x[0] - 1;
116 final double b = x[1] - 1;
117 return -a * a - b * b + 1;
118 }
119 };
120
121 int dim = 2;
122 final double[] maxPoint = new double[dim];
123 for (int i = 0; i < dim; i++) {
124 maxPoint[i] = 1;
125 }
126
127 double[] init = new double[dim];
128
129
130 for (int i = 0; i < dim; i++) {
131 init[i] = maxPoint[i];
132 }
133 doTest(func, maxPoint, init, GoalType.MAXIMIZE, 1e-9, 1e-8);
134
135
136 for (int i = 0; i < dim; i++) {
137 init[i] = maxPoint[i] - 20;
138 }
139 doTest(func, maxPoint, init, GoalType.MAXIMIZE, 1e-9, 1e-8);
140 }
141
142
143
144
145
146
147
148
149 @Test
150 public void testRelativeToleranceOnScaledValues() {
151 final MultivariateFunction func = new MultivariateFunction() {
152 @Override
153 public double value(double[] x) {
154 final double a = x[0] - 1;
155 final double b = x[1] - 1;
156 return a * a * JdkMath.sqrt(JdkMath.abs(a)) + b * b + 1;
157 }
158 };
159
160 int dim = 2;
161 final double[] minPoint = new double[dim];
162 for (int i = 0; i < dim; i++) {
163 minPoint[i] = 1;
164 }
165
166 double[] init = new double[dim];
167
168 for (int i = 0; i < dim; i++) {
169 init[i] = minPoint[i] - 20;
170 }
171
172 final double relTol = 1e-10;
173
174 final int maxEval = 1000;
175
176
177 final PowellOptimizer optim = new PowellOptimizer(relTol, 1e-100);
178
179 final PointValuePair funcResult = optim.optimize(new MaxEval(maxEval),
180 new ObjectiveFunction(func),
181 GoalType.MINIMIZE,
182 new InitialGuess(init));
183 final double funcValue = func.value(funcResult.getPoint());
184 final int funcEvaluations = optim.getEvaluations();
185
186 final double scale = 1e10;
187 final MultivariateFunction funcScaled = new MultivariateFunction() {
188 @Override
189 public double value(double[] x) {
190 return scale * func.value(x);
191 }
192 };
193
194 final PointValuePair funcScaledResult = optim.optimize(new MaxEval(maxEval),
195 new ObjectiveFunction(funcScaled),
196 GoalType.MINIMIZE,
197 new InitialGuess(init));
198 final double funcScaledValue = funcScaled.value(funcScaledResult.getPoint());
199 final int funcScaledEvaluations = optim.getEvaluations();
200
201
202
203 Assert.assertEquals(1, funcScaledValue / (scale * funcValue), relTol);
204
205
206 Assert.assertEquals(funcEvaluations, funcScaledEvaluations);
207 }
208
209
210
211
212
213
214
215
216
217
218 private void doTest(MultivariateFunction func,
219 double[] optimum,
220 double[] init,
221 GoalType goal,
222 double fTol,
223 double pointTol) {
224 final PowellOptimizer optim = new PowellOptimizer(fTol, Math.ulp(1d));
225
226 final PointValuePair result = optim.optimize(new MaxEval(1000),
227 new ObjectiveFunction(func),
228 goal,
229 new InitialGuess(init));
230 final double[] point = result.getPoint();
231
232 for (int i = 0, dim = optimum.length; i < dim; i++) {
233 Assert.assertEquals("found[" + i + "]=" + point[i] + " value=" + result.getValue(),
234 optimum[i], point[i], pointTol);
235 }
236 }
237
238
239
240
241
242
243
244
245
246
247
248
249 private void doTest(MultivariateFunction func,
250 double[] optimum,
251 double[] init,
252 GoalType goal,
253 double fTol,
254 double fLineTol,
255 double pointTol) {
256 final PowellOptimizer optim = new PowellOptimizer(fTol, Math.ulp(1d),
257 fLineTol, Math.ulp(1d));
258
259 final PointValuePair result = optim.optimize(new MaxEval(1000),
260 new ObjectiveFunction(func),
261 goal,
262 new InitialGuess(init));
263 final double[] point = result.getPoint();
264
265 for (int i = 0, dim = optimum.length; i < dim; i++) {
266 Assert.assertEquals("found[" + i + "]=" + point[i] + " value=" + result.getValue(),
267 optimum[i], point[i], pointTol);
268 }
269
270 Assert.assertTrue(optim.getIterations() > 0);
271 }
272 }