gsl_randist__binomial.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /* randist/binomial.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. #include "gsl__config.h"
  20. #include <math.h>
  21. #include "gsl_sys.h"
  22. #include "gsl_rng.h"
  23. #include "gsl_randist.h"
  24. #include "gsl_sf_gamma.h"
  25. /* The binomial distribution has the form,
  26. prob(k) = n!/(k!(n-k)!) * p^k (1-p)^(n-k) for k = 0, 1, ..., n
  27. This is the algorithm from Knuth */
  28. /* Default binomial generator is now in binomial_tpe.c */
  29. unsigned int
  30. gsl_ran_binomial_knuth (const gsl_rng * r, double p, unsigned int n)
  31. {
  32. unsigned int i, a, b, k = 0;
  33. while (n > 10) /* This parameter is tunable */
  34. {
  35. double X;
  36. a = 1 + (n / 2);
  37. b = 1 + n - a;
  38. X = gsl_ran_beta (r, (double) a, (double) b);
  39. if (X >= p)
  40. {
  41. n = a - 1;
  42. p /= X;
  43. }
  44. else
  45. {
  46. k += a;
  47. n = b - 1;
  48. p = (p - X) / (1 - X);
  49. }
  50. }
  51. for (i = 0; i < n; i++)
  52. {
  53. double u = gsl_rng_uniform (r);
  54. if (u < p)
  55. k++;
  56. }
  57. return k;
  58. }
  59. double
  60. gsl_ran_binomial_pdf (const unsigned int k, const double p,
  61. const unsigned int n)
  62. {
  63. if (k > n)
  64. {
  65. return 0;
  66. }
  67. else
  68. {
  69. double P;
  70. if (p == 0)
  71. {
  72. P = (k == 0) ? 1 : 0;
  73. }
  74. else if (p == 1)
  75. {
  76. P = (k == n) ? 1 : 0;
  77. }
  78. else
  79. {
  80. double ln_Cnk = gsl_sf_lnchoose (n, k);
  81. P = ln_Cnk + k * log (p) + (n - k) * log1p (-p);
  82. P = exp (P);
  83. }
  84. return P;
  85. }
  86. }