1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.hipparchus.analysis.solvers;
24
25 import org.hipparchus.analysis.QuinticFunction;
26 import org.hipparchus.analysis.CalculusFieldUnivariateFunction;
27 import org.hipparchus.analysis.UnivariateFunction;
28 import org.hipparchus.analysis.function.Sin;
29 import org.hipparchus.exception.MathIllegalArgumentException;
30 import org.hipparchus.exception.NullArgumentException;
31 import org.hipparchus.util.Binary64;
32 import org.hipparchus.util.FastMath;
33 import org.junit.Assert;
34 import org.junit.Test;
35
36
37
38 public class UnivariateSolverUtilsTest {
39
40 private UnivariateFunction sin = new Sin();
41 private CalculusFieldUnivariateFunction<Binary64> fieldSin = x -> x.sin();
42
43 @Test(expected=NullArgumentException.class)
44 public void testSolveNull() {
45 UnivariateSolverUtils.solve(null, 0.0, 4.0);
46 }
47
48 @Test(expected=MathIllegalArgumentException.class)
49 public void testSolveBadEndpoints() {
50 double root = UnivariateSolverUtils.solve(sin, 4.0, -0.1, 1e-6);
51 System.out.println("root=" + root);
52 }
53
54 @Test
55 public void testSolveBadAccuracy() {
56 try {
57 UnivariateSolverUtils.solve(sin, 0.0, 4.0, 0.0);
58
59 } catch (MathIllegalArgumentException ex) {
60
61 }
62 }
63
64 @Test
65 public void testSolveSin() {
66 double x = UnivariateSolverUtils.solve(sin, 1.0, 4.0);
67 Assert.assertEquals(FastMath.PI, x, 1.0e-4);
68 }
69
70 @Test(expected=NullArgumentException.class)
71 public void testSolveAccuracyNull() {
72 double accuracy = 1.0e-6;
73 UnivariateSolverUtils.solve(null, 0.0, 4.0, accuracy);
74 }
75
76 @Test
77 public void testSolveAccuracySin() {
78 double accuracy = 1.0e-6;
79 double x = UnivariateSolverUtils.solve(sin, 1.0,
80 4.0, accuracy);
81 Assert.assertEquals(FastMath.PI, x, accuracy);
82 }
83
84 @Test(expected=MathIllegalArgumentException.class)
85 public void testSolveNoRoot() {
86 UnivariateSolverUtils.solve(sin, 1.0, 1.5);
87 }
88
89 @Test
90 public void testBracketSin() {
91 double[] result = UnivariateSolverUtils.bracket(sin,
92 0.0, -2.0, 2.0);
93 Assert.assertTrue(sin.value(result[0]) < 0);
94 Assert.assertTrue(sin.value(result[1]) > 0);
95 }
96
97 @Test
98 public void testBracketCentered() {
99 double initial = 0.1;
100 double[] result = UnivariateSolverUtils.bracket(sin, initial, -2.0, 2.0, 0.2, 1.0, 100);
101 Assert.assertTrue(result[0] < initial);
102 Assert.assertTrue(result[1] > initial);
103 Assert.assertTrue(sin.value(result[0]) < 0);
104 Assert.assertTrue(sin.value(result[1]) > 0);
105 }
106
107 @Test
108 public void testBracketLow() {
109 double initial = 0.5;
110 double[] result = UnivariateSolverUtils.bracket(sin, initial, -2.0, 2.0, 0.2, 1.0, 100);
111 Assert.assertTrue(result[0] < initial);
112 Assert.assertTrue(result[1] < initial);
113 Assert.assertTrue(sin.value(result[0]) < 0);
114 Assert.assertTrue(sin.value(result[1]) > 0);
115 }
116
117 @Test
118 public void testBracketHigh(){
119 double initial = -0.5;
120 double[] result = UnivariateSolverUtils.bracket(sin, initial, -2.0, 2.0, 0.2, 1.0, 100);
121 Assert.assertTrue(result[0] > initial);
122 Assert.assertTrue(result[1] > initial);
123 Assert.assertTrue(sin.value(result[0]) < 0);
124 Assert.assertTrue(sin.value(result[1]) > 0);
125 }
126
127 @Test(expected=MathIllegalArgumentException.class)
128 public void testBracketLinear(){
129 UnivariateSolverUtils.bracket(new UnivariateFunction() {
130 public double value(double x) {
131 return 1 - x;
132 }
133 }, 1000, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 100);
134 }
135
136 @Test
137 public void testBracketExponential(){
138 double[] result = UnivariateSolverUtils.bracket(new UnivariateFunction() {
139 public double value(double x) {
140 return 1 - x;
141 }
142 }, 1000, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0, 2.0, 10);
143 Assert.assertTrue(result[0] <= 1);
144 Assert.assertTrue(result[1] >= 1);
145 }
146
147 @Test
148 public void testBracketEndpointRoot() {
149 double[] result = UnivariateSolverUtils.bracket(sin, 1.5, 0, 2.0, 100);
150 Assert.assertEquals(0.0, sin.value(result[0]), 1.0e-15);
151 Assert.assertTrue(sin.value(result[1]) > 0);
152 }
153
154 @Test(expected=NullArgumentException.class)
155 public void testNullFunction() {
156 UnivariateSolverUtils.bracket(null, 1.5, 0, 2.0);
157 }
158
159 @Test(expected=MathIllegalArgumentException.class)
160 public void testBadInitial() {
161 UnivariateSolverUtils.bracket(sin, 2.5, 0, 2.0);
162 }
163
164 @Test(expected=MathIllegalArgumentException.class)
165 public void testBadAdditive() {
166 UnivariateSolverUtils.bracket(sin, 1.0, -2.0, 3.0, -1.0, 1.0, 100);
167 }
168
169 @Test(expected=MathIllegalArgumentException.class)
170 public void testIterationExceeded() {
171 UnivariateSolverUtils.bracket(sin, 1.0, -2.0, 3.0, 1.0e-5, 1.0, 100);
172 }
173
174 @Test(expected=MathIllegalArgumentException.class)
175 public void testBadEndpoints() {
176
177 UnivariateSolverUtils.bracket(sin, 1.5, 2.0, 1.0);
178 }
179
180 @Test(expected=MathIllegalArgumentException.class)
181 public void testBadMaximumIterations() {
182
183 UnivariateSolverUtils.bracket(sin, 1.5, 0, 2.0, 0);
184 }
185
186 @Test
187 public void testFieldBracketSin() {
188 Binary64[] result = UnivariateSolverUtils.bracket(fieldSin,new Binary64(0.0),
189 new Binary64(-2.0),new Binary64(2.0));
190 Assert.assertTrue(fieldSin.value(result[0]).getReal() < 0);
191 Assert.assertTrue(fieldSin.value(result[1]).getReal() > 0);
192 }
193
194 @Test
195 public void testFieldBracketCentered() {
196 Binary64 initial = new Binary64(0.1);
197 Binary64[] result = UnivariateSolverUtils.bracket(fieldSin, initial,
198 new Binary64(-2.0), new Binary64(2.0),
199 new Binary64(0.2), new Binary64(1.0),
200 100);
201 Assert.assertTrue(result[0].getReal() < initial.getReal());
202 Assert.assertTrue(result[1].getReal() > initial.getReal());
203 Assert.assertTrue(fieldSin.value(result[0]).getReal() < 0);
204 Assert.assertTrue(fieldSin.value(result[1]).getReal() > 0);
205 }
206
207 @Test
208 public void testFieldBracketLow() {
209 Binary64 initial = new Binary64(0.5);
210 Binary64[] result = UnivariateSolverUtils.bracket(fieldSin, initial,
211 new Binary64(-2.0), new Binary64(2.0),
212 new Binary64(0.2), new Binary64(1.0),
213 100);
214 Assert.assertTrue(result[0].getReal() < initial.getReal());
215 Assert.assertTrue(result[1].getReal() < initial.getReal());
216 Assert.assertTrue(fieldSin.value(result[0]).getReal() < 0);
217 Assert.assertTrue(fieldSin.value(result[1]).getReal() > 0);
218 }
219
220 @Test
221 public void testFieldBracketHigh(){
222 Binary64 initial = new Binary64(-0.5);
223 Binary64[] result = UnivariateSolverUtils.bracket(fieldSin, initial,
224 new Binary64(-2.0), new Binary64(2.0),
225 new Binary64(0.2), new Binary64(1.0),
226 100);
227 Assert.assertTrue(result[0].getReal() > initial.getReal());
228 Assert.assertTrue(result[1].getReal() > initial.getReal());
229 Assert.assertTrue(fieldSin.value(result[0]).getReal() < 0);
230 Assert.assertTrue(fieldSin.value(result[1]).getReal() > 0);
231 }
232
233 @Test(expected=MathIllegalArgumentException.class)
234 public void testFieldBracketLinear(){
235 UnivariateSolverUtils.bracket(new CalculusFieldUnivariateFunction<Binary64>() {
236 public Binary64 value(Binary64 x) {
237 return x.negate().add(1);
238 }
239 },
240 new Binary64(1000),
241 new Binary64(Double.NEGATIVE_INFINITY), new Binary64(Double.POSITIVE_INFINITY),
242 new Binary64(1.0), new Binary64(1.0), 100);
243 }
244
245 @Test
246 public void testFieldBracketExponential(){
247 Binary64[] result = UnivariateSolverUtils.bracket(new CalculusFieldUnivariateFunction<Binary64>() {
248 public Binary64 value(Binary64 x) {
249 return x.negate().add(1);
250 }
251 },
252 new Binary64(1000),
253 new Binary64(Double.NEGATIVE_INFINITY), new Binary64(Double.POSITIVE_INFINITY),
254 new Binary64(1.0), new Binary64(2.0), 10);
255 Assert.assertTrue(result[0].getReal() <= 1);
256 Assert.assertTrue(result[1].getReal() >= 1);
257 }
258
259 @Test
260 public void testFieldBracketEndpointRoot() {
261 Binary64[] result = UnivariateSolverUtils.bracket(fieldSin,
262 new Binary64(1.5), new Binary64(0),
263 new Binary64(2.0), 100);
264 Assert.assertEquals(0.0, fieldSin.value(result[0]).getReal(), 1.0e-15);
265 Assert.assertTrue(fieldSin.value(result[1]).getReal() > 0);
266 }
267
268 @Test(expected=NullArgumentException.class)
269 public void testFieldNullFunction() {
270 UnivariateSolverUtils.bracket(null, new Binary64(1.5), new Binary64(0), new Binary64(2.0));
271 }
272
273 @Test(expected=MathIllegalArgumentException.class)
274 public void testFieldBadInitial() {
275 UnivariateSolverUtils.bracket(fieldSin, new Binary64(2.5), new Binary64(0), new Binary64(2.0));
276 }
277
278 @Test(expected=MathIllegalArgumentException.class)
279 public void testFieldBadAdditive() {
280 UnivariateSolverUtils.bracket(fieldSin, new Binary64(1.0), new Binary64(-2.0), new Binary64(3.0),
281 new Binary64(-1.0), new Binary64(1.0), 100);
282 }
283
284 @Test(expected=MathIllegalArgumentException.class)
285 public void testFieldIterationExceeded() {
286 UnivariateSolverUtils.bracket(fieldSin, new Binary64(1.0), new Binary64(-2.0), new Binary64(3.0),
287 new Binary64(1.0e-5), new Binary64(1.0), 100);
288 }
289
290 @Test(expected=MathIllegalArgumentException.class)
291 public void testFieldBadEndpoints() {
292
293 UnivariateSolverUtils.bracket(fieldSin, new Binary64(1.5), new Binary64(2.0), new Binary64(1.0));
294 }
295
296 @Test(expected=MathIllegalArgumentException.class)
297 public void testFieldBadMaximumIterations() {
298
299 UnivariateSolverUtils.bracket(fieldSin, new Binary64(1.5), new Binary64(0), new Binary64(2.0), 0);
300 }
301
302
303 @Test
304 public void testBracketLoopConditionForB() {
305 double[] result = UnivariateSolverUtils.bracket(sin, -0.9, -1, 1, 0.1, 1, 100);
306 Assert.assertTrue(result[0] <= 0);
307 Assert.assertTrue(result[1] >= 0);
308 }
309
310 @Test
311 public void testMisc() {
312 UnivariateFunction f = new QuinticFunction();
313 double result;
314
315 result = UnivariateSolverUtils.solve(f, -0.2, 0.2);
316 Assert.assertEquals(result, 0, 1E-8);
317 result = UnivariateSolverUtils.solve(f, -0.1, 0.3);
318 Assert.assertEquals(result, 0, 1E-8);
319 result = UnivariateSolverUtils.solve(f, -0.3, 0.45);
320 Assert.assertEquals(result, 0, 1E-6);
321 result = UnivariateSolverUtils.solve(f, 0.3, 0.7);
322 Assert.assertEquals(result, 0.5, 1E-6);
323 result = UnivariateSolverUtils.solve(f, 0.2, 0.6);
324 Assert.assertEquals(result, 0.5, 1E-6);
325 result = UnivariateSolverUtils.solve(f, 0.05, 0.95);
326 Assert.assertEquals(result, 0.5, 1E-6);
327 result = UnivariateSolverUtils.solve(f, 0.85, 1.25);
328 Assert.assertEquals(result, 1.0, 1E-6);
329 result = UnivariateSolverUtils.solve(f, 0.8, 1.2);
330 Assert.assertEquals(result, 1.0, 1E-6);
331 result = UnivariateSolverUtils.solve(f, 0.85, 1.75);
332 Assert.assertEquals(result, 1.0, 1E-6);
333 result = UnivariateSolverUtils.solve(f, 0.55, 1.45);
334 Assert.assertEquals(result, 1.0, 1E-6);
335 result = UnivariateSolverUtils.solve(f, 0.85, 5);
336 Assert.assertEquals(result, 1.0, 1E-6);
337 }
338 }