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