-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLRpoisson.c
136 lines (113 loc) · 2.7 KB
/
LRpoisson.c
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*!
\file LRpoisson.c
\brief The Poisson distribution with rate \e p > 0.
The pseudo-random numbers are distributed from the Poisson distribution,
which is a discrete distribution describing the number of events
occurring in a fixed interval of time.
The attribute \e p is greater than zero and represents the "rate"
of events per unit interval
(and need not be integer).
Therefore, \e p is the mean number of events per unit interval.
\manonly
PDF(k) = p^k * exp(-p) / k!
CDF(k) = exp(-p) * sum_(n=0)^(k) p^n / n!
\endmanonly
\f{eqnarray*}{
\mbox{PDF}(k) &=
\left\{ \begin{array}{ll}
0, & k < 0 \\
\frac{p^k e^{-p}}{k!}, & 0 \le k .
\end{array} \right.
\\
\\
\mbox{CDF}(k) &=
\left\{ \begin{array}{ll}
0, & k < 0 \\
e^{-p} \sum_{n=0}^{k} \frac{p^n}{n!} , & 0 \le k .
\end{array} \right.
\f}
The default is \f$ p = 1 \f$ and \em q will be set to \f$ e^{-p} \f$
for calculation efficiency.
Do not set \e q when declaring this distribution.
\see LRerlang.c LRnexp.c
\image html PoissonDistribution.png
\image latex PoissonDistribution.eps "Poisson Distribution"
The plots show the distribution functions as continuous only to
visually connect adjacent values but are actually discrete.
*/
/*
* Copyright 2019 R.K. Owen, Ph.D.
* License see lgpl.md (Gnu Lesser General Public License)
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <math.h>
#include "libran.h"
/* int */
/*!
@brief LRi_poisson_RAN(LR_obj *o) - int Poisson distributed variate.
Default values: scale m = 1.
@param o LR_obj object
@return int
*/
int LRi_poisson_RAN(LR_obj *o) {
float zero = 0.0, one = 1.0, u, p = one;
int kk = 0;
if (isnan(o->q))
o->q = expf(-o->p);
do {
do {
u = o->uf(o);
} while (u == zero);
kk++;
p *= u;
} while (p > o->q);
return kk - 1;
}
/*!
@brief LRi_poisson_PDF(LR_obj *o, int x) - Poisson
probablity (or mass) distribution function
@param o LR_obj object
@param x value
@return float PDF at x
*/
float LRi_poisson_PDF(LR_obj *o, int x) {
float zero = 0.0, one = 1.0, p = one;
if (isnan(o->q))
o->q = expf(- o->p);
if (x < 0) return zero;
if (x == 0) {
return o->q;
} else {
for (int nn = 1; nn <= x; nn++) {
p *= (o->p/nn);
}
return p * o->q;
}
}
/*!
@brief LRi_poisson_CDF(LR_obj *o, int x) - Poisson distribution
cumulative distribution function
@param o LR_obj object
@param x value
@return float CDF at x
*/
float LRi_poisson_CDF(LR_obj *o, int x) {
float zero = 0.0, one = 1.0, p = one, s = one;
if (isnan(o->q))
o->q = expf(- o->p);
if (x < 0) return zero;
if (x == 0) {
return o->q;
} else {
for (int nn = 1; nn <= x; nn++) {
p *= (o->p/nn);
s += p;
}
return s * o->q;
}
}
#ifdef __cplusplus
}
#endif