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