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    *      https://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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.analysis.function;
23  
24  import org.hipparchus.analysis.UnivariateFunction;
25  import org.hipparchus.analysis.differentiation.DSFactory;
26  import org.hipparchus.analysis.differentiation.DerivativeStructure;
27  import org.hipparchus.dfp.Dfp;
28  import org.hipparchus.dfp.DfpField;
29  import org.hipparchus.dfp.DfpMath;
30  import org.hipparchus.util.FastMath;
31  import org.junit.Assert;
32  import org.junit.Test;
33  
34  public class SincTest {
35  
36     @Test
37     public void testShortcut() {
38         final Sinc s = new Sinc();
39         final UnivariateFunction f = new UnivariateFunction() {
40             @Override
41             public double value(double x) {
42                 Dfp dfpX = new DfpField(25).newDfp(x);
43                 return DfpMath.sin(dfpX).divide(dfpX).toDouble();
44             }
45         };
46  
47         for (double x = 1e-30; x < 1e10; x *= 2) {
48             final double fX = f.value(x);
49             final double sX = s.value(x);
50             Assert.assertEquals("x=" + x, fX, sX, 2.0e-16);
51         }
52     }
53  
54     @Test
55     public void testCrossings() {
56         final Sinc s = new Sinc(true);
57         final int numCrossings = 1000;
58         final double tol = 2e-16;
59         for (int i = 1; i <= numCrossings; i++) {
60             Assert.assertEquals("i=" + i, 0, s.value(i), tol);
61         }
62     }
63  
64     @Test
65     public void testZero() {
66         final Sinc s = new Sinc();
67         Assert.assertEquals(1d, s.value(0), 0);
68     }
69  
70     @Test
71     public void testEuler() {
72         final Sinc s = new Sinc();
73         final double x = 123456.789;
74         double prod = 1;
75         double xOverPow2 = x / 2;
76         while (xOverPow2 > 0) {
77             prod *= FastMath.cos(xOverPow2);
78             xOverPow2 /= 2;
79         }
80         Assert.assertEquals(prod, s.value(x), 1e-13);
81     }
82  
83     @Test
84     public void testDerivativeZero() {
85         final DerivativeStructure s0 = new Sinc(true).value(new DSFactory(1, 1).variable(0, 0.0));
86         Assert.assertEquals(0, s0.getPartialDerivative(1), 0);
87     }
88  
89     @Test
90     public void testDerivatives1Dot2Unnormalized() {
91         DerivativeStructure s = new Sinc(false).value(new DSFactory(1, 5).variable(0, 1.2));
92         Assert.assertEquals( 0.77669923830602195806, s.getPartialDerivative(0), 1.0e-16);
93         Assert.assertEquals(-0.34528456985779031701, s.getPartialDerivative(1), 1.0e-16);
94         Assert.assertEquals(-0.2012249552097047631,  s.getPartialDerivative(2), 1.0e-16);
95         Assert.assertEquals( 0.2010975926270339262,  s.getPartialDerivative(3), 4.0e-16);
96         Assert.assertEquals( 0.106373929549242204,   s.getPartialDerivative(4), 1.0e-15);
97         Assert.assertEquals(-0.1412599110579478695,  s.getPartialDerivative(5), 3.0e-15);
98     }
99  
100    @Test
101    public void testDerivatives1Dot2Normalized() {
102        DerivativeStructure s = new Sinc(true).value(new DSFactory(1, 5).variable(0, 1.2));
103        Assert.assertEquals(-0.15591488063143983888, s.getPartialDerivative(0), 6.0e-17);
104        Assert.assertEquals(-0.54425176145292298767, s.getPartialDerivative(1), 2.0e-16);
105        Assert.assertEquals(2.4459044611635856107,   s.getPartialDerivative(2), 9.0e-16);
106        Assert.assertEquals(0.5391369206235909586,   s.getPartialDerivative(3), 7.0e-16);
107        Assert.assertEquals(-16.984649869728849865,  s.getPartialDerivative(4), 8.0e-15);
108        Assert.assertEquals(5.0980327462666316586,   s.getPartialDerivative(5), 9.0e-15);
109    }
110 
111    @Test
112    public void testDerivativeShortcut() {
113        final Sinc sinc = new Sinc();
114        final UnivariateFunction f = new UnivariateFunction() {
115                @Override
116             public double value(double x) {
117                    Dfp dfpX = new DfpField(25).newDfp(x);
118                    return DfpMath.cos(dfpX).subtract(DfpMath.sin(dfpX).divide(dfpX)).divide(dfpX).toDouble();
119                }
120            };
121 
122        DSFactory factory = new DSFactory(1, 1);
123        for (double x = 1e-30; x < 1e10; x *= 2) {
124            final double fX = f.value(x);
125            final DerivativeStructure sX = sinc.value(factory.variable(0, x));
126            Assert.assertEquals("x=" + x, fX, sX.getPartialDerivative(1), 3.0e-13);
127        }
128    }
129 }