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