Yup, this is a problem. When I compile and run your program gsl_invBeta.c (which should #include <gsl/gsl_cdf.h>), I get:
Observed: gsl: betainv.c:181: <http://git.savannah.gnu.org/cgit/gsl.git/tree/cdf/betainv.c#n181> ERROR: inverse failed to converge Default GSL error handler invoked. Abort trap: 6 Expected result: 1.0 Result with more precision: 0.99999999999999999999999999980178072518730245884823... For the supplied values of alpha and beta, the CDF rises very steeply near 1 and the inverse CDF is equal to 1.0 within double precision when P>0.5 (that may not be a tight bound, but is a sufficient condition). Generic workaround: #include <stdio.h> #include <gsl/gsl_sf_gamma.h> // Computes the inverse function of gsl_sf_beta_inc by binary search. double qbeta(double p, double a, double b) { double x = 0.5; for (double delta = 0.25; delta > 0; delta /= 2) { const double beta_P = gsl_sf_beta_inc(a, b, x); const double new_x = p > beta_P ? x + delta : x - delta; if (beta_P == p || x == new_x) break; x = new_x; } return x; } int main() { double a = 5.3729222; double b = 0.018122864; double p = 0.67276126; printf("%.18g\n", qbeta(p, a, b)); printf("%.7g (expected: 0.25)\n", qbeta(0.25, 1, 1)); printf("%.7g (expected: 0.9922861)\n", qbeta(0.25, 5, 0.1)); printf("%.7g (expected: 2.954261e-200)\n", qbeta(1e-50, 0.25, 0.5)); return 0; } Hope this helps, -- mj On Fri, Jan 10, 2020 at 1:30 AM Vasu Jaganath <vadie.develo...@gmail.com> wrote: > Martin and others, > > Following up, I have a particular example for which both Q and P variants > of inverse functions fail. > > where as scipy beta.ppf (equivalent to gsl_cdf_beta_Pinv) does the right > thing and converges to 1 or nearest double. > > I am attaching a very simple example with exact same data, the gsl > function fails where as scipy function does the right thing. > > Any thoughts? any workarounds? Maybe there is a way I can specify > convergence criteria? > > Thanks, > Vasu > > > On Wed, Jan 8, 2020 at 12:42 PM Vasu Jaganath <vadie.develo...@gmail.com> > wrote: > >> Thanks Martin, >> >> I will test it out. >> >> On Tue, Jan 7, 2020 at 11:16 PM Martin Jansche <mjans...@gmail.com> >> wrote: >> >>> There are many more floating point values between 0.0 and 0.001 than >>> there are between 0.999 and 1.0. The difference between 1.0 and the next >>> smaller double value is only around 1e-16, but the next larger double value >>> after 0.0 is about 1e-303. So beta_P(0.9, 1, 17) will be necessarily >>> equivalent to 1.0 due to lack of precision, whereas beta_Q(0.9, 1, 17) will >>> be 1e-17. (Haven't tried this in GSL. You may want to try and report back.) >>> >>> On Wed, Jan 8, 2020 at 1:35 AM Vasu Jaganath <vadie.develo...@gmail.com> >>> wrote: >>> >>>> Hi all, >>>> >>>> This is probably a very silly question, >>>> >>>> I don't understand why there are two separate P and Q variants for >>>> CDFs? >>>> particularly for beta distribution? >>>> >>>> >>>> https://www.gnu.org/software/gsl/doc/html/randist.html#the-beta-distribution >>>> >>>> Thanks, >>>> Vasu >>>> >>>