1 #include "test/jemalloc_test.h"
2
3 #define MAX_REL_ERR 1.0e-9
4 #define MAX_ABS_ERR 1.0e-9
5
6 #include <float.h>
7
8 #ifdef __PGI
9 #undef INFINITY
10 #endif
11
12 #ifndef INFINITY
13 #define INFINITY (DBL_MAX + DBL_MAX)
14 #endif
15
16 static bool
double_eq_rel(double a,double b,double max_rel_err,double max_abs_err)17 double_eq_rel(double a, double b, double max_rel_err, double max_abs_err) {
18 double rel_err;
19
20 if (fabs(a - b) < max_abs_err) {
21 return true;
22 }
23 rel_err = (fabs(b) > fabs(a)) ? fabs((a-b)/b) : fabs((a-b)/a);
24 return (rel_err < max_rel_err);
25 }
26
27 static uint64_t
factorial(unsigned x)28 factorial(unsigned x) {
29 uint64_t ret = 1;
30 unsigned i;
31
32 for (i = 2; i <= x; i++) {
33 ret *= (uint64_t)i;
34 }
35
36 return ret;
37 }
38
TEST_BEGIN(test_ln_gamma_factorial)39 TEST_BEGIN(test_ln_gamma_factorial) {
40 unsigned x;
41
42 /* exp(ln_gamma(x)) == (x-1)! for integer x. */
43 for (x = 1; x <= 21; x++) {
44 assert_true(double_eq_rel(exp(ln_gamma(x)),
45 (double)factorial(x-1), MAX_REL_ERR, MAX_ABS_ERR),
46 "Incorrect factorial result for x=%u", x);
47 }
48 }
49 TEST_END
50
51 /* Expected ln_gamma([0.0..100.0] increment=0.25). */
52 static const double ln_gamma_misc_expected[] = {
53 INFINITY,
54 1.28802252469807743, 0.57236494292470008, 0.20328095143129538,
55 0.00000000000000000, -0.09827183642181320, -0.12078223763524518,
56 -0.08440112102048555, 0.00000000000000000, 0.12487171489239651,
57 0.28468287047291918, 0.47521466691493719, 0.69314718055994529,
58 0.93580193110872523, 1.20097360234707429, 1.48681557859341718,
59 1.79175946922805496, 2.11445692745037128, 2.45373657084244234,
60 2.80857141857573644, 3.17805383034794575, 3.56137591038669710,
61 3.95781396761871651, 4.36671603662228680, 4.78749174278204581,
62 5.21960398699022932, 5.66256205985714178, 6.11591589143154568,
63 6.57925121201010121, 7.05218545073853953, 7.53436423675873268,
64 8.02545839631598312, 8.52516136106541467, 9.03318691960512332,
65 9.54926725730099690, 10.07315123968123949, 10.60460290274525086,
66 11.14340011995171231, 11.68933342079726856, 12.24220494005076176,
67 12.80182748008146909, 13.36802367147604720, 13.94062521940376342,
68 14.51947222506051816, 15.10441257307551943, 15.69530137706046524,
69 16.29200047656724237, 16.89437797963419285, 17.50230784587389010,
70 18.11566950571089407, 18.73434751193644843, 19.35823122022435427,
71 19.98721449566188468, 20.62119544270163018, 21.26007615624470048,
72 21.90376249182879320, 22.55216385312342098, 23.20519299513386002,
73 23.86276584168908954, 24.52480131594137802, 25.19122118273868338,
74 25.86194990184851861, 26.53691449111561340, 27.21604439872720604,
75 27.89927138384089389, 28.58652940490193828, 29.27775451504081516,
76 29.97288476399884871, 30.67186010608067548, 31.37462231367769050,
77 32.08111489594735843, 32.79128302226991565, 33.50507345013689076,
78 34.22243445715505317, 34.94331577687681545, 35.66766853819134298,
79 36.39544520803305261, 37.12659953718355865, 37.86108650896109395,
80 38.59886229060776230, 39.33988418719949465, 40.08411059791735198,
81 40.83150097453079752, 41.58201578195490100, 42.33561646075348506,
82 43.09226539146988699, 43.85192586067515208, 44.61456202863158893,
83 45.38013889847690052, 46.14862228684032885, 46.91997879580877395,
84 47.69417578616628361, 48.47118135183522014, 49.25096429545256882,
85 50.03349410501914463, 50.81874093156324790, 51.60667556776436982,
86 52.39726942748592364, 53.19049452616926743, 53.98632346204390586,
87 54.78472939811231157, 55.58568604486942633, 56.38916764371992940,
88 57.19514895105859864, 58.00360522298051080, 58.81451220059079787,
89 59.62784609588432261, 60.44358357816834371, 61.26170176100199427,
90 62.08217818962842927, 62.90499082887649962, 63.73011805151035958,
91 64.55753862700632340, 65.38723171073768015, 66.21917683354901385,
92 67.05335389170279825, 67.88974313718154008, 68.72832516833013017,
93 69.56908092082363737, 70.41199165894616385, 71.25703896716800045,
94 72.10420474200799390, 72.95347118416940191, 73.80482079093779646,
95 74.65823634883015814, 75.51370092648485866, 76.37119786778275454,
96 77.23071078519033961, 78.09222355331530707, 78.95572030266725960,
97 79.82118541361435859, 80.68860351052903468, 81.55795945611502873,
98 82.42923834590904164, 83.30242550295004378, 84.17750647261028973,
99 85.05446701758152983, 85.93329311301090456, 86.81397094178107920,
100 87.69648688992882057, 88.58082754219766741, 89.46697967771913795,
101 90.35493026581838194, 91.24466646193963015, 92.13617560368709292,
102 93.02944520697742803, 93.92446296229978486, 94.82121673107967297,
103 95.71969454214321615, 96.61988458827809723, 97.52177522288820910,
104 98.42535495673848800, 99.33061245478741341, 100.23753653310367895,
105 101.14611615586458981, 102.05634043243354370, 102.96819861451382394,
106 103.88168009337621811, 104.79677439715833032, 105.71347118823287303,
107 106.63176026064346047, 107.55163153760463501, 108.47307506906540198,
108 109.39608102933323153, 110.32063971475740516, 111.24674154146920557,
109 112.17437704317786995, 113.10353686902013237, 114.03421178146170689,
110 114.96639265424990128, 115.90007047041454769, 116.83523632031698014,
111 117.77188139974506953, 118.70999700805310795, 119.64957454634490830,
112 120.59060551569974962, 121.53308151543865279, 122.47699424143097247,
113 123.42233548443955726, 124.36909712850338394, 125.31727114935689826,
114 126.26684961288492559, 127.21782467361175861, 128.17018857322420899,
115 129.12393363912724453, 130.07905228303084755, 131.03553699956862033,
116 131.99338036494577864, 132.95257503561629164, 133.91311374698926784,
117 134.87498931216194364, 135.83819462068046846, 136.80272263732638294,
118 137.76856640092901785, 138.73571902320256299, 139.70417368760718091,
119 140.67392364823425055, 141.64496222871400732, 142.61728282114600574,
120 143.59087888505104047, 144.56574394634486680, 145.54187159633210058,
121 146.51925549072063859, 147.49788934865566148, 148.47776695177302031,
122 149.45888214327129617, 150.44122882700193600, 151.42480096657754984,
123 152.40959258449737490, 153.39559776128982094, 154.38281063467164245,
124 155.37122539872302696, 156.36083630307879844, 157.35163765213474107,
125 158.34362380426921391, 159.33678917107920370, 160.33112821663092973,
126 161.32663545672428995, 162.32330545817117695, 163.32113283808695314,
127 164.32011226319519892, 165.32023844914485267, 166.32150615984036790,
128 167.32391020678358018, 168.32744544842768164, 169.33210678954270634,
129 170.33788918059275375, 171.34478761712384198, 172.35279713916281707,
130 173.36191283062726143, 174.37212981874515094, 175.38344327348534080,
131 176.39584840699734514, 177.40934047306160437, 178.42391476654847793,
132 179.43956662288721304, 180.45629141754378111, 181.47408456550741107,
133 182.49294152078630304, 183.51285777591152737, 184.53382886144947861,
134 185.55585034552262869, 186.57891783333786861, 187.60302696672312095,
135 188.62817342367162610, 189.65435291789341932, 190.68156119837468054,
136 191.70979404894376330, 192.73904728784492590, 193.76931676731820176,
137 194.80059837318714244, 195.83288802445184729, 196.86618167288995096,
138 197.90047530266301123, 198.93576492992946214, 199.97204660246373464,
139 201.00931639928148797, 202.04757043027063901, 203.08680483582807597,
140 204.12701578650228385, 205.16819948264117102, 206.21035215404597807,
141 207.25347005962987623, 208.29754948708190909, 209.34258675253678916,
142 210.38857820024875878, 211.43552020227099320, 212.48340915813977858,
143 213.53224149456323744, 214.58201366511514152, 215.63272214993284592,
144 216.68436345542014010, 217.73693411395422004, 218.79043068359703739,
145 219.84484974781133815, 220.90018791517996988, 221.95644181913033322,
146 223.01360811766215875, 224.07168349307951871, 225.13066465172661879,
147 226.19054832372759734, 227.25133126272962159, 228.31301024565024704,
148 229.37558207242807384, 230.43904356577689896, 231.50339157094342113,
149 232.56862295546847008, 233.63473460895144740, 234.70172344281823484,
150 235.76958639009222907, 236.83832040516844586, 237.90792246359117712,
151 238.97838956183431947, 240.04971871708477238, 241.12190696702904802,
152 242.19495136964280846, 243.26884900298270509, 244.34359696498191283,
153 245.41919237324782443, 246.49563236486270057, 247.57291409618682110,
154 248.65103474266476269, 249.72999149863338175, 250.80978157713354904,
155 251.89040220972316320, 252.97185064629374551, 254.05412415488834199,
156 255.13722002152300661, 256.22113555000953511, 257.30586806178126835,
157 258.39141489572085675, 259.47777340799029844, 260.56494097186322279,
158 261.65291497755913497, 262.74169283208021852, 263.83127195904967266,
159 264.92164979855277807, 266.01282380697938379, 267.10479145686849733,
160 268.19755023675537586, 269.29109765101975427, 270.38543121973674488,
161 271.48054847852881721, 272.57644697842033565, 273.67312428569374561,
162 274.77057798174683967, 275.86880566295326389, 276.96780494052313770,
163 278.06757344036617496, 279.16810880295668085, 280.26940868320008349,
164 281.37147075030043197, 282.47429268763045229, 283.57787219260217171,
165 284.68220697654078322, 285.78729476455760050, 286.89313329542699194,
166 287.99972032146268930, 289.10705360839756395, 290.21513093526289140,
167 291.32395009427028754, 292.43350889069523646, 293.54380514276073200,
168 294.65483668152336350, 295.76660135076059532, 296.87909700685889902,
169 297.99232151870342022, 299.10627276756946458, 300.22094864701409733,
170 301.33634706277030091, 302.45246593264130297, 303.56930318639643929,
171 304.68685676566872189, 305.80512462385280514, 306.92410472600477078,
172 308.04379504874236773, 309.16419358014690033, 310.28529831966631036,
173 311.40710727801865687, 312.52961847709792664, 313.65282994987899201,
174 314.77673974032603610, 315.90134590329950015, 317.02664650446632777,
175 318.15263962020929966, 319.27932333753892635, 320.40669575400545455,
176 321.53475497761127144, 322.66349912672620803, 323.79292633000159185,
177 324.92303472628691452, 326.05382246454587403, 327.18528770377525916,
178 328.31742861292224234, 329.45024337080525356, 330.58373016603343331,
179 331.71788719692847280, 332.85271267144611329, 333.98820480709991898,
180 335.12436183088397001, 336.26118197919845443, 337.39866349777429377,
181 338.53680464159958774, 339.67560367484657036, 340.81505887079896411,
182 341.95516851178109619, 343.09593088908627578, 344.23734430290727460,
183 345.37940706226686416, 346.52211748494903532, 347.66547389743118401,
184 348.80947463481720661, 349.95411804077025408, 351.09940246744753267,
185 352.24532627543504759, 353.39188783368263103, 354.53908551944078908,
186 355.68691771819692349, 356.83538282361303118, 357.98447923746385868,
187 359.13420536957539753
188 };
189
TEST_BEGIN(test_ln_gamma_misc)190 TEST_BEGIN(test_ln_gamma_misc) {
191 unsigned i;
192
193 for (i = 1; i < sizeof(ln_gamma_misc_expected)/sizeof(double); i++) {
194 double x = (double)i * 0.25;
195 assert_true(double_eq_rel(ln_gamma(x),
196 ln_gamma_misc_expected[i], MAX_REL_ERR, MAX_ABS_ERR),
197 "Incorrect ln_gamma result for i=%u", i);
198 }
199 }
200 TEST_END
201
202 /* Expected pt_norm([0.01..0.99] increment=0.01). */
203 static const double pt_norm_expected[] = {
204 -INFINITY,
205 -2.32634787404084076, -2.05374891063182252, -1.88079360815125085,
206 -1.75068607125216946, -1.64485362695147264, -1.55477359459685305,
207 -1.47579102817917063, -1.40507156030963221, -1.34075503369021654,
208 -1.28155156554460081, -1.22652812003661049, -1.17498679206608991,
209 -1.12639112903880045, -1.08031934081495606, -1.03643338949378938,
210 -0.99445788320975281, -0.95416525314619416, -0.91536508784281390,
211 -0.87789629505122846, -0.84162123357291418, -0.80642124701824025,
212 -0.77219321418868492, -0.73884684918521371, -0.70630256284008752,
213 -0.67448975019608171, -0.64334540539291685, -0.61281299101662701,
214 -0.58284150727121620, -0.55338471955567281, -0.52440051270804067,
215 -0.49585034734745320, -0.46769879911450812, -0.43991316567323380,
216 -0.41246312944140462, -0.38532046640756751, -0.35845879325119373,
217 -0.33185334643681652, -0.30548078809939738, -0.27931903444745404,
218 -0.25334710313579978, -0.22754497664114931, -0.20189347914185077,
219 -0.17637416478086135, -0.15096921549677725, -0.12566134685507399,
220 -0.10043372051146975, -0.07526986209982976, -0.05015358346473352,
221 -0.02506890825871106, 0.00000000000000000, 0.02506890825871106,
222 0.05015358346473366, 0.07526986209982990, 0.10043372051146990,
223 0.12566134685507413, 0.15096921549677739, 0.17637416478086146,
224 0.20189347914185105, 0.22754497664114931, 0.25334710313579978,
225 0.27931903444745404, 0.30548078809939738, 0.33185334643681652,
226 0.35845879325119373, 0.38532046640756762, 0.41246312944140484,
227 0.43991316567323391, 0.46769879911450835, 0.49585034734745348,
228 0.52440051270804111, 0.55338471955567303, 0.58284150727121620,
229 0.61281299101662701, 0.64334540539291685, 0.67448975019608171,
230 0.70630256284008752, 0.73884684918521371, 0.77219321418868492,
231 0.80642124701824036, 0.84162123357291441, 0.87789629505122879,
232 0.91536508784281423, 0.95416525314619460, 0.99445788320975348,
233 1.03643338949378938, 1.08031934081495606, 1.12639112903880045,
234 1.17498679206608991, 1.22652812003661049, 1.28155156554460081,
235 1.34075503369021654, 1.40507156030963265, 1.47579102817917085,
236 1.55477359459685394, 1.64485362695147308, 1.75068607125217102,
237 1.88079360815125041, 2.05374891063182208, 2.32634787404084076
238 };
239
TEST_BEGIN(test_pt_norm)240 TEST_BEGIN(test_pt_norm) {
241 unsigned i;
242
243 for (i = 1; i < sizeof(pt_norm_expected)/sizeof(double); i++) {
244 double p = (double)i * 0.01;
245 assert_true(double_eq_rel(pt_norm(p), pt_norm_expected[i],
246 MAX_REL_ERR, MAX_ABS_ERR),
247 "Incorrect pt_norm result for i=%u", i);
248 }
249 }
250 TEST_END
251
252 /*
253 * Expected pt_chi2(p=[0.01..0.99] increment=0.07,
254 * df={0.1, 1.1, 10.1, 100.1, 1000.1}).
255 */
256 static const double pt_chi2_df[] = {0.1, 1.1, 10.1, 100.1, 1000.1};
257 static const double pt_chi2_expected[] = {
258 1.168926411457320e-40, 1.347680397072034e-22, 3.886980416666260e-17,
259 8.245951724356564e-14, 2.068936347497604e-11, 1.562561743309233e-09,
260 5.459543043426564e-08, 1.114775688149252e-06, 1.532101202364371e-05,
261 1.553884683726585e-04, 1.239396954915939e-03, 8.153872320255721e-03,
262 4.631183739647523e-02, 2.473187311701327e-01, 2.175254800183617e+00,
263
264 0.0003729887888876379, 0.0164409238228929513, 0.0521523015190650113,
265 0.1064701372271216612, 0.1800913735793082115, 0.2748704281195626931,
266 0.3939246282787986497, 0.5420727552260817816, 0.7267265822221973259,
267 0.9596554296000253670, 1.2607440376386165326, 1.6671185084541604304,
268 2.2604828984738705167, 3.2868613342148607082, 6.9298574921692139839,
269
270 2.606673548632508, 4.602913725294877, 5.646152813924212,
271 6.488971315540869, 7.249823275816285, 7.977314231410841,
272 8.700354939944047, 9.441728024225892, 10.224338321374127,
273 11.076435368801061, 12.039320937038386, 13.183878752697167,
274 14.657791935084575, 16.885728216339373, 23.361991680031817,
275
276 70.14844087392152, 80.92379498849355, 85.53325420085891,
277 88.94433120715347, 91.83732712857017, 94.46719943606301,
278 96.96896479994635, 99.43412843510363, 101.94074719829733,
279 104.57228644307247, 107.43900093448734, 110.71844673417287,
280 114.76616819871325, 120.57422505959563, 135.92318818757556,
281
282 899.0072447849649, 937.9271278858220, 953.8117189560207,
283 965.3079371501154, 974.8974061207954, 983.4936235182347,
284 991.5691170518946, 999.4334123954690, 1007.3391826856553,
285 1015.5445154999951, 1024.3777075619569, 1034.3538789836223,
286 1046.4872561869577, 1063.5717461999654, 1107.0741966053859
287 };
288
TEST_BEGIN(test_pt_chi2)289 TEST_BEGIN(test_pt_chi2) {
290 unsigned i, j;
291 unsigned e = 0;
292
293 for (i = 0; i < sizeof(pt_chi2_df)/sizeof(double); i++) {
294 double df = pt_chi2_df[i];
295 double ln_gamma_df = ln_gamma(df * 0.5);
296 for (j = 1; j < 100; j += 7) {
297 double p = (double)j * 0.01;
298 assert_true(double_eq_rel(pt_chi2(p, df, ln_gamma_df),
299 pt_chi2_expected[e], MAX_REL_ERR, MAX_ABS_ERR),
300 "Incorrect pt_chi2 result for i=%u, j=%u", i, j);
301 e++;
302 }
303 }
304 }
305 TEST_END
306
307 /*
308 * Expected pt_gamma(p=[0.1..0.99] increment=0.07,
309 * shape=[0.5..3.0] increment=0.5).
310 */
311 static const double pt_gamma_shape[] = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0};
312 static const double pt_gamma_expected[] = {
313 7.854392895485103e-05, 5.043466107888016e-03, 1.788288957794883e-02,
314 3.900956150232906e-02, 6.913847560638034e-02, 1.093710833465766e-01,
315 1.613412523825817e-01, 2.274682115597864e-01, 3.114117323127083e-01,
316 4.189466220207417e-01, 5.598106789059246e-01, 7.521856146202706e-01,
317 1.036125427911119e+00, 1.532450860038180e+00, 3.317448300510606e+00,
318
319 0.01005033585350144, 0.08338160893905107, 0.16251892949777497,
320 0.24846135929849966, 0.34249030894677596, 0.44628710262841947,
321 0.56211891815354142, 0.69314718055994529, 0.84397007029452920,
322 1.02165124753198167, 1.23787435600161766, 1.51412773262977574,
323 1.89711998488588196, 2.52572864430825783, 4.60517018598809091,
324
325 0.05741590094955853, 0.24747378084860744, 0.39888572212236084,
326 0.54394139997444901, 0.69048812513915159, 0.84311389861296104,
327 1.00580622221479898, 1.18298694218766931, 1.38038096305861213,
328 1.60627736383027453, 1.87396970522337947, 2.20749220408081070,
329 2.65852391865854942, 3.37934630984842244, 5.67243336507218476,
330
331 0.1485547402532659, 0.4657458011640391, 0.6832386130709406,
332 0.8794297834672100, 1.0700752852474524, 1.2629614217350744,
333 1.4638400448580779, 1.6783469900166610, 1.9132338090606940,
334 2.1778589228618777, 2.4868823970010991, 2.8664695666264195,
335 3.3724415436062114, 4.1682658512758071, 6.6383520679938108,
336
337 0.2771490383641385, 0.7195001279643727, 0.9969081732265243,
338 1.2383497880608061, 1.4675206597269927, 1.6953064251816552,
339 1.9291243435606809, 2.1757300955477641, 2.4428032131216391,
340 2.7406534569230616, 3.0851445039665513, 3.5043101122033367,
341 4.0575997065264637, 4.9182956424675286, 7.5431362346944937,
342
343 0.4360451650782932, 0.9983600902486267, 1.3306365880734528,
344 1.6129750834753802, 1.8767241606994294, 2.1357032436097660,
345 2.3988853336865565, 2.6740603137235603, 2.9697561737517959,
346 3.2971457713883265, 3.6731795898504660, 4.1275751617770631,
347 4.7230515633946677, 5.6417477865306020, 8.4059469148854635
348 };
349
TEST_BEGIN(test_pt_gamma_shape)350 TEST_BEGIN(test_pt_gamma_shape) {
351 unsigned i, j;
352 unsigned e = 0;
353
354 for (i = 0; i < sizeof(pt_gamma_shape)/sizeof(double); i++) {
355 double shape = pt_gamma_shape[i];
356 double ln_gamma_shape = ln_gamma(shape);
357 for (j = 1; j < 100; j += 7) {
358 double p = (double)j * 0.01;
359 assert_true(double_eq_rel(pt_gamma(p, shape, 1.0,
360 ln_gamma_shape), pt_gamma_expected[e], MAX_REL_ERR,
361 MAX_ABS_ERR),
362 "Incorrect pt_gamma result for i=%u, j=%u", i, j);
363 e++;
364 }
365 }
366 }
367 TEST_END
368
TEST_BEGIN(test_pt_gamma_scale)369 TEST_BEGIN(test_pt_gamma_scale) {
370 double shape = 1.0;
371 double ln_gamma_shape = ln_gamma(shape);
372
373 assert_true(double_eq_rel(
374 pt_gamma(0.5, shape, 1.0, ln_gamma_shape) * 10.0,
375 pt_gamma(0.5, shape, 10.0, ln_gamma_shape), MAX_REL_ERR,
376 MAX_ABS_ERR),
377 "Scale should be trivially equivalent to external multiplication");
378 }
379 TEST_END
380
381 int
main(void)382 main(void) {
383 return test(
384 test_ln_gamma_factorial,
385 test_ln_gamma_misc,
386 test_pt_norm,
387 test_pt_chi2,
388 test_pt_gamma_shape,
389 test_pt_gamma_scale);
390 }
391