1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus;
23
24 import java.util.function.DoubleFunction;
25
26 import org.hipparchus.random.RandomGenerator;
27 import org.hipparchus.random.Well1024a;
28 import org.hipparchus.random.Well19937a;
29 import org.hipparchus.util.FastMath;
30 import org.hipparchus.util.FieldSinCos;
31 import org.hipparchus.util.FieldSinhCosh;
32 import org.hipparchus.util.MathArrays;
33 import org.hipparchus.util.SinCos;
34 import org.junit.Assert;
35 import org.junit.Test;
36
37 public abstract class CalculusFieldElementAbstractTest<T extends CalculusFieldElement<T>> {
38
39 protected abstract T build(double x);
40
41 @Test
42 public void testNewInstance() {
43
44 final double realZero = 0.;
45 final T expectedZero = build(realZero);
46
47 final T actualZero = expectedZero.newInstance(realZero);
48
49 Assert.assertEquals(expectedZero.getReal(), actualZero.getReal(), 0.);
50 }
51
52 @Test
53 public void testAddField() {
54 for (double x = -3; x < 3; x += 0.2) {
55 for (double y = -3; y < 3; y += 0.2) {
56 checkRelative(x + y, build(x).add(build(y)));
57 }
58 }
59 }
60
61 @Test
62 public void testAddDouble() {
63 for (double x = -3; x < 3; x += 0.2) {
64 for (double y = -3; y < 3; y += 0.2) {
65 checkRelative(x + y, build(x).add(y));
66 }
67 }
68 }
69
70 @Test
71 public void testSubtractField() {
72 for (double x = -3; x < 3; x += 0.2) {
73 for (double y = -3; y < 3; y += 0.2) {
74 checkRelative(x - y, build(x).subtract(build(y)));
75 }
76 }
77 }
78
79 @Test
80 public void testSubtractDouble() {
81 for (double x = -3; x < 3; x += 0.2) {
82 for (double y = -3; y < 3; y += 0.2) {
83 checkRelative(x - y, build(x).subtract(y));
84 }
85 }
86 }
87
88 @Test
89 public void testMultiplyField() {
90 for (double x = -3; x < 3; x += 0.2) {
91 for (double y = -3; y < 3; y += 0.2) {
92 checkRelative(x * y, build(x).multiply(build(y)));
93 }
94 }
95 }
96
97 @Test
98 public void testMultiplyDouble() {
99 for (double x = -3; x < 3; x += 0.2) {
100 for (double y = -3; y < 3; y += 0.2) {
101 checkRelative(x * y, build(x).multiply(y));
102 }
103 }
104 }
105
106 @Test
107 public void testMultiplyInt() {
108 for (double x = -3; x < 3; x += 0.2) {
109 for (int y = -10; y < 10; y += 1) {
110 checkRelative(x * y, build(x).multiply(y));
111 }
112 }
113 }
114
115 @Test
116 public void testSquare() {
117 for (double x = -3; x < 3; x += 0.2) {
118 checkRelative(x * x, build(x).square());
119 }
120 }
121
122 @Test
123 public void testDivideField() {
124 for (double x = -3; x < 3; x += 0.2) {
125 for (double y = -3; y < 3; y += 0.2) {
126 checkRelative(x / y, build(x).divide(build(y)));
127 }
128 }
129 }
130
131 @Test
132 public void testDivideDouble() {
133 for (double x = -3; x < 3; x += 0.2) {
134 for (double y = -3; y < 3; y += 0.2) {
135 checkRelative(x / y, build(x).divide(y));
136 }
137 }
138 }
139
140 @Test
141 public void testToDegrees() {
142 for (double x = -0.9; x < 0.9; x += 0.05) {
143 checkRelative(FastMath.toDegrees(x), build(x).toDegrees());
144 }
145 }
146
147 @Test
148 public void testToRadians() {
149 for (double x = -0.9; x < 0.9; x += 0.05) {
150 checkRelative(FastMath.toRadians(x), build(x).toRadians());
151 }
152 }
153
154 @Test
155 public void testCos() {
156 for (double x = -0.9; x < 0.9; x += 0.05) {
157 checkRelative(FastMath.cos(x), build(x).cos());
158 }
159 }
160
161 @Test
162 public void testAcos() {
163 for (double x = -0.9; x < 0.9; x += 0.05) {
164 checkRelative(FastMath.acos(x), build(x).acos());
165 }
166 }
167
168 @Test
169 public void testSin() {
170 for (double x = -0.9; x < 0.9; x += 0.05) {
171 checkRelative(FastMath.sin(x), build(x).sin());
172 }
173 }
174
175 @Test
176 public void testAsin() {
177 for (double x = -0.9; x < 0.9; x += 0.05) {
178 checkRelative(FastMath.asin(x), build(x).asin());
179 }
180 }
181
182 @Test
183 public void testSinCos() {
184 for (double x = -0.9; x < 0.9; x += 0.05) {
185 FieldSinCos<T> sinCos = build(x).sinCos();
186 checkRelative(FastMath.sin(x), sinCos.sin());
187 checkRelative(FastMath.cos(x), sinCos.cos());
188 }
189 }
190
191 @Test
192 public void testSinCosNaN() {
193 FieldSinCos<T> sinCos = build(Double.NaN).sinCos();
194 Assert.assertTrue(sinCos.sin().isNaN());
195 Assert.assertTrue(sinCos.cos().isNaN());
196 }
197
198 @Test
199 public void testSinCosSum() {
200 final RandomGenerator random = new Well19937a(0x4aab62a42c9eb940l);
201 for (int i = 0; i < 10000; ++i) {
202 final double alpha = 10.0 * (2.0 * random.nextDouble() - 1.0);
203 final double beta = 10.0 * (2.0 * random.nextDouble() - 1.0);
204 final T alphaT = build(alpha);
205 final T betaT = build(beta);
206 final SinCos scSum = SinCos.sum(FastMath.sinCos(alpha), FastMath.sinCos(beta));
207 final FieldSinCos<T> scSumT = FieldSinCos.sum(alphaT.sinCos(), betaT.sinCos());
208 checkRelative(scSum.sin(), scSumT.sin());
209 checkRelative(scSum.cos(), scSumT.cos());
210 }
211 }
212
213 @Test
214 public void testSinCosdifference() {
215 final RandomGenerator random = new Well19937a(0x589aaf49471b03d5l);
216 for (int i = 0; i < 10000; ++i) {
217 final double alpha = 10.0 * (2.0 * random.nextDouble() - 1.0);
218 final double beta = 10.0 * (2.0 * random.nextDouble() - 1.0);
219 final T alphaT = build(alpha);
220 final T betaT = build(beta);
221 final SinCos scDifference = SinCos.difference(FastMath.sinCos(alpha), FastMath.sinCos(beta));
222 final FieldSinCos<T> scDifferenceT = FieldSinCos.difference(alphaT.sinCos(), betaT.sinCos());
223 checkRelative(scDifference.sin(), scDifferenceT.sin());
224 checkRelative(scDifference.cos(), scDifferenceT.cos());
225 }
226 }
227
228 @Test
229 public void testTan() {
230 for (double x = -0.9; x < 0.9; x += 0.05) {
231 checkRelative(FastMath.tan(x), build(x).tan());
232 }
233 }
234
235 @Test
236 public void testAtan() {
237 for (double x = -0.9; x < 0.9; x += 0.05) {
238 checkRelative(FastMath.atan(x), build(x).atan());
239 }
240 }
241
242 @Test
243 public void testAtan2() {
244 for (double x = -3; x < 3; x += 0.2) {
245 for (double y = -3; y < 3; y += 0.2) {
246 checkRelative(FastMath.atan2(y, x), build(y).atan2(build(x)));
247 }
248 }
249 }
250
251 @Test
252 public void testAtan2SpecialCases() {
253 checkRelative(FastMath.atan2(+0.0, +0.0), build(+0.0).atan2(build(+0.0)));
254 checkRelative(FastMath.atan2(-0.0, +0.0), build(-0.0).atan2(build(+0.0)));
255 checkRelative(FastMath.atan2(+0.0, -0.0), build(+0.0).atan2(build(-0.0)));
256 checkRelative(FastMath.atan2(-0.0, -0.0), build(-0.0).atan2(build(-0.0)));
257 }
258
259 @Test
260 public void testCosh() {
261 for (double x = -0.9; x < 0.9; x += 0.05) {
262 checkRelative(FastMath.cosh(x), build(x).cosh());
263 }
264 }
265
266 @Test
267 public void testAcosh() {
268 for (double x = 1.1; x < 5.0; x += 0.05) {
269 checkRelative(FastMath.acosh(x), build(x).acosh());
270 }
271 }
272
273 @Test
274 public void testSinh() {
275 for (double x = -0.9; x < 0.9; x += 0.05) {
276 checkRelative(FastMath.sinh(x), build(x).sinh());
277 }
278 }
279
280 @Test
281 public void testAsinh() {
282 for (double x = -0.9; x < 0.9; x += 0.05) {
283 checkRelative(FastMath.asinh(x), build(x).asinh());
284 }
285 }
286
287 @Test
288 public void testSinhCosh() {
289 for (double x = -0.9; x < 0.9; x += 0.05) {
290 FieldSinhCosh<T> sinhCosh = build(x).sinhCosh();
291 checkRelative(FastMath.sinh(x), sinhCosh.sinh());
292 checkRelative(FastMath.cosh(x), sinhCosh.cosh());
293 }
294 }
295
296 @Test
297 public void testSinhCoshNaN() {
298 FieldSinhCosh<T> sinhCosh = build(Double.NaN).sinhCosh();
299 Assert.assertTrue(sinhCosh.sinh().isNaN());
300 Assert.assertTrue(sinhCosh.cosh().isNaN());
301 }
302
303 @Test
304 public void testTanh() {
305 for (double x = -0.9; x < 0.9; x += 0.05) {
306 checkRelative(FastMath.tanh(x), build(x).tanh());
307 }
308 }
309
310 @Test
311 public void testAtanh() {
312 for (double x = -0.9; x < 0.9; x += 0.05) {
313 checkRelative(FastMath.atanh(x), build(x).atanh());
314 }
315 }
316
317 @Test
318 public void testSqrt() {
319 for (double x = 0.01; x < 0.9; x += 0.05) {
320 checkRelative(FastMath.sqrt(x), build(x).sqrt());
321 }
322 }
323
324 @Test
325 public void testCbrt() {
326 for (double x = -0.9; x < 0.9; x += 0.05) {
327 checkRelative(FastMath.cbrt(x), build(x).cbrt());
328 }
329 }
330
331 @Test
332 public void testHypot() {
333 for (double x = -3; x < 3; x += 0.2) {
334 for (double y = -3; y < 3; y += 0.2) {
335 checkRelative(FastMath.hypot(x, y), build(x).hypot(build(y)));
336 }
337 }
338 }
339
340 @Test
341 public void testHypotSpecialCases() {
342 Assert.assertTrue(Double.isNaN(build(Double.NaN).hypot(build(0)).getReal()));
343 Assert.assertTrue(Double.isNaN(build(0).hypot(build(Double.NaN)).getReal()));
344 Assert.assertEquals(Double.POSITIVE_INFINITY, build(Double.POSITIVE_INFINITY).hypot(build(0)).getReal(), 1.0);
345 Assert.assertEquals(Double.POSITIVE_INFINITY, build(Double.NEGATIVE_INFINITY).hypot(build(0)).getReal(), 1.0);
346 Assert.assertEquals(Double.POSITIVE_INFINITY, build(Double.POSITIVE_INFINITY).hypot(build(Double.NaN)).getReal(), 1.0);
347 Assert.assertEquals(Double.POSITIVE_INFINITY, build(Double.NEGATIVE_INFINITY).hypot(build(Double.NaN)).getReal(), 1.0);
348 Assert.assertEquals(Double.POSITIVE_INFINITY, build(0).hypot(build(Double.POSITIVE_INFINITY)).getReal(), 1.0);
349 Assert.assertEquals(Double.POSITIVE_INFINITY, build(0).hypot(build(Double.NEGATIVE_INFINITY)).getReal(), 1.0);
350 Assert.assertEquals(Double.POSITIVE_INFINITY, build(Double.NaN).hypot(build(Double.POSITIVE_INFINITY)).getReal(), 1.0);
351 Assert.assertEquals(Double.POSITIVE_INFINITY, build(Double.NaN).hypot(build(Double.NEGATIVE_INFINITY)).getReal(), 1.0);
352 }
353
354 @Test
355 public void testRootN() {
356 for (double x = -0.9; x < 0.9; x += 0.05) {
357 for (int n = 1; n < 5; ++n) {
358 if (x < 0) {
359 if (n % 2 == 1) {
360 checkRelative(-FastMath.pow(-x, 1.0 / n), build(x).rootN(n));
361 }
362 } else {
363 checkRelative(FastMath.pow(x, 1.0 / n), build(x).rootN(n));
364 }
365 }
366 }
367 }
368
369 @Test
370 public void testPowField() {
371 for (double x = -0.9; x < 0.9; x += 0.05) {
372 for (double y = 0.1; y < 4; y += 0.2) {
373 checkRelative(FastMath.pow(x, y), build(x).pow(build(y)));
374 }
375 }
376 }
377
378 @Test
379 public void testPowDouble() {
380 for (double x = -0.9; x < 0.9; x += 0.05) {
381 for (double y = 0.1; y < 4; y += 0.2) {
382 checkRelative(FastMath.pow(x, y), build(x).pow(y));
383 }
384 checkRelative(FastMath.pow(x, 0.0), build(x).pow(0.0));
385 }
386 }
387
388 @Test
389 public void testPowInt() {
390 for (double x = -0.9; x < 0.9; x += 0.05) {
391 for (int n = 0; n < 5; ++n) {
392 checkRelative(FastMath.pow(x, n), build(x).pow(n));
393 }
394 }
395 }
396
397 @Test
398 public void testExp() {
399 for (double x = -0.9; x < 0.9; x += 0.05) {
400 checkRelative(FastMath.exp(x), build(x).exp());
401 }
402 }
403
404 @Test
405 public void testExpm1() {
406 for (double x = -0.9; x < 0.9; x += 0.05) {
407 checkRelative(FastMath.expm1(x), build(x).expm1());
408 }
409 }
410
411 @Test
412 public void testLog() {
413 for (double x = 0.01; x < 0.9; x += 0.05) {
414 checkRelative(FastMath.log(x), build(x).log());
415 }
416 }
417
418 @Test
419 public void testLog1p() {
420 for (double x = -0.9; x < 0.9; x += 0.05) {
421 checkRelative(FastMath.log1p(x), build(x).log1p());
422 }
423 }
424
425 @Test
426 public void testLog10() {
427 for (double x = -0.9; x < 0.9; x += 0.05) {
428 checkRelative(FastMath.log10(x), build(x).log10());
429 }
430 }
431
432 @Test
433 public void testScalb() {
434 for (double x = -0.9; x < 0.9; x += 0.05) {
435 for (int n = -100; n < 100; ++n) {
436 checkRelative(FastMath.scalb(x, n), build(x).scalb(n));
437 }
438 }
439 }
440
441 @Test
442 public void testUlp() {
443 final RandomGenerator random = new Well19937a(0x36d4f8862421e0e4l);
444 for (int i = -300; i < 300; ++i) {
445 final double x = FastMath.scalb(2.0 * random.nextDouble() - 1.0, i);
446 Assert.assertTrue(FastMath.ulp(x) >= build(x).ulp().getReal());
447 }
448 }
449
450 @Test
451 public void testCeil() {
452 for (double x = -0.9; x < 0.9; x += 0.05) {
453 checkRelative(FastMath.ceil(x), build(x).ceil());
454 }
455 }
456
457 @Test
458 public void testFloor() {
459 for (double x = -0.9; x < 0.9; x += 0.05) {
460 checkRelative(FastMath.floor(x), build(x).floor());
461 }
462 }
463
464 @Test
465 public void testRint() {
466 for (double x = -0.9; x < 0.9; x += 0.05) {
467 checkRelative(FastMath.rint(x), build(x).rint());
468 }
469 }
470
471 @Test
472 public void testRemainderField() {
473 for (double x = -3; x < 3; x += 0.2) {
474 for (double y = -3; y < 3; y += 0.2) {
475 checkRelative(FastMath.IEEEremainder(x, y), build(x).remainder(build(y)));
476 }
477 }
478 }
479
480 @Test
481 public void testRemainderDouble() {
482 for (double x = -3; x < 3; x += 0.2) {
483 for (double y = -3.2; y < 3.2; y += 0.25) {
484 checkRelative(FastMath.IEEEremainder(x, y), build(x).remainder(y));
485 }
486 }
487 }
488
489 @Test
490 public void testCopySignField() {
491 for (double x = -3; x < 3; x += 0.2) {
492 for (double y = -3; y < 3; y += 0.2) {
493 checkRelative(FastMath.copySign(x, y), build(x).copySign(build(y)));
494 }
495 }
496 }
497
498 @Test
499 public void testCopySignDouble() {
500 for (double x = -3; x < 3; x += 0.2) {
501 for (double y = -3; y < 3; y += 0.2) {
502 checkRelative(FastMath.copySign(x, y), build(x).copySign(y));
503 }
504 }
505 }
506
507 @Test
508 public void testCopySignSpecialField() {
509
510 Assert.assertEquals(-2.0, build(-2.0).copySign(build(-5.0)).getReal(), 1.0e-10);
511 Assert.assertEquals(-2.0, build(+2.0).copySign(build(-5.0)).getReal(), 1.0e-10);
512 Assert.assertEquals(+2.0, build(-2.0).copySign(build(+5.0)).getReal(), 1.0e-10);
513 Assert.assertEquals(+2.0, build(+2.0).copySign(build(+5.0)).getReal(), 1.0e-10);
514 Assert.assertEquals(-2.0, build(-2.0).copySign(build(Double.NEGATIVE_INFINITY)).getReal(), 1.0e-10);
515 Assert.assertEquals(-2.0, build(+2.0).copySign(build(Double.NEGATIVE_INFINITY)).getReal(), 1.0e-10);
516 Assert.assertEquals(+2.0, build(-2.0).copySign(build(Double.POSITIVE_INFINITY)).getReal(), 1.0e-10);
517 Assert.assertEquals(+2.0, build(+2.0).copySign(build(Double.POSITIVE_INFINITY)).getReal(), 1.0e-10);
518 Assert.assertEquals(+2.0, build(-2.0).copySign(build(Double.NaN)).getReal(), 1.0e-10);
519 Assert.assertEquals(+2.0, build(-2.0).copySign(build(Double.NaN)).getReal(), 1.0e-10);
520 Assert.assertEquals(+2.0, build(-2.0).copySign(build(-Double.NaN)).getReal(), 1.0e-10);
521 Assert.assertEquals(+2.0, build(-2.0).copySign(build(-Double.NaN)).getReal(), 1.0e-10);
522 Assert.assertEquals(-2.0, build(-2.0).copySign(build(-0.0)).getReal(), 1.0e-10);
523 Assert.assertEquals(-2.0, build(+2.0).copySign(build(-0.0)).getReal(), 1.0e-10);
524 Assert.assertEquals(+2.0, build(-2.0).copySign(build(+0.0)).getReal(), 1.0e-10);
525 Assert.assertEquals(+2.0, build(+2.0).copySign(build(+0.0)).getReal(), 1.0e-10);
526
527 Assert.assertEquals(-3.0, build(+3.0).copySign(build(-0.0).copySign(build(-5.0))).getReal(), 1.0e-10);
528 Assert.assertEquals(-3.0, build(+3.0).copySign(build(+0.0).copySign(build(-5.0))).getReal(), 1.0e-10);
529 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(build(+5.0))).getReal(), 1.0e-10);
530 Assert.assertEquals(+3.0, build(+3.0).copySign(build(+0.0).copySign(build(+5.0))).getReal(), 1.0e-10);
531 Assert.assertEquals(-3.0, build(+3.0).copySign(build(-0.0).copySign(build(Double.NEGATIVE_INFINITY))).getReal(), 1.0e-10);
532 Assert.assertEquals(-3.0, build(+3.0).copySign(build(+0.0).copySign(build(Double.NEGATIVE_INFINITY))).getReal(), 1.0e-10);
533 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(build(Double.POSITIVE_INFINITY))).getReal(), 1.0e-10);
534 Assert.assertEquals(+3.0, build(+3.0).copySign(build(+0.0).copySign(build(Double.POSITIVE_INFINITY))).getReal(), 1.0e-10);
535 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(build(Double.NaN))).getReal(), 1.0e-10);
536 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(build(Double.NaN))).getReal(), 1.0e-10);
537 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(build(-Double.NaN))).getReal(), 1.0e-10);
538 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(build(-Double.NaN))).getReal(), 1.0e-10);
539 Assert.assertEquals(-3.0, build(+3.0).copySign(build(-0.0).copySign(build(-0.0))).getReal(), 1.0e-10);
540 Assert.assertEquals(-3.0, build(+3.0).copySign(build(+0.0).copySign(build(-0.0))).getReal(), 1.0e-10);
541 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(build(+0.0))).getReal(), 1.0e-10);
542 Assert.assertEquals(+3.0, build(+3.0).copySign(build(+0.0).copySign(build(+0.0))).getReal(), 1.0e-10);
543
544 }
545
546 @Test
547 public void testCopySignSpecialDouble() {
548
549 Assert.assertEquals(-2.0, build(-2.0).copySign(-5.0).getReal(), 1.0e-10);
550 Assert.assertEquals(-2.0, build(+2.0).copySign(-5.0).getReal(), 1.0e-10);
551 Assert.assertEquals(+2.0, build(-2.0).copySign(+5.0).getReal(), 1.0e-10);
552 Assert.assertEquals(+2.0, build(+2.0).copySign(+5.0).getReal(), 1.0e-10);
553 Assert.assertEquals(-2.0, build(-2.0).copySign(Double.NEGATIVE_INFINITY).getReal(), 1.0e-10);
554 Assert.assertEquals(-2.0, build(+2.0).copySign(Double.NEGATIVE_INFINITY).getReal(), 1.0e-10);
555 Assert.assertEquals(+2.0, build(-2.0).copySign(Double.POSITIVE_INFINITY).getReal(), 1.0e-10);
556 Assert.assertEquals(+2.0, build(+2.0).copySign(Double.POSITIVE_INFINITY).getReal(), 1.0e-10);
557 Assert.assertEquals(+2.0, build(-2.0).copySign(Double.NaN).getReal(), 1.0e-10);
558 Assert.assertEquals(+2.0, build(-2.0).copySign(Double.NaN).getReal(), 1.0e-10);
559 Assert.assertEquals(+2.0, build(-2.0).copySign(-Double.NaN).getReal(), 1.0e-10);
560 Assert.assertEquals(+2.0, build(-2.0).copySign(-Double.NaN).getReal(), 1.0e-10);
561 Assert.assertEquals(-2.0, build(-2.0).copySign(-0.0).getReal(), 1.0e-10);
562 Assert.assertEquals(-2.0, build(+2.0).copySign(-0.0).getReal(), 1.0e-10);
563 Assert.assertEquals(+2.0, build(-2.0).copySign(+0.0).getReal(), 1.0e-10);
564 Assert.assertEquals(+2.0, build(+2.0).copySign(+0.0).getReal(), 1.0e-10);
565
566 Assert.assertEquals(-3.0, build(+3.0).copySign(build(-0.0).copySign(-5.0)).getReal(), 1.0e-10);
567 Assert.assertEquals(-3.0, build(+3.0).copySign(build(+0.0).copySign(-5.0)).getReal(), 1.0e-10);
568 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(+5.0)).getReal(), 1.0e-10);
569 Assert.assertEquals(+3.0, build(+3.0).copySign(build(+0.0).copySign(+5.0)).getReal(), 1.0e-10);
570 Assert.assertEquals(-3.0, build(+3.0).copySign(build(-0.0).copySign(Double.NEGATIVE_INFINITY)).getReal(), 1.0e-10);
571 Assert.assertEquals(-3.0, build(+3.0).copySign(build(+0.0).copySign(Double.NEGATIVE_INFINITY)).getReal(), 1.0e-10);
572 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(Double.POSITIVE_INFINITY)).getReal(), 1.0e-10);
573 Assert.assertEquals(+3.0, build(+3.0).copySign(build(+0.0).copySign(Double.POSITIVE_INFINITY)).getReal(), 1.0e-10);
574 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(Double.NaN)).getReal(), 1.0e-10);
575 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(Double.NaN)).getReal(), 1.0e-10);
576 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(-Double.NaN)).getReal(), 1.0e-10);
577 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(-Double.NaN)).getReal(), 1.0e-10);
578 Assert.assertEquals(-3.0, build(+3.0).copySign(build(-0.0).copySign(-0.0)).getReal(), 1.0e-10);
579 Assert.assertEquals(-3.0, build(+3.0).copySign(build(+0.0).copySign(-0.0)).getReal(), 1.0e-10);
580 Assert.assertEquals(+3.0, build(+3.0).copySign(build(-0.0).copySign(+0.0)).getReal(), 1.0e-10);
581 Assert.assertEquals(+3.0, build(+3.0).copySign(build(+0.0).copySign(+0.0)).getReal(), 1.0e-10);
582
583 }
584
585 @Test
586 public void testSign() {
587 for (double x = -0.9; x < 0.9; x += 0.05) {
588 checkRelative(FastMath.signum(x), build(x).sign());
589 }
590 }
591
592 @Test
593 public void testLinearCombinationReference() {
594 doTestLinearCombinationReference(x -> build(x), 5.0e-16, 1.0);
595 }
596
597 protected void doTestLinearCombinationReference(final DoubleFunction<T> builder,
598 final double toleranceLinearCombination,
599 final double relativeErrorNaiveImplementation) {
600
601 final T[] a = MathArrays.buildArray(build(0).getField(), 3);
602 a[0] = builder.apply(-1321008684645961.0);
603 a[1] = builder.apply(-5774608829631843.0);
604 a[2] = builder.apply(-7645843051051357.0 / 32.0);
605 final T[] b = MathArrays.buildArray(build(0).getField(), 3);
606 b[0] = builder.apply(-5712344449280879.0 / 16.0);
607 b[1] = builder.apply(-4550117129121957.0 / 16.0);
608 b[2] = builder.apply(8846951984510141.0);
609
610 final T abSumInline = a[0].linearCombination(a[0], b[0], a[1], b[1], a[2], b[2]);
611 final T abSumArray = a[0].linearCombination(a, b);
612 final T abNaive = a[0].multiply(b[0]).add(a[1].multiply(b[1])).add(a[2].multiply(b[2]));
613
614 Assert.assertEquals(abSumInline.getReal(), abSumArray.getReal(), 0);
615 final double reference = -65271563724949.90625;
616 Assert.assertEquals(reference, abSumInline.getReal(),
617 toleranceLinearCombination * FastMath.abs(reference));
618 Assert.assertEquals(relativeErrorNaiveImplementation * FastMath.abs(reference),
619 FastMath.abs(abNaive.subtract(reference).getReal()),
620 1.0e-3 * relativeErrorNaiveImplementation * FastMath.abs(reference));
621
622 }
623
624 @Test
625 public void testLinearCombinationFaFa() {
626 RandomGenerator r = new Well1024a(0xfafal);
627 for (int i = 0; i < 50; ++i) {
628 double[] aD = generateDouble(r, 10);
629 double[] bD = generateDouble(r, 10);
630 T[] aF = toFieldArray(aD);
631 T[] bF = toFieldArray(bD);
632 checkRelative(MathArrays.linearCombination(aD, bD),
633 aF[0].linearCombination(aF, bF));
634 }
635 }
636
637 @Test
638 public void testLinearCombinationDaFa() {
639 RandomGenerator r = new Well1024a(0xdafal);
640 for (int i = 0; i < 50; ++i) {
641 double[] aD = generateDouble(r, 10);
642 double[] bD = generateDouble(r, 10);
643 T[] bF = toFieldArray(bD);
644 checkRelative(MathArrays.linearCombination(aD, bD),
645 bF[0].linearCombination(aD, bF));
646 }
647 }
648
649 @Test
650 public void testLinearCombinationFF2() {
651 RandomGenerator r = new Well1024a(0xff2l);
652 for (int i = 0; i < 50; ++i) {
653 double[] aD = generateDouble(r, 2);
654 double[] bD = generateDouble(r, 2);
655 T[] aF = toFieldArray(aD);
656 T[] bF = toFieldArray(bD);
657 checkRelative(MathArrays.linearCombination(aD[0], bD[0], aD[1], bD[1]),
658 aF[0].linearCombination(aF[0], bF[0], aF[1], bF[1]));
659 }
660 }
661
662 @Test
663 public void testLinearCombinationDF2() {
664 RandomGenerator r = new Well1024a(0xdf2l);
665 for (int i = 0; i < 50; ++i) {
666 double[] aD = generateDouble(r, 2);
667 double[] bD = generateDouble(r, 2);
668 T[] bF = toFieldArray(bD);
669 checkRelative(MathArrays.linearCombination(aD[0], bD[0], aD[1], bD[1]),
670 bF[0].linearCombination(aD[0], bF[0], aD[1], bF[1]));
671 }
672 }
673
674 @Test
675 public void testLinearCombinationFF3() {
676 RandomGenerator r = new Well1024a(0xff3l);
677 for (int i = 0; i < 50; ++i) {
678 double[] aD = generateDouble(r, 3);
679 double[] bD = generateDouble(r, 3);
680 T[] aF = toFieldArray(aD);
681 T[] bF = toFieldArray(bD);
682 checkRelative(MathArrays.linearCombination(aD[0], bD[0], aD[1], bD[1], aD[2], bD[2]),
683 aF[0].linearCombination(aF[0], bF[0], aF[1], bF[1], aF[2], bF[2]));
684 }
685 }
686
687 @Test
688 public void testLinearCombinationDF3() {
689 RandomGenerator r = new Well1024a(0xdf3l);
690 for (int i = 0; i < 50; ++i) {
691 double[] aD = generateDouble(r, 3);
692 double[] bD = generateDouble(r, 3);
693 T[] bF = toFieldArray(bD);
694 checkRelative(MathArrays.linearCombination(aD[0], bD[0], aD[1], bD[1], aD[2], bD[2]),
695 bF[0].linearCombination(aD[0], bF[0], aD[1], bF[1], aD[2], bF[2]));
696 }
697 }
698
699 @Test
700 public void testLinearCombinationFF4() {
701 RandomGenerator r = new Well1024a(0xff4l);
702 for (int i = 0; i < 50; ++i) {
703 double[] aD = generateDouble(r, 4);
704 double[] bD = generateDouble(r, 4);
705 T[] aF = toFieldArray(aD);
706 T[] bF = toFieldArray(bD);
707 checkRelative(MathArrays.linearCombination(aD[0], bD[0], aD[1], bD[1], aD[2], bD[2], aD[3], bD[3]),
708 aF[0].linearCombination(aF[0], bF[0], aF[1], bF[1], aF[2], bF[2], aF[3], bF[3]));
709 }
710 }
711
712 @Test
713 public void testLinearCombinationDF4() {
714 RandomGenerator r = new Well1024a(0xdf4l);
715 for (int i = 0; i < 50; ++i) {
716 double[] aD = generateDouble(r, 4);
717 double[] bD = generateDouble(r, 4);
718 T[] bF = toFieldArray(bD);
719 checkRelative(MathArrays.linearCombination(aD[0], bD[0], aD[1], bD[1], aD[2], bD[2], aD[3], bD[3]),
720 bF[0].linearCombination(aD[0], bF[0], aD[1], bF[1], aD[2], bF[2], aD[3], bF[3]));
721 }
722 }
723
724 @Test
725 public void testGetPi() {
726 checkRelative(FastMath.PI, build(-10).getPi());
727 }
728
729 @Test
730 public void testGetField() {
731 checkRelative(1.0, build(-10).getField().getOne());
732 checkRelative(0.0, build(-10).getField().getZero());
733 }
734
735 @Test
736 public void testAbs() {
737 for (double x = -0.9; x < 0.9; x += 0.05) {
738 checkRelative(FastMath.abs(x), build(x).abs());
739 }
740 }
741
742 @Test
743 public void testRound() {
744 for (double x = -0.9; x < 0.9; x += 0.05) {
745 Assert.assertEquals(FastMath.round(x), build(x).round());
746 }
747 }
748 protected void checkRelative(double expected, T obtained) {
749 Assert.assertEquals(expected, obtained.getReal(), 1.0e-15 * (1 + FastMath.abs(expected)));
750 }
751
752 private double[] generateDouble (final RandomGenerator r, int n) {
753 double[] a = new double[n];
754 for (int i = 0; i < n; ++i) {
755 a[i] = r.nextDouble();
756 }
757 return a;
758 }
759
760 private T[] toFieldArray (double[] a) {
761 T[] f = MathArrays.buildArray(build(0).getField(), a.length);
762 for (int i = 0; i < a.length; ++i) {
763 f[i] = build(a[i]);
764 }
765 return f;
766 }
767
768 }