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

smile.stat.distribution.ExponentialDistribution Maven / Gradle / Ivy

There is a newer version: 2.6.0
Show newest version
/******************************************************************************
 *                   Confidential Proprietary                                 *
 *         (c) Copyright Haifeng Li 2011, All Rights Reserved                 *
 ******************************************************************************/
package smile.stat.distribution;

import smile.math.Math;

/**
 * An exponential distribution describes the times between events in a Poisson
 * process, in which events occur continuously and independently at a constant
 * average rate. Exponential variables can also be used to model situations
 * where certain events occur with a constant probability per unit length,
 * such as the distance between mutations on a DNA strand. In real world
 * scenarios, the assumption of a constant rate is rarely satisfied. But if
 * we focus on a time interval during which the rate is roughly constant, the
 * exponential distribution can be used as a good approximate model.
 * 

* The exponential distribution may be viewed as a continuous counterpart of * the geometric distribution, which describes the number of Bernoulli trials * necessary for a discrete process to change state. In contrast, * the exponential distribution describes the time for a continuous process to * change state. *

* The probability density function of an exponential distribution is * f(x; λ) = λe-λx for x ≥ 0. The cumulative * distribution function is given by F(x; λ) = 1 - e-λ x * for x ≥ 0. An important property of the exponential distribution is that * it is memoryless. This means that if a random variable T is exponentially * distributed, its conditional probability obeys * Pr(T > s + t | T > s) = Pr(T > t) for all s, t ≥ 0. *

* In queuing theory, the service times of agents in a system are often modeled as * exponentially distributed variables. Reliability theory and reliability * engineering also make extensive use of the exponential distribution. Because * of the memoryless property of this distribution, it is well-suited to model * the constant hazard rate portion of the bathtub curve used in reliability * theory. The exponential distribution is however not appropriate to model * the overall lifetime of organisms or technical devices, because the "failure * rates" here are not constant: more failures occur for very young and for * very old systems. * * @author Haifeng Li */ public class ExponentialDistribution extends AbstractDistribution implements ExponentialFamily { private double lambda; /** * Constructor. * @param lambda rate parameter. */ public ExponentialDistribution(double lambda) { if (lambda <= 0) { throw new IllegalArgumentException("Invalid lambda: " + lambda); } this.lambda = lambda; } /** * Constructor. Parameter will be estimated from the data by MLE. */ public ExponentialDistribution(double[] data) { for (int i = 0; i < data.length; i++) { if (data[i] < 0) { throw new IllegalArgumentException("Samples contain negative values."); } } double mean = Math.mean(data); if (mean == 0) { throw new IllegalArgumentException("Samples are all zeros."); } lambda = 1 / mean; } /** * Returns the rate parameter. */ public double getLambda() { return lambda; } @Override public int npara() { return 1; } @Override public double mean() { return 1 / lambda; } @Override public double var() { return 1 / (lambda * lambda); } @Override public double sd() { return 1 / lambda; } @Override public double entropy() { return 1 - Math.log(lambda); } @Override public String toString() { return String.format("Exponential Distribution(%.4f)", lambda); } @Override public double rand() { return -1 / lambda * Math.log(Math.random()); } @Override public double p(double x) { if (x < 0) { return 0.0; } else { return lambda * Math.exp(-lambda * x); } } @Override public double logp(double x) { if (x < 0) { return Double.NEGATIVE_INFINITY; } else { return Math.log(lambda) - lambda * x; } } @Override public double cdf(double x) { if (x < 0) { return 0.0; } else { return 1 - Math.exp(-lambda * x); } } @Override public double quantile(double p) { if (p < 0.0 || p > 1.0) { throw new IllegalArgumentException("Invalid p: " + p); } return -Math.log(1 - p) / lambda; } @Override public Mixture.Component M(double[] x, double[] posteriori) { double alpha = 0.0; double mean = 0.0; for (int i = 0; i < x.length; i++) { alpha += posteriori[i]; mean += x[i] * posteriori[i]; } mean /= alpha; Mixture.Component c = new Mixture.Component(); c.priori = alpha; c.distribution = new ExponentialDistribution(1 / mean); return c; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy