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.random;
23  
24  import org.hipparchus.UnitTestUtils;
25  import org.hipparchus.exception.LocalizedCoreFormats;
26  import org.hipparchus.exception.MathIllegalArgumentException;
27  import org.junit.jupiter.api.Test;
28  
29  import static org.junit.jupiter.api.Assertions.assertEquals;
30  import static org.junit.jupiter.api.Assertions.fail;
31  
32  /**
33   * The class <code>StableRandomGeneratorTest</code> contains tests for the class
34   * {@link StableRandomGenerator}
35   *
36   */
37  class StableRandomGeneratorTest {
38  
39      private RandomGenerator rg = new Well19937c(100);
40      private final static int sampleSize = 10000;
41  
42      /**
43       * Run the double nextDouble() method test Due to leptokurtic property the
44       * acceptance range is widened.
45       *
46       * TODO: verify that tolerance this wide is really OK
47       */
48      @Test
49      void testNextDouble() {
50          StableRandomGenerator generator = new StableRandomGenerator(rg, 1.3,
51                  0.1);
52          double[] sample = new double[2 * sampleSize];
53          for (int i = 0; i < sample.length; ++i) {
54              sample[i] = generator.nextNormalizedDouble();
55          }
56          assertEquals(0.0, UnitTestUtils.mean(sample), 0.3);
57      }
58  
59      /**
60       * If alpha = 2, than it must be Gaussian distribution
61       */
62      @Test
63      void testGaussianCase() {
64          StableRandomGenerator generator = new StableRandomGenerator(rg, 2d, 0.0);
65  
66          double[] sample = new double[sampleSize];
67          for (int i = 0; i < sample.length; ++i) {
68              sample[i] = generator.nextNormalizedDouble();
69          }
70          assertEquals(0.0, UnitTestUtils.mean(sample), 0.02);
71          assertEquals(1.0, UnitTestUtils.variance(sample), 0.02);
72      }
73  
74      /**
75       * If alpha = 1, than it must be Cauchy distribution
76       */
77      @Test
78      void testCauchyCase() {
79          StableRandomGenerator generator = new StableRandomGenerator(rg, 1d, 0.0);
80  
81          final double[] values = new double[sampleSize];
82          for (int i = 0; i < sampleSize; ++i) {
83              values[i] = generator.nextNormalizedDouble();
84          }
85  
86          // Standard Cauchy distribution should have zero median and mode
87          double median = UnitTestUtils.median(values);
88          assertEquals(0.0, median, 0.2);
89      }
90  
91      /**
92       * Input parameter range tests
93       */
94      @Test
95      void testAlphaRangeBelowZero() {
96          try {
97              new StableRandomGenerator(rg, -1.0, 0.0);
98              fail("Expected MathIllegalArgumentException");
99          } catch (MathIllegalArgumentException e) {
100             assertEquals(LocalizedCoreFormats.OUT_OF_RANGE_LEFT, e.getSpecifier());
101             assertEquals(-1.0, ((Double) e.getParts()[0]).doubleValue(), 1.0e-10);
102         }
103     }
104 
105     @Test
106     void testAlphaRangeAboveTwo() {
107         try {
108             new StableRandomGenerator(rg, 3.0, 0.0);
109             fail("Expected MathIllegalArgumentException");
110         } catch (MathIllegalArgumentException e) {
111             assertEquals(LocalizedCoreFormats.OUT_OF_RANGE_LEFT, e.getSpecifier());
112             assertEquals(3.0, ((Double) e.getParts()[0]).doubleValue(), 1.0e-10);
113         }
114     }
115 
116     @Test
117     void testBetaRangeBelowMinusOne() {
118         try {
119             new StableRandomGenerator(rg, 1.0, -2.0);
120             fail("Expected MathIllegalArgumentException");
121         } catch (MathIllegalArgumentException e) {
122             assertEquals(LocalizedCoreFormats.OUT_OF_RANGE_SIMPLE, e.getSpecifier());
123             assertEquals(-2.0, ((Double) e.getParts()[0]).doubleValue(), 1.0e-10);
124         }
125     }
126 
127     @Test
128     void testBetaRangeAboveOne() {
129         try {
130             new StableRandomGenerator(rg, 1.0, 2.0);
131             fail("Expected MathIllegalArgumentException");
132         } catch (MathIllegalArgumentException e) {
133             assertEquals(LocalizedCoreFormats.OUT_OF_RANGE_SIMPLE, e.getSpecifier());
134             assertEquals(2.0, ((Double) e.getParts()[0]).doubleValue(), 1.0e-10);
135         }
136     }
137 }