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