1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.distribution.continuous;
23
24 import org.hipparchus.UnitTestUtils;
25 import org.hipparchus.analysis.UnivariateFunction;
26 import org.hipparchus.analysis.integration.BaseAbstractUnivariateIntegrator;
27 import org.hipparchus.analysis.integration.IterativeLegendreGaussIntegrator;
28 import org.hipparchus.distribution.RealDistribution;
29 import org.hipparchus.exception.MathIllegalArgumentException;
30 import org.hipparchus.util.FastMath;
31 import org.junit.jupiter.api.AfterEach;
32 import org.junit.jupiter.api.BeforeEach;
33 import org.junit.jupiter.api.Test;
34
35 import java.util.ArrayList;
36 import java.util.Collections;
37
38 import static org.junit.jupiter.api.Assertions.assertEquals;
39 import static org.junit.jupiter.api.Assertions.fail;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public abstract class RealDistributionAbstractTest {
74
75
76
77 private RealDistribution distribution;
78
79
80 private double tolerance = 1E-4;
81
82
83 private double[] cumulativeTestPoints;
84
85
86 private double[] cumulativeTestValues;
87
88
89 private double[] inverseCumulativeTestPoints;
90
91
92 private double[] inverseCumulativeTestValues;
93
94
95 private double[] densityTestValues;
96
97
98 private double[] logDensityTestValues;
99
100
101
102
103 public abstract RealDistribution makeDistribution();
104
105
106 public abstract double[] makeCumulativeTestPoints();
107
108
109 public abstract double[] makeCumulativeTestValues();
110
111
112 public abstract double[] makeDensityTestValues();
113
114
115
116
117 public double[] makeLogDensityTestValues() {
118 final double[] densityTestValues = makeDensityTestValues();
119 final double[] logDensityTestValues = new double[densityTestValues.length];
120 for (int i = 0; i < densityTestValues.length; i++) {
121 logDensityTestValues[i] = FastMath.log(densityTestValues[i]);
122 }
123 return logDensityTestValues;
124 }
125
126
127
128
129 public double[] makeInverseCumulativeTestPoints() {
130 return makeCumulativeTestValues();
131 }
132
133
134 public double[] makeInverseCumulativeTestValues() {
135 return makeCumulativeTestPoints();
136 }
137
138
139
140
141
142
143 @BeforeEach
144 public void setUp() {
145 distribution = makeDistribution();
146 cumulativeTestPoints = makeCumulativeTestPoints();
147 cumulativeTestValues = makeCumulativeTestValues();
148 inverseCumulativeTestPoints = makeInverseCumulativeTestPoints();
149 inverseCumulativeTestValues = makeInverseCumulativeTestValues();
150 densityTestValues = makeDensityTestValues();
151 logDensityTestValues = makeLogDensityTestValues();
152 }
153
154
155
156
157 @AfterEach
158 public void tearDown() {
159 distribution = null;
160 cumulativeTestPoints = null;
161 cumulativeTestValues = null;
162 inverseCumulativeTestPoints = null;
163 inverseCumulativeTestValues = null;
164 densityTestValues = null;
165 logDensityTestValues = null;
166 }
167
168
169
170
171
172
173
174 protected void verifyCumulativeProbabilities() {
175
176 for (int i = 0; i < cumulativeTestPoints.length; i++) {
177 UnitTestUtils.customAssertEquals("Incorrect cumulative probability value returned for "
178 + cumulativeTestPoints[i], cumulativeTestValues[i],
179 distribution.cumulativeProbability(cumulativeTestPoints[i]),
180 getTolerance());
181 }
182
183 for (int i = 0; i < cumulativeTestPoints.length; i++) {
184 for (int j = 0; j < cumulativeTestPoints.length; j++) {
185 if (cumulativeTestPoints[i] <= cumulativeTestPoints[j]) {
186 UnitTestUtils.customAssertEquals(cumulativeTestValues[j] - cumulativeTestValues[i],
187 distribution.probability(cumulativeTestPoints[i], cumulativeTestPoints[j]),
188 getTolerance());
189 } else {
190 try {
191 distribution.probability(cumulativeTestPoints[i], cumulativeTestPoints[j]);
192 } catch (MathIllegalArgumentException e) {
193 continue;
194 }
195 fail("distribution.probability(double, double) should have thrown an exception that second argument is too large");
196 }
197 }
198 }
199 }
200
201
202
203
204
205 protected void verifyInverseCumulativeProbabilities() {
206 for (int i = 0; i < inverseCumulativeTestPoints.length; i++) {
207 UnitTestUtils.customAssertEquals("Incorrect inverse cumulative probability value returned for "
208 + inverseCumulativeTestPoints[i], inverseCumulativeTestValues[i],
209 distribution.inverseCumulativeProbability(inverseCumulativeTestPoints[i]),
210 getTolerance());
211 }
212 }
213
214
215
216
217 protected void verifyDensities() {
218 for (int i = 0; i < cumulativeTestPoints.length; i++) {
219 UnitTestUtils.customAssertEquals("Incorrect probability density value returned for "
220 + cumulativeTestPoints[i], densityTestValues[i],
221 distribution.density(cumulativeTestPoints[i]),
222 getTolerance());
223 }
224 }
225
226
227
228
229 protected void verifyLogDensities() {
230 for (int i = 0; i < cumulativeTestPoints.length; i++) {
231 UnitTestUtils.customAssertEquals("Incorrect probability density value returned for "
232 + cumulativeTestPoints[i], logDensityTestValues[i],
233 distribution.logDensity(cumulativeTestPoints[i]),
234 getTolerance());
235 }
236 }
237
238
239
240
241
242
243
244 @Test
245 public void testCumulativeProbabilities() {
246 verifyCumulativeProbabilities();
247 }
248
249
250
251
252
253 @Test
254 public void testInverseCumulativeProbabilities() {
255 verifyInverseCumulativeProbabilities();
256 }
257
258
259
260
261
262 @Test
263 public void testDensities() {
264 verifyDensities();
265 }
266
267
268
269
270
271 @Test
272 public void testLogDensities() {
273 verifyLogDensities();
274 }
275
276
277
278
279 @Test
280 public void testConsistency() {
281 for (int i=1; i < cumulativeTestPoints.length; i++) {
282
283
284 UnitTestUtils.customAssertEquals(0d,
285 distribution.probability
286 (cumulativeTestPoints[i], cumulativeTestPoints[i]), tolerance);
287
288
289 double upper = FastMath.max(cumulativeTestPoints[i], cumulativeTestPoints[i -1]);
290 double lower = FastMath.min(cumulativeTestPoints[i], cumulativeTestPoints[i -1]);
291 double diff = distribution.cumulativeProbability(upper) -
292 distribution.cumulativeProbability(lower);
293 double direct = distribution.probability(lower, upper);
294 UnitTestUtils.customAssertEquals("Inconsistent probability for ("
295 + lower + "," + upper + ")", diff, direct, tolerance);
296 }
297 }
298
299
300
301
302 @Test
303 public void testIllegalArguments() {
304 try {
305 distribution.probability(1, 0);
306 fail("Expecting MathIllegalArgumentException for bad cumulativeProbability interval");
307 } catch (MathIllegalArgumentException ex) {
308
309 }
310 try {
311 distribution.inverseCumulativeProbability(-1);
312 fail("Expecting MathIllegalArgumentException for p = -1");
313 } catch (MathIllegalArgumentException ex) {
314
315 }
316 try {
317 distribution.inverseCumulativeProbability(2);
318 fail("Expecting MathIllegalArgumentException for p = 2");
319 } catch (MathIllegalArgumentException ex) {
320
321 }
322 }
323
324
325
326
327
328
329
330
331
332 @Test
333 public void testDensityIntegrals() {
334 final double tol = 1.0e-9;
335 final BaseAbstractUnivariateIntegrator integrator =
336 new IterativeLegendreGaussIntegrator(5, 1.0e-12, 1.0e-10);
337 final UnivariateFunction d = new UnivariateFunction() {
338 public double value(double x) {
339 return distribution.density(x);
340 }
341 };
342 final ArrayList<Double> integrationTestPoints = new ArrayList<Double>();
343 for (int i = 0; i < cumulativeTestPoints.length; i++) {
344 if (Double.isNaN(cumulativeTestValues[i]) ||
345 cumulativeTestValues[i] < 1.0e-5 ||
346 cumulativeTestValues[i] > 1 - 1.0e-5) {
347 continue;
348 }
349 integrationTestPoints.add(cumulativeTestPoints[i]);
350 }
351 Collections.sort(integrationTestPoints);
352 for (int i = 1; i < integrationTestPoints.size(); i++) {
353 assertEquals(
354 distribution.probability(
355 integrationTestPoints.get(0), integrationTestPoints.get(i)),
356 integrator.integrate(
357 1000000,
358 d, integrationTestPoints.get(0),
359 integrationTestPoints.get(i)), tol);
360 }
361 }
362
363
364
365
366
367 protected double[] getCumulativeTestPoints() {
368 return cumulativeTestPoints;
369 }
370
371
372
373
374 protected void setCumulativeTestPoints(double[] cumulativeTestPoints) {
375 this.cumulativeTestPoints = cumulativeTestPoints;
376 }
377
378
379
380
381 protected double[] getCumulativeTestValues() {
382 return cumulativeTestValues;
383 }
384
385
386
387
388 protected void setCumulativeTestValues(double[] cumulativeTestValues) {
389 this.cumulativeTestValues = cumulativeTestValues;
390 }
391
392 protected double[] getDensityTestValues() {
393 return densityTestValues;
394 }
395
396 protected void setDensityTestValues(double[] densityTestValues) {
397 this.densityTestValues = densityTestValues;
398 }
399
400
401
402
403 protected RealDistribution getDistribution() {
404 return distribution;
405 }
406
407
408
409
410 protected void setDistribution(RealDistribution distribution) {
411 this.distribution = distribution;
412 }
413
414
415
416
417 protected double[] getInverseCumulativeTestPoints() {
418 return inverseCumulativeTestPoints;
419 }
420
421
422
423
424 protected void setInverseCumulativeTestPoints(double[] inverseCumulativeTestPoints) {
425 this.inverseCumulativeTestPoints = inverseCumulativeTestPoints;
426 }
427
428
429
430
431 protected double[] getInverseCumulativeTestValues() {
432 return inverseCumulativeTestValues;
433 }
434
435
436
437
438 protected void setInverseCumulativeTestValues(double[] inverseCumulativeTestValues) {
439 this.inverseCumulativeTestValues = inverseCumulativeTestValues;
440 }
441
442
443
444
445 protected double getTolerance() {
446 return tolerance;
447 }
448
449
450
451
452 protected void setTolerance(double tolerance) {
453 this.tolerance = tolerance;
454 }
455
456 }