/* *
 * Title:        

* Description:

* Copyright: Copyright (c)

* Company:

* @author * @version 1.0 */ package umontreal.iro.lecuyer.probdist; import umontreal.iro.lecuyer.util.Num; import umontreal.iro.lecuyer.util.RootFinder; import umontreal.iro.lecuyer.functions.MathFunction; /** * Extends the class {@link DiscreteDistributionInt} for * the logarithmic distribution. It has shape parameter * θ, where * 0 < θ < 1. * Its mass function is *

*

*
* p(x) = - θx/(x log(1 - θ)        for x = 1, 2, 3,... *

* Its distribution function is *

*

*
* F(x) = -1/log(1-θ)∑i=1xθi/i, & for x > 0. *

* */ public class LogarithmicDist extends DiscreteDistributionInt { private double theta; private double t; private static class Function implements MathFunction { protected double mean; public Function (double mean) { this.mean = mean; } public double evaluate (double x) { if (x <= 0.0 || x >= 1.0) return 1.0e200; return (x + mean * (1.0 - x) * Math.log1p (-x)); } } /** * Constructs a logarithmic distribution with parameter θ = * theta. * */ public LogarithmicDist (double theta) { setTheta (theta); } public double prob (int x) { if (x < 1) return 0; return t*Math.pow (theta, x)/x; } public double cdf (int x) { if (x < 1) return 0; double res = prob (1); double term = res; for (int i = 2; i <= x; i++) { term *= theta; res += term/i; } return res; } public double barF (int x) { if (x <= 1) return 1.0; double res = prob (x); double term = res; int i = x + 1; while (term > EPSILON) { term *= theta*(i-1)/i; res += term; } return res; } public int inverseFInt (double u) { return inverseF (theta, u); } public double getMean() { return LogarithmicDist.getMean (theta); } public double getVariance() { return LogarithmicDist.getVariance (theta); } public double getStandardDeviation() { return LogarithmicDist.getStandardDeviation (theta); } /** * Computes the logarithmic probability p(x). * */ public static double prob (double theta, int x) { if (theta <= 0 || theta >= 1) throw new IllegalArgumentException ("theta not in range (0,1)"); if (x < 1) return 0; return -1.0/Math.log1p(-theta) * Math.pow (theta, x)/x; } /** * Computes the distribution function F(x). * */ public static double cdf (double theta, int x) { if (theta <= 0 || theta >= 1) throw new IllegalArgumentException ("theta not in range (0,1)"); if (x < 1) return 0; double res = prob (theta, 1); double term = res; for (int i = 2; i <= x; i++) { term *= theta; res += term/i; } return res; } /** * Computes the complementary distribution function. * WARNING: The complementary distribution function is defined as * * bar(F)(x) = P[X >= x]. * */ public static double barF (double theta, int x) { if (theta <= 0 || theta >= 1) throw new IllegalArgumentException ("theta not in range (0,1)"); if (x <= 1) return 1.0; double res = prob (theta, x); double term = res; int i = x + 1; while (term > EPSILON) { term *= theta*(i-1)/i; res += term; } return res; } public static int inverseF (double theta, double u) { throw new UnsupportedOperationException(); } /** * Estimates the parameter θ of the logarithmic 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(&thetas;)] * */ 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]; } double mean = (double) sum / (double) n; Function f = new Function (mean); parameters[0] = RootFinder.brentDekker (1e-15, 1.0-1e-15, f, 1e-7); return parameters; } /** * Creates a new instance of a logarithmic distribution with parameter * θ 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 LogarithmicDist getInstanceFromMLE (int[] x, int n) { double parameters[] = getMLE (x, n); return new LogarithmicDist (parameters[0]); } /** * Computes and returns the mean * of the logarithmic distribution with parameter θ = theta. * * @return the mean of the logarithmic distribution * * E[X] = - θ/((1 - θ)ln(1 - θ)) * */ public static double getMean (double theta) { if (theta <= 0.0 || theta >= 1.0) throw new IllegalArgumentException ("theta not in range (0,1)"); return ((-1 / Math.log1p(-theta)) * (theta / (1 - theta))); } /** * Computes and returns the variance * of the logarithmic distribution with parameter θ = theta. * * @return the variance of the logarithmic distribution * * Var[X] = - θ(θ + ln(1 - θ))/((1 - θ)2(ln(1 - θ))2) * */ public static double getVariance (double theta) { if (theta <= 0.0 || theta >= 1.0) throw new IllegalArgumentException ("theta not in range (0,1)"); double v = Math.log1p(-theta); return ((-theta * (theta + v)) / ((1 - theta) * (1 - theta) * v * v)); } /** * Computes and returns the standard deviation of the * logarithmic distribution with parameter θ = theta. * * @return the standard deviation of the logarithmic distribution * */ public static double getStandardDeviation (double theta) { return Math.sqrt (LogarithmicDist.getVariance (theta)); } /** * Returns the θ associated with this object. * */ public double getTheta() { return theta; } /** * Sets the θ associated with this object. * */ public void setTheta (double theta) { if (theta <= 0 || theta >= 1) throw new IllegalArgumentException ("theta not in range (0,1)"); this.theta = theta; t = -1.0/Math.log1p (-theta); supportA = 1; } /** * Return a table containing the parameters of the current distribution. * * */ public double[] getParams () { double[] retour = {theta}; return retour; } public String toString () { return getClass().getSimpleName() + " : theta = " + theta; } }

Ads help maintain this website.