1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.numbers.gamma;
18
19 import org.junit.jupiter.api.Assertions;
20 import org.junit.jupiter.params.ParameterizedTest;
21 import org.junit.jupiter.params.provider.CsvFileSource;
22 import org.junit.jupiter.params.provider.CsvSource;
23 import org.junit.jupiter.params.provider.ValueSource;
24
25
26
27
28 class RegularizedGammaTest {
29 private static final double EPS = Math.ulp(1.0);
30
31
32
33
34
35
36 @ParameterizedTest
37 @ValueSource(doubles = {Double.NaN, 0, -1})
38 void testInvalidArgumentA(double a) {
39
40 assertRegularizedGamma(a, 1.0, Double.NaN);
41 }
42
43
44
45
46
47
48 @ParameterizedTest
49 @ValueSource(doubles = {Double.NaN, -1})
50 void testInvalidArgumentX(double x) {
51
52 assertRegularizedGamma(1.0, x, Double.NaN);
53 }
54
55 @ParameterizedTest
56 @CsvSource({
57
58 "0.250, 0.0, 0, 1",
59 "0.250, 0.250, 0.74367794473146098, 0.25632205526853896",
60 "0.250, 0.50, 0.84648640419167753, 0.15351359580832244",
61 "0.250, 1.0, 0.93207886798989104, 0.067921132010108964",
62 "0.250, 1.50, 0.96658355584102096, 0.033416444158979083",
63 "0.250, 2.0, 0.98271398814048316, 0.017286011859516792",
64 "0.250, 4.0, 0.99845731780336078, 0.0015426821966391837",
65 "0.250, 10.0, 0.99999791696959139, 2.0830304086494328e-06",
66 "0.50, 0.0, 0, 1",
67 "0.50, 0.250, 0.52049987781304641, 0.47950012218695348",
68 "0.50, 0.50, 0.68268949213708585, 0.31731050786291409",
69 "0.50, 1.0, 0.84270079294971489, 0.15729920705028508",
70 "0.50, 1.50, 0.91673548333644961, 0.083264516663550392",
71 "0.50, 2.0, 0.95449973610364158, 0.045500263896358438",
72 "0.50, 4.0, 0.99532226501895271, 0.0046777349810472628",
73 "0.50, 10.0, 0.99999225578356898, 7.7442164310441028e-06",
74 "1.0, 0.0, 0, 1",
75 "1.0, 0.250, 0.22119921692859515, 0.77880078307140488",
76 "1.0, 0.50, 0.39346934028736663, 0.60653065971263342",
77 "1.0, 1.0, 0.63212055882855767, 0.36787944117144233",
78 "1.0, 1.50, 0.77686983985157021, 0.22313016014842982",
79 "1.0, 2.0, 0.8646647167633873, 0.1353352832366127",
80 "1.0, 4.0, 0.98168436111126578, 0.018315638888734182",
81 "1.0, 10.0, 0.99995460007023751, 4.5399929762484827e-05",
82 "1.50, 0.0, 0, 1",
83 "1.50, 0.250, 0.081108588345324126, 0.91889141165467592",
84 "1.50, 0.50, 0.19874804309879915, 0.80125195690120088",
85 "1.50, 1.0, 0.42759329552912018, 0.57240670447087982",
86 "1.50, 1.50, 0.60837482372891105, 0.39162517627108895",
87 "1.50, 2.0, 0.73853587005088939, 0.26146412994911061",
88 "1.50, 4.0, 0.95398829431076859, 0.046011705689231366",
89 "1.50, 10.0, 0.99983025756444721, 0.00016974243555282646",
90 "2.0, 0.0, 0, 1",
91 "2.0, 0.250, 0.026499021160743926, 0.97350097883925613",
92 "2.0, 0.50, 0.090204010431049877, 0.90979598956895014",
93 "2.0, 1.0, 0.26424111765711533, 0.73575888234288467",
94 "2.0, 1.50, 0.44217459962892558, 0.55782540037107442",
95 "2.0, 2.0, 0.59399415029016189, 0.40600584970983811",
96 "2.0, 4.0, 0.90842180555632912, 0.091578194443670935",
97 "2.0, 10.0, 0.99950060077261271, 0.00049939922738733366",
98 "4.0, 0.0, 0, 1",
99 "4.0, 0.250, 0.00013336965051406234, 0.99986663034948597",
100 "4.0, 0.50, 0.001751622556290825, 0.9982483774437092",
101 "4.0, 1.0, 0.018988156876153815, 0.98101184312384615",
102 "4.0, 1.50, 0.065642454378450107, 0.93435754562154993",
103 "4.0, 2.0, 0.1428765395014529, 0.85712346049854715",
104 "4.0, 4.0, 0.56652987963329116, 0.4334701203667089",
105 "4.0, 10.0, 0.98966394932407431, 0.010336050675925723",
106 "10.0, 0.0, 0, 1",
107 "10.0, 0.250, 2.0942485399973598e-13, 0.99999999999979061",
108 "10.0, 0.50, 1.7096700293489097e-10, 0.99999999982903298",
109 "10.0, 1.0, 1.1142547833872003e-07, 0.99999988857452171",
110 "10.0, 1.50, 4.0975009763948422e-06, 0.99999590249902359",
111 "10.0, 2.0, 4.6498075017263825e-05, 0.99995350192498278",
112 "10.0, 4.0, 0.0081322427969338588, 0.99186775720306619",
113 "10.0, 10.0, 0.54207028552814784, 0.4579297144718521",
114 })
115 void testRegularizedGamma(double a, double x, double p, double q) {
116 final double actualP = RegularizedGamma.P.value(a, x);
117 final double actualQ = RegularizedGamma.Q.value(a, x);
118 final double eps = 1e-14;
119 Assertions.assertEquals(p, actualP, p * eps);
120 Assertions.assertEquals(q, actualQ, q * eps);
121 }
122
123
124
125
126
127
128
129
130 @ParameterizedTest
131 @CsvSource(value = {
132
133 "5.0,2.5,21.38827245393963,0.8911780189141513,2.6117275460603704,0.10882198108584876",
134
135 "19.24400520324707,21.168405532836914,4.0308280447358675E15,0.3084240508178698,9.038282597080282E15,0.6915759491821302",
136
137 "664.0791015625,1328.158203125,Infinity,4.90100553385586E-91,Infinity,1.0",
138
139 "0.9759566783905029,1.0735523700714111,0.33659577343416824,0.33179703084688433,0.6778671124302277,0.6682029691531157",
140
141 "0.4912221431732178,0.9824442863464355,0.2840949896471149,0.1575143024618326,1.519518937513272,0.8424856975381674",
142 })
143 void testIGammaPolicy(double a, double x, double upper, double q, double lower, double p) {
144
145 Assertions.assertThrows(ArithmeticException.class, () -> RegularizedGamma.P.value(a, x, EPS, 1), "p");
146 Assertions.assertThrows(ArithmeticException.class, () -> RegularizedGamma.Q.value(a, x, EPS, 1), "q");
147
148
149
150
151 if ((int) p != p) {
152 final double p1 = RegularizedGamma.P.value(a, x);
153 final double p2 = RegularizedGamma.P.value(a, x, 1e-3, Integer.MAX_VALUE);
154 assertCloser("p", p, p1, p2);
155 }
156 if ((int) q != q) {
157 final double q1 = RegularizedGamma.Q.value(a, x);
158 final double q2 = RegularizedGamma.Q.value(a, x, 1e-3, Integer.MAX_VALUE);
159 assertCloser("q", q, q1, q2);
160 }
161 }
162
163 @ParameterizedTest
164 @CsvFileSource(resources = "igamma_med_data_p_derivative.csv")
165 void testGammaPDerivative(double a, double x, double expected) {
166 final double actual = RegularizedGamma.P.derivative(a, x);
167 TestUtils.assertEquals(expected, actual, 5);
168 Assertions.assertEquals(-actual, RegularizedGamma.Q.derivative(a, x));
169 }
170
171
172
173
174
175
176
177
178 private static void assertRegularizedGamma(double a, double x, double p) {
179 final double actualP = RegularizedGamma.P.value(a, x);
180 final double actualQ = RegularizedGamma.Q.value(a, x);
181 Assertions.assertEquals(p, actualP);
182 Assertions.assertEquals(1 - p, actualQ);
183 }
184
185
186
187
188 private static void assertCloser(String msg, double expected, double x, double y) {
189 final double dx = Math.abs(expected - x);
190 final double dy = Math.abs(expected - y);
191 Assertions.assertTrue(dx < dy,
192 () -> String.format("%s %s : %s (%s) : %s (%s)", msg, expected, x, dx, y, dy));
193 }
194 }