All Downloads are FREE. Search and download functionalities are using the official Maven repository.

umontreal.iro.lecuyer.probdist.LognormalDist Maven / Gradle / Ivy

Go to download

SSJ is a Java library for stochastic simulation, developed under the direction of Pierre L'Ecuyer, in the Département d'Informatique et de Recherche Opérationnelle (DIRO), at the Université de Montréal. It provides facilities for generating uniform and nonuniform random variates, computing different measures related to probability distributions, performing goodness-of-fit tests, applying quasi-Monte Carlo methods, collecting (elementary) statistics, and programming discrete-event simulations with both events and processes.

The newest version!


/*
 * Class:        LognormalDist
 * Description:  lognormal distribution
 * Environment:  Java
 * Software:     SSJ 
 * Copyright (C) 2001  Pierre L'Ecuyer and Université de Montréal
 * Organization: DIRO, Université de Montréal
 * @author       
 * @since

 * SSJ is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License (GPL) as published by the
 * Free Software Foundation, either version 3 of the License, or
 * any later version.

 * SSJ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * A copy of the GNU General Public License is available at
   GPL licence site.
 */

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; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy