/* *
* Title:
* Description:
* Copyright: Copyright (c)
* Company:
* @author
* @version 1.0
*/
package umontreal.iro.lecuyer.probdist;
import umontreal.iro.lecuyer.util.*;
import umontreal.iro.lecuyer.functions.MathFunction;
import optimization.*;
/**
* Extends the class {@link ContinuousDistribution} for the half-normal
* distribution with parameters μ and
* σ > 0.
* Its density is
*
*
*
* f (x) = ((2/π)1/2/σ)e-(x-μ)2/(2σ2), for x > = μ,
*
*
*
*
* f (x) = 0 for x < μ,
*
*
*/
public class HalfNormalDist extends ContinuousDistribution {
protected double mu;
protected double sigma;
protected double C1;
/**
* Constructs a HalfNormalDist object with parameters μ =
* mu and σ = sigma.
*
*/
public HalfNormalDist (double mu, double sigma) {
setParams (mu, sigma);
}
public double density (double x) {
final double z = (x-mu)/sigma;
if (z < 0.0)
return 0.0;
return C1 * Math.exp(-z*z/2.0);
}
public double cdf (double x) {
return cdf (mu, sigma, x);
}
public double barF (double x) {
return barF (mu, sigma, x);
}
public double inverseF (double u) {
return inverseF (mu, sigma, u);
}
public double getMean() {
return HalfNormalDist.getMean (mu, sigma);
}
public double getVariance() {
return HalfNormalDist.getVariance (mu, sigma);
}
public double getStandardDeviation() {
return HalfNormalDist.getStandardDeviation (mu, sigma);
}
/**
* Computes the density function of the half-normal distribution.
*
* @param mu the parameter mu
*
* @param sigma the parameter sigma
*
* @param x the value at which the density is evaluated
*
* @return returns the density function
*
*/
public static double density (double mu, double sigma, double x) {
if (sigma <= 0.0)
throw new IllegalArgumentException ("sigma <= 0");
final double Z = (x-mu)/sigma;
if (Z < 0.0) return 0.0;
return Math.sqrt(2.0/Math.PI) / sigma * Math.exp(-Z*Z/2.0);
}
/**
* Computes the distribution function.
*
* @param mu the parameter mu
*
* @param sigma the parameter sigma
*
* @param x the value at which the distribution is evaluated
*
* @return returns the cdf function
*
*/
public static double cdf (double mu, double sigma, double x) {
if (sigma <= 0.0)
throw new IllegalArgumentException ("sigma <= 0");
final double Z = (x-mu)/sigma;
if (Z <= 0.0) return 0.0;
return Num.erf(Z/Num.RAC2);
}
/**
* Computes the complementary distribution function.
*
* @param mu the parameter mu
*
* @param sigma the parameter sigma
*
* @param x the value at which the complementary distribution is evaluated
*
* @return returns the complementary distribution function
*
*/
public static double barF (double mu, double sigma, double x) {
if (sigma <= 0.0)
throw new IllegalArgumentException ("sigma <= 0");
final double Z = (x-mu)/sigma;
if (Z <= 0.0) return 1.0;
return Num.erfc(Z/Num.RAC2);
}
/**
* Computes the inverse of the distribution function.
*
* @param mu the parameter mu
*
* @param sigma the parameter sigma
*
* @param u the value at which the inverse distribution is evaluated
*
* @return returns the inverse distribution function
*
*/
public static double inverseF (double mu, double sigma, double u) {
if (sigma <= 0.0)
throw new IllegalArgumentException ("sigma <= 0");
if (u > 1.0 || u < 0.0)
throw new IllegalArgumentException ("u not in [0,1]");
if (u <= 0.0) return mu;
if (u >= 1.0)
return Double.POSITIVE_INFINITY;
final double Z = Num.RAC2 * Num.erfInv(u);
return mu + sigma * Z;
}
/**
* Estimates the parameters μ and σ of the half-normal 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: [μ, σ].
*
* @param x the list of observations to use to evaluate parameters
*
* @param n the number of observations to use to evaluate parameters
*
* @return returns the parameters [μ, σ]
*
*/
public static double[] getMLE (double[] x, int n) {
if (n <= 0)
throw new IllegalArgumentException ("n <= 0");
double mu = Double.MAX_VALUE;
for (int i = 0 ; i < n ; ++i)
if (x[i] < mu)
mu = x[i];
double sigma = 0.0;
for (int i = 0 ; i < n ; ++i)
sigma += (x[i]-mu)*(x[i]-mu);
double[] parametres = new double [2];
parametres[0] = mu;
parametres[1] = Math.sqrt(sigma/n);
return parametres;
}
/**
* Estimates the parameter σ of the half-normal distribution using the
* maximum likelihood method from the n observations x[i],
* i = 0, 1,…, n - 1 and the parameter μ = mu. The estimate is
* returned in a one-element array: [σ].
*
* @param x the list of observations to use to evaluate parameters
*
* @param n the number of observations to use to evaluate parameter
*
* @param mu the parameter mu
*
* @return returns the parameter [σ]
*
*/
public static double[] getMLE (double[] x, int n, double mu) {
if (n <= 0)
throw new IllegalArgumentException ("n <= 0");
double sigma = 0.0;
for (int i = 0 ; i < n ; ++i)
sigma += (x[i]-mu)*(x[i]-mu);
double[] parametres = new double [1];
parametres[0] = Math.sqrt(sigma/n);
return parametres;
}
/**
* Computes and returns the mean
*
* E[X] = μ + σ(2 / π)1/2.
*
* @param mu the parameter mu
*
* @param sigma the parameter sigma
*
* @return returns the mean
*
*/
public static double getMean (double mu, double sigma) {
if (sigma <= 0.0)
throw new IllegalArgumentException ("sigma <= 0");
return mu + sigma*Math.sqrt(2.0/Math.PI);
}
/**
* Computes and returns the variance
*
* Var[X] = (1 - 2/π)σ2.
*
* @param mu the parameter mu
*
* @param sigma the parameter sigma
*
* @return returns the variance
*
*/
public static double getVariance (double mu, double sigma) {
if (sigma <= 0.0)
throw new IllegalArgumentException ("sigma <= 0");
return (1.0 - 2.0/Math.PI)*sigma*sigma;
}
/**
* Computes the standard deviation of the half-normal distribution with
* parameters μ and σ.
*
* @param mu the parameter mu
*
* @param sigma the parameter sigma
*
* @return returns the standard deviation
*
*/
public static double getStandardDeviation (double mu, double sigma) {
return Math.sqrt (HalfNormalDist.getVariance (mu, sigma));
}
/**
* Returns the parameter μ of this object.
*
* @return returns the parameter mu
*
*/
public double getMu() {
return mu;
}
/**
* Returns the parameter σ of this object.
*
* @return returns the parameter sigma
*
*/
public double getSigma() {
return sigma;
}
/**
* Sets the parameters μ and σ.
*
* @param mu the parameter mu
*
* @param sigma the parameter sigma
*
*
*/
public void setParams (double mu, double sigma) {
if (sigma <= 0.0)
throw new IllegalArgumentException ("sigma <= 0");
this.mu = mu;
this.sigma = sigma;
C1 = Math.sqrt(2.0/Math.PI) / sigma;
}
/**
* Return a table containing the parameters of the current distribution.
* This table is put in regular order: [μ, σ].
*
* @return returns the parameters [μ, σ]
*
*/
public double[] getParams () {
double[] retour = {mu, sigma};
return retour;
}
/**
* Returns a String containing information about the current distribution.
*
* @return returns a String containing information about the current distribution.
*
*/
public String toString () {
return getClass().getSimpleName() + " : mu = " + mu + ", sigma = " + sigma;
}
}
Ads help maintain this website.