1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.hipparchus.analysis.differentiation;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.CalculusFieldElementAbstractTest;
21 import org.hipparchus.UnitTestUtils;
22 import org.hipparchus.analysis.FieldUnivariateFunction;
23 import org.hipparchus.exception.LocalizedCoreFormats;
24 import org.hipparchus.exception.MathIllegalArgumentException;
25 import org.hipparchus.util.FastMath;
26 import org.hipparchus.util.FieldSinCos;
27 import org.hipparchus.util.MathArrays;
28 import org.junit.jupiter.api.Test;
29
30 import static org.junit.jupiter.api.Assertions.assertEquals;
31 import static org.junit.jupiter.api.Assertions.assertNotSame;
32 import static org.junit.jupiter.api.Assertions.fail;
33
34
35
36
37 public abstract class UnivariateDerivativeAbstractTest<T extends UnivariateDerivative<T>>
38 extends CalculusFieldElementAbstractTest<T> {
39
40 protected abstract int getMaxOrder();
41
42 @Override
43 protected abstract T build(final double x);
44
45 @Test
46 public void testOrder() {
47 assertEquals(getMaxOrder(), build(0).getOrder());
48 }
49
50 @Test
51 public void testNewInstance() {
52 T ud = build(5.25);
53 assertEquals(5.25, ud.getValue(), 1.0e-15);
54 assertEquals(1.0, ud.getDerivative(1), 1.0e-15);
55 T newInstance = ud.newInstance(7.5);
56 assertEquals(7.5, newInstance.getValue(), 1.0e-15);
57 assertEquals(0.0, newInstance.getDerivative(1), 1.0e-15);
58 }
59
60 @Test
61 public void testGetPartialDerivative() {
62 try {
63 build(3.0).getPartialDerivative(0, 1);
64 fail("an exception should have been thrown");
65 } catch( MathIllegalArgumentException miae) {
66 assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
67 assertEquals(2, ((Integer) miae.getParts()[0]).intValue());
68 assertEquals(1, ((Integer) miae.getParts()[1]).intValue());
69 }
70 }
71
72 @Test
73 public void testGetDerivative() {
74 T x = build(3.0);
75 T ud = x.square();
76 try {
77 ud.getDerivative(-1);
78 fail("an exception should have been thrown");
79 } catch (MathIllegalArgumentException miae) {
80 assertEquals(LocalizedCoreFormats.DERIVATION_ORDER_NOT_ALLOWED, miae.getSpecifier());
81 }
82 assertEquals(9.0, ud.getValue(), 1.0e-15);
83 assertEquals(9.0, ud.getDerivative(0), 1.0e-15);
84 assertEquals(6.0, ud.getDerivative(1), 1.0e-15);
85 for (int n = 2; n <= getMaxOrder(); ++n) {
86 assertEquals(n == 2 ? 2.0 : 0.0, ud.getDerivative(n), 1.0e-15);
87 }
88 try {
89 ud.getDerivative(getMaxOrder() + 1);
90 fail("an exception should have been thrown");
91 } catch (MathIllegalArgumentException miae) {
92 assertEquals(LocalizedCoreFormats.DERIVATION_ORDER_NOT_ALLOWED, miae.getSpecifier());
93 }
94 }
95
96 @Test
97 public void testGetFreeParameters() {
98 assertEquals(1, build(3.0).getFreeParameters());
99 }
100
101 protected void checkAgainstDS(final double x, final FieldUnivariateFunction f) {
102 final T xUD = build(x);
103 final T yUD = f.value(xUD);
104 final DerivativeStructure yDS = f.value(xUD.toDerivativeStructure());
105 for (int i = 0; i <= yUD.getOrder(); ++i) {
106 if (Double.isNaN(yDS.getPartialDerivative(i))) {
107 assertEquals(yDS.getPartialDerivative(i),
108 yUD.getDerivative(i));
109 }else {
110 assertEquals(yDS.getPartialDerivative(i),
111 yUD.getDerivative(i),
112 4.0e-14* FastMath.abs(yDS.getPartialDerivative(i)));
113 }
114 }
115 }
116
117 @Test
118 public void testArithmeticVsDS() {
119 for (double x = -1.25; x < 1.25; x+= 0.5) {
120 checkAgainstDS(x,
121 new FieldUnivariateFunction() {
122 public <S extends CalculusFieldElement<S>> S value(S x) {
123 final S y = x.add(3).multiply(x).subtract(5).multiply(0.5);
124 return y.negate().divide(4).divide(x).add(y).subtract(x).multiply(2).reciprocal();
125 }
126 });
127 }
128 }
129
130 @Test
131 public void testRemainderDoubleVsDS() {
132 for (double x = -1.25; x < 1.25; x+= 0.5) {
133 checkAgainstDS(x,
134 new FieldUnivariateFunction() {
135 public <S extends CalculusFieldElement<S>> S value(S x) {
136 return x.remainder(0.5);
137 }
138 });
139 }
140 }
141
142 @Test
143 public void testRemainderUdVsDS() {
144 for (double x = -1.25; x < 1.25; x+= 0.5) {
145 checkAgainstDS(x,
146 new FieldUnivariateFunction() {
147 public <S extends CalculusFieldElement<S>> S value(S x) {
148 return x.remainder(x.divide(0.7));
149 }
150 });
151 }
152 }
153
154 @Test
155 public void testAbsVsDS() {
156 for (double x = -1.25; x < 1.25; x+= 0.5) {
157 checkAgainstDS(x,
158 new FieldUnivariateFunction() {
159 public <S extends CalculusFieldElement<S>> S value(S x) {
160 return x.abs();
161 }
162 });
163 }
164 }
165
166 @Test
167 public void testScalbVsDS() {
168 for (int n = -4; n < 4; ++n) {
169 final int theN = n;
170 for (double x = -1.25; x < 1.25; x+= 0.5) {
171 checkAgainstDS(x,
172 new FieldUnivariateFunction() {
173 public <S extends CalculusFieldElement<S>> S value(S x) {
174 return x.scalb(theN);
175 }
176 });
177 }
178 }
179 }
180
181 @Test
182 public void testUlpVsDS() {
183 for (double x = -1.25; x < 1.25; x+= 0.0001) {
184 checkAgainstDS(x,
185 new FieldUnivariateFunction() {
186 public <S extends CalculusFieldElement<S>> S value(S x) {
187 return x.ulp();
188 }
189 });
190 }
191 }
192
193 @Test
194 public void testHypotVsDS() {
195 for (double x = -3.25; x < 3.25; x+= 0.5) {
196 checkAgainstDS(x,
197 new FieldUnivariateFunction() {
198 public <S extends CalculusFieldElement<S>> S value(S x) {
199 return x.cos().multiply(5).hypot(x.sin().multiply(2));
200 }
201 });
202 }
203 }
204
205 @Test
206 public void testAtan2VsDS() {
207 for (double x = -3.25; x < 3.25; x+= 0.5) {
208 checkAgainstDS(x,
209 new FieldUnivariateFunction() {
210 public <S extends CalculusFieldElement<S>> S value(S x) {
211 return x.cos().multiply(5).atan2(x.sin().multiply(2));
212 }
213 });
214 }
215 }
216
217 @Test
218 public void testPowersVsDS() {
219 for (double x = -3.25; x < 3.25; x+= 0.5) {
220 checkAgainstDS(x,
221 new FieldUnivariateFunction() {
222 public <S extends CalculusFieldElement<S>> S value(S x) {
223 final FieldSinCos<S> sc = x.sinCos();
224 return x.pow(3.2).add(x.pow(2)).subtract(sc.cos().abs().pow(sc.sin()));
225 }
226 });
227 }
228 }
229
230 @Test
231 public void testSqrtVsDS() {
232 for (double x = 0.001; x < 3.25; x+= 0.5) {
233 checkAgainstDS(x,
234 new FieldUnivariateFunction() {
235 public <S extends CalculusFieldElement<S>> S value(S x) {
236 return x.sqrt();
237 }
238 });
239 }
240 }
241
242 @Test
243 public void testCbrtVsDS() {
244 for (double x = 0.001; x < 3.25; x+= 0.5) {
245 checkAgainstDS(x,
246 new FieldUnivariateFunction() {
247 public <S extends CalculusFieldElement<S>> S value(S x) {
248 return x.cbrt();
249 }
250 });
251 }
252 }
253
254 @Test
255 public void testRootsVsDS() {
256 for (double x = 0.001; x < 3.25; x+= 0.5) {
257 checkAgainstDS(x,
258 new FieldUnivariateFunction() {
259 public <S extends CalculusFieldElement<S>> S value(S x) {
260 return x.rootN(5);
261 }
262 });
263 }
264 }
265
266 @Test
267 public void testExpsLogsVsDS() {
268 for (double x = 2.5; x < 3.25; x+= 0.125) {
269 checkAgainstDS(x,
270 new FieldUnivariateFunction() {
271 public <S extends CalculusFieldElement<S>> S value(S x) {
272 return x.exp().add(x.multiply(0.5).expm1()).log().log10().log1p();
273 }
274 });
275 }
276 }
277
278 @Test
279 public void testTrigonometryVsDS() {
280 for (double x = -3.25; x < 3.25; x+= 0.5) {
281 checkAgainstDS(x,
282 new FieldUnivariateFunction() {
283 public <S extends CalculusFieldElement<S>> S value(S x) {
284 return x.cos().multiply(x.sin()).atan().divide(12).asin().multiply(0.1).acos().tan();
285 }
286 });
287 }
288 }
289
290 @Test
291 public void testHyperbolicVsDS() {
292 for (double x = -1.25; x < 1.25; x+= 0.5) {
293 checkAgainstDS(x,
294 new FieldUnivariateFunction() {
295 public <S extends CalculusFieldElement<S>> S value(S x) {
296 return x.cosh().multiply(x.sinh()).multiply(12).abs().acosh().asinh().divide(7).tanh().multiply(0.1).atanh();
297 }
298 });
299 }
300 }
301
302 @Test
303 public void testConvertersVsDS() {
304 for (double x = -1.25; x < 1.25; x+= 0.5) {
305 checkAgainstDS(x,
306 new FieldUnivariateFunction() {
307 public <S extends CalculusFieldElement<S>> S value(S x) {
308 return x.multiply(5).toDegrees().subtract(x).toRadians();
309 }
310 });
311 }
312 }
313
314 @Test
315 public void testLinearCombination2D2FVsDS() {
316 for (double x = -1.25; x < 1.25; x+= 0.5) {
317 checkAgainstDS(x,
318 new FieldUnivariateFunction() {
319 public <S extends CalculusFieldElement<S>> S value(S x) {
320 return x.linearCombination(1.0, x.multiply(0.9),
321 2.0, x.multiply(0.8));
322 }
323 });
324 }
325 }
326
327 @Test
328 public void testLinearCombination2F2FVsDS() {
329 for (double x = -1.25; x < 1.25; x+= 0.5) {
330 checkAgainstDS(x,
331 new FieldUnivariateFunction() {
332 public <S extends CalculusFieldElement<S>> S value(S x) {
333 return x.linearCombination(x.add(1), x.multiply(0.9),
334 x.add(2), x.multiply(0.8));
335 }
336 });
337 }
338 }
339
340 @Test
341 public void testLinearCombination3D3FVsDS() {
342 for (double x = -1.25; x < 1.25; x+= 0.5) {
343 checkAgainstDS(x,
344 new FieldUnivariateFunction() {
345 public <S extends CalculusFieldElement<S>> S value(S x) {
346 return x.linearCombination(1.0, x.multiply(0.9),
347 2.0, x.multiply(0.8),
348 3.0, x.multiply(0.7));
349 }
350 });
351 }
352 }
353
354 @Test
355 public void testLinearCombination3F3FVsDS() {
356 for (double x = -1.25; x < 1.25; x+= 0.5) {
357 checkAgainstDS(x,
358 new FieldUnivariateFunction() {
359 public <S extends CalculusFieldElement<S>> S value(S x) {
360 return x.linearCombination(x.add(1), x.multiply(0.9),
361 x.add(2), x.multiply(0.8),
362 x.add(3), x.multiply(0.7));
363 }
364 });
365 }
366 }
367
368 @Test
369 public void testLinearCombination4D4FVsDS() {
370 for (double x = -1.25; x < 1.25; x+= 0.5) {
371 checkAgainstDS(x,
372 new FieldUnivariateFunction() {
373 public <S extends CalculusFieldElement<S>> S value(S x) {
374 return x.linearCombination(1.0, x.multiply(0.9),
375 2.0, x.multiply(0.8),
376 3.0, x.multiply(0.7),
377 4.0, x.multiply(0.6));
378 }
379 });
380 }
381 }
382
383 @Test
384 public void testLinearCombination4F4FVsDS() {
385 for (double x = -1.25; x < 1.25; x+= 0.5) {
386 checkAgainstDS(x,
387 new FieldUnivariateFunction() {
388 public <S extends CalculusFieldElement<S>> S value(S x) {
389 return x.linearCombination(x.add(1), x.multiply(0.9),
390 x.add(2), x.multiply(0.8),
391 x.add(3), x.multiply(0.7),
392 x.add(4), x.multiply(0.6));
393 }
394 });
395 }
396 }
397
398 @Test
399 public void testLinearCombinationnDnFVsDS() {
400 for (double x = -1.25; x < 1.25; x+= 0.5) {
401 checkAgainstDS(x,
402 new FieldUnivariateFunction() {
403 public <S extends CalculusFieldElement<S>> S value(S x) {
404 final S[] b = MathArrays.buildArray(x.getField(), 4);
405 b[0] = x.add(0.9);
406 b[1] = x.add(0.8);
407 b[2] = x.add(0.7);
408 b[3] = x.add(0.6);
409 return x.linearCombination(new double[] { 1, 2, 3, 4 }, b);
410 }
411 });
412 }
413 }
414
415 @Test
416 public void testLinearCombinationnFnFVsDS() {
417 for (double x = -1.25; x < 1.25; x+= 0.5) {
418 checkAgainstDS(x,
419 new FieldUnivariateFunction() {
420 public <S extends CalculusFieldElement<S>> S value(S x) {
421 final S[] a = MathArrays.buildArray(x.getField(), 4);
422 a[0] = x.add(1);
423 a[1] = x.add(2);
424 a[2] = x.add(3);
425 a[3] = x.add(4);
426 final S[] b = MathArrays.buildArray(x.getField(), 4);
427 b[0] = x.add(0.9);
428 b[1] = x.add(0.8);
429 b[2] = x.add(0.7);
430 b[3] = x.add(0.6);
431 return x.linearCombination(a, b);
432 }
433 });
434 }
435 }
436
437 @Test
438 public void testSerialization() {
439 T a = build(1.3);
440 @SuppressWarnings("unchecked")
441 T b = (T) UnitTestUtils.serializeAndRecover(a);
442 assertEquals(a, b);
443 assertNotSame(a, b);
444 }
445
446 @Test
447 public void testZero() {
448 T zero = build(17.0).getField().getZero();
449 for (int i = 0; i <= zero.getOrder(); ++i) {
450 assertEquals(0.0, zero.getDerivative(i), 1.0e-15);
451 }
452 }
453
454 @Test
455 public void testOne() {
456 T one = build(17.0).getField().getOne();
457 for (int i = 0; i <= one.getOrder(); ++i) {
458 assertEquals(i == 0 ? 1.0 : 0.0, one.getDerivative(i), 1.0e-15);
459 }
460 }
461
462 }