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  
23  package org.hipparchus.analysis.function;
24  
25  import org.hipparchus.analysis.UnivariateFunction;
26  import org.hipparchus.analysis.differentiation.DSFactory;
27  import org.hipparchus.analysis.differentiation.DerivativeStructure;
28  import org.hipparchus.analysis.differentiation.UnivariateDifferentiableFunction;
29  import org.hipparchus.exception.MathIllegalArgumentException;
30  import org.hipparchus.exception.NullArgumentException;
31  import org.hipparchus.util.FastMath;
32  import org.junit.jupiter.api.Test;
33  
34  import static org.junit.jupiter.api.Assertions.assertEquals;
35  import static org.junit.jupiter.api.Assertions.assertThrows;
36  import static org.junit.jupiter.api.Assertions.assertTrue;
37  
38  /**
39   * Test for class {@link Gaussian}.
40   */
41  class GaussianTest {
42      private final double EPS = Math.ulp(1d);
43  
44      @Test
45      void testPreconditions() {
46          assertThrows(MathIllegalArgumentException.class, () -> {
47              new Gaussian(1, 2, -1);
48          });
49      }
50  
51      @Test
52      void testSomeValues() {
53          final UnivariateFunction f = new Gaussian();
54  
55          assertEquals(1 / FastMath.sqrt(2 * Math.PI), f.value(0), EPS);
56      }
57  
58      @Test
59      void testLargeArguments() {
60          final UnivariateFunction f = new Gaussian();
61  
62          assertEquals(0, f.value(Double.NEGATIVE_INFINITY), 0);
63          assertEquals(0, f.value(-Double.MAX_VALUE), 0);
64          assertEquals(0, f.value(-1e2), 0);
65          assertEquals(0, f.value(1e2), 0);
66          assertEquals(0, f.value(Double.MAX_VALUE), 0);
67          assertEquals(0, f.value(Double.POSITIVE_INFINITY), 0);
68      }
69  
70      @Test
71      void testDerivatives() {
72          final UnivariateDifferentiableFunction gaussian = new Gaussian(2.0, 0.9, 3.0);
73          final DerivativeStructure dsX = new DSFactory(1, 4).variable(0, 1.1);
74          final DerivativeStructure dsY = gaussian.value(dsX);
75          assertEquals( 1.9955604901712128349,   dsY.getValue(),              EPS);
76          assertEquals(-0.044345788670471396332, dsY.getPartialDerivative(1), EPS);
77          assertEquals(-0.22074348138190206174,  dsY.getPartialDerivative(2), EPS);
78          assertEquals( 0.014760030401924800557, dsY.getPartialDerivative(3), EPS);
79          assertEquals( 0.073253159785035691678, dsY.getPartialDerivative(4), EPS);
80      }
81  
82      @Test
83      void testDerivativeLargeArguments() {
84          final Gaussian f = new Gaussian(0, 1e-50);
85  
86          DSFactory factory = new DSFactory(1, 1);
87          assertEquals(0, f.value(factory.variable(0, Double.NEGATIVE_INFINITY)).getPartialDerivative(1), 0);
88          assertEquals(0, f.value(factory.variable(0, -Double.MAX_VALUE)).getPartialDerivative(1), 0);
89          assertEquals(0, f.value(factory.variable(0, -1e50)).getPartialDerivative(1), 0);
90          assertEquals(0, f.value(factory.variable(0, -1e2)).getPartialDerivative(1), 0);
91          assertEquals(0, f.value(factory.variable(0, 1e2)).getPartialDerivative(1), 0);
92          assertEquals(0, f.value(factory.variable(0, 1e50)).getPartialDerivative(1), 0);
93          assertEquals(0, f.value(factory.variable(0, Double.MAX_VALUE)).getPartialDerivative(1), 0);
94          assertEquals(0, f.value(factory.variable(0, Double.POSITIVE_INFINITY)).getPartialDerivative(1), 0);
95      }
96  
97      @Test
98      void testDerivativesNaN() {
99          final Gaussian f = new Gaussian(0, 1e-50);
100         final DerivativeStructure fx = f.value(new DSFactory(1, 5).variable(0, Double.NaN));
101         for (int i = 0; i <= fx.getOrder(); ++i) {
102             assertTrue(Double.isNaN(fx.getPartialDerivative(i)));
103         }
104     }
105 
106     @Test
107     void testParametricUsage1() {
108         assertThrows(NullArgumentException.class, () -> {
109             final Gaussian.Parametric g = new Gaussian.Parametric();
110             g.value(0, null);
111         });
112     }
113 
114     @Test
115     void testParametricUsage2() {
116         assertThrows(MathIllegalArgumentException.class, () -> {
117             final Gaussian.Parametric g = new Gaussian.Parametric();
118             g.value(0, new double[]{0});
119         });
120     }
121 
122     @Test
123     void testParametricUsage3() {
124         assertThrows(MathIllegalArgumentException.class, () -> {
125             final Gaussian.Parametric g = new Gaussian.Parametric();
126             g.value(0, new double[]{0, 1, 0});
127         });
128     }
129 
130     @Test
131     void testParametricUsage4() {
132         assertThrows(NullArgumentException.class, () -> {
133             final Gaussian.Parametric g = new Gaussian.Parametric();
134             g.gradient(0, null);
135         });
136     }
137 
138     @Test
139     void testParametricUsage5() {
140         assertThrows(MathIllegalArgumentException.class, () -> {
141             final Gaussian.Parametric g = new Gaussian.Parametric();
142             g.gradient(0, new double[]{0});
143         });
144     }
145 
146     @Test
147     void testParametricUsage6() {
148         assertThrows(MathIllegalArgumentException.class, () -> {
149             final Gaussian.Parametric g = new Gaussian.Parametric();
150             g.gradient(0, new double[]{0, 1, 0});
151         });
152     }
153 
154     @Test
155     void testParametricValue() {
156         final double norm = 2;
157         final double mean = 3;
158         final double sigma = 4;
159         final Gaussian f = new Gaussian(norm, mean, sigma);
160 
161         final Gaussian.Parametric g = new Gaussian.Parametric();
162         assertEquals(f.value(-1), g.value(-1, new double[] {norm, mean, sigma}), 0);
163         assertEquals(f.value(0), g.value(0, new double[] {norm, mean, sigma}), 0);
164         assertEquals(f.value(2), g.value(2, new double[] {norm, mean, sigma}), 0);
165     }
166 
167     @Test
168     void testParametricGradient() {
169         final double norm = 2;
170         final double mean = 3;
171         final double sigma = 4;
172         final Gaussian.Parametric f = new Gaussian.Parametric();
173 
174         final double x = 1;
175         final double[] grad = f.gradient(1, new double[] {norm, mean, sigma});
176         final double diff = x - mean;
177         final double n = FastMath.exp(-diff * diff / (2 * sigma * sigma));
178         assertEquals(n, grad[0], EPS);
179         final double m = norm * n * diff / (sigma * sigma);
180         assertEquals(m, grad[1], EPS);
181         final double s = m * diff / sigma;
182         assertEquals(s, grad[2], EPS);
183     }
184 }