25package umontreal.ssj.probdist;
27import umontreal.ssj.util.*;
28import umontreal.ssj.functions.MathFunction;
55 private static final double EPS2 = 1000.0 *
EPSILON;
62 public Func1(
double p,
int[] x,
int m) {
68 public double evaluate(
double gam) {
73 for (
int j = 0; j < m; j++)
75 return sum / m + Math.log(p) -
Num.
digamma(gam);
82 protected double mean;
85 public Function(
int m,
int max,
double mean,
int[] Fj) {
89 this.Fj =
new int[Fj.length];
90 System.arraycopy(Fj, 0, this.Fj, 0, Fj.length);
93 public double evaluate(
double s) {
96 double p = s / (s + mean);
98 for (
int j = 0; j < max; j++)
99 sum += Fj[j] / (s + (
double) j);
101 return sum + m * Math.log(p);
105 private static class FuncInv
extends Function implements
MathFunction {
107 public FuncInv(
int m,
int max,
double mean,
int[] Fj) {
108 super(m, max, mean, Fj);
111 public double evaluate(
double nu) {
112 double r = nu * mean;
114 for (
int j = 0; j < max; j++)
115 sum += Fj[j] / (1.0 + nu * j);
117 return (nu * sum - m * Math.log1p(r));
154 public static double MAXN = 100000;
160 protected NegativeBinomialDist() {
188 return prob(n, p, x);
190 if (x > xmax || x < xmin)
191 return prob(n, p, x);
193 return pdf[x - xmin];
196 public double cdf(
int x) {
210 return cdf[x - xmin];
213 return 1.0 -
cdf[x + 1 - xmin];
239 return cdf[x - xmin];
241 return 1.0 -
cdf[x - 1 - xmin];
245 if ((
cdf ==
null) || (u <= EPS2))
248 return super.inverseFInt(u);
252 return NegativeBinomialDist.getMean(n, p);
256 return NegativeBinomialDist.getVariance(n, p);
260 return NegativeBinomialDist.getStandardDeviation(n, p);
267 public static double prob(
double n,
double p,
int x) {
273 if (p < 0.0 || p > 1.0)
274 throw new IllegalArgumentException(
"p not in [0, 1]");
276 throw new IllegalArgumentException(
"n <= 0.0");
291 throw new IllegalArgumentException(
"term overflow");
298 public static double cdf(
double n,
double p,
int x) {
300 final int LIM1 = 100000;
301 double sum, term, termmode;
303 final double q = 1.0 - p;
305 if (p < 0.0 || p > 1.0)
306 throw new IllegalArgumentException(
"p not in [0, 1]");
308 throw new IllegalArgumentException(
"n <= 0.0");
318 mode = 1 + (int) Math.floor((n * q - 1.0) / p);
325 sum = term = termmode =
prob(n, p, mode);
326 for (i = mode; i > 0; i--) {
327 term *= i / (q * (n + i - 1.0));
334 for (i = mode; i < x; i++) {
335 term *= q * (n + i) / (i + 1);
353 public static double barF(
double n,
double p,
int x) {
354 return 1.0 -
cdf(n, p, x - 1);
360 public static int inverseF(
double n,
double p,
double u) {
361 if (u < 0.0 || u > 1.0)
362 throw new IllegalArgumentException(
"u is not in [0,1]");
363 if (p < 0.0 || p > 1.0)
364 throw new IllegalArgumentException(
"p not in [0, 1]");
366 throw new IllegalArgumentException(
"n <= 0");
371 if (u <=
prob(n, p, 0))
374 return Integer.MAX_VALUE;
376 double sum, term, termmode;
377 final double q = 1.0 - p;
380 int mode = 1 + (int) Math.floor((n * q - 1.0) / p);
384 term =
prob(n, p, i);
385 while ((term >= u) && (term > Double.MIN_NORMAL)) {
387 term =
prob(n, p, i);
390 if (term <= Double.MIN_NORMAL) {
392 term =
prob(n, p, i);
393 while (term >= u && (term > Double.MIN_NORMAL)) {
394 term *= i / (q * (n + i - 1.0));
400 sum = termmode =
prob(n, p, i);
402 for (i = mode; i > 0; i--) {
403 term *= i / (q * (n + i - 1.0));
414 while ((sum < u) && (sum > prev)) {
415 term *= q * (n + i) / (i + 1);
424 term *= i / (q * (n + i - 1.0));
447 public static double[]
getMLE(
int[] x,
int m,
double n) {
449 throw new IllegalArgumentException(
"m <= 0");
451 for (
int i = 0; i < m; i++) {
455 double[] param =
new double[1];
456 param[0] = n / (n + mean);
471 double parameters[] =
getMLE(x, m, n);
472 return new NegativeBinomialDist(n, parameters[0]);
491 public static double[]
getMLE1(
int[] x,
int m,
double p) {
493 throw new IllegalArgumentException(
"m <= 0");
495 for (
int i = 0; i < m; i++)
499 double gam0 = mean * p / (1.0 - p);
500 double[] param =
new double[1];
501 Func1 f =
new Func1(p, x, m);
517 double param[] =
getMLE1(x, m, p);
518 return new NegativeBinomialDist(param[0], p);
539 public static double[]
getMLE(
int[] x,
int m) {
541 throw new IllegalArgumentException(
"m<= 0");
544 int max = Integer.MIN_VALUE;
546 for (i = 0; i < m; i++) {
551 double mean = sum / (double) m;
554 for (i = 0; i < m; i++)
555 var += (x[i] - mean) * (x[i] - mean);
559 throw new UnsupportedOperationException(
"mean >= variance");
561 double estimGamma = (mean * mean) / (var - mean);
563 int[] Fj =
new int[max];
564 for (j = 0; j < max; j++) {
566 for (i = 0; i < m; i++)
573 double[] param =
new double[3];
574 Function f =
new Function(m, max, mean, Fj);
576 param[2] = param[1] / (param[1] + mean);
585 double parameters[] =
new double[2];
586 parameters[0] = param[1];
587 parameters[1] = param[2];
601 double parameters[] =
getMLE(x, m);
602 return new NegativeBinomialDist(parameters[0], parameters[1]);
622 throw new IllegalArgumentException(
"m <= 0");
625 int max = Integer.MIN_VALUE;
627 for (i = 0; i < m; i++) {
635 for (i = 0; i < m; i++)
636 var += (x[i] - mean) * (x[i] - mean);
640 throw new UnsupportedOperationException(
"mean >= variance");
643 int[] Fj =
new int[max];
644 for (j = 0; j < max; j++) {
646 for (i = 0; i < m; i++)
653 FuncInv f =
new FuncInv(m, max, mean, Fj);
665 public static double getMean(
double n,
double p) {
666 if (p < 0.0 || p > 1.0)
667 throw new IllegalArgumentException(
"p not in [0, 1]");
669 throw new IllegalArgumentException(
"n <= 0");
671 return (n * (1 - p) / p);
682 if (p < 0.0 || p > 1.0)
683 throw new IllegalArgumentException(
"p not in [0, 1]");
685 throw new IllegalArgumentException(
"n <= 0");
687 return (n * (1 - p) / (p * p));
697 return Math.sqrt(NegativeBinomialDist.getVariance(n, p));
738 if (p < 0.0 || p > 1.0)
739 throw new IllegalArgumentException(
"p not in [0, 1]");
741 throw new IllegalArgumentException(
"n <= 0");
747 mode = 1 + (int) Math.floor((n * (1.0 - p) - 1.0) / p);
755 if (mode < 0.0 || mode >
MAXN) {
767 Nmax = (int) (n * (1.0 - p) / p + 16 * Math.sqrt(n * (1.0 - p) / (p * p)));
770 P =
new double[1 + Nmax];
779 while (i > 0 && P[i] >= epsilon) {
780 P[i - 1] = P[i] * i / ((1.0 - p) * (n + i - 1));
787 while (P[i] >= epsilon) {
788 P[i + 1] = P[i] * (1.0 - p) * (n + i) / (i + 1);
793 double[] nT =
new double[1 + Nmax];
794 System.arraycopy(P, 0, nT, 0, P.length);
801 for (i = imin; i <= imax; i++)
806 F =
new double[1 + Nmax];
809 while (i < imax && F[i] < 0.5) {
811 F[i] = F[i - 1] + P[i];
823 F[i] = P[i] + F[i + 1];
829 pdf =
new double[imax + 1 - imin];
830 cdf =
new double[imax + 1 - imin];
831 System.arraycopy(P, imin, pdf, 0, imax + 1 - imin);
832 System.arraycopy(F, imin,
cdf, 0, imax + 1 - imin);
841 double[] retour = { n, p };
849 return getClass().getSimpleName() +
" : n = " + n +
", p = " + p;
Extends the class ContinuousDistribution for the beta distribution.
double barF(double x)
Returns the complementary distribution function.
double cdf(double x)
Returns the distribution function .
Classes implementing discrete distributions over the integers should inherit from this class.
static double EPSILON
Environment variable that determines what probability terms can be considered as negligible when buil...
static double MAXN
If the maximum term is greater than this constant, then the tables will not be precomputed.
static double prob(double n, double p, int x)
Computes the probability defined in ( fmass-negbin ).
static double barF(double n, double p, int x)
Returns , the complementary distribution function.
double getGamma()
Returns the parameter of this object.
static int inverseF(double n, double p, double u)
Computes the inverse function without precomputing tables.
void setParams(double n, double p)
Sets the parameter and of this object.
static double[] getMLE(int[] x, int m)
Estimates the parameter of the negative binomial distribution using the maximum likelihood method,...
static NegativeBinomialDist getInstanceFromMLE(int[] x, int m)
Creates a new instance of a negative binomial distribution with parameters and estimated using the ...
double barF(int x)
Returns , the complementary distribution function.
static double getMLEninv(int[] x, int m)
Estimates and returns the parameter of the negative binomial distribution using the maximum likeliho...
static double getStandardDeviation(double n, double p)
Computes and returns the standard deviation of the negative binomial distribution with parameters an...
static double getVariance(double n, double p)
Computes and returns the variance of the negative binomial distribution with parameters and.
double cdf(int x)
Returns the distribution function evaluated at (see ( FDistDisc )).
double[] getParams()
Return a table containing the parameters of the current distribution.
double prob(int x)
Returns , the probability of .
double getVariance()
Returns the variance of the distribution function.
static double getMean(double n, double p)
Computes and returns the mean of the negative binomial distribution with parameters and .
double getN()
Returns the parameter of this object.
static double cdf(double n, double p, int x)
Computes the distribution function.
static double[] getMLE(int[] x, int m, double n)
Estimates the parameter of the negative binomial distribution using the maximum likelihood method,...
int inverseFInt(double u)
Returns the inverse distribution function , where.
static NegativeBinomialDist getInstanceFromMLE(int[] x, int m, double n)
Creates a new instance of a negative binomial distribution with parameters given and estimated usin...
NegativeBinomialDist(double n, double p)
Creates an object that contains the probability terms ( fmass-negbin ) and the distribution function ...
double getMean()
Returns the mean of the distribution function.
static double[] getMLE1(int[] x, int m, double p)
Estimates the parameter of the negative binomial distribution using the maximum likelihood method,...
double getP()
Returns the parameter of this object.
String toString()
Returns a String containing information about the current distribution.
static NegativeBinomialDist getInstanceFromMLE1(int[] x, int m, double p)
Creates a new instance of a negative binomial distribution with parameters given and estimated usin...
double getStandardDeviation()
Returns the standard deviation of the distribution function.
This class provides various constants and methods to compute numerical quantities such as factorials,...
static double lnGamma(double x)
Returns the natural logarithm of the gamma function evaluated at x.
static final int DBL_MIN_EXP
Smallest int such that is representable (approximately) as a normalised double.
static double lnFactorial(int n)
Returns the value of , the natural logarithm of factorial .
static final int DBL_MAX_EXP
Largest int such that is representable (approximately) as a double.
static double digamma(double x)
Returns the value of the logarithmic derivative of the Gamma function .
static final double LN2
The values of .
This class provides numerical methods to solve non-linear equations.
static double brentDekker(double a, double b, MathFunction f, double tol)
Computes a root of the function in f using the Brent-Dekker method.
This interface should be implemented by classes which represent univariate mathematical functions.