3 * Copyright (C) 2003, 2007 Brian Gough
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22 #include <gsl/gsl_cdf.h>
23 #include <gsl/gsl_math.h>
24 #include <gsl/gsl_randist.h>
25 #include <gsl/gsl_sf_gamma.h>
30 gsl_cdf_gamma_Pinv (const double P, const double a, const double b)
43 /* Consider, small, large and intermediate cases separately. The
44 boundaries at 0.05 and 0.95 have not been optimised, but seem ok
45 for an initial approximation. */
49 double x0 = exp ((gsl_sf_lngamma (a) + log (P)) / a);
54 double x0 = -log1p (-P) + gsl_sf_lngamma (a);
59 double xg = gsl_cdf_ugaussian_Pinv (P);
60 double x0 = (xg < -sqrt (a)) ? a : sqrt (a) * xg + a;
64 /* Use Lagrange's interpolation for E(x)/phi(x0) to work backwards
65 to an improved value of x (Abramowitz & Stegun, 3.6.6)
67 where E(x)=P-integ(phi(u),u,x0,x) and phi(u) is the pdf.
71 double lambda, dP, phi;
75 dP = P - gsl_cdf_gamma_P (x, a, 1.0);
76 phi = gsl_ran_gamma_pdf (x, a, 1.0);
78 if (dP == 0.0 || n++ > 32)
81 lambda = dP / GSL_MAX (2 * fabs (dP / x), phi);
84 double step0 = lambda;
85 double step1 = -((a - 1) / x - 1) * lambda * lambda / 4.0;
88 if (fabs (step1) < fabs (step0))
98 if (fabs (step0) > 1e-10 * x)
103 if (fabs(dP) > GSL_SQRT_DBL_EPSILON * P)
105 GSL_ERROR_VAL("inverse failed to converge", GSL_EFAILED, GSL_NAN);
113 gsl_cdf_gamma_Qinv (const double Q, const double a, const double b)
126 /* Consider, small, large and intermediate cases separately. The
127 boundaries at 0.05 and 0.95 have not been optimised, but seem ok
128 for an initial approximation. */
132 double x0 = -log (Q) + gsl_sf_lngamma (a);
137 double x0 = exp ((gsl_sf_lngamma (a) + log1p (-Q)) / a);
142 double xg = gsl_cdf_ugaussian_Qinv (Q);
143 double x0 = (xg < -sqrt (a)) ? a : sqrt (a) * xg + a;
147 /* Use Lagrange's interpolation for E(x)/phi(x0) to work backwards
148 to an improved value of x (Abramowitz & Stegun, 3.6.6)
150 where E(x)=P-integ(phi(u),u,x0,x) and phi(u) is the pdf.
154 double lambda, dQ, phi;
158 dQ = Q - gsl_cdf_gamma_Q (x, a, 1.0);
159 phi = gsl_ran_gamma_pdf (x, a, 1.0);
161 if (dQ == 0.0 || n++ > 32)
164 lambda = -dQ / GSL_MAX (2 * fabs (dQ / x), phi);
167 double step0 = lambda;
168 double step1 = -((a - 1) / x - 1) * lambda * lambda / 4.0;
171 if (fabs (step1) < fabs (step0))
181 if (fabs (step0) > 1e-10 * x)