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.numbers.angle;
18  
19  import java.util.function.DoubleUnaryOperator;
20  
21  import org.junit.jupiter.api.Assertions;
22  import org.junit.jupiter.api.Test;
23  
24  /**
25   * Test cases for the {@link Reduce} class.
26   */
27  class ReduceTest {
28      @Test
29      void testReduce() {
30          final double period = 12.222;
31          final double offset = 13456.789;
32  
33          final double delta = 1.5;
34  
35          double orig = offset + 122456789 * period + delta;
36          double expected = delta;
37  
38          final Reduce r = new Reduce(offset, period);
39          Assertions.assertEquals(expected,
40                                  r.applyAsDouble(orig),
41                                  1e-7);
42  
43          orig = offset - 123356789 * period - delta;
44          expected = Math.abs(period) - delta;
45          Assertions.assertEquals(expected,
46                                  r.applyAsDouble(orig),
47                                  1e-6);
48  
49          orig = offset - 123446789 * period + delta;
50          expected = delta;
51          Assertions.assertEquals(expected,
52                                  r.applyAsDouble(orig),
53                                  1e-6);
54      }
55  
56      @Test
57      void testNaN() {
58          final double[] values = new double[] {
59              12.345, -9876.5, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY
60          };
61  
62          for (double offset : values) {
63              for (double period : values) {
64                  for (double x : values) {
65                      final boolean expectedNaN = Double.isNaN(x) || Double.isInfinite(x) ||
66                          Double.isNaN(period) || Double.isInfinite(period) ||
67                          Double.isNaN(offset) || Double.isInfinite(offset);
68  
69                      final double v = new Reduce(offset, period).applyAsDouble(x);
70                      if (expectedNaN) {
71                          Assertions.assertTrue(Double.isNaN(v));
72                      } else {
73                          Assertions.assertFalse(Double.isNaN(v));
74                      }
75                  }
76              }
77          }
78      }
79  
80      @Test
81      void testReduceNegativePeriod() {
82          final double period = 12.222;
83          final double offset = 13;
84          final double delta = 1.5;
85          double orig = offset + 122456789 * period + delta;
86          double expected = delta;
87  
88          final Reduce r1 = new Reduce(offset, period);
89          final Reduce r2 = new Reduce(offset, -period);
90          Assertions.assertEquals(expected,
91                                  r1.applyAsDouble(orig),
92                                  1e-7);
93          Assertions.assertEquals(r1.applyAsDouble(orig),
94                                  r2.applyAsDouble(orig),
95                                  0d);
96      }
97  
98      @Test
99      void testReduceComparedWithNormalize() {
100         final double period = 2 * Math.PI;
101         for (double lo = -15; lo <= 15; lo += 1) {
102             final DoubleUnaryOperator n = Angle.Rad.normalizer(lo);
103             final Reduce reduce = new Reduce(lo, period);
104             for (double a = -15; a <= 15; a += 0.5) {
105                 final double nA = n.applyAsDouble(a);
106                 final double r = reduce.applyAsDouble(a) + lo;
107                 Assertions.assertEquals(nA, r, Math.ulp(nA),
108                                         "a=" + a + " lo=" + lo);
109             }
110         }
111     }
112 }