25package umontreal.ssj.probdist;
27import umontreal.ssj.util.*;
55 protected double alpha;
56 protected double beta;
57 protected double a, b;
58 protected double bminusa;
59 protected double logFactor;
60 protected double Beta;
61 protected double logBeta;
63 private static class Optim
implements Lmder_fcn {
67 public Optim(
double a,
double b) {
72 public void fcn(
int m,
int n,
double[] x,
double[] fvec,
double[][] fjac,
int iflag[]) {
73 if (x[1] <= 0.0 || x[2] <= 0.0) {
74 final double BIG = 1.0e100;
89 }
else if (iflag[1] == 2) {
114 public BetaDist(
double alpha,
double beta,
double a,
double b) {
120 if (x <= a || x >= b)
122 double temp = (alpha - 1) * Math.log(x - a) + (beta - 1) * Math.log(b - x);
124 return Math.exp(logFactor + temp);
127 public double cdf(
double x) {
128 return cdf(alpha, beta, (x - a) / bminusa);
133 return barF(alpha, beta, (x - a) / bminusa);
138 return a + (b - a) *
inverseF(alpha, beta, u);
143 return BetaDist.getMean(alpha, beta, a, b);
148 return BetaDist.getVariance(alpha, beta, a, b);
153 return BetaDist.getStandardDeviation(alpha, beta, a, b);
160 public static double density(
double alpha,
double beta,
double x) {
161 return density(alpha, beta, 0.0, 1.0, x);
167 public static double density(
double alpha,
double beta,
double a,
double b,
double x) {
169 throw new IllegalArgumentException(
"a >= b");
170 if (x <= a || x >= b)
173 double z = -
Num.
lnBeta(alpha, beta) - (alpha + beta - 1) * Math.log(b - a) + (alpha - 1) * Math.log(x - a)
174 + (beta - 1) * Math.log(b - x);
178 static double beta_g(
double x) {
184 return -beta_g(1.0 / x);
188 final double y = 1.0 - x;
190 return (1.0 - x * x + 2.0 * x * Math.log(x)) / (y * y);
195 final double EPS = 1.0e-12;
202 term = ypow / (j * (j + 1));
205 }
while (Math.abs(term / sum) > EPS);
210 private static double bolshev(
double alpha,
double beta,
int d,
double x) {
216 boolean flag =
false;
217 double u, temp, yd, gam;
227 u = alpha + 0.5 * beta - 0.5;
229 temp = x / (2.0 - x);
231 temp = (1.0 - x) / (1.0 + x);
233 gam = (Math.exp(beta * Math.log(yd) - yd -
Num.
lnGamma(beta))
234 * (2.0 * yd * yd - (beta - 1.0) * yd - (beta * beta - 1.0))) / (24.0 * u * u);
236 yd = GammaDist.barF(beta, d, yd);
237 return Math.max(0, yd - gam);
239 yd = GammaDist.cdf(beta, d, yd);
244 private static double peizer(
double alpha,
double beta,
double x) {
246 double temp, h1, h3, y;
247 h1 = alpha + beta - 1.0;
250 temp = 1.0 + y * beta_g((alpha - 0.5) / (h1 * x));
252 temp = GammaDist.mybelog((alpha - 0.5) / (h1 * x));
254 h3 = Math.sqrt((temp + x * beta_g((beta - 0.5) / (h1 * y))) / ((h1 + 1.0 / 6.0) * x * y))
255 * ((h1 + 1.0 / 3.0 + 0.02 * (1.0 / alpha + 1.0 / beta + 1.0 / (alpha + beta))) * x - alpha + 1.0 / 3.0
256 - 0.02 / alpha - 0.01 / (alpha + beta));
258 return NormalDist.cdf01(h3);
261 private static double donato(
double alpha,
double beta,
double x) {
266 double mid = (alpha + 1.0) / (alpha + beta + 2.0);
268 return 1.0 - donato(beta, alpha, 1.0 - x);
270 final int MMAX = 100;
271 double[] Ta =
new double[1 + MMAX];
272 double[] Tb =
new double[1 + MMAX];
277 if ((beta <= MMAX) && (beta % 1.0 < 1.0e-100)) {
284 for (m = 1; m < M1; m++) {
285 tem = alpha + 2 * m - 1;
286 Ta[m + 1] = (alpha + m - 1) * (alpha + beta + m - 1) * (beta - m) * m * x * x / (tem * tem);
290 tem = alpha * (alpha + beta) / (alpha + 1);
291 Tb[1] = alpha - tem * x;
293 for (m = 1; m < M1; m++) {
294 tem = (alpha + m) * (alpha + beta + m) / (alpha + 2 * m + 1);
295 tem1 = m * (beta - m) / (alpha + 2 * m - 1);
296 Tb[m + 1] = alpha + 2 * m + (tem1 - tem) * x;
299 while (0. == Tb[M1] && M1 > 1) {
305 for (m = M1; m > 0; m--) {
306 con = Ta[m] / (Tb[m] + con);
309 tem = Num.lnBeta(alpha, beta) - alpha * Math.log(x) - beta * Math.log1p(-x);
310 return con * Math.exp(-tem);
317 public static double cdf(
double alpha,
double beta,
double x) {
319 throw new IllegalArgumentException(
"alpha <= 0");
321 throw new IllegalArgumentException(
"beta <= 0");
328 return Math.pow(x, alpha);
330 final double ALPHABETAMAX = 10000.0;
331 final double ALPHABETALIM = 30.0;
333 if (Math.max(alpha, beta) <= ALPHABETAMAX) {
334 return donato(alpha, beta, x);
337 if ((alpha > ALPHABETAMAX && beta < ALPHABETALIM) || (beta > ALPHABETAMAX && alpha < ALPHABETALIM)) {
338 return bolshev(alpha, beta, 12, x);
341 return peizer(alpha, beta, x);
353 public static double cdf(
double alpha,
double beta,
double a,
double b,
double x) {
354 return cdf(alpha, beta, (x - a) / (b - a));
361 public static double barF(
double alpha,
double beta,
double x) {
362 return cdf(beta, alpha, 1.0 - x);
368 public static double barF(
double alpha,
double beta,
double a,
double b,
double x) {
370 throw new IllegalArgumentException(
"a >= b");
371 return cdf(beta, alpha, (b - x) / (b - a));
375 public static double inverseF(
double alpha,
double beta,
int d,
double u) {
377 throw new IllegalArgumentException(
"alpha <= 0");
379 throw new IllegalArgumentException(
"beta <= 0");
381 throw new IllegalArgumentException(
"d <= 0");
382 if (u > 1.0 || u < 0.0)
383 throw new IllegalArgumentException(
"u not in [0,1]");
392 final double MACHEP = 1.11022302462515654042E-16;
393 final double MAXLOG = 7.09782712893383996843E2;
394 final double MINLOG = -7.08396418532264106224E2;
397 boolean ihalve =
false;
398 boolean newt =
false;
400 double p = 0, q = 0, y0 = 0, z = 0, y = 0, x = 0, x0, x1, lgm = 0, yp = 0, di = 0, dithresh = 0, yl, yh, xt = 0;
409 if (alpha <= 1.0 || beta <= 1.0) {
421 mainloop:
while (
true) {
426 for (i = 0; i < 100; i++) {
428 x = x0 + di * (x1 - x0);
433 x = x0 + di * (x1 - x0);
440 yp = (x1 - x0) / (x1 + x0);
441 if (Math.abs(yp) < dithresh) {
446 if (Math.abs(yp) < dithresh) {
458 di = 1.0 - (1.0 - di) * (1.0 - di);
462 di = (y0 - y) / (yh - yl);
489 if (rflg && x1 < MACHEP) {
502 di = (y - y0) / (yh - yl);
522 lgm = Num.lnGamma(p + q) - Num.lnGamma(p) - Num.lnGamma(q);
524 for (i = 0; i < 8; i++) {
541 if (x >= 1.0 || x <= 0.0)
544 z = (p - 1.0) * Math.log(x) + (q - 1.0) * Math.log1p(-x) + lgm;
554 y = (x - x0) / (x1 - x0);
555 xt = x0 + 0.5 * y * (x - x0);
560 y = (x1 - x) / (x1 - x0);
561 xt = x1 - 0.5 * y * (x1 - x);
566 if (Math.abs(z / x) < 128.0 * MACHEP)
570 dithresh = 256.0 * MACHEP;
575 yp = -NormalDist.inverseF01(u);
590 lgm = (yp * yp - 3.0) / 6.0;
591 x = 2.0 / (1.0 / (2.0 * p - 1.0) + 1.0 / (2.0 * q - 1.0));
592 z = yp * Math.sqrt(x + lgm) / x
593 - (1.0 / (2.0 * q - 1.0) - 1.0 / (2.0 * p - 1.0)) * (lgm + 5.0 / 6.0 - 2.0 / (3.0 * x));
600 x = p / (p + q * Math.exp(z));
603 if (Math.abs(yp) < 0.2) {
624 public static double inverseF(
double alpha,
double beta,
double u) {
625 return inverseF(alpha, beta, 12, u);
629 public static double inverseF(
double alpha,
double beta,
double a,
double b,
int d,
double u) {
631 throw new IllegalArgumentException(
"a >= b");
632 return a + (b - a) *
inverseF(alpha, beta, d, u);
640 public static double inverseF(
double alpha,
double beta,
double a,
double b,
double u) {
642 throw new IllegalArgumentException(
"a >= b");
643 return a + (b - a) *
inverseF(alpha, beta, u);
665 public static double[]
getMLE(
double[] x,
int n) {
667 throw new IllegalArgumentException(
"n <= 0");
672 for (
int i = 0; i < n; i++) {
679 b += Math.log1p(-x[i]);
683 double mean = sum / n;
686 for (
int i = 0; i < n; i++)
687 sum += (x[i] - mean) * (x[i] - mean);
688 double var = sum / (n - 1);
690 Optim system =
new Optim(a, b);
692 double[] param =
new double[3];
693 param[1] = mean * ((mean * (1.0 - mean) / var) - 1.0);
694 param[2] = (1.0 - mean) * ((mean * (1.0 - mean) / var) - 1.0);
695 double[] fvec =
new double[3];
696 double[][] fjac =
new double[3][3];
697 int[] info =
new int[2];
698 int[] ipvt =
new int[3];
700 Minpack_f77.lmder1_f77(system, 2, 2, param, fvec, fjac, 1e-5, info, ipvt);
702 double parameters[] =
new double[2];
703 parameters[0] = param[1];
704 parameters[1] = param[2];
719 double parameters[] =
getMLE(x, n);
720 return new BetaDist(parameters[0], parameters[1]);
730 public static double getMean(
double alpha,
double beta) {
731 return getMean(alpha, beta, 0.0, 1.0);
741 public static double getMean(
double alpha,
double beta,
double a,
double b) {
743 throw new IllegalArgumentException(
"alpha <= 0");
745 throw new IllegalArgumentException(
"beta <= 0");
747 return (alpha * b + beta * a) / (alpha + beta);
772 public static double getVariance(
double alpha,
double beta,
double a,
double b) {
774 throw new IllegalArgumentException(
"alpha <= 0");
776 throw new IllegalArgumentException(
"beta <= 0");
778 return ((alpha * beta) * (b - a) * (b - a)) / ((alpha + beta) * (alpha + beta) * (alpha + beta + 1));
788 return Math.sqrt(
BetaDist.getVariance(alpha, beta));
798 return Math.sqrt(
BetaDist.getVariance(alpha, beta, a, b));
832 public void setParams(
double alpha,
double beta,
double a,
double b) {
834 throw new IllegalArgumentException(
"alpha <= 0");
836 throw new IllegalArgumentException(
"beta <= 0");
838 throw new IllegalArgumentException(
"a >= b");
841 supportA = this.a = a;
842 supportB = this.b = b;
850 Beta = Math.exp(logBeta);
852 this.logFactor = -logBeta - Math.log(bminusa) * (alpha + beta - 1);
860 double[] retour = { alpha, beta, a, b };
869 return getClass().getSimpleName() +
" : alpha = " + alpha +
", beta = " + beta;
static double getVariance(double alpha, double beta, double a, double b)
Computes and returns the variance of the beta distribution with parameters and.
static double density(double alpha, double beta, double x)
Same as density(alpha,beta, 0, 1, x).
static double cdf(double alpha, double beta, double a, double b, double x)
Computes the distribution function.
static double barF(double alpha, double beta, double a, double b, double x)
Computes the complementary distribution function.
double getBeta()
Returns the parameter of this object.
static double getStandardDeviation(double alpha, double beta, double a, double b)
Computes the standard deviation of the beta distribution with parameters and , over the interval .
void setParams(double alpha, double beta, double a, double b)
Sets the parameters of the current distribution.
double inverseF(double u)
Returns the inverse distribution function .
double barF(double x)
Returns the complementary distribution function.
BetaDist(double alpha, double beta, double a, double b)
Constructs a BetaDist object with parameters alpha, beta and domain.
double cdf(double x)
Returns the distribution function .
double getAlpha()
Returns the parameter of this object.
double getB()
Returns the parameter of this object.
double getVariance()
Returns the variance.
static double getStandardDeviation(double alpha, double beta)
Computes the standard deviation of the beta distribution with parameters and , over the interval .
double getA()
Returns the parameter of this object.
static BetaDist getInstanceFromMLE(double[] x, int n)
Creates a new instance of a beta distribution with parameters.
double[] getParams()
Return an array containing the parameters of the current distribution as [ , , , ].
static double cdf(double alpha, double beta, double x)
Same as cdf(alpha, beta, 0,1, x).
static double density(double alpha, double beta, double a, double b, double x)
Computes the density function of the beta distribution.
static double inverseF(double alpha, double beta, double u)
Same as inverseF(alpha,beta, 0, 1, u).
String toString()
Returns a String containing information about the current distribution.
double density(double x)
Returns , the density evaluated at .
double getStandardDeviation()
Returns the standard deviation.
static double getVariance(double alpha, double beta)
Computes and returns the variance of the beta distribution with parameters and.
static double getMean(double alpha, double beta)
Computes and returns the mean of the beta distribution with parameters and , over the interval .
static double inverseF(double alpha, double beta, double a, double b, double u)
Returns the inverse beta distribution function using the algorithm implemented in imos00a .
static double barF(double alpha, double beta, double x)
Same as barF(alpha, beta, 0,1, x).
double getMean()
Returns the mean.
static double[] getMLE(double[] x, int n)
Estimates the parameters of the beta distribution over the interval using the maximum likelihood me...
BetaDist(double alpha, double beta)
Constructs a BetaDist object with parameters alpha, beta and default domain .
static double getMean(double alpha, double beta, double a, double b)
Computes and returns the mean of the beta distribution with parameters.
Classes implementing continuous distributions should inherit from this base class.
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 trigamma(double x)
Returns the value of the trigamma function , the derivative of the digamma function,...
static double lnBeta(double lam, double nu)
Computes the natural logarithm of the Beta function .
static double digamma(double x)
Returns the value of the logarithmic derivative of the Gamma function .