double normqtlQ (double prob, double mean, double var) { /* --- quantile of normal distrib. */ assert((var > 0) /* check the function arguments */ && (prob >= 0) && (prob <= 1)); if (var == 1) return mean -unitqtlP(prob); return mean -unitqtlP(prob) *sqrt(var); } /* normqtlQ() */
double GammaqtlP (double prob, double k, double theta) { /* --- quantile of Gamma distribution */ int n = 0; /* loop variable */ double x, f, a, d, dx, dp; /* buffers */ assert((k > 0) && (theta > 0) /* check the function arguments */ && (prob >= 0) && (prob <= 1)); if (prob >= 1.0) return INFINITY; if (prob <= 0.0) return 0; /* handle limiting values */ if (prob < 0.05) x = exp(logGamma(k) +log(prob) /k); else if (prob > 0.95) x = logGamma(k) -log1p(-prob); else { /* distinguish three prob. ranges */ f = unitqtlP(prob); a = sqrt(k); x = (f >= -a) ? a *f +k : k; } /* compute initial approximation */ do { /* Lagrange's interpolation */ dp = prob -GammacdfP(x, k, 1); if ((dp == 0) || (++n > 33)) break; f = Gammapdf(x, k, 1); a = 2 *fabs(dp/x); a = dx = dp /((a > f) ? a : f); d = -0.25 *((k-1)/x -1) *a*a; if (fabs(d) < fabs(a)) dx += d; if (x +dx > 0) x += dx; else x /= 2; } while (fabs(a) > 1e-10 *x); if (fabs(dp) > EPS_QTL *prob) return -1; return x *theta; /* check for convergence and */ } /* GammaqtlP() */ /* return the computed quantile */