[go: up one dir, main page]

Menu

[9bd658]: / src / Common / prob.cc  Maximize  Restore  History

Download this file

102 lines (79 with data), 2.5 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
// A. L. Delcher
//
// File: prob.cc
//
// Last Modified: 30 December 2002
//
// Routines to do probability things
#include "prob.hh"
int Binomial_Cutoff
(int n, double p, double e_prob)
// Return k such that the probability of >= k successes in
// n trials is < e_prob , where p is the probability
// of success of each trial.
{
double lambda, target, sum, term, q;
int i;
if (n <= 0)
{
sprintf (Clean_Exit_Msg_Line, "ERROR: n = %d <= 0", n);
Clean_Exit (Clean_Exit_Msg_Line, __FILE__, __LINE__);
}
lambda = n * p;
q = 1.0 - p;
if (Verbose > 3)
fprintf (stderr, "Binomial Cutoff: n = %d p = %e lambda = %e\n",
n, p, lambda);
if (n >= 30.0)
{
if (lambda <= 5.0)
{
// use Poisson approximation
if (Verbose > 4)
fprintf (stderr, "Binomial Cutoff: using Poisson approximation\n");
target = (1.0 - e_prob) * exp (lambda);
sum = term = 1.0;
for (i = 1; sum <= target && i < 50; i ++)
{
term = term * lambda / (double) i;
sum += term;
}
if (sum <= target)
fprintf (stderr, "Binomial Cutoff: sum <= target... Is this a problem?\n");
}
else // lambda > 5.0
{
// use Normal approximation
if (Verbose > 4)
fprintf (stderr, "Binomial Cutoff: using Normal approximation\n");
double t, x, y;
if (e_prob <= 0.5)
t = sqrt (- 2.0 * log (e_prob));
else
t = sqrt (- 2.0 * log ((1.0 - e_prob)));
y = t - (((0.010328 * t + 0.802853) * t + 2.515517)
/
(((0.001308 * t + 0.189269) * t + 1.432788) * t + 1.0));
if (e_prob <= 0.5)
x = y;
else
x = -y;
i = int (ceil (x * sqrt (lambda * q) + lambda));
}
}
else
{
// brute force
if (Verbose > 4)
fprintf (stderr, "Binomial Cutoff: using brute force method\n");
target = 1.0 - e_prob;
sum = term = pow (q, n);
for (i = 1; sum <= target && i < n; i ++)
{
term *= double (n + 1 - i) / i;
term *= p / q;
sum += term;
}
}
return i;
}