/* * Copyright (C) 1994. James Darrell McCauley. (darrell@mccauley-usa.com) * http://mccauley-usa.com/ * * This program is free software under the GPL (>=v2) * Read the file GPL.TXT coming with GRASS for details. */ #include #include #include "zufall.h" /*-Poisson generator for distribution function of p's: * q(mu,p) = exp(-mu) mu**p/p! */ int fische (int n, double *mu, int *p) { int left, indx[1024], i, k, nsegs, p0, ii, jj, nl0; double q[1024], u[1024], q0, pmu; --p; if (n <= 0) return 0; pmu = exp (-(*mu)); p0 = 0; nsegs = (n - 1) / 1024; left = n - (nsegs << 10); ++nsegs; nl0 = left; for (k = 1; k <= nsegs; ++k) { for (i = 1; i <= left; ++i) { indx[i - 1] = i; p[p0 + i] = 0; q[i - 1] = 1.0; } do /* Begin iterative loop on segment of p's */ { zufall (left, u); /* Get the needed uniforms */ jj = 0; for (i = 1; i <= left; ++i) { ii = indx[i - 1]; q0 = q[ii - 1] * u[i - 1]; q[ii - 1] = q0; if (q0 > pmu) { indx[jj++] = ii; ++p[p0 + ii]; } } left = jj; /* any left in this segment? */ } while (left > 0); p0 += nl0; nl0 = left = 1024; } return 0; } /* fische */