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.MethodSource;
25
26
27
28
29
30 class FDistributionTest extends BaseContinuousDistributionTest {
31 @Override
32 ContinuousDistribution makeDistribution(Object... parameters) {
33 final double df1 = (Double) parameters[0];
34 final double df2 = (Double) parameters[1];
35 return FDistribution.of(df1, df2);
36 }
37
38 @Override
39 Object[][] makeInvalidParameters() {
40 return new Object[][] {
41 {0.0, 1.0},
42 {-0.1, 1.0},
43 {1.0, 0.0},
44 {1.0, -0.1},
45 };
46 }
47
48 @Override
49 String[] getParameterNames() {
50 return new String[] {"NumeratorDegreesOfFreedom", "DenominatorDegreesOfFreedom"};
51 }
52
53 @Override
54 protected double getRelativeTolerance() {
55 return 8e-15;
56 }
57
58
59
60 @ParameterizedTest
61 @MethodSource
62 void testAdditionalMoments(double numeratorDegreesOfFreedom,
63 double denominatorDegreesOfFreedom,
64 double mean,
65 double variance) {
66 final FDistribution dist = FDistribution.of(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom);
67 testMoments(dist, mean, variance, DoubleTolerances.equals());
68 }
69
70 static Stream<Arguments> testAdditionalMoments() {
71 return Stream.of(
72 Arguments.of(1, 2, Double.NaN, Double.NaN),
73 Arguments.of(1, 3, 3.0 / (3 - 2), Double.NaN),
74 Arguments.of(1, 5, 5.0 / (5 - 2), (2 * 5 * 5 * 4) / 9.0)
75 );
76 }
77
78 @Test
79 void testLargeDegreesOfFreedom() {
80 final double x0 = 0.999;
81 final FDistribution fd = FDistribution.of(100000, 100000);
82 final double p = fd.cumulativeProbability(x0);
83 final double x = fd.inverseCumulativeProbability(p);
84 Assertions.assertEquals(x0, x, 1.0e-5);
85 }
86
87 @Test
88 void testSmallDegreesOfFreedom() {
89 final double x0 = 0.975;
90 FDistribution fd = FDistribution.of(1, 1);
91 double p = fd.cumulativeProbability(x0);
92 double x = fd.inverseCumulativeProbability(p);
93 Assertions.assertEquals(x0, x, 1.0e-5);
94
95 fd = FDistribution.of(1, 2);
96 p = fd.cumulativeProbability(x0);
97 x = fd.inverseCumulativeProbability(p);
98 Assertions.assertEquals(x0, x, 1.0e-5);
99 }
100
101 @Test
102 void testMath785() {
103
104 final double prob = 0.01;
105 final FDistribution f = FDistribution.of(200000, 200000);
106 final double result = f.inverseCumulativeProbability(prob);
107 Assertions.assertTrue(result < 1.0, "Failing to calculate inverse cumulative probability");
108 }
109
110 @ParameterizedTest
111 @MethodSource
112 void testAdditionalLogDensity(double numeratorDegreesOfFreedom,
113 double denominatorDegreesOfFreedom,
114 double[] points,
115 double[] values) {
116 testLogDensity(FDistribution.of(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom),
117 points, values, createRelTolerance(1e-15));
118 }
119
120 static Stream<Arguments> testAdditionalLogDensity() {
121
122
123
124 final double[] x = new double[] {1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9};
125 return Stream.of(
126 Arguments.of(100, 100, x,
127 new double[] {
128 -56.96014024624318913110565,
129 -165.8559950938238412964495,
130 -282.3927517845117162132265,
131 -399.7346409939330236149964,
132 -517.157481231596055999464,
133 -634.5884209792423525846316,
134 -752.0201707219881824362492,
135 -869.4520014646850073211334,
136 -986.883840307381342156051}),
137 Arguments.of(952, 912, x,
138 new double[] {
139 -509.5128641158461391223255,
140 -1485.417858108384337659572,
141 -2529.705750311339816652123,
142 -3581.184004620825529681231,
143 -4633.385040722443349533971,
144 -5685.658392700035382988623,
145 -6737.938976642435125691553,
146 -7790.220283785087985050541,
147 -8842.501663247803879775318}),
148
149 Arguments.of(1e-100, 1,
150 new double[] {1e-200, 1e-250, 1e-300},
151 new double[] {
152 229.5653621188446231302736,
153 344.6946167685469072592738,
154 459.8238714182491914891139})
155 );
156 }
157
158 @ParameterizedTest
159 @MethodSource
160 void testAdditionalDensity(double numeratorDegreesOfFreedom,
161 double denominatorDegreesOfFreedom,
162 double[] points,
163 double[] values,
164 double relativeError) {
165 testDensity(FDistribution.of(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom),
166 points, values, createRelTolerance(relativeError));
167 }
168
169 static Stream<Arguments> testAdditionalDensity() {
170
171
172
173 return Stream.of(
174 Arguments.of(100, 100,
175 new double[] {1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 3e6, 4e6, 4.5e6, 5e6, 1e7},
176 new double[] {
177 1.830313161302986740491046e-25,
178 9.325165326363852979476269e-73,
179 2.282370632180103030176872e-123,
180 2.49718772086196154389661e-174,
181 2.51976260334572601372639e-225,
182 2.522031398014840106819471e-276,
183 1.171103964711921105069224e-300,
184 4.97420298008526384736197e-307,
185 1.224464123468993962344698e-309,
186 5.679564178845752345371413e-312,
187 0
188 }, 3e-13),
189 Arguments.of(952, 912,
190 new double[] {10, 11, 12, 13, 14, 15, 16, 17, 18},
191 new double[] {5.264712450643104177155291e-222,
192 1.083049754753448067375765e-237,
193 2.996024821196787172008532e-252,
194 7.919262482129153149257417e-266,
195 1.511696585130734458293958e-278,
196 1.652611434344889324846565e-290,
197 8.522337060963566999523664e-302,
198 1.760000675560273604454495e-312,
199 1.266172656954210816606837e-322
200 }, 2e-13),
201
202 Arguments.of(1e-100, 1,
203 new double[] {1e-200, 1e-250, 1e-300},
204 new double[] {
205 5.000000000000000189458187e+99,
206 4.999999999999999829961813e+149,
207 4.99999999999999997466404e+199
208 }, 5e-14)
209 );
210 }
211 }