34 #if defined (HAVE_CONFIG_H)
48 #define NAN octave_NaN
50 #define INFINITE lo_ieee_isinf
51 #define RUNI oct_randu()
52 #define RNOR oct_randn()
53 #define LGAMMA xlgamma
83 #define C0 9.18938533204672742e-01
84 #define C1 8.33333333333333333e-02
85 #define C3 -2.77777777777777778e-03
86 #define C5 7.93650793650793651e-04
87 #define C7 -5.95238095238095238e-04
89 static double logfak[30L] =
91 0.00000000000000000, 0.00000000000000000, 0.69314718055994531,
92 1.79175946922805500, 3.17805383034794562, 4.78749174278204599,
93 6.57925121201010100, 8.52516136106541430, 10.60460290274525023,
94 12.80182748008146961, 15.10441257307551530, 17.50230784587388584,
95 19.98721449566188615, 22.55216385312342289, 25.19122118273868150,
96 27.89927138384089157, 30.67186010608067280, 33.50507345013688888,
97 36.39544520803305358, 39.33988418719949404, 42.33561646075348503,
98 45.38013889847690803, 48.47118135183522388, 51.60667556776437357,
99 54.78472939811231919, 58.00360522298051994, 61.26170176100200198,
100 64.55753862700633106, 67.88974313718153498, 71.25703896716800901
109 return ((k + 0.5)*log (k) - k +
C0 + r*(
C1 + rr*(
C3 + rr*(
C5 + rr*
C7))));
112 return (logfak[(
int)k]);
148 f (
double k,
double l_nu,
double c_pm)
150 return exp (k * l_nu -
flogfak (k) - c_pm);
156 static double my_last = -1.0;
157 static double m, k2, k4, k1, k5;
158 static double dl, dr,
r1,
r2, r4, r5, ll, lr, l_my, c_pm,
159 f1, f2, f4, f5, p1, p2, p3, p4, p5, p6;
167 Ds = sqrt (my + 0.25);
172 k2 =
ceil (my - 0.5 - Ds);
173 k4 =
floor (my - 0.5 + Ds);
174 k1 = k2 + k2 - m + 1L;
184 r4 = my / (k4 + 1.0);
185 r5 = my / (k5 + 1.0);
196 f2 =
f (k2, l_my, c_pm);
197 f4 =
f (k4, l_my, c_pm);
198 f1 =
f (k1, l_my, c_pm);
199 f5 =
f (k5, l_my, c_pm);
203 p1 = f2 * (dl + 1.0);
205 p3 = f4 * (dr + 1.0) + p2;
215 if ((U =
RUNI * p6) < p2)
220 if ((V = U - p1) < 0.0)
return (k2 +
floor (U/f2));
223 if ((W = V / dl) < f1 )
return (k1 +
floor (V/f1));
228 if (W <= f2 - Dk * (f2 - f2/r2))
232 if ((V = f2 + f2 - W) < 1.0)
235 if (V <= f2 + Dk * (1.0 - f2)/(dl + 1.0))
239 if (V <=
f (Y, l_my, c_pm))
return (Y);
247 if ((V = U - p3) < 0.0)
return (k4 -
floor ((U - p2)/f4));
250 if ((W = V / dr) < f5 )
return (k5 -
floor (V/f5));
255 if (W <= f4 - Dk * (f4 - f4*r4))
259 if ((V = f4 + f4 - W) < 1.0)
262 if (V <= f4 + Dk * (1.0 - f4)/ dr)
266 if (V <=
f (Y, l_my, c_pm))
return (Y);
275 Dk =
floor (1.0 - log (W)/ll);
276 if ((X = k1 - Dk) < 0L)
continue;
278 if (W <= f1 - Dk * (f1 - f1/r1))
283 Dk =
floor (1.0 - log (W)/lr);
286 if (W <= f5 - Dk * (f5 - f5*r5))
294 if (log (W) <= X * l_my -
flogfak (X) - c_pm)
return (X);
320 int intlambda = (
int)
floor (lambda);
325 t[0] = P = exp (-lambda);
326 for (tableidx = 1; tableidx <= intlambda; tableidx++)
328 P = P*lambda/(double)tableidx;
329 t[tableidx] = t[tableidx-1] + P;
341 int k = (u > 0.458 ? intlambda : 0);
353 if (++k < tableidx)
goto nextk;
359 P = P*lambda/(double)tableidx;
360 t[tableidx] = t[tableidx-1] + P;
363 if (t[tableidx] == t[tableidx-1]) t[tableidx] = 1.0;
365 if (u <= t[tableidx-1])
break;
371 p[i] = (double)(tableidx-1);
382 int intlambda = (
int)
floor (lambda);
387 t[0] = P = exp (-lambda);
388 for (tableidx = 1; tableidx <= intlambda; tableidx++)
390 P = P*lambda/(double)tableidx;
391 t[tableidx] = t[tableidx-1] + P;
397 int k = (u > 0.458 ? intlambda : 0);
404 if (++k < tableidx)
goto nextk;
408 P = P*lambda/(double)tableidx;
409 t[tableidx] = t[tableidx-1] + P;
410 if (t[tableidx] == t[tableidx-1]) t[tableidx] = 1.0;
412 if (u <= t[tableidx-1])
break;
415 p[i] = (
float)(tableidx-1);
423 double sq = sqrt (2.0*lambda);
424 double alxm = log (lambda);
425 double g = lambda*alxm -
LGAMMA(lambda+1.0);
428 for (i = 0; i < n; i++)
436 em = sq * y + lambda;
439 t = 0.9*(1.0+y*y)*exp (em*alxm-
flogfak (em)-g);
449 double sq = sqrt (2.0*lambda);
450 double alxm = log (lambda);
451 double g = lambda*alxm -
LGAMMA(lambda+1.0);
454 for (i = 0; i < n; i++)
462 em = sq * y + lambda;
465 t = 0.9*(1.0+y*y)*exp (em*alxm-
flogfak (em)-g);
502 const double sqrtL = sqrt (L);
503 for (i = 0; i < n; i++)
517 if (L < 0.0) ret =
NAN;
546 if (ret < 0.0) ret = 0.0;
574 const double sqrtL = sqrt (L);
575 for (i = 0; i < n; i++)
590 if (L < 0.0) ret =
NAN;
619 if (ret < 0.0) ret = 0.0;