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