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.statistics.distribution;
18  
19  import java.util.stream.Stream;
20  import org.junit.jupiter.api.Assertions;
21  import org.junit.jupiter.api.Test;
22  import org.junit.jupiter.params.ParameterizedTest;
23  import org.junit.jupiter.params.provider.Arguments;
24  import org.junit.jupiter.params.provider.CsvSource;
25  import org.junit.jupiter.params.provider.MethodSource;
26  
27  /**
28   * Test cases for {@link TDistribution}.
29   * Extends {@link BaseContinuousDistributionTest}. See javadoc of that class for details.
30   */
31  class TDistributionTest extends BaseContinuousDistributionTest {
32      @Override
33      ContinuousDistribution makeDistribution(Object... parameters) {
34          final double df = (Double) parameters[0];
35          return TDistribution.of(df);
36      }
37  
38      @Override
39      Object[][] makeInvalidParameters() {
40          return new Object[][] {
41              {0.0},
42              {-0.1}
43          };
44      }
45  
46      @Override
47      String[] getParameterNames() {
48          return new String[] {"DegreesOfFreedom"};
49      }
50  
51      @Override
52      protected double getRelativeTolerance() {
53          return 1e-15;
54      }
55  
56      //-------------------- Additional test cases -------------------------------
57  
58      @ParameterizedTest
59      @MethodSource
60      void testAdditionalMoments(double df, double mean, double variance) {
61          final TDistribution dist = TDistribution.of(df);
62          testMoments(dist, mean, variance, DoubleTolerances.equals());
63      }
64  
65      static Stream<Arguments> testAdditionalMoments() {
66          return Stream.of(
67              Arguments.of(1.5, 0, Double.POSITIVE_INFINITY),
68              Arguments.of(2.1, 0, 2.1 / (2.1 - 2.0)),
69              Arguments.of(12.1, 0, 12.1 / (12.1 - 2.0))
70          );
71      }
72  
73      /**
74       * @see <a href="https://issues.apache.orgg/bugzilla/show_bug.cgi?id=27243">
75       *      Bug report that prompted this unit test.</a>
76       */
77      @Test
78      void testCumulativeProbabilityAgainstStackOverflow() {
79          final TDistribution td = TDistribution.of(5.);
80          Assertions.assertDoesNotThrow(() -> {
81              td.cumulativeProbability(.1);
82              td.cumulativeProbability(.01);
83          });
84      }
85  
86      /*
87       * Adding this test to benchmark against tables published by NIST
88       * http://itl.nist.gov/div898/handbook/eda/section3/eda3672.htm
89       * Have chosen tabulated results for degrees of freedom 2,10,30,100
90       * Have chosen problevels from 0.10 to 0.001
91       */
92      @ParameterizedTest
93      @MethodSource
94      void testNistData(double t, double[] x, double[] expected) {
95          // Data points are not very exact so use a low tolerance.
96          final DoubleTolerance tolerance = createAbsTolerance(1e-4);
97          testSurvivalProbability(TDistribution.of(t), x, expected, tolerance);
98      }
99  
100     static Stream<Arguments> testNistData() {
101         final double[] prob = new double[]{0.10, 0.05, 0.025, 0.01, 0.005, 0.001};
102         return Stream.of(
103             Arguments.of(2, new double[] {1.886, 2.920, 4.303, 6.965, 9.925, 22.327}, prob),
104             Arguments.of(10, new double[]{1.372, 1.812, 2.228, 2.764, 3.169, 4.143}, prob),
105             Arguments.of(30, new double[]{1.310, 1.697, 2.042, 2.457, 2.750, 3.385}, prob),
106             Arguments.of(100, new double[]{1.290, 1.660, 1.984, 2.364, 2.626, 3.174}, prob)
107         );
108     }
109 
110 
111     // See https://issues.apache.org/jira/browse/STATISTICS-25
112     @ParameterizedTest
113     @CsvSource({
114         // Data from r stats TDist
115         "1.00E+00, 0.025, 0.31811106676706130125, 0.50795608991202578775",
116         "1.00E+01, 0.025, 0.38897465512398698984, 0.50972659510159001872",
117         "1.00E+02, 0.025, 0.39782060538246560855, 0.50994760809308248284",
118         "1.00E+03, 0.025, 0.39871781392704330749, 0.50997002433945715083",
119         "1.00E+04, 0.025, 0.39880764764142323520, 0.50997226878155033081",
120         "1.00E+05, 0.025, 0.39881663212763956983, 0.50997249325358851024",
121         "1.00E+06, 0.025, 0.39881753058739516371, 0.50997251570107027252",
122         "2.00E+06, 0.025, 0.39881758050188537146, 0.50997251694815404210",
123         "2.98E+06, 0.025, 0.39881759691671903045, 0.50997251735826898411",
124         "2.99E+06, 0.025, 0.39881759702875807516, 0.50997251736106818942",
125         "3.00E+06, 0.025, 0.39881759714005016182, 0.50997251736384874299",
126         "4.00E+06, 0.025, 0.39881760545913280680, 0.50997251757169603792",
127         "1.00E+07, 0.025, 0.39881762043348206737, 0.50997251794582121320",
128         "1.00E+08, 0.025, 0.39881762941809190126, 0.50997251817029631837",
129         "1.00E+09, 0.025, 0.39881763031655281804, 0.50997251819274391771",
130         "1.00E+10, 0.025, 0.39881763040639894857, 0.50997251819498856662",
131         "1.00E+11, 0.025, 0.39881763041538353942, 0.50997251819521305372",
132         "1.00E+12, 0.025, 0.39881763041628198740, 0.50997251819523548022",
133         "1.00E+13, 0.025, 0.39881763041637185996, 0.50997251819523781169",
134         "1.00E+14, 0.025, 0.39881763041638085276, 0.50997251819523803373",
135         "1.00E+15, 0.025, 0.39881763041638174094, 0.50997251819523803373",
136         "1.00E+16, 0.025, 0.39881763041638179645, 0.50997251819523803373",
137         "1.00E+17, 0.025, 0.39881763041638179645, 0.50997251819523803373",
138         "1.00E+18, 0.025, 0.39881763041638179645, 0.50997251819523803373",
139     })
140     void testStatistics25(double df, double x, double pdf, double cdf) {
141         final TDistribution dist = TDistribution.of(df);
142 
143         final double density = dist.density(x);
144         Assertions.assertEquals(pdf, density, 4 * Math.ulp(pdf),
145             () -> "pdf error: " + (Double.doubleToLongBits(pdf) - Double.doubleToRawLongBits(density)));
146 
147         final double p = dist.cumulativeProbability(x);
148         Assertions.assertEquals(cdf, p, 6 * Math.ulp(cdf),
149             () -> "cdf error: " + (Double.doubleToLongBits(cdf) - Double.doubleToRawLongBits(p)));
150     }
151 }