25package umontreal.ssj.probdist;
27import umontreal.ssj.util.*;
28import umontreal.ssj.functions.MathFunction;
63 protected static final int PREC = 15;
67 private static final double PROB_MIN = Double.MIN_VALUE / EPS;
68 private static final boolean DETAIL =
false;
69 private static final double PARLIM = 1000.0;
72 private double lambda;
74 private int jmin = -1;
75 private int jmax = -1;
79 protected double lambda;
82 public Function(
double nu,
double lambda,
double u) {
88 public double evaluate(
double x) {
89 return u -
cdf(nu, lambda, x);
93 private static double getXLIM(
double nu,
double lambda) {
95 return (1600.0 + 20.0 * (nu + lambda));
103 double lam = pois.getLambda();
104 double sig = Math.sqrt(lam);
105 int j = (int) (lam - 7.0 * sig);
108 while (j > 0 && pois.cdf(j) > EPS)
118 double lam = pois.getLambda();
119 double sig = Math.sqrt(lam);
120 int j = (int) (lam + 7.0 * sig);
121 while (pois.barF(j) > EPS)
138 public double cdf(
double x) {
141 if (x >= getXLIM(nu, lambda))
144 if (nu >= PARLIM || lambda >= PARLIM)
145 return cdfPenev(
false, nu, lambda, x);
147 return cdfExact(pois, jmax, nu, lambda, x);
153 if (x >= getXLIM(nu, lambda))
156 if (nu >= PARLIM || lambda >= PARLIM)
157 return cdfPenev(
true, nu, lambda, x);
159 return barFExact(pois, jmin, nu, lambda, x);
184 public static double density(
double nu,
double lambda,
double x) {
186 throw new IllegalArgumentException(
"nu <= 0");
188 throw new IllegalArgumentException(
"lambda < 0");
193 if (x >= getXLIM(nu, lambda))
196 final double a = 0.5 * nu - 1.0;
197 double z = lambda * x;
200 final long JMAX = (long) (0.5 * z / (a + Math.sqrt(a * a + z)));
203 double termMax = -0.5 * (x + lambda) + 0.25 * (nu - 2) * Math.log(x / lambda)
207 termMax = Math.exp(termMax);
210 double sum = termMax;
211 double term = termMax;
215 while (j > 0 && term > sum * EPS) {
216 term *= y * j * (j + a);
224 while (term > sum * EPS) {
225 term *= y / (j * (j + a));
248 public static double cdf(
double nu,
double lambda,
double x) {
250 throw new IllegalArgumentException(
"nu <= 0");
252 throw new IllegalArgumentException(
"lambda < 0");
257 if (x >= getXLIM(nu, lambda))
260 if (nu >= PARLIM || lambda >= PARLIM)
261 return cdfPenev(
false, nu, lambda, x);
264 int j = calcJmax(pois);
265 return cdfExact(pois, j, nu, lambda, x);
268 private static double cdfExact(
PoissonDist pois,
int jmax,
double nu,
double lambda,
double x) {
269 final int JMED = (int) (lambda / 2.0);
272 double chicdf =
GammaDist.
cdf(j + 0.5 * nu, 0.5, PREC, x);
276 double chiterm = x / (j + 0.5 * nu) *
GammaDist.
density(j + 0.5 * nu, 0.5, x);
277 double prob = pois.
prob(j);
278 double sum = prob * chicdf;
281 System.out.println(
PrintfFormat.
NEWLINE +
"----------------------------------- cdf efficace");
282 System.out.print(
" j chi term chi CDF");
290 while (j >= 0 && (prob > sum * EPS || j >= JMED)) {
291 if (chicdf <= PROB_MIN) {
292 chicdf = GammaDist.cdf(j + nu / 2.0, 0.5, PREC, x);
293 chiterm = x / (j + 0.5 * nu) * GammaDist.density(j + nu / 2.0, 0.5, x);
295 chiterm *= (2 + 2 * j + nu) / x;
298 if (chicdf >= 1.0 - EPS)
299 return sum + pois.
cdf(j);
301 sum += prob * chicdf;
332 private static double cdfPearson(
boolean bar,
double nu,
double lambda,
double x) {
335 double t2 = (nu + 2.0 * lambda);
336 double t3 = (nu + 3.0 * lambda);
337 double lib = t2 * t2 * t2 / (t3 * t3);
338 double z = x + lambda * lambda / t3;
340 return GammaDist.barF(lib / 2.0, 0.5, PREC, t2 * z / t3);
342 return GammaDist.cdf(lib / 2.0, 0.5, PREC, t2 * z / t3);
345 private static double penevH(
double y) {
351 return ((1.0 - y) * Math.log1p(-y) + y - 0.5 * y * y) / (y * y);
354 private static double penevB(
double mu,
double s,
double h1) {
356 final double f = 1.0 + 2.0 * mu * s;
357 final double g = 1.0 + 3.0 * mu * s;
358 final double c = (f - 2.0 * h1 - s * f) / (f - 2.0 * h1);
359 double B = -1.5 * (1.0 + 4.0 * mu * s) / (f * f);
360 B += 5.0 * g * g / (3.0 * f * f * f) + 2.0 * g / ((s - 1.0) * f * f);
361 B += 3.0 * c / ((s - 1.0) * (s - 1.0) * f);
362 B -= c * c * (1.0 + 2.0 * penevH(c)) / (2.0 * (s - 1.0) * (s - 1.0) * f);
366 private static double getPenevLim(
double nu,
double lam) {
374 private static double cdfPenev(
boolean bar,
double nu,
double lambda,
double x) {
381 double lim = getPenevLim(nu, lambda);
382 double mean = nu + lambda;
383 if (x >= mean - lim && x <= mean + lim)
384 return cdfPearson(bar, nu, lambda, x);
386 final double mu = lambda / nu;
387 final double s = (Math.sqrt(1.0 + 4.0 * x * mu / nu) - 1.0) / (2.0 * mu);
390 final double h1 = penevH(1.0 - s);
391 final double B = penevB(mu, s, h1);
392 final double f = 1.0 + 2.0 * mu * s;
393 double z = nu * (s - 1.0) * (s - 1.0) * (0.5 / s + mu - h1 / s) - Math.log(1.0 / s - 2.0 * h1 / (s * f))
396 if (z < 0.0 || z != z)
397 return cdfPearson(bar, nu, lambda, x);
403 return NormalDist.barF01(z);
405 return NormalDist.cdf01(z);
414 public static double barF(
double nu,
double lambda,
double x) {
416 throw new IllegalArgumentException(
"nu <= 0");
418 throw new IllegalArgumentException(
"lambda < 0");
423 if (x >= getXLIM(nu, lambda))
426 if (nu >= PARLIM || lambda >= PARLIM)
427 return cdfPenev(
true, nu, lambda, x);
430 int j = calcJmin(pois);
431 return barFExact(pois, j, nu, lambda, x);
456 private static double barFExact(
PoissonDist pois,
int jmin,
double nu,
double lambda,
double x) {
457 final int JMED = (int) (lambda / 2.0);
464 double prob = pois.
prob(j);
465 double sum = prob * chibar;
469 System.out.println(
PrintfFormat.
NEWLINE +
"--------------------------------- barF efficace");
470 System.out.print(
" j Poisson p chi term");
478 while (prob > sum * EPS || j <= JMED) {
479 if (chibar <= PROB_MIN) {
480 chibar = GammaDist.barF(j + nu / 2.0, 0.5, PREC, x);
481 chiterm = 2.0 * GammaDist.density(j + 0.5 * nu, 0.5, x);
483 chiterm *= x / (2 * j - 2 + nu);
487 return sum + pois.
barF(j);
489 sum += prob * chibar;
506 public static double inverseF(
double nu,
double lambda,
double u) {
508 throw new IllegalArgumentException(
"nu <= 0");
510 throw new IllegalArgumentException(
"lambda < 0");
511 if (u < 0.0 || u > 1.0)
512 throw new IllegalArgumentException(
"u not in [0,1]");
514 return Double.POSITIVE_INFINITY;
520 double x = inverse9(nu, lambda, u);
521 double v =
cdf(nu, lambda, x);
523 Function f =
new Function(nu, lambda, u);
527 v = getXLIM(nu, lambda);
533 private static double inverse9(
double nu,
double lambda,
double u) {
536 double a = nu + lambda;
537 double b = (nu + 2.0 * lambda) / (a * a);
538 double t = z * Math.sqrt(2.0 * b / 9.0) - 2.0 * b / 9.0 + 1.0;
539 return a * t * t * t;
549 public static double getMean(
double nu,
double lambda) {
551 throw new IllegalArgumentException(
"nu <= 0");
553 throw new IllegalArgumentException(
"lambda <= 0");
566 throw new IllegalArgumentException(
"nu <= 0");
568 throw new IllegalArgumentException(
"lambda <= 0");
569 return 2.0 * (nu + 2.0 * lambda);
603 throw new IllegalArgumentException(
"nu <= 0");
605 throw new IllegalArgumentException(
"lambda < 0");
607 throw new IllegalArgumentException(
"lambda = 0");
609 this.lambda = lambda;
611 if (nu >= PARLIM || lambda >= PARLIM)
614 jmax = calcJmax(pois);
615 jmin = calcJmin(pois);
622 double[] retour = { nu, lambda };
630 return getClass().getSimpleName() +
": nu = " + nu +
", lambda = " + lambda;
double getNu()
Returns the parameter of this object.
double density(double x)
Returns , the density evaluated at .
double[] getParams()
Returns a table containing the parameters of the current distribution.
double getMean()
Returns the mean.
static double density(double nu, double lambda, double x)
Computes the density function ( nc-fchi2 ) for a noncentral chi-square distribution with nu degrees ...
double inverseF(double u)
Returns the inverse distribution function .
static double getStandardDeviation(double nu, double lambda)
Computes and returns the standard deviation of the noncentral chi-square distribution with parameters...
String toString()
Returns a String containing information about the current distribution.
double cdf(double x)
Returns the distribution function .
static double inverseF(double nu, double lambda, double u)
Computes the inverse of the noncentral chi-square distribution with.
void setParams(double nu, double lambda)
Sets the parameters nu and lambda of this object.
static double getMean(double nu, double lambda)
Computes and returns the mean of the noncentral chi-square distribution with parameters nu and lam...
ChiSquareNoncentralDist(double nu, double lambda)
Constructs a noncentral chi-square distribution with nu degrees of freedom and noncentrality paramet...
double getVariance()
Returns the variance.
static double getVariance(double nu, double lambda)
Computes and returns the variance of the noncentral chi-square distribution with parameters nu and ...
static double barF(double nu, double lambda, double x)
Computes the complementary noncentral chi-square distribution function with nu degrees of freedom an...
static double cdf(double nu, double lambda, double x)
Computes the noncentral chi-square distribution function ( nc-cdfchi2 ) with nu degrees of freedom a...
double getLambda()
Returns the parameter of this object.
double getStandardDeviation()
Returns the standard deviation.
double barF(double x)
Returns the complementary distribution function.
Classes implementing continuous distributions should inherit from this base class.
Extends the class ContinuousDistribution for the gamma distribution tjoh95a (page 337) with shape pa...
double inverseF(double u)
Returns the inverse distribution function .
double cdf(double x)
Returns the distribution function .
double density(double x)
Returns , the density evaluated at .
double barF(double x)
Returns the complementary distribution function.
Extends the class ContinuousDistribution for the normal distribution (e.g., tjoh95a (page 80)).
static double inverseF01(double u)
Same as inverseF(0, 1, u).
Extends the class DiscreteDistributionInt for the Poisson distribution slaw00a (page 325) with mean.
double cdf(int x)
Returns the distribution function evaluated at (see ( FDistDisc )).
double barF(int x)
Returns , the complementary distribution function.
double prob(int x)
Returns , the probability of .
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 double lnFactorial(int n)
Returns the value of , the natural logarithm of factorial .
static final double TEN_NEG_POW[]
Contains the precomputed negative powers of 10.
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.