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