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

umontreal.iro.lecuyer.probdist.DiscreteDistributionInt 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:        DiscreteDistributionInt
 * Description:  discrete distributions over the integers
 * 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;

/**
 * Classes implementing discrete distributions over the integers should
 * inherit from this class.
 * It specifies the signatures of methods for computing the mass function
 * (or probability) 
 * p(x) = P[X = x], distribution function F(x),
 * complementary distribution function bar(F)(x),
 * and inverse distribution function F-1(u), for a random variable X
 * with a discrete distribution over the integers.
 * 
 * 

* WARNING: the complementary distribution function is defined as * * bar(F)(j) = P[X >= j] (for integers j, so that for discrete distributions * in SSJ, * F(j) + bar(F)(j)≠1 since both include the term P[X = j]. * *

* The implementing classes provide both static and non-static methods * to compute the above functions. * The non-static methods require the creation of an object of * class {@link umontreal.iro.lecuyer.probdist.DiscreteDistributionInt DiscreteDistributionInt}; * all the non-negligible terms of the mass and distribution functions will be * precomputed by the constructor and kept in arrays. Subsequent accesses * will be very fast. * The static methods do not require the construction of an object. * These static methods are not specified in this abstract class because * the number and types of their parameters depend on the distribution. * When methods have to be called several times * with the same parameters for the distributions, * it is usually more efficient to create an object and use its non-static * methods instead of the static ones. * This trades memory for speed. * */ public abstract class DiscreteDistributionInt implements Distribution { /** * Environment variable that determines what probability terms can * be considered as negligible when building precomputed tables for * distribution and mass functions. Probabilities smaller than EPSILON * are not stored in the * {@link umontreal.iro.lecuyer.probdist.DiscreteDistribution DiscreteDistribution} objects * (such as those of class {@link PoissonDist}, etc.), but are computed * directly each time they are needed (which should be very seldom). * The default value is set to 10-16. * */ public static double EPSILON = 1.0e-16; /* For better precision in the tails, we keep the cumulative probabilities (F) in cdf[x] for x <= xmed (i.e. cdf[x] is the sum off all the probabi- lities pdf[i] for i <= x), and the complementary cumulative probabilities (1 - F) in cdf[x] for x > xmed (i.e. cdf[x] is the sum off all the probabilities pdf[i] for i >= x). */ protected final static double EPS_EXTRA = 1.0e-6; protected double cdf[] = null; // cumulative probabilities protected double pdf[] = null; // probability terms or mass distribution protected int xmin = 0; // pdf[x] < EPSILON for x < xmin protected int xmax = 0; // pdf[x] < EPSILON for x > xmax // xmed is such that cdf[xmed] >= 0.5 and cdf[xmed - 1] < 0.5. protected int xmed = 0; /* cdf[x] = F(x) for x <= xmed, and cdf[x] = bar_F(x) for x > xmed */ protected int supportA = Integer.MIN_VALUE; protected int supportB = Integer.MAX_VALUE; /** * Returns p(x), the probability of x. * * @param x value at which the mass function must be evaluated * * @return the mass function evaluated at x * */ public abstract double prob (int x); /** * Returns the distribution function F evaluated at x * (see). * Calls the {@link #cdf(int) cdf}(int) method. * * @param x value at which the distribution function must be evaluated * * @return the distribution function evaluated at x * */ public double cdf (double x) { return cdf ((int) x); } /** * Returns the distribution function F evaluated at x * (see). * * @param x value at which the distribution function must be evaluated * * @return the distribution function evaluated at x * */ public abstract double cdf (int x); /** * Returns bar(F)(x), the complementary distribution function. * Calls the {@link #barF(int) barF}(int) method. * * @param x value at which the complementary distribution function * must be evaluated * * @return the complementary distribution function evaluated at x * */ public double barF (double x) { return barF ((int) x); } /** * Returns bar(F)(x), the complementary * distribution function. See the WARNING above. * * @param x value at which the complementary distribution function * must be evaluated * * @return the complementary distribution function evaluated at x * */ public double barF (int x) { return 1.0 - cdf (x - 1); } /** * Returns the lower limit xa of the support of the probability * mass function. The probability is 0 for all x < xa. * * @return x lower limit of support * */ public int getXinf() { return supportA; } /** * Returns the upper limit xb of the support of the probability * mass function. The probability is 0 for all x > xb. * * @return x upper limit of support * */ public int getXsup() { return supportB; } /** * Returns the inverse distribution function * F-1(u), where * 0 <= u <= 1. Calls the inverseFInt method. * * @param u value in the interval (0, 1) for which * the inverse distribution function is evaluated * * @return the inverse distribution function evaluated at u * @exception IllegalArgumentException if u is not in the interval (0, 1) * * @exception ArithmeticException if the inverse cannot be computed, * for example if it would give infinity in a theoritical context * * */ public double inverseF (double u) { return inverseFInt (u); } /** * Returns the inverse distribution function * F-1(u), where * 0 <= u <= 1. * The default implementation uses binary search. * * @param u value in the interval (0, 1) for which * the inverse distribution function is evaluated * * @return the inverse distribution function evaluated at u * @exception IllegalArgumentException if u is not in the interval (0, 1) * * @exception ArithmeticException if the inverse cannot be computed, * for example if it would give infinity in a theoritical context * * */ public int inverseFInt (double u) { int i, j, k; if (u < 0.0 || u > 1.0) throw new IllegalArgumentException ("u is not in [0,1]"); if (u <= 0.0) return supportA; if (u >= 1.0) return supportB; // Remember: the upper part of cdf contains the complementary distribu- // tion for xmed < s <= xmax, and the lower part of cdf the // distribution for xmin <= x <= xmed if (u <= cdf[xmed - xmin]) { // In the lower part of cdf if (u <= cdf[0]) return xmin; i = 0; j = xmed - xmin; while (i < j) { k = (i + j) / 2; if (u > cdf[k]) i = k + 1; else j = k; } } else { // In the upper part of cdf u = 1 - u; if (u < cdf[xmax - xmin]) return xmax; i = xmed - xmin + 1; j = xmax - xmin; while (i < j) { k = (i + j) / 2; if (u < cdf[k]) i = k + 1; else j = k; } i--; } return i + xmin; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy