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