View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.field;
18  
19  import org.junit.Assert;
20  import org.junit.Test;
21  
22  import org.apache.commons.numbers.core.Sum;
23  import org.apache.commons.rng.UniformRandomProvider;
24  import org.apache.commons.rng.simple.RandomSource;
25  import org.apache.commons.math4.legacy.core.RealFieldElement;
26  import org.apache.commons.math4.legacy.core.MathArrays;
27  import org.apache.commons.math4.core.jdkmath.JdkMath;
28  
29  public abstract class ExtendedFieldElementAbstractTest<T extends RealFieldElement<T>> {
30  
31      protected abstract T build(double x);
32  
33      @Test
34      public void testAddField() {
35          for (double x = -3; x < 3; x += 0.2) {
36              for (double y = -3; y < 3; y += 0.2) {
37                  checkRelative(x + y, build(x).add(build(y)));
38              }
39          }
40      }
41  
42      @Test
43      public void testAddDouble() {
44          for (double x = -3; x < 3; x += 0.2) {
45              for (double y = -3; y < 3; y += 0.2) {
46                  checkRelative(x + y, build(x).add(y));
47              }
48          }
49      }
50  
51      @Test
52      public void testSubtractField() {
53          for (double x = -3; x < 3; x += 0.2) {
54              for (double y = -3; y < 3; y += 0.2) {
55                  checkRelative(x - y, build(x).subtract(build(y)));
56              }
57          }
58      }
59  
60      @Test
61      public void testSubtractDouble() {
62          for (double x = -3; x < 3; x += 0.2) {
63              for (double y = -3; y < 3; y += 0.2) {
64                  checkRelative(x - y, build(x).subtract(y));
65              }
66          }
67      }
68  
69      @Test
70      public void testMultiplyField() {
71          for (double x = -3; x < 3; x += 0.2) {
72              for (double y = -3; y < 3; y += 0.2) {
73                  checkRelative(x * y, build(x).multiply(build(y)));
74              }
75          }
76      }
77  
78      @Test
79      public void testMultiplyDouble() {
80          for (double x = -3; x < 3; x += 0.2) {
81              for (double y = -3; y < 3; y += 0.2) {
82                  checkRelative(x * y, build(x).multiply(y));
83              }
84          }
85      }
86  
87      @Test
88      public void testMultiplyInt() {
89          for (double x = -3; x < 3; x += 0.2) {
90              for (int y = -10; y < 10; y += 1) {
91                  checkRelative(x * y, build(x).multiply(y));
92              }
93          }
94      }
95  
96      @Test
97      public void testDivideField() {
98          for (double x = -3; x < 3; x += 0.2) {
99              for (double y = -3; y < 3; y += 0.2) {
100                 checkRelative(x / y, build(x).divide(build(y)));
101             }
102         }
103     }
104 
105     @Test
106     public void testDivideDouble() {
107         for (double x = -3; x < 3; x += 0.2) {
108             for (double y = -3; y < 3; y += 0.2) {
109                     checkRelative(x / y, build(x).divide(y));
110             }
111         }
112     }
113 
114     @Test
115     public void testRemainderField() {
116         for (double x = -3; x < 3; x += 0.2) {
117             for (double y = -3; y < 3; y += 0.2) {
118                 checkRelative(JdkMath.IEEEremainder(x, y), build(x).remainder(build(y)));
119             }
120         }
121     }
122 
123     @Test
124     public void testRemainderDouble() {
125         for (double x = -3; x < 3; x += 0.2) {
126             for (double y = -3.2; y < 3.2; y += 0.25) {
127                 checkRelative(JdkMath.IEEEremainder(x, y), build(x).remainder(y));
128             }
129         }
130     }
131 
132     @Test
133     public void testCos() {
134         for (double x = -0.9; x < 0.9; x += 0.05) {
135             checkRelative(JdkMath.cos(x), build(x).cos());
136         }
137     }
138 
139     @Test
140     public void testAcos() {
141         for (double x = -0.9; x < 0.9; x += 0.05) {
142             checkRelative(JdkMath.acos(x), build(x).acos());
143         }
144     }
145 
146     @Test
147     public void testSin() {
148         for (double x = -0.9; x < 0.9; x += 0.05) {
149             checkRelative(JdkMath.sin(x), build(x).sin());
150         }
151     }
152 
153     @Test
154     public void testAsin() {
155         for (double x = -0.9; x < 0.9; x += 0.05) {
156             checkRelative(JdkMath.asin(x), build(x).asin());
157         }
158     }
159 
160     @Test
161     public void testTan() {
162         for (double x = -0.9; x < 0.9; x += 0.05) {
163             checkRelative(JdkMath.tan(x), build(x).tan());
164         }
165     }
166 
167     @Test
168     public void testAtan() {
169         for (double x = -0.9; x < 0.9; x += 0.05) {
170             checkRelative(JdkMath.atan(x), build(x).atan());
171         }
172     }
173 
174     @Test
175     public void testAtan2() {
176         for (double x = -3; x < 3; x += 0.2) {
177             for (double y = -3; y < 3; y += 0.2) {
178                 checkRelative(JdkMath.atan2(x, y), build(x).atan2(build(y)));
179             }
180         }
181     }
182 
183     @Test
184     public void testCosh() {
185         for (double x = -0.9; x < 0.9; x += 0.05) {
186             checkRelative(JdkMath.cosh(x), build(x).cosh());
187         }
188     }
189 
190     @Test
191     public void testAcosh() {
192         for (double x = 1.1; x < 5.0; x += 0.05) {
193             checkRelative(JdkMath.acosh(x), build(x).acosh());
194         }
195     }
196 
197     @Test
198     public void testSinh() {
199         for (double x = -0.9; x < 0.9; x += 0.05) {
200             checkRelative(JdkMath.sinh(x), build(x).sinh());
201         }
202     }
203 
204     @Test
205     public void testAsinh() {
206         for (double x = -0.9; x < 0.9; x += 0.05) {
207             checkRelative(JdkMath.asinh(x), build(x).asinh());
208         }
209     }
210 
211     @Test
212     public void testTanh() {
213         for (double x = -0.9; x < 0.9; x += 0.05) {
214             checkRelative(JdkMath.tanh(x), build(x).tanh());
215         }
216     }
217 
218     @Test
219     public void testAtanh() {
220         for (double x = -0.9; x < 0.9; x += 0.05) {
221             checkRelative(JdkMath.atanh(x), build(x).atanh());
222         }
223     }
224 
225     @Test
226     public void testSqrt() {
227         for (double x = 0.01; x < 0.9; x += 0.05) {
228             checkRelative(JdkMath.sqrt(x), build(x).sqrt());
229         }
230     }
231 
232     @Test
233     public void testCbrt() {
234         for (double x = -0.9; x < 0.9; x += 0.05) {
235             checkRelative(JdkMath.cbrt(x), build(x).cbrt());
236         }
237     }
238 
239     @Test
240     public void testHypot() {
241         for (double x = -3; x < 3; x += 0.2) {
242             for (double y = -3; y < 3; y += 0.2) {
243                 checkRelative(JdkMath.hypot(x, y), build(x).hypot(build(y)));
244             }
245         }
246     }
247 
248     @Test
249     public void testRootN() {
250         for (double x = -0.9; x < 0.9; x += 0.05) {
251             for (int n = 1; n < 5; ++n) {
252                 if (x < 0) {
253                     if ((n & 1) == 1) {
254                         checkRelative(-JdkMath.pow(-x, 1.0 / n), build(x).rootN(n));
255                     }
256                 } else {
257                     checkRelative(JdkMath.pow(x, 1.0 / n), build(x).rootN(n));
258                 }
259             }
260         }
261     }
262 
263     @Test
264     public void testPowField() {
265         for (double x = -0.9; x < 0.9; x += 0.05) {
266             for (double y = 0.1; y < 4; y += 0.2) {
267                 checkRelative(JdkMath.pow(x, y), build(x).pow(build(y)));
268             }
269         }
270     }
271 
272     @Test
273     public void testPowDouble() {
274         for (double x = -0.9; x < 0.9; x += 0.05) {
275             for (double y = 0.1; y < 4; y += 0.2) {
276                 checkRelative(JdkMath.pow(x, y), build(x).pow(y));
277             }
278         }
279     }
280 
281     @Test
282     public void testPowInt() {
283         for (double x = -0.9; x < 0.9; x += 0.05) {
284             for (int n = 0; n < 5; ++n) {
285                 checkRelative(JdkMath.pow(x, n), build(x).pow(n));
286             }
287         }
288     }
289 
290     @Test
291     public void testExp() {
292         for (double x = -0.9; x < 0.9; x += 0.05) {
293             checkRelative(JdkMath.exp(x), build(x).exp());
294         }
295     }
296 
297     @Test
298     public void testExpm1() {
299         for (double x = -0.9; x < 0.9; x += 0.05) {
300             checkRelative(JdkMath.expm1(x), build(x).expm1());
301         }
302     }
303 
304     @Test
305     public void testLog() {
306         for (double x = 0.01; x < 0.9; x += 0.05) {
307             checkRelative(JdkMath.log(x), build(x).log());
308         }
309     }
310 
311     @Test
312     public void testLog1p() {
313         for (double x = -0.9; x < 0.9; x += 0.05) {
314             checkRelative(JdkMath.log1p(x), build(x).log1p());
315         }
316     }
317 
318     @Test
319     public void testLog10() {
320         for (double x = -0.9; x < 0.9; x += 0.05) {
321             checkRelative(JdkMath.log10(x), build(x).log10());
322         }
323     }
324 
325     @Test
326     public void testAbs() {
327         for (double x = -0.9; x < 0.9; x += 0.05) {
328             checkRelative(JdkMath.abs(x), build(x).abs());
329         }
330     }
331 
332     @Test
333     public void testCeil() {
334         for (double x = -0.9; x < 0.9; x += 0.05) {
335             checkRelative(JdkMath.ceil(x), build(x).ceil());
336         }
337     }
338 
339     @Test
340     public void testFloor() {
341         for (double x = -0.9; x < 0.9; x += 0.05) {
342             checkRelative(JdkMath.floor(x), build(x).floor());
343         }
344     }
345 
346     @Test
347     public void testRint() {
348         for (double x = -0.9; x < 0.9; x += 0.05) {
349             checkRelative(JdkMath.rint(x), build(x).rint());
350         }
351     }
352 
353     @Test
354     public void testRound() {
355         for (double x = -0.9; x < 0.9; x += 0.05) {
356             Assert.assertEquals(JdkMath.round(x), build(x).round());
357         }
358     }
359 
360     @Test
361     public void testSignum() {
362         for (double x = -0.9; x < 0.9; x += 0.05) {
363             checkRelative(JdkMath.signum(x), build(x).signum());
364         }
365     }
366 
367     @Test
368     public void testCopySignField() {
369         for (double x = -3; x < 3; x += 0.2) {
370             for (double y = -3; y < 3; y += 0.2) {
371                 checkRelative(JdkMath.copySign(x, y), build(x).copySign(build(y)));
372             }
373         }
374     }
375 
376     @Test
377     public void testCopySignDouble() {
378         for (double x = -3; x < 3; x += 0.2) {
379             for (double y = -3; y < 3; y += 0.2) {
380                 checkRelative(JdkMath.copySign(x, y), build(x).copySign(y));
381             }
382         }
383     }
384 
385     @Test
386     public void testScalb() {
387         for (double x = -0.9; x < 0.9; x += 0.05) {
388             for (int n = -100; n < 100; ++n) {
389                 checkRelative(JdkMath.scalb(x, n), build(x).scalb(n));
390             }
391         }
392     }
393 
394     @Test
395     public void testLinearCombinationFaFa() {
396         UniformRandomProvider r = RandomSource.WELL_1024_A.create(0xfafaL);
397         for (int i = 0; i < 50; ++i) {
398             double[] aD = generateDouble(r, 10);
399             double[] bD = generateDouble(r, 10);
400             T[] aF      = toFieldArray(aD);
401             T[] bF      = toFieldArray(bD);
402             checkRelative(Sum.ofProducts(aD, bD).getAsDouble(),
403                           aF[0].linearCombination(aF, bF));
404         }
405     }
406 
407     @Test
408     public void testLinearCombinationDaFa() {
409         UniformRandomProvider r = RandomSource.WELL_1024_A.create(0xdafaL);
410         for (int i = 0; i < 50; ++i) {
411             double[] aD = generateDouble(r, 10);
412             double[] bD = generateDouble(r, 10);
413             T[] bF      = toFieldArray(bD);
414             checkRelative(Sum.ofProducts(aD, bD).getAsDouble(),
415                           bF[0].linearCombination(aD, bF));
416         }
417     }
418 
419     @Test
420     public void testLinearCombinationFF2() {
421         UniformRandomProvider r = RandomSource.WELL_1024_A.create(0xff2L);
422         for (int i = 0; i < 50; ++i) {
423             double[] aD = generateDouble(r, 2);
424             double[] bD = generateDouble(r, 2);
425             T[] aF      = toFieldArray(aD);
426             T[] bF      = toFieldArray(bD);
427             checkRelative(Sum.create()
428                           .addProduct(aD[0], bD[0])
429                           .addProduct(aD[1], bD[1]).getAsDouble(),
430                           aF[0].linearCombination(aF[0], bF[0], aF[1], bF[1]));
431         }
432     }
433 
434     @Test
435     public void testLinearCombinationDF2() {
436         UniformRandomProvider r = RandomSource.WELL_1024_A.create(0xdf2L);
437         for (int i = 0; i < 50; ++i) {
438             double[] aD = generateDouble(r, 2);
439             double[] bD = generateDouble(r, 2);
440             T[] bF      = toFieldArray(bD);
441             checkRelative(Sum.create()
442                           .addProduct(aD[0], bD[0])
443                           .addProduct(aD[1], bD[1]).getAsDouble(),
444                           bF[0].linearCombination(aD[0], bF[0], aD[1], bF[1]));
445         }
446     }
447 
448     @Test
449     public void testLinearCombinationFF3() {
450         UniformRandomProvider r = RandomSource.WELL_1024_A.create(0xff3L);
451         for (int i = 0; i < 50; ++i) {
452             double[] aD = generateDouble(r, 3);
453             double[] bD = generateDouble(r, 3);
454             T[] aF      = toFieldArray(aD);
455             T[] bF      = toFieldArray(bD);
456             checkRelative(Sum.create()
457                           .addProduct(aD[0], bD[0])
458                           .addProduct(aD[1], bD[1])
459                           .addProduct(aD[2], bD[2]).getAsDouble(),
460                           aF[0].linearCombination(aF[0], bF[0], aF[1], bF[1], aF[2], bF[2]));
461         }
462     }
463 
464     @Test
465     public void testLinearCombinationDF3() {
466         UniformRandomProvider r = RandomSource.WELL_1024_A.create(0xdf3L);
467         for (int i = 0; i < 50; ++i) {
468             double[] aD = generateDouble(r, 3);
469             double[] bD = generateDouble(r, 3);
470             T[] bF      = toFieldArray(bD);
471             checkRelative(Sum.create()
472                           .addProduct(aD[0], bD[0])
473                           .addProduct(aD[1], bD[1])
474                           .addProduct(aD[2], bD[2]).getAsDouble(),
475                           bF[0].linearCombination(aD[0], bF[0], aD[1], bF[1], aD[2], bF[2]));
476         }
477     }
478 
479     @Test
480     public void testLinearCombinationFF4() {
481         UniformRandomProvider r = RandomSource.WELL_1024_A.create(0xff4L);
482         for (int i = 0; i < 50; ++i) {
483             double[] aD = generateDouble(r, 4);
484             double[] bD = generateDouble(r, 4);
485             T[] aF      = toFieldArray(aD);
486             T[] bF      = toFieldArray(bD);
487             checkRelative(Sum.create()
488                           .addProduct(aD[0], bD[0])
489                           .addProduct(aD[1], bD[1])
490                           .addProduct(aD[2], bD[2])
491                           .addProduct(aD[3], bD[3]).getAsDouble(),
492                           aF[0].linearCombination(aF[0], bF[0], aF[1], bF[1], aF[2], bF[2], aF[3], bF[3]));
493         }
494     }
495 
496     @Test
497     public void testLinearCombinationDF4() {
498         UniformRandomProvider r = RandomSource.WELL_1024_A.create(0xdf4L);
499         for (int i = 0; i < 50; ++i) {
500             double[] aD = generateDouble(r, 4);
501             double[] bD = generateDouble(r, 4);
502             T[] bF      = toFieldArray(bD);
503             checkRelative(Sum.create()
504                           .addProduct(aD[0], bD[0])
505                           .addProduct(aD[1], bD[1])
506                           .addProduct(aD[2], bD[2])
507                           .addProduct(aD[3], bD[3]).getAsDouble(),
508                           bF[0].linearCombination(aD[0], bF[0], aD[1], bF[1], aD[2], bF[2], aD[3], bF[3]));
509         }
510     }
511 
512     @Test
513     public void testGetField() {
514         checkRelative(1.0, build(-10).getField().getOne());
515         checkRelative(0.0, build(-10).getField().getZero());
516     }
517 
518     private void checkRelative(double expected, T obtained) {
519         Assert.assertEquals(expected, obtained.getReal(), 1.0e-15 * (1 + JdkMath.abs(expected)));
520     }
521 
522     @Test
523     public void testEquals() {
524         T t1a = build(1.0);
525         T t1b = build(1.0);
526         T t2  = build(2.0);
527         Assert.assertEquals(t1a, t1a);
528         Assert.assertEquals(t1a, t1b);
529         Assert.assertNotEquals(t1a, t2);
530         Assert.assertNotEquals(t1a, new Object());
531     }
532 
533     @Test
534     public void testHash() {
535         T t1a = build(1.0);
536         T t1b = build(1.0);
537         T t2  = build(2.0);
538         Assert.assertEquals(t1a.hashCode(), t1b.hashCode());
539         Assert.assertTrue(t1a.hashCode() != t2.hashCode());
540     }
541 
542     private double[] generateDouble (final UniformRandomProvider r, int n) {
543         double[] a = new double[n];
544         for (int i = 0; i < n; ++i) {
545             a[i] = r.nextDouble();
546         }
547         return a;
548     }
549 
550     private T[] toFieldArray (double[] a) {
551         T[] f = MathArrays.buildArray(build(0).getField(), a.length);
552         for (int i = 0; i < a.length; ++i) {
553             f[i] = build(a[i]);
554         }
555         return f;
556     }
557 }