package umontreal.iro.lecuyer.randvar;
import umontreal.iro.lecuyer.rng.*;
import umontreal.iro.lecuyer.probdist.*;
/**
* This class implements normal random variate generators using
* the polar method with rejection.
* Since the method generates two variates at a time,
* the second variate is returned upon the next call to {@link #nextDouble nextDouble}.
*
*/
public class NormalPolarGen extends NormalGen {
// used by polar method which calculate always two random values;
private boolean available = false;
private double[] variates = new double[2];
private static double[] staticVariates = new double[2];
/**
* Creates a normal random variate generator with mean mu
* and standard deviation sigma, using stream s.
*
*/
public NormalPolarGen (RandomStream s, double mu, double sigma) {
super (s, null);
setParams (mu, sigma);
}
/**
* Creates a standard normal random variate generator with μ = 0
* and σ = 1, using stream s.
*
*/
public NormalPolarGen (RandomStream s) {
this (s, 0.0, 1.0);
}
/**
* Creates a random variate generator for
* the normal distribution dist and stream s.
*
*/
public NormalPolarGen (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 {
polar (stream, mu, sigma, variates);
available = true;
return mu + sigma*variates[0];
}
}
public static double nextDouble (RandomStream s, double mu, double sigma) {
polar (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 M E T H O D S <<<<<<<<<<<<<<<<<<<<
// Polar method with rejection
private static void polar (RandomStream stream, double mu,
double sigma, double[] variates) {
double x, y, s;
do {
x = 2*stream.nextDouble() - 1;
y = 2*stream.nextDouble() - 1;
s = x*x + y*y;
} while (s > 1.0 || s == 0.0);
double temp = Math.sqrt (-2.0*Math.log (s)/s);
variates[0] = y*temp;
variates[1] = x*temp;
}
}
Ads help maintain this website.