Blame cdf/binomial.c

Packit 67cb25
/* cdf/binomial.c
Packit 67cb25
 * 
Packit 67cb25
 * Copyright (C) 2004 Jason H. Stover.
Packit 67cb25
 * Copyright (C) 2004 Giulio Bottazzi
Packit 67cb25
 * 
Packit 67cb25
 * This program is free software; you can redistribute it and/or modify
Packit 67cb25
 * it under the terms of the GNU General Public License as published by
Packit 67cb25
 * the Free Software Foundation; either version 3 of the License, or (at
Packit 67cb25
 * your option) any later version.
Packit 67cb25
 * 
Packit 67cb25
 * This program is distributed in the hope that it will be useful, but
Packit 67cb25
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 67cb25
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 67cb25
 * General Public License for more details.
Packit 67cb25
 * 
Packit 67cb25
 * You should have received a copy of the GNU General Public License
Packit 67cb25
 * along with this program; if not, write to the Free Software
Packit 67cb25
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Packit 67cb25
 */
Packit 67cb25
Packit 67cb25
#include <config.h>
Packit 67cb25
#include <math.h>
Packit 67cb25
#include <gsl/gsl_math.h>
Packit 67cb25
#include <gsl/gsl_cdf.h>
Packit 67cb25
#include <gsl/gsl_sf_gamma.h>
Packit 67cb25
Packit 67cb25
#include "error.h"
Packit 67cb25
Packit 67cb25
/* Computes the cumulative distribution function for a binomial
Packit 67cb25
   random variable. For a binomial random variable X with n trials
Packit 67cb25
   and success probability p,
Packit 67cb25
   
Packit 67cb25
           Pr( X <= k ) = Pr( Y >= p )
Packit 67cb25
 
Packit 67cb25
   where Y is a beta random variable with parameters k+1 and n-k.
Packit 67cb25
 
Packit 67cb25
   The binomial distribution has the form,
Packit 67cb25
Packit 67cb25
   prob(k) =  n!/(k!(n-k)!) *  p^k (1-p)^(n-k) for k = 0, 1, ..., n
Packit 67cb25
Packit 67cb25
   The cumulated distributions can be expressed in terms of normalized
Packit 67cb25
   incomplete beta functions (see Abramowitz & Stegun eq. 26.5.26 and
Packit 67cb25
   eq. 6.6.3).
Packit 67cb25
Packit 67cb25
   Reference: 
Packit 67cb25
  
Packit 67cb25
   W. Feller, "An Introduction to Probability and Its
Packit 67cb25
   Applications," volume 1. Wiley, 1968. Exercise 45, page 173,
Packit 67cb25
   chapter 6.
Packit 67cb25
 */
Packit 67cb25
Packit 67cb25
#include <config.h>
Packit 67cb25
#include <math.h>
Packit 67cb25
#include <gsl/gsl_math.h>
Packit 67cb25
#include <gsl/gsl_errno.h>
Packit 67cb25
#include <gsl/gsl_cdf.h>
Packit 67cb25
Packit 67cb25
double
Packit 67cb25
gsl_cdf_binomial_P (const unsigned int k, const double p, const unsigned int n)
Packit 67cb25
{
Packit 67cb25
  double P;
Packit 67cb25
  double a;
Packit 67cb25
  double b;
Packit 67cb25
Packit 67cb25
  if (p > 1.0 || p < 0.0)
Packit 67cb25
    {
Packit 67cb25
      CDF_ERROR ("p < 0 or p > 1", GSL_EDOM);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  if (k >= n)
Packit 67cb25
    {
Packit 67cb25
      P = 1.0;
Packit 67cb25
    }
Packit 67cb25
  else
Packit 67cb25
    {
Packit 67cb25
      a = (double) k + 1.0;
Packit 67cb25
      b = (double) n - k;
Packit 67cb25
      P = gsl_cdf_beta_Q (p, a, b);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  return P;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
double
Packit 67cb25
gsl_cdf_binomial_Q (const unsigned int k, const double p, const unsigned int n)
Packit 67cb25
{
Packit 67cb25
  double Q;
Packit 67cb25
  double a;
Packit 67cb25
  double b;
Packit 67cb25
Packit 67cb25
  if (p > 1.0 || p < 0.0)
Packit 67cb25
    {
Packit 67cb25
      CDF_ERROR ("p < 0 or p > 1", GSL_EDOM);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  if (k >= n)
Packit 67cb25
    {
Packit 67cb25
      Q = 0.0;
Packit 67cb25
    }
Packit 67cb25
  else
Packit 67cb25
    {
Packit 67cb25
      a = (double) k + 1.0;
Packit 67cb25
      b = (double) n - k;
Packit 67cb25
      Q = gsl_cdf_beta_P (p, a, b);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  return Q;
Packit 67cb25
}