26package umontreal.ssj.randvar;
28import umontreal.ssj.rng.*;
29import umontreal.ssj.probdist.*;
30import umontreal.ssj.util.Num;
31import cern.jet.stat.Gamma;
66 private static final double q1 = 0.0416666664;
67 private static final double q2 = 0.0208333723;
68 private static final double q3 = 0.0079849875;
69 private static final double q4 = 0.0015746717;
70 private static final double q5 = -0.0003349403;
71 private static final double q6 = 0.0003340332;
72 private static final double q7 = 0.0006053049;
73 private static final double q8 = -0.0004701849;
74 private static final double q9 = 0.0001710320;
75 private static final double a1 = 0.333333333;
76 private static final double a2 = -0.249999949;
77 private static final double a3 = 0.199999867;
78 private static final double a4 = -0.166677482;
79 private static final double a5 = 0.142873973;
80 private static final double a6 = -0.124385581;
81 private static final double a7 = 0.110368310;
82 private static final double a8 = -0.112750886;
83 private static final double a9 = 0.104089866;
84 private static final double e1 = 1.000000000;
85 private static final double e2 = 0.499999994;
86 private static final double e3 = 0.166666848;
87 private static final double e4 = 0.041664508;
88 private static final double e5 = 0.008345522;
89 private static final double e6 = 0.001353826;
90 private static final double e7 = 0.000247453;
98 private static final int gs = 0;
99 private static final int gd = 1;
112 private static final double USE_LMS_THRESHOLD = 0.1;
137 this(s, s, alpha, lambda);
149 setParams(dist.getAlpha(), dist.getLambda());
150 beta = 1.0 / dist.getLambda();
178 double s_ = 0, ss = 0, d = 0, q0 = 0, r = 0, c = 0, si = 0, b = 0;
180 if (alpha < USE_LMS_THRESHOLD) {
182 return acceptanceRejectionLms(s, aux, alpha, 1.0 / lambda);
185 else if (alpha < 1.0) {
187 b = 1.0 + 0.36788794412 * alpha;
193 d = 5.656854249 - 12.0 * s_;
197 q0 = ((((((((q9 * r + q8) * r + q7) * r + q6) * r + q5) * r + q4) * r + q3) * r + q2) * r + q1) * r;
199 if (alpha > 13.022) {
204 b = 1.654 + 0.0076 * ss;
205 si = 1.68 / s_ + 0.275;
206 c = 0.062 / s_ + 0.024;
209 b = 0.463 + s_ - 0.178 * ss;
211 c = 0.195 / s_ - 0.079 + 0.016 * s_;
214 return acceptanceRejection(s, aux, alpha, 1.0 / lambda, 0, gen, b, s_, ss, d, r, q0, c, si);
218 if (alpha < USE_LMS_THRESHOLD)
219 return acceptanceRejectionLms(stream, auxStream, alpha, beta);
221 return acceptanceRejection(stream, auxStream, alpha, beta, gamma, gen, b, s, ss, d, r, q0, c, si);
238 if (alpha < USE_LMS_THRESHOLD)
239 return acceptanceRejectionLmsLog(stream, auxStream, alpha, beta);
241 return Math.log(acceptanceRejection(stream, auxStream, alpha, beta, gamma, gen, b, s, ss, d, r, q0, c, si));
255 double s_ = 0, ss = 0, d = 0, q0 = 0, r = 0, c = 0, si = 0, b = 0;
257 if (alpha < USE_LMS_THRESHOLD) {
259 return acceptanceRejectionLmsLog(s, aux, alpha, 1.0 / lambda);
261 return Math.log(
nextDouble(s, aux, alpha, lambda));
273 double gamma,
int gen,
double b,
double s,
double ss,
double d,
double r,
double q0,
double c,
double si) {
276 double q, sign_U, t, v, w, x;
283 X = Math.exp(Math.log(p) / alpha);
287 X = -Math.log((b - p) / alpha);
288 if (Math.log(stream.
nextDouble()) <= ((alpha - 1.0) * Math.log(X)))
306 if (d * U <= t * t * t)
313 if (Math.abs(v) > 0.25)
314 q = q0 - s * t + 0.25 * t * t + (ss + ss) * Math.log(1. + v);
317 * ((((((((a9 * v + a8) * v + a7) * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1)
320 if (Math.log(1. - U) <= q)
327 E = -Math.log(stream.nextDouble());
328 U = stream.nextDouble();
330 sign_U = (U > 0) ? 1. : -1.;
331 t = b + (E * si) * sign_U;
332 }
while (t <= -0.71874483771719);
336 if (Math.abs(v) > 0.25)
337 q = q0 - s * t + 0.25 * t * t + (ss + ss) * Math.log(1. + v);
340 * ((((((((a9 * v + a8) * v + a7) * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1)
348 w = Math.exp(q) - 1.;
350 w = ((((((e7 * q + e6) * q + e5) * q + e4) * q + e3) * q + e2) * q + e1) * q;
353 if (c * U * sign_U <= w * Math.exp(E - 0.5 * t * t)) {
362 throw new IllegalStateException();
365 return gamma + beta * X;
372 private static double acceptanceRejectionLms(RandomStream stream, RandomStream auxStream,
double alpha,
375 return Math.exp(acceptanceRejectionLmsLog(stream, auxStream, alpha, scale));
385 private static double acceptanceRejectionLmsLog(RandomStream stream, RandomStream auxStream,
double alpha,
388 double lambda = 1.0 / alpha - 1.0;
389 double w = alpha /
Num.EBASE / (1.0 - alpha);
390 double r = 1.0 / (1.0 + w);
391 double c = 1.0 / Gamma.gamma(alpha + 1.0);
393 double u = stream.nextDouble();
398 z = -Math.log(u / r);
400 z = Math.log(auxStream.nextDouble()) / lambda;
402 if (functionHLms(z, alpha, c) / functionEtaLms(z, alpha, lambda, w, c) > auxStream.nextDouble()) {
406 u = auxStream.nextDouble();
408 return Math.log(scale) - (Z / alpha);
412 private static double functionHLms(
double z,
double alpha,
double c) {
413 return c * Math.exp(-z - Math.exp(-z / alpha));
417 private static double functionEtaLms(
double z,
double alpha,
double lambda,
double w,
double c) {
419 return c * Math.exp(-z);
421 return c * w * lambda * Math.exp(lambda * z);
424 private void init() {
428 b = 1.0 + 0.36788794412 * alpha;
434 d = 5.656854249 - 12.0 * s;
438 q0 = ((((((((q9 * r + q8) * r + q7) * r + q6) * r + q5) * r + q4) * r + q3) * r + q2) * r + q1) * r;
440 if (alpha > 13.022) {
445 b = 1.654 + 0.0076 * ss;
446 si = 1.68 / s + 0.275;
447 c = 0.062 / s + 0.024;
450 b = 0.463 + s - 0.178 * ss;
452 c = 0.195 / s - 0.079 + 0.016 * s;
Extends the class ContinuousDistribution for the gamma distribution tjoh95a (page 337) with shape pa...
Extends the class ContinuousDistribution for the normal distribution (e.g., tjoh95a (page 80)).
static double inverseF01(double u)
Same as inverseF(0, 1, u).
GammaAcceptanceRejectionGen(RandomStream s, RandomStream aux, GammaDist dist)
Creates a new generator object for the gamma distribution dist, using main stream s and auxiliary str...
static double nextDoubleLog(RandomStream s, double alpha, double lambda)
Same as nextDoubleLog (s, s, alpha, lambda).
static double nextDouble(RandomStream s, double alpha, double lambda)
Same as nextDouble (s, s, alpha, lambda).
GammaAcceptanceRejectionGen(RandomStream s, RandomStream aux, double alpha, double lambda)
Creates a gamma random variate generator with parameters.
GammaAcceptanceRejectionGen(RandomStream s, double alpha, double lambda)
Creates a gamma random variate generator with parameters.
RandomStream getAuxStream()
Returns the auxiliary stream associated with this object.
double nextDoubleLog()
Returns the natural log value of a new gamma variate.
static double nextDoubleLog(RandomStream s, RandomStream aux, double alpha, double lambda)
Returns the natural log value of a new gamma variate with parameters.
static double nextDouble(RandomStream s, RandomStream aux, double alpha, double lambda)
Generates a new gamma variate with parameters  alpha and  lambda, using main stream s and auxilia...
GammaAcceptanceRejectionGen(RandomStream s, GammaDist dist)
Creates a new generator object for the gamma distribution dist and stream s for both the main and aux...
double nextDouble()
Generates a random number from the continuous distribution contained in this object.
GammaGen(RandomStream s, double alpha, double lambda)
Creates a gamma random variate generator with parameters.
void setParams(double alpha, double lambda)
Sets the parameter and of this object.
static final double EBASE
The constant .
This interface defines the basic structures to handle multiple streams of uniform (pseudo)random numb...
double nextDouble()
Returns a (pseudo)random number from the uniform distribution over the interval , using this stream,...