/* *
 * Title:        

* Description:

* Copyright: Copyright (c)

* Company:

* @author * @version 1.0 */ package umontreal.iro.lecuyer.probdist; import umontreal.iro.lecuyer.util.*; /** * Extends the class {@link ContinuousDistribution} for the * lognormal distribution. It has scale * parameter μ and shape parameter * σ > 0. * The density is *

*

*
* f (x) = ((2π)1/2σx)-1e-(ln(x)-μ)2/(2σ2)        for x > 0, *

* and 0 elsewhere. The distribution function is *

*

*
* F(x) = Φ((ln(x)-μ)/σ)        for x > 0, *

* where Φ is the standard normal distribution function. * Its inverse is given by *

*

*
* F-1(u) = eμ+σΦ-1(u)        for 0 <= u < 1. *

* If ln(Y) has a normal distribution, then Y has a * lognormal distribution with the same parameters. * *

* This class relies on the methods * {@link NormalDist#cdf01 NormalDist.cdf01} and * {@link NormalDist#inverseF01 NormalDist.inverseF01} * of {@link NormalDist} to approximate Φ and Φ-1. * */ public class LognormalDist extends ContinuousDistribution { private double mu; private double sigma; /** * Constructs a LognormalDist object with default * parameters μ = 0 and * σ = 1. * */ public LognormalDist() { setParams (0.0, 1.0); } /** * Constructs a LognormalDist object with parameters * μ = mu and σ = sigma. * */ public LognormalDist (double mu, double sigma) { setParams (mu, sigma); } public double density (double x) { return density (mu, sigma, x); } 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 LognormalDist.getMean (mu, sigma); } public double getVariance() { return LognormalDist.getVariance (mu, sigma); } public double getStandardDeviation() { return LognormalDist.getStandardDeviation (mu, sigma); } /** * Computes the lognormal density function * f (x). * */ public static double density (double mu, double sigma, double x) { if (sigma <= 0) throw new IllegalArgumentException ("sigma <= 0"); if (x <= 0) return 0; double diff = Math.log (x) - mu; return Math.exp (-diff*diff/(2*sigma*sigma))/ (Math.sqrt (2*Math.PI)*sigma*x); } /** * Computes the lognormal distribution function, using * {@link NormalDist#cdf01 cdf01}. * */ public static double cdf (double mu, double sigma, double x) { if (sigma <= 0.0) throw new IllegalArgumentException ("sigma <= 0"); if (x <= 0.0) return 0.0; return NormalDist.cdf01 ((Math.log (x) - mu)/sigma); } /** * Computes the lognormal complementary distribution function * bar(F)(x), * using {@link NormalDist#barF01 NormalDist.barF01}. * */ public static double barF (double mu, double sigma, double x) { if (sigma <= 0.0) throw new IllegalArgumentException ("sigma <= 0"); if (x <= 0.0) return 1.0; return NormalDist.barF01 ((Math.log (x) - mu)/sigma); } /** * Computes the inverse of the lognormal distribution function, * using {@link NormalDist#inverseF01 NormalDist.inverseF01}. * */ public static double inverseF (double mu, double sigma, double u) { double t, v; 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 (Num.DBL_EPSILON >= 1.0 - u) return Double.POSITIVE_INFINITY; if (u <= 0.0) return 0.0; t = NormalDist.inverseF01 (u); v = mu + sigma * t; if ((t >= XBIG) || (v >= Num.DBL_MAX_EXP * Num.LN2)) return Double.POSITIVE_INFINITY; if ((t <= -XBIG) || (v <= -Num.DBL_MAX_EXP*Num.LN2)) return 0.0; return Math.exp (v); } /** * Estimates the parameters * (μ, σ) of the lognormal 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"); final double LN_EPS = Num.LN_DBL_MIN - Num.LN2; double parameters[]; parameters = new double[2]; double sum = 0.0; for (int i = 0; i < n; i++) { if (x[i] > 0.0) sum += Math.log (x[i]); else sum += LN_EPS; // log(DBL_MIN / 2) } parameters[0] = sum / n; double temp; sum = 0.0; for (int i = 0; i < n; i++) { if (x[i] > 0.0) temp = Math.log (x[i]) - parameters[0]; else temp = LN_EPS - parameters[0]; sum += temp * temp; } parameters[1] = Math.sqrt (sum / n); return parameters; } /** * Creates a new instance of a lognormal 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 LognormalDist getInstanceFromMLE (double[] x, int n) { double parameters[] = getMLE (x, n); return new LognormalDist (parameters[0], parameters[1]); } /** * Computes and returns the mean * E[X] = eμ+σ2/2 * of the lognormal distribution with parameters μ and σ. * * @return the mean of the lognormal distribution * */ public static double getMean (double mu, double sigma) { if (sigma <= 0.0) throw new IllegalArgumentException ("sigma <= 0"); return (Math.exp(mu + (sigma * sigma) / 2.0)); } /** * Computes and returns the variance * * Var[X] = e2μ+σ2(eσ2 - 1) * of the lognormal distribution with parameters μ and σ. * * @return the variance of the lognormal distribution * */ public static double getVariance (double mu, double sigma) { if (sigma <= 0.0) throw new IllegalArgumentException ("sigma <= 0"); return (Math.exp(2.0 * mu + sigma * sigma) * (Math.exp(sigma * sigma) - 1.0)); } /** * Computes and returns the standard deviation * of the lognormal distribution with parameters μ and σ. * * @return the standard deviation of the lognormal distribution * */ public static double getStandardDeviation (double mu, double sigma) { return Math.sqrt (LognormalDist.getVariance (mu, sigma)); } /** * Returns the parameter μ of this object. * */ public double getMu() { return mu; } /** * Returns the parameter σ of this object. * */ public double getSigma() { return sigma; } /** * Sets the parameters μ and σ of this object. * */ public void setParams (double mu, double sigma) { if (sigma <= 0) throw new IllegalArgumentException ("sigma <= 0"); this.mu = mu; this.sigma = sigma; 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, sigma}; return retour; } public String toString () { return getClass().getSimpleName() + " : mu = " + mu + ", sigma = " + sigma; } }

Ads help maintain this website.