Database Reference
In-Depth Information
double nextZNormal() {
if(ready) { ready = false;return z2; }
double theta = nextUniform(0,2*Math.PI);
double r = Math.
sqrt
(nextExponential(0.5));
z2 = r*Math.
sin
(theta);ready = true;
return r*Math.
cos
(theta);
}
This produces draws from the “Standard Normal,” which has a mean of 0
and a standard deviation of 1. These can be translated and scaled to produce
a draw from any normal distribution:
public double
nextNormal(
double
mu,
double
sig) {
return
mu + sig*nextZNormal();
}
Gamma, Chi-Square, and Beta Random Numbers
Despite being closely related to the exponential distribution, drawing
gamma random numbers is comparatively difficult. If the shape parameter
k is an integer then it would be possible to simply draw k exponentials with
the appropriate scale parameter and add them to get a draw from a gamma
distribution.
Of course, this has a number of drawbacks, the inability to deal with
non-integer values of k being chief among them. The approach used more
often is a technique called
rejection sampling
.
In rejection sampling, another distribution, f(x)—which envelops the target
distribution, g(x), but is easy to sample from—is selected. The envelope
distribution for the gamma distribution has the following density
implementation:
protected double gamma_f(double x,double a) {
double L = Math.
sqrt
(2*a - 1);
double y = Math.
log
(4) - a + (L+a)*Math.
log
(a)
+ (L-1)*Math.
log
(x) - Gamma.
logGamma
(a)
- 2*Math.
log
(Math.
pow
(a, L) + Math.
pow
(x, L));
return Math.
exp
(y);
}