1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 import org.junit.jupiter.params.provider.ValueSource;
27
28
29
30
31
32 class TDistributionTest extends BaseContinuousDistributionTest {
33 @Override
34 ContinuousDistribution makeDistribution(Object... parameters) {
35 final double df = (Double) parameters[0];
36 return TDistribution.of(df);
37 }
38
39 @Override
40 Object[][] makeInvalidParameters() {
41 return new Object[][] {
42 {0.0},
43 {-0.1}
44 };
45 }
46
47 @Override
48 String[] getParameterNames() {
49 return new String[] {"DegreesOfFreedom"};
50 }
51
52 @Override
53 protected double getRelativeTolerance() {
54 return 1e-15;
55 }
56
57
58
59 @ParameterizedTest
60 @MethodSource
61 void testAdditionalMoments(double df, double mean, double variance) {
62 final TDistribution dist = TDistribution.of(df);
63 testMoments(dist, mean, variance, DoubleTolerances.equals());
64 }
65
66 static Stream<Arguments> testAdditionalMoments() {
67 return Stream.of(
68 Arguments.of(1.5, 0, Double.POSITIVE_INFINITY),
69 Arguments.of(2.1, 0, 2.1 / (2.1 - 2.0)),
70 Arguments.of(12.1, 0, 12.1 / (12.1 - 2.0))
71 );
72 }
73
74
75
76
77
78 @Test
79 void testCumulativeProbabilityAgainstStackOverflow() {
80 final TDistribution td = TDistribution.of(5.);
81 Assertions.assertDoesNotThrow(() -> {
82 td.cumulativeProbability(.1);
83 td.cumulativeProbability(.01);
84 });
85 }
86
87
88
89
90
91
92
93 @ParameterizedTest
94 @MethodSource
95 void testNistData(double t, double[] x, double[] expected) {
96
97 final DoubleTolerance tolerance = createAbsTolerance(1e-4);
98 testSurvivalProbability(TDistribution.of(t), x, expected, tolerance);
99 }
100
101 static Stream<Arguments> testNistData() {
102 final double[] prob = new double[]{0.10, 0.05, 0.025, 0.01, 0.005, 0.001};
103 return Stream.of(
104 Arguments.of(2, new double[] {1.886, 2.920, 4.303, 6.965, 9.925, 22.327}, prob),
105 Arguments.of(10, new double[]{1.372, 1.812, 2.228, 2.764, 3.169, 4.143}, prob),
106 Arguments.of(30, new double[]{1.310, 1.697, 2.042, 2.457, 2.750, 3.385}, prob),
107 Arguments.of(100, new double[]{1.290, 1.660, 1.984, 2.364, 2.626, 3.174}, prob)
108 );
109 }
110
111
112
113 @ParameterizedTest
114 @CsvSource({
115
116 "1.00E+00, 0.025, 0.31811106676706130125, 0.50795608991202578775",
117 "1.00E+01, 0.025, 0.38897465512398698984, 0.50972659510159001872",
118 "1.00E+02, 0.025, 0.39782060538246560855, 0.50994760809308248284",
119 "1.00E+03, 0.025, 0.39871781392704330749, 0.50997002433945715083",
120 "1.00E+04, 0.025, 0.39880764764142323520, 0.50997226878155033081",
121 "1.00E+05, 0.025, 0.39881663212763956983, 0.50997249325358851024",
122 "1.00E+06, 0.025, 0.39881753058739516371, 0.50997251570107027252",
123 "2.00E+06, 0.025, 0.39881758050188537146, 0.50997251694815404210",
124 "2.98E+06, 0.025, 0.39881759691671903045, 0.50997251735826898411",
125 "2.99E+06, 0.025, 0.39881759702875807516, 0.50997251736106818942",
126 "3.00E+06, 0.025, 0.39881759714005016182, 0.50997251736384874299",
127 "4.00E+06, 0.025, 0.39881760545913280680, 0.50997251757169603792",
128 "1.00E+07, 0.025, 0.39881762043348206737, 0.50997251794582121320",
129 "1.00E+08, 0.025, 0.39881762941809190126, 0.50997251817029631837",
130 "1.00E+09, 0.025, 0.39881763031655281804, 0.50997251819274391771",
131 "1.00E+10, 0.025, 0.39881763040639894857, 0.50997251819498856662",
132 "1.00E+11, 0.025, 0.39881763041538353942, 0.50997251819521305372",
133 "1.00E+12, 0.025, 0.39881763041628198740, 0.50997251819523548022",
134 "1.00E+13, 0.025, 0.39881763041637185996, 0.50997251819523781169",
135 "1.00E+14, 0.025, 0.39881763041638085276, 0.50997251819523803373",
136 "1.00E+15, 0.025, 0.39881763041638174094, 0.50997251819523803373",
137 "1.00E+16, 0.025, 0.39881763041638179645, 0.50997251819523803373",
138 "1.00E+17, 0.025, 0.39881763041638179645, 0.50997251819523803373",
139 "1.00E+18, 0.025, 0.39881763041638179645, 0.50997251819523803373",
140 })
141 void testStatistics25(double df, double x, double pdf, double cdf) {
142 final TDistribution dist = TDistribution.of(df);
143
144 final double density = dist.density(x);
145 Assertions.assertEquals(pdf, density, 4 * Math.ulp(pdf),
146 () -> "pdf error: " + (Double.doubleToLongBits(pdf) - Double.doubleToRawLongBits(density)));
147
148 final double p = dist.cumulativeProbability(x);
149 Assertions.assertEquals(cdf, p, 6 * Math.ulp(cdf),
150 () -> "cdf error: " + (Double.doubleToLongBits(cdf) - Double.doubleToRawLongBits(p)));
151 }
152
153
154
155
156
157
158 @ParameterizedTest
159 @ValueSource(doubles = {1, 42, 1e25})
160 void testInverseSymmetryEdgeCase(double df) {
161 final TDistribution dist = TDistribution.of(df);
162 final double p = 0.5;
163 final double t = 0.0;
164 Assertions.assertEquals(t, dist.inverseCumulativeProbability(p));
165 Assertions.assertEquals(t, dist.inverseSurvivalProbability(p));
166 }
167 }