aboutsummaryrefslogtreecommitdiff
path: root/sys/base/rng/poisson.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/base/rng/poisson.c')
-rw-r--r--sys/base/rng/poisson.c126
1 files changed, 0 insertions, 126 deletions
diff --git a/sys/base/rng/poisson.c b/sys/base/rng/poisson.c
deleted file mode 100644
index 3ec15c9..0000000
--- a/sys/base/rng/poisson.c
+++ /dev/null
@@ -1,126 +0,0 @@
-#include "internal.h"
-
-/*
- * Ahrens, J. H., & Dieter, U. (1982).
- * Computer Generation of Poisson Deviates from Modified Normal Distributions.
- */
-static double factorial[10] = {1., 1., 2., 6., 24., 120., 720., 5040., 40320., 362880.};
-static double coeffs[9] = {
- -.500000000, +.333333333, -.249999856,
- +.200011780, -.166684875, +.142187833,
- -.124196313, +.125005956, -.114265030,
-};
-
-static inline
-double
-log1pmx(double x, double off)
-{
- int i;
- double r, t;
-
- if(-0.25 < x && x < 0.25) {
- r = 0;
- t = 1;
- for(i=0;i<arrlen(coeffs);i++) {
- r += coeffs[i]*t;
- t *= x;
- }
-
- return x*x*r;
- }
- return log(1+x) - off;
-}
-
-static inline
-double
-procf(double mu, double s, int64 K, double *px, double *py, double *fx, double *fy)
-{
- double d, V, X;
- double w, b1, b2, c1, c2, c3, c0, c;
-
- w = 0.3989422804014327/s;
- b1 = 0.041666666666666664/mu;
- b2 = 0.3*b1*b1;
- c3 = 0.14285714285714285*b1*b2;
- c2 = b2 - 15.*c3;
- c1 = b1 - 6.*b2 + 45.*c3;
- c0 = 1 - b1 + 3.*b2 - 15.*c3;
- c = .1069/mu;
-
- if(K < 10) {
- *px = -mu;
- *py = pow(mu,K) / factorial[K];
- }else{
- d = 0.08333333333333333/K;
- d = d - 4.8*d*d*d;
- V = (mu - K) / K;
-
- *px = K*log1pmx(V,mu-K) - d;
- *py = 0.3989422804014327/sqrt(K);
- }
-
- X = (K - mu + 0.5)/s;
- *fx = -0.5*X*X;
- *fy = w*(((c3*X*X + c2)*X*X + c1)*X*X + c0);
-
- return c;
-}
-
-static inline
-uint64
-bigpoisson(double mu)
-{
- int64 L,K;
- double G,s,d,U,E,T;
- double px,py,fx,fy,c;
-
- s = sqrt(mu);
- d = 6*mu*mu;
- L = floor(mu - 1.1484);
-
-stepN:
- G = mu + s*rng·normal();
- K = floor(G);
- if(K<0)
- goto stepP;
-stepI:
- if(K>=L)
- return K;
-stepS:
- U = rng·random();
- if(d*U >= (mu-K)*(mu-K)*(mu-K))
- return K;
-stepP:
- if(G < 0)
- goto stepE;
-stepQ:
- c = procf(mu, s, K, &px, &py, &fx, &fy);
-stepE:
- E = rng·exponential(1.0);
- U = rng·random();
- U = U + U - 1;
- T = 1.8 + copysign(E,U);
- if(T < 0.6744)
- goto stepE;
- K = floor(mu + s*T);
- c = procf(mu, s, K, &px, &py, &fx, &fy);
-stepH:
- if(c*fabs(U) > (py*exp(px + E) - fy*exp(fx + E)))
- goto stepE;
- return K;
-}
-
-uint64
-rng·poisson(double mean)
-{
- int64 n;
- double z;
-
- if(mean<10.0) {
- for(n=0, z=rng·exponential(1.0); z<mean; ++n, z+=rng·exponential(1.0))
- ;
- return n;
- }
-
- return bigpoisson(mean);
-}