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;
18
19 import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
20 import org.apache.commons.math4.legacy.optim.InitialGuess;
21 import org.apache.commons.math4.legacy.optim.MaxEval;
22 import org.apache.commons.math4.legacy.optim.PointValuePair;
23 import org.apache.commons.math4.legacy.optim.SimplePointChecker;
24 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv.SimplexOptimizer;
25 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv.Simplex;
26 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv.NelderMeadTransform;
27 import org.junit.Assert;
28 import org.junit.Test;
29
30 public class MultivariateFunctionPenaltyAdapterTest {
31 @Test
32 public void testStartSimplexInsideRange() {
33 final BiQuadratic biQuadratic = new BiQuadratic(2.0, 2.5, 1.0, 3.0, 2.0, 3.0);
34 final MultivariateFunctionPenaltyAdapter wrapped
35 = new MultivariateFunctionPenaltyAdapter(biQuadratic,
36 biQuadratic.getLower(),
37 biQuadratic.getUpper(),
38 1000.0, new double[] { 100.0, 100.0 });
39
40 SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
41
42 final PointValuePair optimum
43 = optimizer.optimize(new MaxEval(300),
44 new ObjectiveFunction(wrapped),
45 Simplex.alongAxes(new double[] { 1.0, 0.5 }),
46 new NelderMeadTransform(),
47 GoalType.MINIMIZE,
48 new InitialGuess(new double[] { 1.5, 2.25 }));
49
50 Assert.assertEquals(biQuadratic.getBoundedXOptimum(), optimum.getPoint()[0], 2e-7);
51 Assert.assertEquals(biQuadratic.getBoundedYOptimum(), optimum.getPoint()[1], 2e-7);
52 }
53
54 @Test
55 public void testStartSimplexOutsideRange() {
56 final BiQuadratic biQuadratic = new BiQuadratic(2.0, 2.5, 1.0, 3.0, 2.0, 3.0);
57 final MultivariateFunctionPenaltyAdapter wrapped
58 = new MultivariateFunctionPenaltyAdapter(biQuadratic,
59 biQuadratic.getLower(),
60 biQuadratic.getUpper(),
61 1000.0, new double[] { 100.0, 100.0 });
62
63 SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
64
65 final PointValuePair optimum
66 = optimizer.optimize(new MaxEval(300),
67 new ObjectiveFunction(wrapped),
68 Simplex.alongAxes(new double[] { 1.0, 0.5 }),
69 new NelderMeadTransform(),
70 GoalType.MINIMIZE,
71 new InitialGuess(new double[] { -1.5, 4.0 }));
72
73 Assert.assertEquals(biQuadratic.getBoundedXOptimum(), optimum.getPoint()[0], 2e-7);
74 Assert.assertEquals(biQuadratic.getBoundedYOptimum(), optimum.getPoint()[1], 2e-7);
75 }
76
77 @Test
78 public void testOptimumOutsideRange() {
79 final BiQuadratic biQuadratic = new BiQuadratic(4.0, 0.0, 1.0, 3.0, 2.0, 3.0);
80 final MultivariateFunctionPenaltyAdapter wrapped
81 = new MultivariateFunctionPenaltyAdapter(biQuadratic,
82 biQuadratic.getLower(),
83 biQuadratic.getUpper(),
84 1000.0, new double[] { 100.0, 100.0 });
85
86 SimplexOptimizer optimizer = new SimplexOptimizer(new SimplePointChecker<>(1.0e-11, 1.0e-20));
87
88 final PointValuePair optimum
89 = optimizer.optimize(new MaxEval(600),
90 new ObjectiveFunction(wrapped),
91 Simplex.alongAxes(new double[] { 1.0, 0.5 }),
92 new NelderMeadTransform(),
93 GoalType.MINIMIZE,
94 new InitialGuess(new double[] { -1.5, 4.0 }));
95
96 Assert.assertEquals(biQuadratic.getBoundedXOptimum(), optimum.getPoint()[0], 2e-7);
97 Assert.assertEquals(biQuadratic.getBoundedYOptimum(), optimum.getPoint()[1], 2e-7);
98 }
99
100 @Test
101 public void testUnbounded() {
102 final BiQuadratic biQuadratic = new BiQuadratic(4.0, 0.0,
103 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
104 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
105 final MultivariateFunctionPenaltyAdapter wrapped
106 = new MultivariateFunctionPenaltyAdapter(biQuadratic,
107 biQuadratic.getLower(),
108 biQuadratic.getUpper(),
109 1000.0, new double[] { 100.0, 100.0 });
110
111 SimplexOptimizer optimizer = new SimplexOptimizer(1e-10, 1e-30);
112
113 final PointValuePair optimum
114 = optimizer.optimize(new MaxEval(300),
115 new ObjectiveFunction(wrapped),
116 Simplex.alongAxes(new double[] { 1.0, 0.5 }),
117 new NelderMeadTransform(),
118 GoalType.MINIMIZE,
119 new InitialGuess(new double[] { -1.5, 4.0 }));
120
121 Assert.assertEquals(biQuadratic.getBoundedXOptimum(), optimum.getPoint()[0], 2e-7);
122 Assert.assertEquals(biQuadratic.getBoundedYOptimum(), optimum.getPoint()[1], 2e-7);
123 }
124
125 @Test
126 public void testHalfBounded() {
127 final BiQuadratic biQuadratic = new BiQuadratic(4.0, 4.0,
128 1.0, Double.POSITIVE_INFINITY,
129 Double.NEGATIVE_INFINITY, 3.0);
130 final MultivariateFunctionPenaltyAdapter wrapped
131 = new MultivariateFunctionPenaltyAdapter(biQuadratic,
132 biQuadratic.getLower(),
133 biQuadratic.getUpper(),
134 1000.0, new double[] { 100.0, 100.0 });
135
136 SimplexOptimizer optimizer = new SimplexOptimizer(new SimplePointChecker<PointValuePair>(1.0e-10, 1.0e-20));
137
138 final PointValuePair optimum
139 = optimizer.optimize(new MaxEval(400),
140 new ObjectiveFunction(wrapped),
141 Simplex.alongAxes(new double[] { 1.0, 0.5 }),
142 new NelderMeadTransform(),
143 GoalType.MINIMIZE,
144 new InitialGuess(new double[] { -1.5, 4.0 }));
145
146 Assert.assertEquals(biQuadratic.getBoundedXOptimum(), optimum.getPoint()[0], 2e-7);
147 Assert.assertEquals(biQuadratic.getBoundedYOptimum(), optimum.getPoint()[1], 2e-7);
148 }
149
150 private static final class BiQuadratic implements MultivariateFunction {
151
152 private final double xOptimum;
153 private final double yOptimum;
154
155 private final double xMin;
156 private final double xMax;
157 private final double yMin;
158 private final double yMax;
159
160 BiQuadratic(final double xOptimum, final double yOptimum,
161 final double xMin, final double xMax,
162 final double yMin, final double yMax) {
163 this.xOptimum = xOptimum;
164 this.yOptimum = yOptimum;
165 this.xMin = xMin;
166 this.xMax = xMax;
167 this.yMin = yMin;
168 this.yMax = yMax;
169 }
170
171 @Override
172 public double value(double[] point) {
173
174 Assert.assertTrue(point[0] >= xMin);
175 Assert.assertTrue(point[0] <= xMax);
176 Assert.assertTrue(point[1] >= yMin);
177 Assert.assertTrue(point[1] <= yMax);
178
179 final double dx = point[0] - xOptimum;
180 final double dy = point[1] - yOptimum;
181 return dx * dx + dy * dy;
182 }
183
184 public double[] getLower() {
185 return new double[] { xMin, yMin };
186 }
187
188 public double[] getUpper() {
189 return new double[] { xMax, yMax };
190 }
191
192 public double getBoundedXOptimum() {
193 return (xOptimum < xMin) ? xMin : ((xOptimum > xMax) ? xMax : xOptimum);
194 }
195
196 public double getBoundedYOptimum() {
197 return (yOptimum < yMin) ? yMin : ((yOptimum > yMax) ? yMax : yOptimum);
198 }
199 }
200 }