/* *
* Title:
* Description:
* Copyright: Copyright (c)
* Company:
* @author
* @version 1.0
*/
package umontreal.iro.lecuyer.probdist;
import umontreal.iro.lecuyer.probdist.NormalDist;
import umontreal.iro.lecuyer.util.*;
import umontreal.iro.lecuyer.functions.MathFunction;
/**
* Extends the class {@link ContinuousDistribution} for
* the inverse Gaussian distribution with location parameter
* μ > 0 and scale parameter
* λ > 0.
* Its density is
*
*
*
* f (x) = (λ/ (2πx^3))1/2e-λ(x-μ)2/(2μ2x), for x > 0.
*
* The distribution function is given by
*
*
*
* F(x) = Φ((λ/x)1/2(x/μ -1)) + e2λ/μΦ(- (λ/x)1/2(x/μ + 1)),
*
* where Φ is the standard normal distribution function.
*
*
* The non-static versions of the methods cdf, barF,
* and inverseF call the static version of the same name.
*
*/
public class InverseGaussianDist extends ContinuousDistribution {
protected double mu;
protected double lambda;
private static class Function implements MathFunction {
protected double mu;
protected double lambda;
protected double u;
public Function (double mu, double lambda, double u) {
this.mu = mu;
this.lambda = lambda;
this.u = u;
}
public double evaluate (double x) {
return u - cdf(mu, lambda, x);
}
}
/**
* Constructs the inverse Gaussian distribution with parameters μ and λ.
*
*/
public InverseGaussianDist (double mu, double lambda) {
setParams (mu, lambda);
}
public double density (double x) {
return density (mu, lambda, x);
}
public double cdf (double x) {
return cdf (mu, lambda, x);
}
public double barF (double x) {
return barF (mu, lambda, x);
}
public double inverseF (double u) {
return inverseF (mu, lambda, u);
}
public double getMean() {
return getMean (mu, lambda);
}
public double getVariance() {
return getVariance (mu, lambda);
}
public double getStandardDeviation() {
return getStandardDeviation (mu, lambda);
}
/**
* Computes the density function for the
* inverse gaussian distribution with parameters μ and λ,
* evaluated at x.
*
*/
public static double density (double mu, double lambda, double x) {
if (mu <= 0.0)
throw new IllegalArgumentException ("mu <= 0");
if (lambda <= 0.0)
throw new IllegalArgumentException ("lambda <= 0");
if (x <= 0.0)
return 0.0;
double sqrtX = Math.sqrt (x);
return (Math.sqrt (lambda / (2 * Math.PI)) / (sqrtX * sqrtX * sqrtX) *
Math.exp (-lambda * (x - 2 * mu + (mu * mu / x)) / (2 * mu * mu)));
}
/**
* Computes the distribution function
* of the inverse gaussian distribution with parameters μ and
* λ, evaluated at x.
*
*/
public static double cdf (double mu, double lambda, double x) {
if (mu <= 0.0)
throw new IllegalArgumentException ("mu <= 0");
if (lambda <= 0.0)
throw new IllegalArgumentException ("lambda <= 0");
if (x <= 0.0)
return 0.0;
double temp = Math.sqrt (lambda / x);
double z = temp * (x / mu - 1.0);
double w = temp * (x / mu + 1.0);
// C'est bien un + dans exp (2 * lambda / mu)
return (NormalDist.cdf01 (z) +
Math.exp (2 * lambda / mu) * NormalDist.cdf01 (-w));
}
/**
* Computes the complementary distribution function of the inverse gaussian distribution
* with parameters μ and λ, evaluated at x.
*
*/
public static double barF (double mu, double lambda, double x) {
return 1.0 - cdf (mu, lambda, x);
}
/**
* Computes the inverse of the inverse gaussian distribution
* with parameters μ and λ.
*
*/
public static double inverseF (double mu, double lambda, double u) {
if (mu <= 0.0)
throw new IllegalArgumentException ("mu <= 0");
if (lambda <= 0.0)
throw new IllegalArgumentException ("lambda <= 0");
if (u < 0.0 || u > 1.0)
throw new IllegalArgumentException ("u must be in [0,1]");
if (u == 1.0)
return Double.POSITIVE_INFINITY;
if (u == 0.0)
return 0.0;
Function f = new Function (mu, lambda, u);
// Find interval containing root = x*
double sig = getStandardDeviation(mu, lambda);
double x0 = 0.0;
double x = mu;
double v = cdf(mu, lambda, x);
while (v < u) {
x0 = x;
x += 3.0*sig;
v = cdf(mu, lambda, x);
}
return RootFinder.brentDekker (x0, x, f, 1e-12);
}
/**
* Estimates the parameters
* (μ, λ) of the inverse gaussian distribution
* using the maximum likelihood method, from the n observations
* x[i],
* i = 0, 1,…, n - 1. The estimates are returned in a two-element
* array, in regular order: [μ, λ].
*
* @param x the list of observations used to evaluate parameters
*
* @param n the number of observations used to evaluate parameters
*
* @return returns the parameters [hat(μ),
* hat(λ)]
*
*/
public static double[] getMLE (double[] x, int n) {
if (n <= 0)
throw new IllegalArgumentException ("n <= 0");
double parameters[];
parameters = new double[2];
double sum = 0;
for (int i = 0; i < n; i++) {
sum += x[i];
}
parameters[0] = sum / (double) n;
sum = 0;
for (int i = 0; i < n; i++) {
sum += ((1.0 / (double) x[i]) - (1.0 / parameters[0]));
}
parameters[1] = (double) n / (double) sum;
return parameters;
}
/**
* Creates a new instance of an inverse gaussian distribution with parameters
* μ and λ estimated using the maximum likelihood method based on
* the n observations x[i],
* i = 0, 1,…, n - 1.
*
* @param x the list of observations to use to evaluate parameters
*
* @param n the number of observations to use to evaluate parameters
*
*
*/
public static InverseGaussianDist getInstanceFromMLE (double[] x, int n) {
double parameters[] = getMLE (x, n);
return new InverseGaussianDist (parameters[0], parameters[1]);
}
/**
* Returns the mean
* E[X] = μ of the
* inverse gaussian distribution with parameters μ and λ.
*
* @return the mean of the inverse gaussian distribution
* E[X] = μ
*
*/
public static double getMean (double mu, double lambda) {
if (mu <= 0.0)
throw new IllegalArgumentException ("mu <= 0");
if (lambda <= 0.0)
throw new IllegalArgumentException ("lambda <= 0");
return mu;
}
/**
* Computes and returns the variance
* Var[X] = μ3/λ of
* the inverse gaussian distribution with parameters μ and λ.
*
* @return the variance of the inverse gaussian distribution
*
* Var[X] = μ3/λ
*
*/
public static double getVariance (double mu, double lambda) {
if (mu <= 0.0)
throw new IllegalArgumentException ("mu <= 0");
if (lambda <= 0.0)
throw new IllegalArgumentException ("lambda <= 0");
return (mu * mu * mu / lambda);
}
/**
* Computes and returns the standard deviation
* of the inverse gaussian distribution with parameters μ and λ.
*
* @return the standard deviation of the inverse gaussian distribution
*
*/
public static double getStandardDeviation (double mu, double lambda) {
return Math.sqrt (getVariance (mu, lambda));
}
/**
* Returns the parameter λ of this object.
*
*/
public double getLambda() {
return lambda;
}
/**
* Returns the parameter μ of this object.
*
*/
public double getMu() {
return mu;
}
/**
* Sets the parameters μ and λ of this object.
*
*/
public void setParams (double mu, double lambda) {
if (mu <= 0.0)
throw new IllegalArgumentException ("mu <= 0");
if (lambda <= 0.0)
throw new IllegalArgumentException ("lambda <= 0");
this.mu = mu;
this.lambda = lambda;
supportA = 0.0;
}
/**
* Return a table containing the parameters of the current distribution.
* This table is put in regular order: [μ, λ].
*
*
*/
public double[] getParams () {
double[] retour = {mu, lambda};
return retour;
}
public String toString () {
return getClass().getSimpleName() + " : mu = " + mu + ", lambda = " + lambda;
}
}
Ads help maintain this website.