1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.statistics.distribution;
19
20 import java.math.BigDecimal;
21 import org.junit.jupiter.api.Assertions;
22 import org.junit.jupiter.api.Test;
23 import org.junit.jupiter.params.ParameterizedTest;
24 import org.junit.jupiter.params.provider.CsvFileSource;
25
26
27
28
29
30 class NormalDistributionTest extends BaseContinuousDistributionTest {
31
32
33 private static final NormalDistribution STANDARD_NORMAL = NormalDistribution.of(0, 1);
34
35 @Override
36 ContinuousDistribution makeDistribution(Object... parameters) {
37 final double mean = (Double) parameters[0];
38 final double sd = (Double) parameters[1];
39 return NormalDistribution.of(mean, sd);
40 }
41
42 @Override
43 Object[][] makeInvalidParameters() {
44 return new Object[][] {
45 {0.0, 0.0},
46 {0.0, -0.1}
47 };
48 }
49
50 @Override
51 String[] getParameterNames() {
52 return new String[] {"Mean", "StandardDeviation"};
53 }
54
55 @Override
56 protected double getRelativeTolerance() {
57
58 return 10 * RELATIVE_EPS;
59 }
60
61
62
63 @Test
64 void testCumulativeProbabilityExtremes() {
65 final NormalDistribution dist = NormalDistribution.of(0, 1);
66 testCumulativeProbability(dist,
67 new double[] {-Double.MAX_VALUE, Double.MAX_VALUE,
68 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY},
69 new double[] {0, 1, 0, 1},
70 DoubleTolerances.equals());
71 }
72
73
74
75
76
77 @Test
78 void testLowerTail() {
79 final NormalDistribution dist = NormalDistribution.of(0, 1);
80 for (int i = 0; i < 100; i++) {
81 final double cdf = dist.cumulativeProbability(-i);
82 if (i < 39) {
83 Assertions.assertTrue(cdf > 0);
84 } else {
85 Assertions.assertEquals(0, cdf);
86 }
87 final double sf = dist.survivalProbability(-i);
88 if (i < 9) {
89 Assertions.assertTrue(sf < 1);
90 } else {
91 Assertions.assertEquals(1, sf);
92 }
93 }
94 }
95
96
97
98
99
100 @Test
101 void testUpperTail() {
102 final NormalDistribution dist = NormalDistribution.of(0, 1);
103 for (int i = 0; i < 100; i++) {
104 final double cdf = dist.cumulativeProbability(i);
105 if (i < 9) {
106 Assertions.assertTrue(cdf < 1);
107 } else {
108 Assertions.assertEquals(1, cdf);
109 }
110
111 final double sf = dist.survivalProbability(i);
112 if (i < 39) {
113 Assertions.assertTrue(sf > 0);
114 } else {
115 Assertions.assertEquals(0, sf);
116 }
117 }
118 }
119
120 @Test
121 void testMath1257() {
122 final ContinuousDistribution dist = NormalDistribution.of(0, 1);
123 final double x = -10;
124 final double expected = 7.61985e-24;
125 final double v = dist.cumulativeProbability(x);
126 Assertions.assertEquals(1.0, v / expected, 1e-5);
127 }
128
129 @Test
130 void testMath280() {
131 final NormalDistribution dist = NormalDistribution.of(0, 1);
132
133
134 double result;
135 result = dist.inverseCumulativeProbability(0.841344746068543);
136 TestUtils.assertEquals(1.0, result, createRelTolerance(1e-15));
137 result = dist.inverseCumulativeProbability(0.9772498680518209);
138 TestUtils.assertEquals(2.0, result, createRelTolerance(1e-14));
139 result = dist.inverseCumulativeProbability(0.9986501019683698);
140 TestUtils.assertEquals(3.0, result, createRelTolerance(1e-13));
141 result = dist.inverseCumulativeProbability(0.9999683287581673);
142 TestUtils.assertEquals(4.0, result, createRelTolerance(1e-12));
143 }
144
145
146
147
148
149
150
151 @Test
152 void testInverseCDF() {
153 final NormalDistribution dist = NormalDistribution.of(0, 1);
154 Assertions.assertEquals(0.0, dist.inverseCumulativeProbability(0.5));
155
156 double x = 0;
157 for (;;) {
158 x -= 1;
159 final double cdf = dist.cumulativeProbability(x);
160 if (cdf == 0) {
161 break;
162 }
163 final double x0 = dist.inverseCumulativeProbability(cdf);
164
165 Assertions.assertEquals(x, x0, Math.abs(x) * 1e-11, () -> "CDF = " + cdf);
166 }
167 }
168
169
170
171
172
173
174
175
176
177 @ParameterizedTest
178 @CsvFileSource(resources = "normpdf.csv")
179 void testPDF(double x, BigDecimal expected) {
180 assertPDF(x, expected, 2);
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194 @ParameterizedTest
195 @CsvFileSource(resources = "normpdf2.csv")
196 void testPDF2(double x, BigDecimal expected) {
197 assertPDF(x, expected, 3);
198 }
199
200 private static void assertPDF(double x, BigDecimal expected, int ulpTolerance) {
201 final double e = expected.doubleValue();
202 final double a = STANDARD_NORMAL.density(x);
203 Assertions.assertEquals(e, a, Math.ulp(e) * ulpTolerance,
204 () -> "ULP error: " + expected.subtract(new BigDecimal(a)).doubleValue() / Math.ulp(e));
205 }
206 }