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.Field;
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.assertNotEquals;
32 import static org.junit.jupiter.api.Assertions.assertNotSame;
33 import static org.junit.jupiter.api.Assertions.assertSame;
34 import static org.junit.jupiter.api.Assertions.fail;
35
36
37
38
39 public abstract class FieldUnivariateDerivative1AbstractTest<T extends CalculusFieldElement<T>>
40 extends CalculusFieldElementAbstractTest<FieldUnivariateDerivative1<T>> {
41
42 protected abstract Field<T> getValueField();
43
44 protected FieldUnivariateDerivative1<T> build(double value) {
45 final Field<T> valueField = getValueField();
46 return new FieldUnivariateDerivative1<>(valueField.getZero().newInstance(value),
47 valueField.getOne());
48 }
49
50 protected T buildScalar(double value) {
51 return getValueField().getZero().newInstance(value);
52 }
53
54 private int getMaxOrder() {
55 return 1;
56 }
57
58 protected FieldUnivariateDerivative1<T> build(final double f0, final double f1) {
59 T prototype = build(0.0).getValue();
60 return new FieldUnivariateDerivative1<>(prototype.newInstance(f0),
61 prototype.newInstance(f1));
62 }
63
64 @Test
65 public void testOrder() {
66 assertEquals(getMaxOrder(), build(0).getOrder());
67 }
68
69 @Test
70 public void testNewInstance() {
71 FieldUnivariateDerivative1<T> ud = build(5.25);
72 assertEquals(5.25, ud.getValue().getReal(), 1.0e-15);
73 assertEquals(1.0, ud.getDerivative(1).getReal(), 1.0e-15);
74 FieldUnivariateDerivative1<T> newInstance = ud.newInstance(7.5);
75 assertEquals(7.5, newInstance.getValue().getReal(), 1.0e-15);
76 assertEquals(0.0, newInstance.getDerivative(1).getReal(), 1.0e-15);
77 }
78
79 @Test
80 public void testGetPartialDerivative() {
81 try {
82 build(3.0).getPartialDerivative(0, 1);
83 fail("an exception should have been thrown");
84 } catch( MathIllegalArgumentException miae) {
85 assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
86 assertEquals(2, ((Integer) miae.getParts()[0]).intValue());
87 assertEquals(1, ((Integer) miae.getParts()[1]).intValue());
88 }
89 }
90
91 @Test
92 public void testGetDerivative() {
93 FieldUnivariateDerivative1<T> x = build(3.0);
94 FieldUnivariateDerivative1<T> ud = x.square();
95 try {
96 ud.getDerivative(-1);
97 fail("an exception should have been thrown");
98 } catch (MathIllegalArgumentException miae) {
99 assertEquals(LocalizedCoreFormats.DERIVATION_ORDER_NOT_ALLOWED, miae.getSpecifier());
100 }
101 assertEquals(9.0, ud.getValue().getReal(), 1.0e-15);
102 assertEquals(9.0, ud.getDerivative(0).getReal(), 1.0e-15);
103 assertEquals(6.0, ud.getDerivative(1).getReal(), 1.0e-15);
104 for (int n = 2; n <= getMaxOrder(); ++n) {
105 assertEquals(n == 2 ? 2.0 : 0.0, ud.getDerivative(n).getReal(), 1.0e-15);
106 }
107 try {
108 ud.getDerivative(getMaxOrder() + 1);
109 fail("an exception should have been thrown");
110 } catch (MathIllegalArgumentException miae) {
111 assertEquals(LocalizedCoreFormats.DERIVATION_ORDER_NOT_ALLOWED, miae.getSpecifier());
112 }
113 }
114
115 @Test
116 public void testGetFreeParameters() {
117 assertEquals(1, build(3.0).getFreeParameters());
118 }
119
120 protected void checkAgainstDS(final double x,
121 final FieldUnivariateFunction f) {
122 final FieldUnivariateDerivative1<T> xUD = build(x);
123 final FieldUnivariateDerivative1<T> yUD = f.value(xUD);
124 final FieldDerivativeStructure<T> yDS = f.value(
125 xUD.toDerivativeStructure());
126 for (int i = 0; i <= yUD.getOrder(); ++i) {
127 if (Double.isNaN(yDS.getPartialDerivative(i).getReal())) {
128 assertEquals(yDS.getPartialDerivative(i).getReal(),
129 yUD.getDerivative(i).getReal());
130 } else {
131 assertEquals(yDS.getPartialDerivative(i).getReal(),
132 yUD.getDerivative(i).getReal(),
133 4.0e-14 * FastMath.abs(yDS.getPartialDerivative(i).getReal()));
134 }
135 }
136 }
137
138 @Test
139 public void testFieldAdd() {
140 check(build(1.0, 2.0).add(buildScalar(5.0)), 6.0, 2.0);
141 }
142
143 @Test
144 public void testFieldSubtract() {
145 check(build(1.0, 2.0).subtract(buildScalar(5.0)), -4.0, 2.0);
146 }
147
148 @Test
149 public void testFieldMultiply() {
150 check(build(1.0, 2.0).multiply(buildScalar(5.0)), 5.0, 10.0);
151 }
152
153 @Test
154 public void testFieldDivide() {
155 check(build(1.0, 5.0).divide(buildScalar(5.0)), 0.2, 1.0);
156 }
157
158 @Test
159 public void testCopySignField() {
160
161 FieldUnivariateDerivative1<T> minusOne = build(-1.0);
162 assertEquals(+1.0, minusOne.copySign(buildScalar(+1.0)).getReal(), 1.0e-15);
163 assertEquals(-1.0, minusOne.copySign(buildScalar(-1.0)).getReal(), 1.0e-15);
164 assertEquals(+1.0, minusOne.copySign(buildScalar(+0.0)).getReal(), 1.0e-15);
165 assertEquals(-1.0, minusOne.copySign(buildScalar(-0.0)).getReal(), 1.0e-15);
166 assertEquals(+1.0, minusOne.copySign(buildScalar(Double.NaN)).getReal(), 1.0e-15);
167
168 FieldUnivariateDerivative1<T> plusOne = build(1.0);
169 assertEquals(+1.0, plusOne.copySign(buildScalar(+1.0)).getReal(), 1.0e-15);
170 assertEquals(-1.0, plusOne.copySign(buildScalar(-1.0)).getReal(), 1.0e-15);
171 assertEquals(+1.0, plusOne.copySign(buildScalar(+0.0)).getReal(), 1.0e-15);
172 assertEquals(-1.0, plusOne.copySign(buildScalar(-0.0)).getReal(), 1.0e-15);
173 assertEquals(+1.0, plusOne.copySign(buildScalar(Double.NaN)).getReal(), 1.0e-15);
174
175 }
176
177 @Test
178 public void testRemainderField() {
179 double epsilon = 2.0e-15;
180 for (double x = -1.7; x < 2; x += 0.2) {
181 FieldUnivariateDerivative1<T> dsX = build(x);
182 for (double y = -1.7; y < 2; y += 0.2) {
183 FieldUnivariateDerivative1<T> remainder = dsX.remainder(buildScalar(y));
184 FieldUnivariateDerivative1<T> ref = dsX.subtract(x - FastMath.IEEEremainder(x, y));
185 FieldUnivariateDerivative1<T> zero = remainder.subtract(ref);
186 assertEquals(0, zero.getFirstDerivative().getReal(), epsilon);
187 }
188 }
189 }
190
191 @Test
192 public void testArithmeticVsDS() {
193 for (double x = -1.25; x < 1.25; x+= 0.5) {
194 checkAgainstDS(x,
195 new FieldUnivariateFunction() {
196 public <S extends CalculusFieldElement<S>> S value(S x) {
197 final S y = x.add(3).multiply(x).subtract(5).multiply(0.5);
198 return y.negate().divide(4).divide(x).add(y).subtract(x).multiply(2).reciprocal();
199 }
200 });
201 }
202 }
203
204 @Test
205 public void testRemainderDoubleVsDS() {
206 for (double x = -1.25; x < 1.25; x+= 0.5) {
207 checkAgainstDS(x,
208 new FieldUnivariateFunction() {
209 public <S extends CalculusFieldElement<S>> S value(S x) {
210 return x.remainder(0.5);
211 }
212 });
213 }
214 }
215
216 @Test
217 public void testRemainderUdVsDS() {
218 for (double x = -1.25; x < 1.25; x+= 0.5) {
219 checkAgainstDS(x,
220 new FieldUnivariateFunction() {
221 public <S extends CalculusFieldElement<S>> S value(S x) {
222 return x.remainder(x.divide(0.7));
223 }
224 });
225 }
226 }
227
228 @Test
229 public void testAbsVsDS() {
230 for (double x = -1.25; x < 1.25; x+= 0.5) {
231 checkAgainstDS(x,
232 new FieldUnivariateFunction() {
233 public <S extends CalculusFieldElement<S>> S value(S x) {
234 return x.abs();
235 }
236 });
237 }
238 }
239
240 @Test
241 public void testScalbVsDS() {
242 for (int n = -4; n < 4; ++n) {
243 final int theN = n;
244 for (double x = -1.25; x < 1.25; x+= 0.5) {
245 checkAgainstDS(x,
246 new FieldUnivariateFunction() {
247 public <S extends CalculusFieldElement<S>> S value(S x) {
248 return x.scalb(theN);
249 }
250 });
251 }
252 }
253 }
254
255 @Test
256 public void testUlpVsDS() {
257 for (double x = -1.25; x < 1.25; x+= 0.0001) {
258 checkAgainstDS(x,
259 new FieldUnivariateFunction() {
260 public <S extends CalculusFieldElement<S>> S value(S x) {
261 return x.ulp();
262 }
263 });
264 }
265 }
266
267 @Test
268 public void testHypotVsDS() {
269 for (double x = -3.25; x < 3.25; x+= 0.5) {
270 checkAgainstDS(x,
271 new FieldUnivariateFunction() {
272 public <S extends CalculusFieldElement<S>> S value(S x) {
273 return x.cos().multiply(5).hypot(x.sin().multiply(2));
274 }
275 });
276 }
277 }
278
279 @Test
280 public void testAtan2VsDS() {
281 for (double x = -3.25; x < 3.25; x+= 0.5) {
282 checkAgainstDS(x,
283 new FieldUnivariateFunction() {
284 public <S extends CalculusFieldElement<S>> S value(S x) {
285 return x.cos().multiply(5).atan2(x.sin().multiply(2));
286 }
287 });
288 }
289 }
290
291 @Test
292 public void testPowersVsDS() {
293 for (double x = -3.25; x < 3.25; x+= 0.5) {
294 checkAgainstDS(x,
295 new FieldUnivariateFunction() {
296 public <S extends CalculusFieldElement<S>> S value(S x) {
297 final FieldSinCos<S> sc = x.sinCos();
298 return x.pow(3.2).add(x.pow(2)).subtract(sc.cos().abs().pow(sc.sin()));
299 }
300 });
301 }
302 }
303
304 @Test
305 public void testRootsVsDS() {
306 for (double x = 0.001; x < 3.25; x+= 0.5) {
307 checkAgainstDS(x,
308 new FieldUnivariateFunction() {
309 public <S extends CalculusFieldElement<S>> S value(S x) {
310 return x.rootN(5);
311 }
312 });
313 }
314 }
315
316 @Test
317 public void testExpsLogsVsDS() {
318 for (double x = 2.5; x < 3.25; x+= 0.125) {
319 checkAgainstDS(x,
320 new FieldUnivariateFunction() {
321 public <S extends CalculusFieldElement<S>> S value(S x) {
322 return x.exp().add(x.multiply(0.5).expm1()).log().log10().log1p();
323 }
324 });
325 }
326 }
327
328 @Test
329 public void testTrigonometryVsDS() {
330 for (double x = -3.25; x < 3.25; x+= 0.5) {
331 checkAgainstDS(x,
332 new FieldUnivariateFunction() {
333 public <S extends CalculusFieldElement<S>> S value(S x) {
334 return x.cos().multiply(x.sin()).atan().divide(12).asin().multiply(0.1).acos().tan();
335 }
336 });
337 }
338 }
339
340 @Test
341 public void testHyperbolicVsDS() {
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.cosh().multiply(x.sinh()).multiply(12).abs().acosh().asinh().divide(7).tanh().multiply(0.1).atanh();
347 }
348 });
349 }
350 }
351
352 @Test
353 public void testConvertersVsDS() {
354 for (double x = -1.25; x < 1.25; x+= 0.5) {
355 checkAgainstDS(x,
356 new FieldUnivariateFunction() {
357 public <S extends CalculusFieldElement<S>> S value(S x) {
358 return x.multiply(5).toDegrees().subtract(x).toRadians();
359 }
360 });
361 }
362 }
363
364 @Test
365 public void testLinearCombination2D2FVsDS() {
366 for (double x = -1.25; x < 1.25; x+= 0.5) {
367 checkAgainstDS(x,
368 new FieldUnivariateFunction() {
369 public <S extends CalculusFieldElement<S>> S value(S x) {
370 return x.linearCombination(1.0, x.multiply(0.9),
371 2.0, x.multiply(0.8));
372 }
373 });
374 }
375 }
376
377 @Test
378 public void testLinearCombination2F2FVsDS() {
379 for (double x = -1.25; x < 1.25; x+= 0.5) {
380 checkAgainstDS(x,
381 new FieldUnivariateFunction() {
382 public <S extends CalculusFieldElement<S>> S value(S x) {
383 return x.linearCombination(x.add(1), x.multiply(0.9),
384 x.add(2), x.multiply(0.8));
385 }
386 });
387 }
388 }
389
390 @Test
391 public void testLinearCombination3D3FVsDS() {
392 for (double x = -1.25; x < 1.25; x+= 0.5) {
393 checkAgainstDS(x,
394 new FieldUnivariateFunction() {
395 public <S extends CalculusFieldElement<S>> S value(S x) {
396 return x.linearCombination(1.0, x.multiply(0.9),
397 2.0, x.multiply(0.8),
398 3.0, x.multiply(0.7));
399 }
400 });
401 }
402 }
403
404 @Test
405 public void testLinearCombination3F3FVsDS() {
406 for (double x = -1.25; x < 1.25; x+= 0.5) {
407 checkAgainstDS(x,
408 new FieldUnivariateFunction() {
409 public <S extends CalculusFieldElement<S>> S value(S x) {
410 return x.linearCombination(x.add(1), x.multiply(0.9),
411 x.add(2), x.multiply(0.8),
412 x.add(3), x.multiply(0.7));
413 }
414 });
415 }
416 }
417
418 @Test
419 public void testLinearCombination4D4FVsDS() {
420 for (double x = -1.25; x < 1.25; x+= 0.5) {
421 checkAgainstDS(x,
422 new FieldUnivariateFunction() {
423 public <S extends CalculusFieldElement<S>> S value(S x) {
424 return x.linearCombination(1.0, x.multiply(0.9),
425 2.0, x.multiply(0.8),
426 3.0, x.multiply(0.7),
427 4.0, x.multiply(0.6));
428 }
429 });
430 }
431 }
432
433 @Test
434 public void testLinearCombination4F4FVsDS() {
435 for (double x = -1.25; x < 1.25; x+= 0.5) {
436 checkAgainstDS(x,
437 new FieldUnivariateFunction() {
438 public <S extends CalculusFieldElement<S>> S value(S x) {
439 return x.linearCombination(x.add(1), x.multiply(0.9),
440 x.add(2), x.multiply(0.8),
441 x.add(3), x.multiply(0.7),
442 x.add(4), x.multiply(0.6));
443 }
444 });
445 }
446 }
447
448 @Test
449 public void testLinearCombinationnDnFVsDS() {
450 for (double x = -1.25; x < 1.25; x+= 0.5) {
451 checkAgainstDS(x,
452 new FieldUnivariateFunction() {
453 public <S extends CalculusFieldElement<S>> S value(S x) {
454 final S[] b = MathArrays.buildArray(x.getField(), 4);
455 b[0] = x.add(0.9);
456 b[1] = x.add(0.8);
457 b[2] = x.add(0.7);
458 b[3] = x.add(0.6);
459 return x.linearCombination(new double[] { 1, 2, 3, 4 }, b);
460 }
461 });
462 }
463 }
464
465 @Test
466 public void testLinearCombinationnFnFVsDS() {
467 for (double x = -1.25; x < 1.25; x+= 0.5) {
468 checkAgainstDS(x,
469 new FieldUnivariateFunction() {
470 public <S extends CalculusFieldElement<S>> S value(S x) {
471 final S[] a = MathArrays.buildArray(x.getField(), 4);
472 a[0] = x.add(1);
473 a[1] = x.add(2);
474 a[2] = x.add(3);
475 a[3] = x.add(4);
476 final S[] b = MathArrays.buildArray(x.getField(), 4);
477 b[0] = x.add(0.9);
478 b[1] = x.add(0.8);
479 b[2] = x.add(0.7);
480 b[3] = x.add(0.6);
481 return x.linearCombination(a, b);
482 }
483 });
484 }
485 }
486
487 @Test
488 public void testLinearCombinationField() {
489 final T[] a = MathArrays.buildArray(getValueField(), 3);
490 a[0] = buildScalar(-1321008684645961.0 / 268435456.0);
491 a[1] = buildScalar(-5774608829631843.0 / 268435456.0);
492 a[2] = buildScalar(-7645843051051357.0 / 8589934592.0);
493 final FieldUnivariateDerivative1<T>[] b = MathArrays.buildArray(FieldUnivariateDerivative1Field.getUnivariateDerivative1Field(getValueField()), 3);
494 b[0] = build(-5712344449280879.0 / 2097152.0);
495 b[1] = build(-4550117129121957.0 / 2097152.0);
496 b[2] = build(8846951984510141.0 / 131072.0);
497
498 final FieldUnivariateDerivative1<T> abSumInline = b[0].linearCombination(a[0], b[0],
499 a[1], b[1],
500 a[2], b[2]);
501 final FieldUnivariateDerivative1<T> abSumArray = b[0].linearCombination(a, b);
502 assertEquals(abSumInline.getReal(), abSumArray.getReal(), 3.0e-8);
503 assertEquals(-1.8551294182586248737720779899, abSumInline.getReal(), 5.0e-8);
504 assertEquals(abSumInline.getFirstDerivative().getReal(), abSumArray.getFirstDerivative().getReal(), 3.0e-8);
505 }
506
507 @Test
508 public void testZero() {
509 FieldUnivariateDerivative1<T> zero = build(17.0).getField().getZero();
510 for (int i = 0; i <= zero.getOrder(); ++i) {
511 assertEquals(0.0, zero.getDerivative(i).getReal(), 1.0e-15);
512 }
513 }
514
515 @Test
516 public void testOne() {
517 FieldUnivariateDerivative1<T> one = build(17.0).getField().getOne();
518 for (int i = 0; i <= one.getOrder(); ++i) {
519 assertEquals(i == 0 ? 1.0 : 0.0, one.getDerivative(i).getReal(), 1.0e-15);
520 }
521 }
522
523 @Test
524 public void testGetFirstDerivative() {
525 FieldUnivariateDerivative1<T> ud1 = build(-0.5, 2.5);
526 assertEquals(-0.5, ud1.getReal(), 1.0e-15);
527 assertEquals(-0.5, ud1.getValue().getReal(), 1.0e-15);
528 assertEquals(+2.5, ud1.getFirstDerivative().getReal(), 1.0e-15);
529 }
530
531 @Test
532 public void testConversion() {
533 FieldUnivariateDerivative1<T> udA = build(-0.5, 2.5);
534 FieldDerivativeStructure<T> ds = udA.toDerivativeStructure();
535 assertEquals(1, ds.getFreeParameters());
536 assertEquals(1, ds.getOrder());
537 assertEquals(-0.5, ds.getValue().getReal(), 1.0e-15);
538 assertEquals(-0.5, ds.getPartialDerivative(0).getReal(), 1.0e-15);
539 assertEquals( 2.5, ds.getPartialDerivative(1).getReal(), 1.0e-15);
540 FieldUnivariateDerivative1<T> udB = new FieldUnivariateDerivative1<>(ds);
541 assertNotSame(udA, udB);
542 assertEquals(udA, udB);
543 try {
544 new FieldUnivariateDerivative1<>(new FDSFactory<>(getValueField(), 2, 2).variable(0, 1.0));
545 fail("an exception should have been thrown");
546 } catch (MathIllegalArgumentException miae) {
547 assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
548 }
549 try {
550 new FieldUnivariateDerivative1<>(new FDSFactory<>(getValueField(), 1, 2).variable(0, 1.0));
551 fail("an exception should have been thrown");
552 } catch (MathIllegalArgumentException miae) {
553 assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
554 }
555 }
556
557 @Test
558 public void testDoublePow() {
559 assertSame(build(3).getField().getZero(), FieldUnivariateDerivative1.pow(0.0, build(1.5)));
560 FieldUnivariateDerivative1<T> ud = FieldUnivariateDerivative1.pow(2.0, build(1.5));
561 DSFactory factory = new DSFactory(1, 1);
562 DerivativeStructure ds = factory.constant(2.0).pow(factory.variable(0, 1.5));
563 assertEquals(ds.getValue(), ud.getValue().getReal(), 1.0e-15);
564 assertEquals(ds.getPartialDerivative(1), ud.getFirstDerivative().getReal(), 1.0e-15);
565 }
566
567 @Test
568 public void testTaylor() {
569 assertEquals(2.5, build(2, 1).taylor(0.5).getReal(), 1.0e-15);
570 assertEquals(2.5, build(2, 1).taylor(getValueField().getZero().newInstance(0.5)).getReal(), 1.0e-15);
571 }
572
573 @Test
574 public void testEquals() {
575 FieldUnivariateDerivative1<T> ud1 = build(12, -34);
576 assertEquals(ud1, ud1);
577 assertNotEquals("", ud1);
578 assertEquals(ud1, build(12, -34));
579 assertNotEquals(ud1, build(21, -34));
580 assertNotEquals(ud1, build(12, -43));
581 assertNotEquals(ud1, build(21, -43));
582 }
583
584 @Test
585 public void testRunTimeClass() {
586 Field<FieldUnivariateDerivative1<T>> field = build(0.0).getField();
587 assertEquals(FieldUnivariateDerivative1.class, field.getRuntimeClass());
588 }
589
590 private void check(FieldUnivariateDerivative1<T> ud1, double value, double derivative) {
591
592
593 assertEquals(value, ud1.getReal(), 1.0e-15);
594
595
596 assertEquals(derivative, ud1.getFirstDerivative().getReal(), 1.0e-15);
597
598 }
599
600 }