package umontreal.iro.lecuyer.randvar;
import umontreal.iro.lecuyer.rng.*;
import umontreal.iro.lecuyer.probdist.*;
/**
* This class implements normal random variate generators using
* the Box-Muller method.
* Since the method generates two variates at a time,
* the second variate is returned upon the next call to the {@link #nextDouble nextDouble}.
*
*/
public class NormalBoxMullerGen extends NormalGen {
private boolean available = false;
private double[] variates = new double[2];
private static double[] staticVariates = new double[2];
// used by polar method which calculate always two random values;
/**
* Creates a normal random variate generator with mean mu
* and standard deviation sigma, using stream s.
*
*/
public NormalBoxMullerGen (RandomStream s, double mu, double sigma) {
super (s, null);
setParams (mu, sigma);
}
/**
* Creates a standard normal random variate generator with mean
* 0 and standard deviation 1, using stream s.
*
*/
public NormalBoxMullerGen (RandomStream s) {
this (s, 0.0, 1.0);
}
/**
* Creates a random variate generator for the normal distribution
* dist and stream s.
*
*/
public NormalBoxMullerGen (RandomStream s, NormalDist dist) {
super (s, dist);
if (dist != null)
setParams (dist.getMu(), dist.getSigma());
}
public double nextDouble() {
if (available) {
available = false;
return mu + sigma*variates[1];
}
else {
boxMuller (stream, mu, sigma, variates);
available = true;
return mu + sigma*variates[0];
}
}
public static double nextDouble (RandomStream s, double mu, double sigma) {
boxMuller (s, mu, sigma, staticVariates);
return mu + sigma*staticVariates[0];
}
/**
* Generates a variate from the normal distribution with
* parameters μ = mu and σ = sigma, using
* stream s.
*
*/
//>>>>>>>>>>>>>>>>>>>> P R I V A T E S M E T H O D S <<<<<<<<<<<<<<<<<<<<
private static void boxMuller (RandomStream stream, double mu,
double sigma, double[] variates) {
final double pi = Math.PI;
double u,v,s;
u = stream.nextDouble();
v = stream.nextDouble();
s = Math.sqrt (-2.0*Math.log (u));
variates[1] = s*Math.sin (2*pi*v);
variates[0] = s*Math.cos (2*pi*v);
}
}
Ads help maintain this website.