1b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans#ifndef JEMALLOC_ENABLE_INLINE
2b1941c615023cab9baf0a78a28df1e3b4972434fJason Evansdouble	ln_gamma(double x);
3b1941c615023cab9baf0a78a28df1e3b4972434fJason Evansdouble	i_gamma(double x, double p, double ln_gamma_p);
4b1941c615023cab9baf0a78a28df1e3b4972434fJason Evansdouble	pt_norm(double p);
5b1941c615023cab9baf0a78a28df1e3b4972434fJason Evansdouble	pt_chi2(double p, double df, double ln_gamma_df_2);
6b1941c615023cab9baf0a78a28df1e3b4972434fJason Evansdouble	pt_gamma(double p, double shape, double scale, double ln_gamma_shape);
7b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans#endif
8b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
9b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans#if (defined(JEMALLOC_ENABLE_INLINE) || defined(MATH_C_))
10b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans/*
11b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * Compute the natural log of Gamma(x), accurate to 10 decimal places.
12b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *
13b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * This implementation is based on:
14b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *
15b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *   Pike, M.C., I.D. Hill (1966) Algorithm 291: Logarithm of Gamma function
16b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *   [S14].  Communications of the ACM 9(9):684.
17b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans */
18b1941c615023cab9baf0a78a28df1e3b4972434fJason EvansJEMALLOC_INLINE double
19b1941c615023cab9baf0a78a28df1e3b4972434fJason Evansln_gamma(double x)
20b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans{
21b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	double f, z;
22b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
23b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	assert(x > 0.0);
24b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
25b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	if (x < 7.0) {
26b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		f = 1.0;
27b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		z = x;
28b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		while (z < 7.0) {
29b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			f *= z;
30b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			z += 1.0;
31b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		}
32b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		x = z;
33b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		f = -log(f);
34b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	} else
35b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		f = 0.0;
36b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
37b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	z = 1.0 / (x * x);
38b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
39b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	return (f + (x-0.5) * log(x) - x + 0.918938533204673 +
40b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	    (((-0.000595238095238 * z + 0.000793650793651) * z -
41b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	    0.002777777777778) * z + 0.083333333333333) / x);
42b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans}
43b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
44b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans/*
45b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * Compute the incomplete Gamma ratio for [0..x], where p is the shape
46b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * parameter, and ln_gamma_p is ln_gamma(p).
47b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *
48b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * This implementation is based on:
49b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *
50b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *   Bhattacharjee, G.P. (1970) Algorithm AS 32: The incomplete Gamma integral.
51b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *   Applied Statistics 19:285-287.
52b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans */
53b1941c615023cab9baf0a78a28df1e3b4972434fJason EvansJEMALLOC_INLINE double
54b1941c615023cab9baf0a78a28df1e3b4972434fJason Evansi_gamma(double x, double p, double ln_gamma_p)
55b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans{
56b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	double acu, factor, oflo, gin, term, rn, a, b, an, dif;
57b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	double pn[6];
58b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	unsigned i;
59b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
60b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	assert(p > 0.0);
61b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	assert(x >= 0.0);
62b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
63b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	if (x == 0.0)
64b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		return (0.0);
65b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
66b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	acu = 1.0e-10;
67b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	oflo = 1.0e30;
68b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	gin = 0.0;
69b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	factor = exp(p * log(x) - x - ln_gamma_p);
70b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
71b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	if (x <= 1.0 || x < p) {
72b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		/* Calculation by series expansion. */
73b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		gin = 1.0;
74b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		term = 1.0;
75b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		rn = p;
76b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
77b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		while (true) {
78b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			rn += 1.0;
79b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			term *= x / rn;
80b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			gin += term;
81b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			if (term <= acu) {
82b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				gin *= factor / p;
83b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				return (gin);
84b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			}
85b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		}
86b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	} else {
87b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		/* Calculation by continued fraction. */
88b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		a = 1.0 - p;
89b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		b = a + x + 1.0;
90b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		term = 0.0;
91b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		pn[0] = 1.0;
92b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		pn[1] = x;
93b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		pn[2] = x + 1.0;
94b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		pn[3] = x * b;
95b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		gin = pn[2] / pn[3];
96b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
97b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		while (true) {
98b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			a += 1.0;
99b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			b += 2.0;
100b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			term += 1.0;
101b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			an = a * term;
102b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			for (i = 0; i < 2; i++)
103b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				pn[i+4] = b * pn[i+2] - an * pn[i];
104b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			if (pn[5] != 0.0) {
105b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				rn = pn[4] / pn[5];
106b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				dif = fabs(gin - rn);
107b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				if (dif <= acu && dif <= acu * rn) {
108b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans					gin = 1.0 - factor * gin;
109b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans					return (gin);
110b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				}
111b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				gin = rn;
112b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			}
113b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			for (i = 0; i < 4; i++)
114b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				pn[i] = pn[i+2];
115b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
116b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			if (fabs(pn[4]) >= oflo) {
117b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				for (i = 0; i < 4; i++)
118b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans					pn[i] /= oflo;
119b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			}
120b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		}
121b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	}
122b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans}
123b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
124b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans/*
125b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * Given a value p in [0..1] of the lower tail area of the normal distribution,
126b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * compute the limit on the definite integral from [-inf..z] that satisfies p,
127b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * accurate to 16 decimal places.
128b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *
129b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * This implementation is based on:
130b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *
131b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *   Wichura, M.J. (1988) Algorithm AS 241: The percentage points of the normal
132b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *   distribution.  Applied Statistics 37(3):477-484.
133b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans */
134b1941c615023cab9baf0a78a28df1e3b4972434fJason EvansJEMALLOC_INLINE double
135b1941c615023cab9baf0a78a28df1e3b4972434fJason Evanspt_norm(double p)
136b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans{
137b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	double q, r, ret;
138b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
139b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	assert(p > 0.0 && p < 1.0);
140b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
141b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	q = p - 0.5;
142b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	if (fabs(q) <= 0.425) {
143b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		/* p close to 1/2. */
144b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		r = 0.180625 - q * q;
145b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		return (q * (((((((2.5090809287301226727e3 * r +
146b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    3.3430575583588128105e4) * r + 6.7265770927008700853e4) * r
147b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    + 4.5921953931549871457e4) * r + 1.3731693765509461125e4) *
148b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    r + 1.9715909503065514427e3) * r + 1.3314166789178437745e2)
149b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    * r + 3.3871328727963666080e0) /
150b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    (((((((5.2264952788528545610e3 * r +
151b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    2.8729085735721942674e4) * r + 3.9307895800092710610e4) * r
152b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    + 2.1213794301586595867e4) * r + 5.3941960214247511077e3) *
153b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    r + 6.8718700749205790830e2) * r + 4.2313330701600911252e1)
154b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    * r + 1.0));
155b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	} else {
156b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		if (q < 0.0)
157b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			r = p;
158b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		else
159b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			r = 1.0 - p;
160b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		assert(r > 0.0);
161b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
162b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		r = sqrt(-log(r));
163b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		if (r <= 5.0) {
164b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			/* p neither close to 1/2 nor 0 or 1. */
165b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			r -= 1.6;
166b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			ret = ((((((((7.74545014278341407640e-4 * r +
167b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    2.27238449892691845833e-2) * r +
168b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    2.41780725177450611770e-1) * r +
169b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    1.27045825245236838258e0) * r +
170b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    3.64784832476320460504e0) * r +
171b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    5.76949722146069140550e0) * r +
172b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    4.63033784615654529590e0) * r +
173b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    1.42343711074968357734e0) /
174b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    (((((((1.05075007164441684324e-9 * r +
175b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    5.47593808499534494600e-4) * r +
176b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    1.51986665636164571966e-2)
177b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    * r + 1.48103976427480074590e-1) * r +
178b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    6.89767334985100004550e-1) * r +
179b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    1.67638483018380384940e0) * r +
180b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    2.05319162663775882187e0) * r + 1.0));
181b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		} else {
182b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			/* p near 0 or 1. */
183b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			r -= 5.0;
184b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			ret = ((((((((2.01033439929228813265e-7 * r +
185b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    2.71155556874348757815e-5) * r +
186b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    1.24266094738807843860e-3) * r +
187b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    2.65321895265761230930e-2) * r +
188b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    2.96560571828504891230e-1) * r +
189b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    1.78482653991729133580e0) * r +
190b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    5.46378491116411436990e0) * r +
191b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    6.65790464350110377720e0) /
192b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    (((((((2.04426310338993978564e-15 * r +
193b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    1.42151175831644588870e-7) * r +
194b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    1.84631831751005468180e-5) * r +
195b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    7.86869131145613259100e-4) * r +
196b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    1.48753612908506148525e-2) * r +
197b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    1.36929880922735805310e-1) * r +
198b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    5.99832206555887937690e-1)
199b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			    * r + 1.0));
200b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		}
201b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		if (q < 0.0)
202b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			ret = -ret;
203b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		return (ret);
204b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	}
205b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans}
206b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
207b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans/*
208b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * Given a value p in [0..1] of the lower tail area of the Chi^2 distribution
209b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * with df degrees of freedom, where ln_gamma_df_2 is ln_gamma(df/2.0), compute
210b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * the upper limit on the definite integral from [0..z] that satisfies p,
211b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * accurate to 12 decimal places.
212b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *
213b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * This implementation is based on:
214b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *
215b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *   Best, D.J., D.E. Roberts (1975) Algorithm AS 91: The percentage points of
216b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *   the Chi^2 distribution.  Applied Statistics 24(3):385-388.
217b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *
218b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *   Shea, B.L. (1991) Algorithm AS R85: A remark on AS 91: The percentage
219b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans *   points of the Chi^2 distribution.  Applied Statistics 40(1):233-235.
220b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans */
221b1941c615023cab9baf0a78a28df1e3b4972434fJason EvansJEMALLOC_INLINE double
222b1941c615023cab9baf0a78a28df1e3b4972434fJason Evanspt_chi2(double p, double df, double ln_gamma_df_2)
223b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans{
224b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	double e, aa, xx, c, ch, a, q, p1, p2, t, x, b, s1, s2, s3, s4, s5, s6;
225b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	unsigned i;
226b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
227b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	assert(p >= 0.0 && p < 1.0);
228b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	assert(df > 0.0);
229b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
230b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	e = 5.0e-7;
231b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	aa = 0.6931471805;
232b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
233b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	xx = 0.5 * df;
234b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	c = xx - 1.0;
235b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
236b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	if (df < -1.24 * log(p)) {
237b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		/* Starting approximation for small Chi^2. */
238b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		ch = pow(p * xx * exp(ln_gamma_df_2 + xx * aa), 1.0 / xx);
239b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		if (ch - e < 0.0)
240b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			return (ch);
241b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	} else {
242b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		if (df > 0.32) {
243b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			x = pt_norm(p);
244b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			/*
245b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			 * Starting approximation using Wilson and Hilferty
246b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			 * estimate.
247b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			 */
248b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			p1 = 0.222222 / df;
249b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			ch = df * pow(x * sqrt(p1) + 1.0 - p1, 3.0);
250b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			/* Starting approximation for p tending to 1. */
251b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			if (ch > 2.2 * df + 6.0) {
252b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				ch = -2.0 * (log(1.0 - p) - c * log(0.5 * ch) +
253b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				    ln_gamma_df_2);
254b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			}
255b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		} else {
256b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			ch = 0.4;
257b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			a = log(1.0 - p);
258b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			while (true) {
259b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				q = ch;
260b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				p1 = 1.0 + ch * (4.67 + ch);
261b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				p2 = ch * (6.73 + ch * (6.66 + ch));
262b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				t = -0.5 + (4.67 + 2.0 * ch) / p1 - (6.73 + ch
263b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				    * (13.32 + 3.0 * ch)) / p2;
264b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				ch -= (1.0 - exp(a + ln_gamma_df_2 + 0.5 * ch +
265b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				    c * aa) * p2 / p1) / t;
266b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans				if (fabs(q / ch - 1.0) - 0.01 <= 0.0)
267b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans					break;
268b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			}
269b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		}
270b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	}
271b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
272b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	for (i = 0; i < 20; i++) {
273b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		/* Calculation of seven-term Taylor series. */
274b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		q = ch;
275b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		p1 = 0.5 * ch;
276b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		if (p1 < 0.0)
277b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			return (-1.0);
278b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		p2 = p - i_gamma(p1, xx, ln_gamma_df_2);
279b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		t = p2 * exp(xx * aa + ln_gamma_df_2 + p1 - c * log(ch));
280b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		b = t / ch;
281b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		a = 0.5 * t - b * c;
282b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		s1 = (210.0 + a * (140.0 + a * (105.0 + a * (84.0 + a * (70.0 +
283b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    60.0 * a))))) / 420.0;
284b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		s2 = (420.0 + a * (735.0 + a * (966.0 + a * (1141.0 + 1278.0 *
285b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    a)))) / 2520.0;
286b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		s3 = (210.0 + a * (462.0 + a * (707.0 + 932.0 * a))) / 2520.0;
287b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		s4 = (252.0 + a * (672.0 + 1182.0 * a) + c * (294.0 + a *
288b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    (889.0 + 1740.0 * a))) / 5040.0;
289b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		s5 = (84.0 + 264.0 * a + c * (175.0 + 606.0 * a)) / 2520.0;
290b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		s6 = (120.0 + c * (346.0 + 127.0 * c)) / 5040.0;
291b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		ch += t * (1.0 + 0.5 * t * s1 - b * c * (s1 - b * (s2 - b * (s3
292b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		    - b * (s4 - b * (s5 - b * s6))))));
293b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans		if (fabs(q / ch - 1.0) <= e)
294b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans			break;
295b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	}
296b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
297b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	return (ch);
298b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans}
299b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
300b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans/*
301b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * Given a value p in [0..1] and Gamma distribution shape and scale parameters,
302b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * compute the upper limit on the definite integeral from [0..z] that satisfies
303b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans * p.
304b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans */
305b1941c615023cab9baf0a78a28df1e3b4972434fJason EvansJEMALLOC_INLINE double
306b1941c615023cab9baf0a78a28df1e3b4972434fJason Evanspt_gamma(double p, double shape, double scale, double ln_gamma_shape)
307b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans{
308b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans
309b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans	return (pt_chi2(p, shape * 2.0, ln_gamma_shape) * 0.5 * scale);
310b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans}
311b1941c615023cab9baf0a78a28df1e3b4972434fJason Evans#endif
312