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