/* *
* Title:
* Description:
* Copyright: Copyright (c)
* Company:
* @author
* @version 1.0
*/
package umontreal.iro.lecuyer.probdist;
import umontreal.iro.lecuyer.util.Num;
/**
* Extends the class {@link DiscreteDistributionInt} for
* the geometric distribution with parameter
* p, where 0 < p < 1.
* Its mass function is
*
*
*
* p(x) = p (1 - p)x, for x = 0, 1, 2,…
*
* The distribution function is given by
*
*
*
* F(x) = 1 - (1 - p)x+1, for x = 0, 1, 2,…
*
* and its inverse is
*
*
*
* F-1(u) = floor(ln(1 - u)/ln(1 - p)), for 0 <= u < 1.
*
*
*/
public class GeometricDist extends DiscreteDistributionInt {
private double p;
private double vp;
/**
* Constructs a geometric distribution with parameter p.
*
*/
public GeometricDist (double p) {
if (p < 0 || p > 1)
throw new IllegalArgumentException ("p not in range (0,1)");
setP(p);
vp = Math.log1p (-p);
}
public double prob (int x) {
return prob (p, x);
}
public double cdf (int x) {
return cdf (p, x);
}
public double barF (int x) {
return barF (p, x);
}
public int inverseFInt (double u) {
if (u > 1.0 || u < 0.0)
throw new IllegalArgumentException ("u not in [0,1]");
if (p >= 1.0)
return 0;
if (u <= 0.0)
return 0;
if (u >= 1.0 || p <= 0.0)
return Integer.MAX_VALUE;
return (int)Math.floor (Math.log1p (-u)/vp);
}
public double getMean() {
return GeometricDist.getMean (p);
}
public double getVariance() {
return GeometricDist.getVariance (p);
}
public double getStandardDeviation() {
return GeometricDist.getStandardDeviation (p);
}
/**
* Computes the geometric probability p(x).
*
*/
public static double prob (double p, int x) {
if (p < 0 || p > 1)
throw new IllegalArgumentException ("p not in range (0,1)");
if (p <= 0)
return 0;
if (p >= 1)
return 0;
if (x < 0)
return 0;
return p*Math.pow (1 - p, x);
}
/**
* Computes the distribution function F(x).
*
*/
public static double cdf (double p, int x) {
if (p < 0.0 || p > 1.0)
throw new IllegalArgumentException ("p not in [0,1]");
if (x < 0)
return 0.0;
if (p >= 1.0) // In fact, p == 1
return 1.0;
if (p <= 0.0) // In fact, p == 0
return 0.0;
return 1.0 - Math.pow (1.0 - p, (double)x + 1.0);
}
/**
* Computes the complementary distribution function.
* WARNING: The complementary distribution function is defined as
*
* bar(F)(x) = P[X >= x].
*
*/
public static double barF (double p, int x) {
if (p < 0.0 || p > 1.0)
throw new IllegalArgumentException ("p not in [0,1]");
if (x < 0)
return 1.0;
if (p >= 1.0) // In fact, p == 1
return 0.0;
if (p <= 0.0) // In fact, p == 0
return 1.0;
return Math.pow (1.0 - p, x);
}
private static double pold = -1.0;
private static double v = -1.0;
/**
* Computes the inverse of the geometric
* distribution.
*
*/
public static int inverseF (double p, double u) {
if (p > 1.0 || p < 0.0)
throw new IllegalArgumentException ( "p not in [0,1]");
if (u > 1.0 || u < 0.0)
throw new IllegalArgumentException ("u not in [0,1]");
if (p >= 1.0)
return 0;
if (u <= 0.0)
return 0;
if (u >= 1.0 || p <= 0.0)
return Integer.MAX_VALUE;
if (pold != p) {
pold = p;
v = Math.log1p (-p);
}
return (int)Math.floor (Math.log1p (-u)/v);
}
/**
* Estimates the parameter p of the geometric distribution
* using the maximum likelihood method, from the n observations
* x[i],
* i = 0, 1,…, n - 1. The estimate is returned in element 0
* of the returned array.
*
* @param x the list of observations used to evaluate parameters
*
* @param n the number of observations used to evaluate parameters
*
* @return returns the parameter [hat(p)]
*
*/
public static double[] getMLE (int[] x, int n) {
if (n <= 0)
throw new IllegalArgumentException ("n <= 0");
double parameters[];
parameters = new double[1];
double sum = 0.0;
for (int i = 0; i < n; i++) {
sum += x[i];
}
parameters[0] = 1.0 / (((double) sum / (double) n) + 1.0);
return parameters;
}
/**
* Creates a new instance of a geometric distribution with parameter p
* 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 GeometricDist getInstanceFromMLE (int[] x, int n) {
double parameters[] = getMLE (x, n);
return new GeometricDist (parameters[0]);
}
/**
* Computes and returns the mean
* E[X] = (1 - p)/p of the
* geometric distribution with parameter p.
*
* @return the mean of the geometric distribution
* E[X] = (1 - p)/p
*
*/
public static double getMean (double p) {
if (p < 0.0 || p > 1.0)
throw new IllegalArgumentException ("p not in range (0,1)");
return (1 - p) / p;
}
/**
* Computes and returns the variance
* Var[X] = (1 - p)/p2
* of the geometric distribution with parameter p.
*
* @return the variance of the Geometric distribution
*
* Var[X] = (1 - p)/p2
*
*/
public static double getVariance (double p) {
if (p < 0.0 || p > 1.0)
throw new IllegalArgumentException ("p not in range (0,1)");
return ((1 - p) / (p * p));
}
/**
* Computes and returns the standard deviation of the geometric
* distribution with parameter p.
*
* @return the standard deviation of the geometric distribution
*
*/
public static double getStandardDeviation (double p) {
return Math.sqrt (GeometricDist.getVariance (p));
}
/**
* Returns the p associated with this object.
*
*/
public double getP() {
return p;
}
/**
* Resets the value of p associated with this object.
*
*/
public void setP (double p) {
this.p = p;
supportA = 0;
}
/**
* Return a table containing the parameters of the current distribution.
*
*
*/
public double[] getParams () {
double[] retour = {p};
return retour;
}
public String toString () {
return getClass().getSimpleName() + " : p = " + p;
}
}
Ads help maintain this website.