GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
randpoisson.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2006-2017 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 /* Original version written by Paul Kienzle distributed as free
24  software in the in the public domain. */
25 
26 /* Needs the following defines:
27  * NAN: value to return for Not-A-Number
28  * RUNI: uniform generator on (0,1)
29  * RNOR: normal generator
30  * LGAMMA: log gamma function
31  * INFINITE: function to test whether a value is infinite
32  */
33 
34 #if defined (HAVE_CONFIG_H)
35 # include "config.h"
36 #endif
37 
38 #include "f77-fcn.h"
39 #include "lo-error.h"
40 #include "lo-ieee.h"
41 #include "lo-math.h"
42 #include "lo-slatec-proto.h"
43 #include "randmtzig.h"
44 #include "randpoisson.h"
45 
46 #undef INFINITE
47 #define INFINITE lo_ieee_isinf
48 #define RUNI oct_randu()
49 #define RNOR oct_randn()
50 #define LGAMMA xlgamma
51 
52 static double
53 xlgamma (double x)
54 {
55  double result;
56 #if defined (HAVE_LGAMMA)
57  result = lgamma (x);
58 #else
59  double sgngam;
60 
61  if (lo_ieee_isnan (x))
62  result = x;
63  else if (x <= 0 || lo_ieee_isinf (x))
64  result = octave_Inf;
65  else
66  F77_XFCN (dlgams, DLGAMS, (&x, &result, &sgngam));
67 #endif
68  return result;
69 }
70 
71 /* ---- pprsc.c from Stadloeber's winrand --- */
72 
73 /* flogfak(k) = ln(k!) */
74 static double
75 flogfak (double k)
76 {
77 #define C0 9.18938533204672742e-01
78 #define C1 8.33333333333333333e-02
79 #define C3 -2.77777777777777778e-03
80 #define C5 7.93650793650793651e-04
81 #define C7 -5.95238095238095238e-04
82 
83  static double logfak[30L] =
84  {
85  0.00000000000000000, 0.00000000000000000, 0.69314718055994531,
86  1.79175946922805500, 3.17805383034794562, 4.78749174278204599,
87  6.57925121201010100, 8.52516136106541430, 10.60460290274525023,
88  12.80182748008146961, 15.10441257307551530, 17.50230784587388584,
89  19.98721449566188615, 22.55216385312342289, 25.19122118273868150,
90  27.89927138384089157, 30.67186010608067280, 33.50507345013688888,
91  36.39544520803305358, 39.33988418719949404, 42.33561646075348503,
92  45.38013889847690803, 48.47118135183522388, 51.60667556776437357,
93  54.78472939811231919, 58.00360522298051994, 61.26170176100200198,
94  64.55753862700633106, 67.88974313718153498, 71.25703896716800901
95  };
96 
97  double r, rr;
98 
99  if (k >= 30.0)
100  {
101  r = 1.0 / k;
102  rr = r * r;
103  return ((k + 0.5)*std::log (k) - k + C0 + r*(C1 + rr*(C3 + rr*(C5 + rr*C7))));
104  }
105  else
106  return (logfak[static_cast<int> (k)]);
107 }
108 
109 /******************************************************************
110  * *
111  * Poisson Distribution - Patchwork Rejection/Inversion *
112  * *
113  ******************************************************************
114  * *
115  * For parameter my < 10, Tabulated Inversion is applied. *
116  * For my >= 10, Patchwork Rejection is employed: *
117  * The area below the histogram function f(x) is rearranged in *
118  * its body by certain point reflections. Within a large center *
119  * interval variates are sampled efficiently by rejection from *
120  * uniform hats. Rectangular immediate acceptance regions speed *
121  * up the generation. The remaining tails are covered by *
122  * exponential functions. *
123  * *
124  ******************************************************************
125  * *
126  * FUNCTION : - pprsc samples a random number from the Poisson *
127  * distribution with parameter my > 0. *
128  * REFERENCE : - H. Zechner (1994): Efficient sampling from *
129  * continuous and discrete unimodal distributions, *
130  * Doctoral Dissertation, 156 pp., Technical *
131  * University Graz, Austria. *
132  * SUBPROGRAM : - drand(seed) ... (0,1)-Uniform generator with *
133  * unsigned long integer *seed. *
134  * *
135  * Implemented by H. Zechner, January 1994 *
136  * Revised by F. Niederl, July 1994 *
137  * *
138  ******************************************************************/
139 
140 static double
141 f (double k, double l_nu, double c_pm)
142 {
143  return exp (k * l_nu - flogfak (k) - c_pm);
144 }
145 
146 static double
147 pprsc (double my)
148 {
149  static double my_last = -1.0;
150  static double m, k2, k4, k1, k5;
151  static double dl, dr, r1, r2, r4, r5, ll, lr, l_my, c_pm,
152  f1, f2, f4, f5, p1, p2, p3, p4, p5, p6;
153  double Dk, X, Y;
154  double Ds, U, V, W;
155 
156  if (my != my_last)
157  { /* set-up */
158  my_last = my;
159  /* approximate deviation of reflection points k2, k4 from my - 1/2 */
160  Ds = sqrt (my + 0.25);
161 
162  /* mode m, reflection points k2 and k4, and points k1 and k5, */
163  /* which delimit the centre region of h(x) */
164  m = std::floor (my);
165  k2 = ceil (my - 0.5 - Ds);
166  k4 = std::floor (my - 0.5 + Ds);
167  k1 = k2 + k2 - m + 1L;
168  k5 = k4 + k4 - m;
169 
170  /* range width of the critical left and right centre region */
171  dl = (k2 - k1);
172  dr = (k5 - k4);
173 
174  /* recurrence constants r(k)=p(k)/p(k-1) at k = k1, k2, k4+1, k5+1 */
175  r1 = my / k1;
176  r2 = my / k2;
177  r4 = my / (k4 + 1.0);
178  r5 = my / (k5 + 1.0);
179 
180  /* reciprocal values of the scale parameters of exp. tail envelope */
181  ll = std::log (r1); /* expon. tail left */
182  lr = -std::log (r5); /* expon. tail right*/
183 
184  /* Poisson constants, necessary for computing function values f(k) */
185  l_my = std::log (my);
186  c_pm = m * l_my - flogfak (m);
187 
188  /* function values f(k) = p(k)/p(m) at k = k2, k4, k1, k5 */
189  f2 = f (k2, l_my, c_pm);
190  f4 = f (k4, l_my, c_pm);
191  f1 = f (k1, l_my, c_pm);
192  f5 = f (k5, l_my, c_pm);
193 
194  /* area of the two centre and the two exponential tail regions */
195  /* area of the two immediate acceptance regions between k2, k4 */
196  p1 = f2 * (dl + 1.0); /* immed. left */
197  p2 = f2 * dl + p1; /* centre left */
198  p3 = f4 * (dr + 1.0) + p2; /* immed. right */
199  p4 = f4 * dr + p3; /* centre right */
200  p5 = f1 / ll + p4; /* exp. tail left */
201  p6 = f5 / lr + p5; /* exp. tail right*/
202  }
203 
204  for (;;)
205  {
206  /* generate uniform number U -- U(0, p6) */
207  /* case distinction corresponding to U */
208  if ((U = RUNI * p6) < p2)
209  { /* centre left */
210 
211  /* immediate acceptance region
212  R2 = [k2, m) *[0, f2), X = k2, ... m -1 */
213  if ((V = U - p1) < 0.0) return (k2 + std::floor (U/f2));
214  /* immediate acceptance region
215  R1 = [k1, k2)*[0, f1), X = k1, ... k2-1 */
216  if ((W = V / dl) < f1 ) return (k1 + std::floor (V/f1));
217 
218  /* computation of candidate X < k2, and its counterpart Y > k2 */
219  /* either squeeze-acceptance of X or acceptance-rejection of Y */
220  Dk = std::floor (dl * RUNI) + 1.0;
221  if (W <= f2 - Dk * (f2 - f2/r2))
222  { /* quick accept of */
223  return (k2 - Dk); /* X = k2 - Dk */
224  }
225  if ((V = f2 + f2 - W) < 1.0)
226  { /* quick reject of Y*/
227  Y = k2 + Dk;
228  if (V <= f2 + Dk * (1.0 - f2)/(dl + 1.0))
229  { /* quick accept of */
230  return (Y); /* Y = k2 + Dk */
231  }
232  if (V <= f (Y, l_my, c_pm)) return (Y); /* final accept of Y*/
233  }
234  X = k2 - Dk;
235  }
236  else if (U < p4)
237  { /* centre right */
238  /* immediate acceptance region
239  R3 = [m, k4+1)*[0, f4), X = m, ... k4 */
240  if ((V = U - p3) < 0.0) return (k4 - std::floor ((U - p2)/f4));
241  /* immediate acceptance region
242  R4 = [k4+1, k5+1)*[0, f5) */
243  if ((W = V / dr) < f5 ) return (k5 - std::floor (V/f5));
244 
245  /* computation of candidate X > k4, and its counterpart Y < k4 */
246  /* either squeeze-acceptance of X or acceptance-rejection of Y */
247  Dk = std::floor (dr * RUNI) + 1.0;
248  if (W <= f4 - Dk * (f4 - f4*r4))
249  { /* quick accept of */
250  return (k4 + Dk); /* X = k4 + Dk */
251  }
252  if ((V = f4 + f4 - W) < 1.0)
253  { /* quick reject of Y*/
254  Y = k4 - Dk;
255  if (V <= f4 + Dk * (1.0 - f4)/ dr)
256  { /* quick accept of */
257  return (Y); /* Y = k4 - Dk */
258  }
259  if (V <= f (Y, l_my, c_pm)) return (Y); /* final accept of Y*/
260  }
261  X = k4 + Dk;
262  }
263  else
264  {
265  W = RUNI;
266  if (U < p5)
267  { /* expon. tail left */
268  Dk = std::floor (1.0 - std::log (W)/ll);
269  if ((X = k1 - Dk) < 0L) continue; /* 0 <= X <= k1 - 1 */
270  W *= (U - p4) * ll; /* W -- U(0, h(x)) */
271  if (W <= f1 - Dk * (f1 - f1/r1))
272  return (X); /* quick accept of X*/
273  }
274  else
275  { /* expon. tail right*/
276  Dk = std::floor (1.0 - std::log (W)/lr);
277  X = k5 + Dk; /* X >= k5 + 1 */
278  W *= (U - p5) * lr; /* W -- U(0, h(x)) */
279  if (W <= f5 - Dk * (f5 - f5*r5))
280  return (X); /* quick accept of X*/
281  }
282  }
283 
284  /* acceptance-rejection test of candidate X from the original area */
285  /* test, whether W <= f(k), with W = U*h(x) and U -- U(0, 1)*/
286  /* log f(X) = (X - m)*log(my) - log X! + log m! */
287  if (std::log (W) <= X * l_my - flogfak (X) - c_pm) return (X);
288  }
289 }
290 /* ---- pprsc.c end ------ */
291 
292 /* The remainder of the file is by Paul Kienzle */
293 
294 /* Given uniform u, find x such that CDF(L,x)==u. Return x. */
295 static void
296 poisson_cdf_lookup (double lambda, double *p, size_t n)
297 {
298  /* Table size is predicated on the maximum value of lambda
299  * we want to store in the table, and the maximum value of
300  * returned by the uniform random number generator on [0,1).
301  * With lambda==10 and u_max = 1 - 1/(2^32+1), we
302  * have poisson_pdf(lambda,36) < 1-u_max. If instead our
303  * generator uses more bits of mantissa or returns a value
304  * in the range [0,1], then for lambda==10 we need a table
305  * size of 46 instead. For long doubles, the table size
306  * will need to be longer still. */
307 #define TABLESIZE 46
308  double t[TABLESIZE];
309 
310  /* Precompute the table for the u up to and including 0.458.
311  * We will almost certainly need it. */
312  int intlambda = static_cast<int> (std::floor (lambda));
313  double P;
314  int tableidx;
315  size_t i = n;
316 
317  t[0] = P = exp (-lambda);
318  for (tableidx = 1; tableidx <= intlambda; tableidx++)
319  {
320  P = P*lambda/static_cast<double> (tableidx);
321  t[tableidx] = t[tableidx-1] + P;
322  }
323 
324  while (i-- > 0)
325  {
326  double u = RUNI;
327 
328  /* If u > 0.458 we know we can jump to floor(lambda) before
329  * comparing (this observation is based on Stadlober's winrand
330  * code). For lambda >= 1, this will be a win. Lambda < 1
331  * is already fast, so adding an extra comparison is not a
332  * problem. */
333  int k = (u > 0.458 ? intlambda : 0);
334 
335  /* We aren't using a for loop here because when we find the
336  * right k we want to jump to the next iteration of the
337  * outer loop, and the continue statement will only work for
338  * the inner loop. */
339  nextk:
340  if (u <= t[k])
341  {
342  p[i] = static_cast<double> (k);
343  continue;
344  }
345  if (++k < tableidx)
346  goto nextk;
347 
348  /* We only need high values of the table very rarely so we
349  * don't automatically compute the entire table. */
350  while (tableidx < TABLESIZE)
351  {
352  P = P*lambda/static_cast<double> (tableidx);
353  t[tableidx] = t[tableidx-1] + P;
354  /* Make sure we converge to 1.0 just in case u is uniform
355  * on [0,1] rather than [0,1). */
356  if (t[tableidx] == t[tableidx-1]) t[tableidx] = 1.0;
357  tableidx++;
358  if (u <= t[tableidx-1]) break;
359  }
360 
361  /* We are assuming that the table size is big enough here.
362  * This should be true even if RUNI is returning values in
363  * the range [0,1] rather than [0,1). */
364  p[i] = static_cast<double> (tableidx-1);
365  }
366 }
367 
368 static void
369 poisson_cdf_lookup_float (double lambda, float *p, size_t n)
370 {
371  double t[TABLESIZE];
372 
373  /* Precompute the table for the u up to and including 0.458.
374  * We will almost certainly need it. */
375  int intlambda = static_cast<int> (std::floor (lambda));
376  double P;
377  int tableidx;
378  size_t i = n;
379 
380  t[0] = P = exp (-lambda);
381  for (tableidx = 1; tableidx <= intlambda; tableidx++)
382  {
383  P = P*lambda/static_cast<double> (tableidx);
384  t[tableidx] = t[tableidx-1] + P;
385  }
386 
387  while (i-- > 0)
388  {
389  double u = RUNI;
390  int k = (u > 0.458 ? intlambda : 0);
391  nextk:
392  if (u <= t[k])
393  {
394  p[i] = static_cast<float> (k);
395  continue;
396  }
397  if (++k < tableidx)
398  goto nextk;
399 
400  while (tableidx < TABLESIZE)
401  {
402  P = P*lambda/static_cast<double> (tableidx);
403  t[tableidx] = t[tableidx-1] + P;
404  if (t[tableidx] == t[tableidx-1]) t[tableidx] = 1.0;
405  tableidx++;
406  if (u <= t[tableidx-1]) break;
407  }
408 
409  p[i] = static_cast<float> (tableidx-1);
410  }
411 }
412 
413 /* From Press, et al., Numerical Recipes */
414 static void
415 poisson_rejection (double lambda, double *p, size_t n)
416 {
417  double sq = sqrt (2.0*lambda);
418  double alxm = std::log (lambda);
419  double g = lambda*alxm - LGAMMA(lambda+1.0);
420  size_t i;
421 
422  for (i = 0; i < n; i++)
423  {
424  double y, em, t;
425  do
426  {
427  do
428  {
429  y = tan (M_PI*RUNI);
430  em = sq * y + lambda;
431  } while (em < 0.0);
432  em = std::floor (em);
433  t = 0.9*(1.0+y*y)*exp (em*alxm-flogfak (em)-g);
434  } while (RUNI > t);
435  p[i] = em;
436  }
437 }
438 
439 /* From Press, et al., Numerical Recipes */
440 static void
441 poisson_rejection_float (double lambda, float *p, size_t n)
442 {
443  double sq = sqrt (2.0*lambda);
444  double alxm = std::log (lambda);
445  double g = lambda*alxm - LGAMMA(lambda+1.0);
446  size_t i;
447 
448  for (i = 0; i < n; i++)
449  {
450  double y, em, t;
451  do
452  {
453  do
454  {
455  y = tan (M_PI*RUNI);
456  em = sq * y + lambda;
457  } while (em < 0.0);
458  em = std::floor (em);
459  t = 0.9*(1.0+y*y)*exp (em*alxm-flogfak (em)-g);
460  } while (RUNI > t);
461  p[i] = em;
462  }
463 }
464 
465 /* The cutoff of L <= 1e8 in the following two functions before using
466  * the normal approximation is based on:
467  * > L=1e8; x=floor(linspace(0,2*L,1000));
468  * > max(abs(normal_pdf(x,L,L)-poisson_pdf(x,L)))
469  * ans = 1.1376e-28
470  * For L=1e7, the max is around 1e-9, which is within the step size of RUNI.
471  * For L>1e10 the pprsc function breaks down, as I saw from the histogram
472  * of a large sample, so 1e8 is both small enough and large enough. */
473 
474 /* Generate a set of poisson numbers with the same distribution */
475 void
476 oct_fill_randp (double L, octave_idx_type n, double *p)
477 {
479  if (L < 0.0 || INFINITE(L))
480  {
481  for (i=0; i<n; i++)
483  }
484  else if (L <= 10.0)
485  {
486  poisson_cdf_lookup (L, p, n);
487  }
488  else if (L <= 1e8)
489  {
490  for (i=0; i<n; i++)
491  p[i] = pprsc (L);
492  }
493  else
494  {
495  /* normal approximation: from Phys. Rev. D (1994) v50 p1284 */
496  const double sqrtL = sqrt (L);
497  for (i = 0; i < n; i++)
498  {
499  p[i] = std::floor (RNOR*sqrtL + L + 0.5);
500  if (p[i] < 0.0)
501  p[i] = 0.0; /* will probably never happen */
502  }
503  }
504 }
505 
506 /* Generate one poisson variate */
507 double
508 oct_randp (double L)
509 {
510  double ret;
511  if (L < 0.0) ret = octave::numeric_limits<double>::NaN ();
512  else if (L <= 12.0)
513  {
514  /* From Press, et al. Numerical recipes */
515  double g = exp (-L);
516  int em = -1;
517  double t = 1.0;
518  do
519  {
520  ++em;
521  t *= RUNI;
522  } while (t > g);
523  ret = em;
524  }
525  else if (L <= 1e8)
526  {
527  /* numerical recipes */
528  poisson_rejection (L, &ret, 1);
529  }
530  else if (INFINITE(L))
531  {
532  /* FIXME: R uses NaN, but the normal approximation suggests that
533  * limit should be Inf. Which is correct? */
535  }
536  else
537  {
538  /* normal approximation: from Phys. Rev. D (1994) v50 p1284 */
539  ret = std::floor (RNOR*sqrt (L) + L + 0.5);
540  if (ret < 0.0) ret = 0.0; /* will probably never happen */
541  }
542  return ret;
543 }
544 
545 /* Generate a set of poisson numbers with the same distribution */
546 void
548 {
549  double L = FL;
551  if (L < 0.0 || INFINITE(L))
552  {
553  for (i=0; i<n; i++)
555  }
556  else if (L <= 10.0)
557  {
558  poisson_cdf_lookup_float (L, p, n);
559  }
560  else if (L <= 1e8)
561  {
562  for (i=0; i<n; i++)
563  p[i] = pprsc (L);
564  }
565  else
566  {
567  /* normal approximation: from Phys. Rev. D (1994) v50 p1284 */
568  const double sqrtL = sqrt (L);
569  for (i = 0; i < n; i++)
570  {
571  p[i] = std::floor (RNOR*sqrtL + L + 0.5);
572  if (p[i] < 0.0)
573  p[i] = 0.0; /* will probably never happen */
574  }
575  }
576 }
577 
578 /* Generate one poisson variate */
579 float
580 oct_float_randp (float FL)
581 {
582  double L = FL;
583  float ret;
584  if (L < 0.0) ret = octave::numeric_limits<float>::NaN ();
585  else if (L <= 12.0)
586  {
587  /* From Press, et al. Numerical recipes */
588  double g = exp (-L);
589  int em = -1;
590  double t = 1.0;
591  do
592  {
593  ++em;
594  t *= RUNI;
595  } while (t > g);
596  ret = em;
597  }
598  else if (L <= 1e8)
599  {
600  /* numerical recipes */
601  poisson_rejection_float (L, &ret, 1);
602  }
603  else if (INFINITE(L))
604  {
605  /* FIXME: R uses NaN, but the normal approximation suggests that
606  * limit should be Inf. Which is correct? */
608  }
609  else
610  {
611  /* normal approximation: from Phys. Rev. D (1994) v50 p1284 */
612  ret = std::floor (RNOR*sqrt (L) + L + 0.5);
613  if (ret < 0.0) ret = 0.0; /* will probably never happen */
614  }
615  return ret;
616 }
#define C5
F77_RET_T const F77_INT const F77_INT const F77_INT const F77_DBLE const F77_DBLE F77_INT F77_DBLE * V
#define C7
subroutine dlgams(X, DLGAM, SGNGAM)
Definition: dlgams.f:2
ar P
Definition: __luinc__.cc:49
static void poisson_cdf_lookup(double lambda, double *p, size_t n)
Definition: randpoisson.cc:296
for large enough k
Definition: lu.cc:606
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the base of natural logarithms The constant ex $e satisfies the equation log(e)
double ceil(double x)
Definition: lo-mappers.h:138
#define RUNI
Definition: randpoisson.cc:48
#define TABLESIZE
static double flogfak(double k)
Definition: randpoisson.cc:75
#define INFINITE
Definition: randpoisson.cc:47
#define lo_ieee_isinf(x)
Definition: lo-ieee.h:111
static double xlgamma(double x)
Definition: randpoisson.cc:53
u
Definition: lu.cc:138
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
Definition: ov-usr-fcn.cc:935
static void poisson_rejection_float(double lambda, float *p, size_t n)
Definition: randpoisson.cc:441
#define F77_XFCN(f, F, args)
Definition: f77-fcn.h:52
#define C0
#define lo_ieee_isnan(x)
Definition: lo-ieee.h:103
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup calculate Y_a and Y _d item Given Y
Definition: DASPK-opts.cc:739
#define RNOR
Definition: randpoisson.cc:49
double oct_randp(double L)
Definition: randpoisson.cc:508
#define octave_Inf
Definition: lo-ieee.h:33
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
static double pprsc(double my)
Definition: randpoisson.cc:147
OCTAVE_EXPORT octave_value_list W
Definition: qz.cc:216
static void poisson_rejection(double lambda, double *p, size_t n)
Definition: randpoisson.cc:415
static void poisson_cdf_lookup_float(double lambda, float *p, size_t n)
Definition: randpoisson.cc:369
void oct_fill_float_randp(float FL, octave_idx_type n, float *p)
Definition: randpoisson.cc:547
With real return the complex result
Definition: data.cc:3375
#define LGAMMA
Definition: randpoisson.cc:50
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
p
Definition: lu.cc:138
#define C3
the element is set to zero In other the statement xample y
Definition: data.cc:5342
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol NaN(Not a Number).NaN is the result of operations which do not produce a well defined 0 result.Common operations which produce a NaN are arithmetic with infinity ex($\infty-\infty $)
double floor(double x)
Definition: lo-mappers.cc:330
double lgamma(double x)
Definition: lo-specfun.cc:353
static double f(double k, double l_nu, double c_pm)
Definition: randpoisson.cc:141
float oct_float_randp(float FL)
Definition: randpoisson.cc:580
#define C1
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE * x
void oct_fill_randp(double L, octave_idx_type n, double *p)
Definition: randpoisson.cc:476