package umontreal.iro.lecuyer.randvar;
import umontreal.iro.lecuyer.rng.*;
import umontreal.iro.lecuyer.probdist.*;
/**
* This class implements inverse gaussian random variate generators using
* the many-to-one transformation method of Michael, Schucany and Haas (MHS).
*
*/
public class InverseGaussianMSHGen extends InverseGaussianGen {
private NormalGen genN;
/**
* Creates an inverse gaussian random variate generator with
* parameters μ = mu and λ = lambda,
* using streams s and sn.
*
*/
public InverseGaussianMSHGen (RandomStream s, NormalGen sn,
double mu, double lambda) {
super (s, null);
setParams (mu, lambda, sn);
}
/**
* Creates a new generator for the distribution dist
* using streams s and sn.
*
*/
public InverseGaussianMSHGen (RandomStream s, NormalGen sn,
InverseGaussianDist dist) {
super (s, dist);
if (dist != null)
setParams (dist.getMu(), dist.getLambda(), sn);
}
/**
* Generates a new variate from the inverse gaussian
* distribution with parameters μ = mu and λ =
* lambda, using streams s and sn.
*
*/
public static double nextDouble (RandomStream s, NormalGen sn,
double mu, double lambda) {
return mhs(s, sn, mu, lambda);
}
public double nextDouble() {
return mhs(stream, genN, mu, lambda);
}
//>>>>>>>>>>>>>>>>>>>> P R I V A T E M E T H O D S <<<<<<<<<<<<<<<<<<<<
private static double mhs (RandomStream stream, NormalGen genN,
double mu, double lambda) {
if (lambda <= 0.0)
throw new IllegalArgumentException ("lambda <= 0");
if (mu <= 0.0)
throw new IllegalArgumentException ("mu <= 0");
double z = genN.nextDouble ();
double ymu = mu*z*z;
double x1 = mu + 0.5*mu*ymu/lambda - 0.5*mu/lambda *
Math.sqrt(4.0*ymu*lambda + ymu*ymu);
double u = stream.nextDouble();
if (u <= mu/(mu + x1))
return x1;
return mu*mu/x1;
}
protected void setParams (double mu, double lambda, NormalGen sn) {
setParams (mu, lambda);
this.genN = sn;
}
}
Ads help maintain this website.