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