1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.hipparchus.distribution.discrete;
24
25 import org.hipparchus.UnitTestUtils;
26 import org.hipparchus.distribution.IntegerDistribution;
27 import org.hipparchus.exception.MathIllegalArgumentException;
28 import org.hipparchus.util.Precision;
29 import org.junit.jupiter.api.Test;
30
31 import static org.junit.jupiter.api.Assertions.assertEquals;
32 import static org.junit.jupiter.api.Assertions.assertTrue;
33 import static org.junit.jupiter.api.Assertions.fail;
34
35
36
37
38 public class HypergeometricDistributionTest extends IntegerDistributionAbstractTest {
39
40
41
42
43 public HypergeometricDistributionTest() {
44 setTolerance(1e-12);
45 }
46
47
48
49
50 @Override
51 public IntegerDistribution makeDistribution() {
52 return new HypergeometricDistribution(10, 5, 5);
53 }
54
55
56 @Override
57 public int[] makeDensityTestPoints() {
58 return new int[] {-1, 0, 1, 2, 3, 4, 5, 10};
59 }
60
61
62
63
64
65 @Override
66 public double[] makeDensityTestValues() {
67 return new double[] {0d, 0.00396825396825, 0.0992063492063, 0.396825396825, 0.396825396825,
68 0.0992063492063, 0.00396825396825, 0d};
69 }
70
71
72
73
74
75 @Override
76 public double[] makeLogDensityTestValues() {
77
78 return new double[] {Double.NEGATIVE_INFINITY, -5.52942908751142, -2.31055326264322, -0.924258901523332,
79 -0.924258901523332, -2.31055326264322, -5.52942908751142, Double.NEGATIVE_INFINITY};
80 }
81
82
83 @Override
84 public int[] makeCumulativeTestPoints() {
85 return makeDensityTestPoints();
86 }
87
88
89
90
91
92 @Override
93 public double[] makeCumulativeTestValues() {
94 return new double[] {0d, 0.00396825396825, 0.103174603175, .5, 0.896825396825, 0.996031746032,
95 1, 1};
96 }
97
98
99 @Override
100 public double[] makeInverseCumulativeTestPoints() {
101 return new double[] {0d, 0.001d, 0.010d, 0.025d, 0.050d, 0.100d, 0.999d,
102 0.990d, 0.975d, 0.950d, 0.900d, 1d};
103 }
104
105
106 @Override
107 public int[] makeInverseCumulativeTestValues() {
108 return new int[] {0, 0, 1, 1, 1, 1, 5, 4, 4, 4, 4, 5};
109 }
110
111
112
113
114 @Test
115 void testDegenerateNoFailures() {
116 HypergeometricDistribution dist = new HypergeometricDistribution(5,5,3);
117 setDistribution(dist);
118 setCumulativeTestPoints(new int[] {-1, 0, 1, 3, 10 });
119 setCumulativeTestValues(new double[] {0d, 0d, 0d, 1d, 1d});
120 setDensityTestPoints(new int[] {-1, 0, 1, 3, 10});
121 setDensityTestValues(new double[] {0d, 0d, 0d, 1d, 0d});
122 setInverseCumulativeTestPoints(new double[] {0.1d, 0.5d});
123 setInverseCumulativeTestValues(new int[] {3, 3});
124 verifyDensities();
125 verifyCumulativeProbabilities();
126 verifyInverseCumulativeProbabilities();
127 assertEquals(3, dist.getSupportLowerBound());
128 assertEquals(3, dist.getSupportUpperBound());
129 }
130
131
132 @Test
133 void testDegenerateNoSuccesses() {
134 HypergeometricDistribution dist = new HypergeometricDistribution(5,0,3);
135 setDistribution(dist);
136 setCumulativeTestPoints(new int[] {-1, 0, 1, 3, 10 });
137 setCumulativeTestValues(new double[] {0d, 1d, 1d, 1d, 1d});
138 setDensityTestPoints(new int[] {-1, 0, 1, 3, 10});
139 setDensityTestValues(new double[] {0d, 1d, 0d, 0d, 0d});
140 setInverseCumulativeTestPoints(new double[] {0.1d, 0.5d});
141 setInverseCumulativeTestValues(new int[] {0, 0});
142 verifyDensities();
143 verifyCumulativeProbabilities();
144 verifyInverseCumulativeProbabilities();
145 assertEquals(0, dist.getSupportLowerBound());
146 assertEquals(0, dist.getSupportUpperBound());
147 }
148
149
150 @Test
151 void testDegenerateFullSample() {
152 HypergeometricDistribution dist = new HypergeometricDistribution(5,3,5);
153 setDistribution(dist);
154 setCumulativeTestPoints(new int[] {-1, 0, 1, 3, 10 });
155 setCumulativeTestValues(new double[] {0d, 0d, 0d, 1d, 1d});
156 setDensityTestPoints(new int[] {-1, 0, 1, 3, 10});
157 setDensityTestValues(new double[] {0d, 0d, 0d, 1d, 0d});
158 setInverseCumulativeTestPoints(new double[] {0.1d, 0.5d});
159 setInverseCumulativeTestValues(new int[] {3, 3});
160 verifyDensities();
161 verifyCumulativeProbabilities();
162 verifyInverseCumulativeProbabilities();
163 assertEquals(3, dist.getSupportLowerBound());
164 assertEquals(3, dist.getSupportUpperBound());
165 }
166
167 @Test
168 void testPreconditions() {
169 try {
170 new HypergeometricDistribution(0, 3, 5);
171 fail("negative population size. MathIllegalArgumentException expected");
172 } catch(MathIllegalArgumentException ex) {
173
174 }
175 try {
176 new HypergeometricDistribution(5, -1, 5);
177 fail("negative number of successes. MathIllegalArgumentException expected");
178 } catch(MathIllegalArgumentException ex) {
179
180 }
181 try {
182 new HypergeometricDistribution(5, 3, -1);
183 fail("negative sample size. MathIllegalArgumentException expected");
184 } catch(MathIllegalArgumentException ex) {
185
186 }
187 try {
188 new HypergeometricDistribution(5, 6, 5);
189 fail("numberOfSuccesses > populationSize. MathIllegalArgumentException expected");
190 } catch(MathIllegalArgumentException ex) {
191
192 }
193 try {
194 new HypergeometricDistribution(5, 3, 6);
195 fail("sampleSize > populationSize. MathIllegalArgumentException expected");
196 } catch(MathIllegalArgumentException ex) {
197
198 }
199 }
200
201 @Test
202 void testAccessors() {
203 HypergeometricDistribution dist = new HypergeometricDistribution(5, 3, 4);
204 assertEquals(5, dist.getPopulationSize());
205 assertEquals(3, dist.getNumberOfSuccesses());
206 assertEquals(4, dist.getSampleSize());
207 }
208
209 @Test
210 void testLargeValues() {
211 int populationSize = 3456;
212 int sampleSize = 789;
213 int numberOfSucceses = 101;
214 double[][] data = {
215 {0.0, 2.75646034603961e-12, 2.75646034603961e-12, 1.0},
216 {1.0, 8.55705370142386e-11, 8.83269973602783e-11, 0.999999999997244},
217 {2.0, 1.31288129219665e-9, 1.40120828955693e-9, 0.999999999911673},
218 {3.0, 1.32724172984193e-8, 1.46736255879763e-8, 0.999999998598792},
219 {4.0, 9.94501711734089e-8, 1.14123796761385e-7, 0.999999985326375},
220 {5.0, 5.89080768883643e-7, 7.03204565645028e-7, 0.999999885876203},
221 {20.0, 0.0760051397707708, 0.27349758476299, 0.802507555007781},
222 {21.0, 0.087144222047629, 0.360641806810619, 0.72650241523701},
223 {22.0, 0.0940378846881819, 0.454679691498801, 0.639358193189381},
224 {23.0, 0.0956897500614809, 0.550369441560282, 0.545320308501199},
225 {24.0, 0.0919766921922999, 0.642346133752582, 0.449630558439718},
226 {25.0, 0.083641637261095, 0.725987771013677, 0.357653866247418},
227 {96.0, 5.93849188852098e-57, 1.0, 6.01900244560712e-57},
228 {97.0, 7.96593036832547e-59, 1.0, 8.05105570861321e-59},
229 {98.0, 8.44582921934367e-61, 1.0, 8.5125340287733e-61},
230 {99.0, 6.63604297068222e-63, 1.0, 6.670480942963e-63},
231 {100.0, 3.43501099007557e-65, 1.0, 3.4437972280786e-65},
232 {101.0, 8.78623800302957e-68, 1.0, 8.78623800302957e-68},
233 };
234
235 testHypergeometricDistributionProbabilities(populationSize, sampleSize, numberOfSucceses, data);
236 }
237
238 private void testHypergeometricDistributionProbabilities(int populationSize, int sampleSize, int numberOfSucceses, double[][] data) {
239 HypergeometricDistribution dist = new HypergeometricDistribution(populationSize, numberOfSucceses, sampleSize);
240 for (int i = 0; i < data.length; ++i) {
241 int x = (int)data[i][0];
242 double pmf = data[i][1];
243 double actualPmf = dist.probability(x);
244 UnitTestUtils.customAssertRelativelyEquals("Expected equals for <"+x+"> pmf", pmf, actualPmf, 1.0e-9);
245
246 double cdf = data[i][2];
247 double actualCdf = dist.cumulativeProbability(x);
248 UnitTestUtils.customAssertRelativelyEquals("Expected equals for <"+x+"> cdf", cdf, actualCdf, 1.0e-9);
249
250 double cdf1 = data[i][3];
251 double actualCdf1 = dist.upperCumulativeProbability(x);
252 UnitTestUtils.customAssertRelativelyEquals("Expected equals for <"+x+"> cdf1", cdf1, actualCdf1, 1.0e-9);
253 }
254 }
255
256 @Test
257 void testMoreLargeValues() {
258 int populationSize = 26896;
259 int sampleSize = 895;
260 int numberOfSucceses = 55;
261 double[][] data = {
262 {0.0, 0.155168304750504, 0.155168304750504, 1.0},
263 {1.0, 0.29437545000746, 0.449543754757964, 0.844831695249496},
264 {2.0, 0.273841321577003, 0.723385076334967, 0.550456245242036},
265 {3.0, 0.166488572570786, 0.889873648905753, 0.276614923665033},
266 {4.0, 0.0743969744713231, 0.964270623377076, 0.110126351094247},
267 {5.0, 0.0260542785784855, 0.990324901955562, 0.0357293766229237},
268 {20.0, 3.57101101678792e-16, 1.0, 3.78252101622096e-16},
269 {21.0, 2.00551638598312e-17, 1.0, 2.11509999433041e-17},
270 {22.0, 1.04317070180562e-18, 1.0, 1.09583608347287e-18},
271 {23.0, 5.03153504903308e-20, 1.0, 5.266538166725e-20},
272 {24.0, 2.2525984149695e-21, 1.0, 2.35003117691919e-21},
273 {25.0, 9.3677424515947e-23, 1.0, 9.74327619496943e-23},
274 {50.0, 9.83633962945521e-69, 1.0, 9.8677629437617e-69},
275 {51.0, 3.13448949497553e-71, 1.0, 3.14233143064882e-71},
276 {52.0, 7.82755221928122e-74, 1.0, 7.84193567329055e-74},
277 {53.0, 1.43662126065532e-76, 1.0, 1.43834540093295e-76},
278 {54.0, 1.72312692517348e-79, 1.0, 1.7241402776278e-79},
279 {55.0, 1.01335245432581e-82, 1.0, 1.01335245432581e-82},
280 };
281 testHypergeometricDistributionProbabilities(populationSize, sampleSize, numberOfSucceses, data);
282 }
283
284 @Test
285 void testMoments() {
286 final double tol = 1e-9;
287 HypergeometricDistribution dist;
288
289 dist = new HypergeometricDistribution(1500, 40, 100);
290 assertEquals(dist.getNumericalMean(), 40d * 100d / 1500d, tol);
291 assertEquals(dist.getNumericalVariance(), ( 100d * 40d * (1500d - 100d) * (1500d - 40d) ) / ( (1500d * 1500d * 1499d) ), tol);
292
293 dist = new HypergeometricDistribution(3000, 55, 200);
294 assertEquals(dist.getNumericalMean(), 55d * 200d / 3000d, tol);
295 assertEquals(dist.getNumericalVariance(), ( 200d * 55d * (3000d - 200d) * (3000d - 55d) ) / ( (3000d * 3000d * 2999d) ), tol);
296 }
297
298 @Test
299 void testMath644() {
300 int N = 14761461;
301 int m = 1035;
302 int n = 1841;
303
304 int k = 0;
305 final HypergeometricDistribution dist = new HypergeometricDistribution(N, m, n);
306
307 assertEquals(0, Precision.compareTo(1.0, dist.upperCumulativeProbability(k), 1));
308 assertTrue(Precision.compareTo(dist.cumulativeProbability(k), 0.0, 1) > 0);
309
310
311 double upper = 1.0 - dist.cumulativeProbability(k) + dist.probability(k);
312 assertEquals(0, Precision.compareTo(1.0, upper, 1));
313 }
314
315 @Test
316 void testMath1356() {
317 HypergeometricDistribution dist = new HypergeometricDistribution(11, 11, 1);
318 assertEquals(1.0, dist.probability(1), 1e-6);
319 assertEquals(0.0, dist.probability(0), 1e-6);
320
321 dist = new HypergeometricDistribution(11, 11, 11);
322 assertEquals(0.0, dist.probability(0), 1e-6);
323 assertEquals(0.0, dist.probability(1), 1e-6);
324 assertEquals(0.0, dist.probability(10), 1e-6);
325 assertEquals(1.0, dist.probability(11), 1e-6);
326 }
327 }