Added MACS source
[htsworkflow.git] / htswanalysis / MACS / lib / gsl / gsl-1.11 / randist / fdist.c
1 /* randist/fdist.c
2  * 
3  * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough
4  * 
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.
9  * 
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.
14  * 
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 #include <config.h>
21 #include <math.h>
22 #include <gsl/gsl_sf_gamma.h>
23 #include <gsl/gsl_rng.h>
24 #include <gsl/gsl_randist.h>
25
26 /* The F distribution has the form
27
28    p(x) dx = (nu1^(nu1/2) nu2^(nu2/2) Gamma((nu1 + nu2)/2) /
29    Gamma(nu1/2) Gamma(nu2/2)) *
30    x^(nu1/2 - 1) (nu2 + nu1 * x)^(-nu1/2 -nu2/2) dx
31
32    The method used here is the one described in Knuth */
33
34 double
35 gsl_ran_fdist (const gsl_rng * r, const double nu1, const double nu2)
36 {
37
38   double Y1 =  gsl_ran_gamma (r, nu1 / 2, 2.0);
39   double Y2 =  gsl_ran_gamma (r, nu2 / 2, 2.0);
40
41   double f = (Y1 * nu2) / (Y2 * nu1);
42
43   return f;
44 }
45
46 double
47 gsl_ran_fdist_pdf (const double x, const double nu1, const double nu2)
48 {
49   if (x < 0)
50     {
51       return 0 ;
52     }
53   else
54     {
55       double p;
56       double lglg = (nu1 / 2) * log (nu1) + (nu2 / 2) * log (nu2) ;
57
58       double lg12 = gsl_sf_lngamma ((nu1 + nu2) / 2);
59       double lg1 = gsl_sf_lngamma (nu1 / 2);
60       double lg2 = gsl_sf_lngamma (nu2 / 2);
61       
62       p = exp (lglg + lg12 - lg1 - lg2)
63         * pow (x, nu1 / 2 - 1) * pow (nu2 + nu1 * x, -nu1 / 2 - nu2 / 2);
64       
65       return p;
66     }
67 }