66 private final boolean DEBUG =
false;
67 protected static final double HALF_PI = Math.PI / 2.0;
68 private final double epsc = 1.0e-5;
69 private final double HUGE = Double.MAX_VALUE / 2.0;
76 private final int K0 = 128;
88 private double bright;
104 private double epstail;
105 private boolean lcutF =
false;
106 private boolean rcutF =
false;
108 protected void printArray(
double[] U) {
109 System.out.print(
" Tableau = (");
110 for (
int j = 0; j < U.length; j++)
111 System.out.printf(
" %f", U[j]);
112 System.out.println(
" )");
124 public double evaluate(
double x) {
129 private void init(
double xc,
double epsu,
int n) {
130 double[] zs =
new double[n + 1];
131 double[] ys =
new double[n + 1];
132 double[] xs =
new double[n + 1];
133 double[] vs =
new double[n + 1];
134 double[] us =
new double[n + 1];
135 double[] cs =
new double[n + 1];
140 if (I0 > 1.05 || I0 < 0.95)
141 throw new IllegalStateException(
" NOT a probability density");
142 epstail = 0.05 * epsu * I0;
143 epstail = Math.min(epstail, 1.e-10);
144 epstail = Math.max(epstail, 1.e-15);
145 double tol = epstail;
146 findCutoff(bleft, epstail,
false);
147 findCutoff(bright, epstail,
true);
149 System.out.println(
"lcutF = " + lcutF +
"\nrcutF = " + rcutF +
"\n");
158 final double HMIN = 1.0e-12;
159 double h = (br - bl) / K0;
165 System.out.println(
" k a_k F_k h");
169 calcChebyX(zs, xs, n, h);
170 calcU(m_dens, A[k], xs, us, n, tol);
174 for (j = 1; j <= n; j++)
178 eps = calcEps(m_dens, A[k], ys, vs, n, tol);
179 }
catch (IllegalArgumentException e) {
188 if (k + 1 >= A.length)
190 copy(k, cs, us, xs, n);
192 System.out.printf(
" %d %16.12f %20.16g %g%n", k, A[k], F[k], h);
194 throw new IllegalStateException(
"Unable to compute CDF");
197 if (eps < epsu / 3.0)
208 System.out.printf(
" %d %16.12f %20.16g %g%n", k, A[k], F[k], A[k] - A[k - 1]);
209 System.out.println(
"\nFin du tableau");
212 while (k > 0 && F[k] >= 1.) {
238 setParams(dist,
null, xc, eps, order);
239 init(xc, eps, order);
252 setParams(
null, dens, xc, eps, order);
253 init(xc, eps, order);
260 return m_dens.evaluate(x);
266 public double cdf(
double x) {
267 throw new UnsupportedOperationException(
"cdf not implemented");
274 if (u < 0.0 || u > 1.0)
275 throw new IllegalArgumentException(
"u not in [0,1]");
280 if ((u < epstail) && lcutF)
281 return uinvLeftTail(u);
282 if ((u > 1.0 - epstail) && rcutF)
283 return uinvRightTail(u);
285 int k = searchIndex(u);
286 double x = A[k] +
Misc.
evalPoly(order, U[k], C[k], u - F[k]);
320 double[] retour = { xc, epsu0, order };
331 private void createIndex(
int Kmax) {
334 Index =
new int[Imax + 1];
336 Index[Imax] = Kmax - 1;
339 for (
int i = 1; i < Imax; i++) {
340 u = (double) i / Imax;
347 private int searchIndex(
double u) {
349 int i = (int) (Imax * u);
351 while (u >= F[k] && k < Kmax)
358 private void copy(
int k,
double[] cs,
double[] us,
double[] xs,
int n) {
360 for (
int j = 0; j <= n; j++) {
365 A[k + 1] = A[k] + xs[n];
366 F[k + 1] = F[k] + us[n];
369 private double calcEps(MathFunction dens,
double a,
double[] Y,
double[] V,
int n,
double tol) {
380 for (
int j = 1; j <= n; j++) {
381 u += MathFunctionUtil.gaussLobatto(dens, a + Y[j - 1], a + Y[j], tol);
382 dif = Math.abs(u - V[j]);
389 private void NEval(
double[] C,
double[] U,
double[] T,
double[] Y,
int n) {
395 boolean fail =
false;
397 for (j = 1; j <= n; j++) {
398 Y[j] = Misc.evalPoly(n, U, C, T[j]);
405 for (j = 1; j <= n; j++)
406 Y[j] = Misc.evalPoly(1, U, C, T[j]);
410 private void calcU(MathFunction dens,
double a,
double[] X,
double[] U,
int n,
double tol) {
418 for (
int j = 1; j <= n; j++)
419 U[j] = U[j - 1] + MathFunctionUtil.gaussLobatto(dens, a + X[j - 1], a + X[j], tol);
422 private void reserve(
int m,
int n) {
426 C = reserve(C, m, n);
427 U = reserve(U, m, n);
428 X = reserve(X, m, n);
431 private double[] reserve(
double[] T,
int m) {
434 T =
new double[K0 + 1];
440 double[] tem =
new double[m + 1];
441 for (
int i = 0; i <= m; i++)
447 double[] tem =
new double[2 * m + 1];
448 for (
int i = 0; i <= m; i++)
455 private double[][] reserve(
double[][] T,
int m,
int n) {
458 T =
new double[K0 + 1][n + 1];
464 double[][] tem =
new double[m + 1][n + 1];
466 for (
int i = 0; i <= m; i++) {
467 for (j = 0; j <= n; j++)
474 double[][] tem =
new double[2 * m + 1][n + 1];
476 for (
int i = 0; i <= m; i++) {
477 for (j = 0; j <= n; j++)
485 private void NTest(
double[] U,
double[] T,
int n) {
491 for (k = 1; k <= n; k++) {
492 T[k] = (U[k - 1] + U[k]) / 2.;
493 for (j = 0; j < 2; j++) {
496 for (i = 0; i <= n; i++) {
510 private void calcChebyZ(
double[] Z,
int n) {
513 double phi = HALF_PI / (n + 1);
514 double c = Math.cos(phi);
517 for (
int j = 0; j < n; j++) {
519 temp = Math.sin((j + 1) * phi);
526 private void calcChebyX(
double[] Z,
double[] X,
int n,
double h) {
528 for (
int j = 1; j < n; j++)
534 private double binSearch(
double xa,
double xb,
double eps,
boolean right) {
541 final double epslow = 0.1 * eps;
543 boolean fini =
false;
548 if ((xb - xa) < eps * Math.abs(x) || (xb - xa) < eps) {
553 y = m_dens.evaluate(x);
556 }
else if (y > eps) {
565 if ((xb - xa) < eps * Math.abs(x) || (xb - xa) < eps) {
570 y = m_dens.evaluate(x);
573 }
else if (y > eps) {
580 System.out.printf(
"binSearch x = %g f = %g r = %g%n", x, y, y / eps);
585 private void findSupport(
double xc) {
591 boolean flagL =
false;
592 boolean flagR =
false;
593 final double DELTA = 1.0e-100;
594 final double DELTAR = 1.0e-14;
596 double bl = supportA;
597 double br = supportB;
599 if (bl > Double.NEGATIVE_INFINITY) {
601 y = m_dens.evaluate(bl);
603 if (y >= HUGE || y <= 0.0) {
605 x = bl + DELTAR * Math.abs(bl);
609 y = m_dens.evaluate(x);
613 throw new UnsupportedOperationException(
"Infinite density at left boundary");
622 if (br < Double.POSITIVE_INFINITY) {
624 y = m_dens.evaluate(br);
626 if (y >= HUGE || y <= 0.0) {
628 x = br - DELTAR * Math.abs(br);
632 y = m_dens.evaluate(x);
636 throw new UnsupportedOperationException(
"Infinite density at right boundary");
652 y = m_dens.evaluate(xc);
653 double epsy = 1.0e-13 * y;
661 while (m_dens.evaluate(xb) >= epsy) {
672 x = binSearch(xa, xb, epsy,
true);
680 while (m_dens.evaluate(xa) >= epsy) {
691 x = binSearch(xa, xb, epsy,
false);
696 protected void setParams(ContinuousDistribution dist, MathFunction dens,
double xc,
double eps,
int order) {
699 throw new IllegalArgumentException(
"eps < 10^{-15}");
701 throw new IllegalArgumentException(
"eps > 10^{-3}");
703 throw new IllegalArgumentException(
"order < 3");
705 throw new IllegalArgumentException(
"order > 12");
710 StringBuffer sb =
new StringBuffer(
"InverseDistFromDensity: ");
714 m_dens =
new MaDensite(dist);
715 sb.append(dist.toString());
717 name = sb.toString();
720 private double uinvLeftTail(
double u) {
725 x = bl + lc1 * Math.log(u * lc2);
727 x = bl + lc1 * (Math.pow(u * lc2, lc3) - 1.);
733 private double uinvRightTail(
double u) {
739 x = br + rc1 * Math.log(v * rc2);
741 x = br + rc1 * (Math.pow(v * rc2, rc3) - 1.);
747 private void findCutoff(
double x0,
double eps,
boolean right) {
755 final double epsx = 1.0e-3;
756 final double range = bright - bleft;
760 del = m_dens.evaluate(bright) - m_dens.evaluate(bright - epsx);
761 if ((supportB < Double.POSITIVE_INFINITY)
762 && (supportB - bright <= epsx || supportB - bright <= Math.abs(supportB) * epsx)) {
780 del = m_dens.evaluate(bleft + epsx) - m_dens.evaluate(bleft);
781 if ((supportA > Double.NEGATIVE_INFINITY)
782 && (bleft - supportA <= epsx || bleft - supportA <= Math.abs(supportA) * epsx)) {
801 double h = 1.0 / 64.0;
802 h = Math.max(h, (bright - bleft) / (1024));
804 double y = 0, yl = 0, yr = 0, yprime = 0;
807 final int ITERMAX = 30;
808 boolean fini =
false;
810 while (!fini && iter < ITERMAX) {
812 boolean ended =
false;
815 while (!ended && it < 10) {
817 if (x + h > supportB)
819 if (x - h < supportA)
821 yr = m_dens.evaluate(x + h);
822 y = m_dens.evaluate(x);
823 yl = m_dens.evaluate(x - h);
824 if (!(yl == 0 || yr == 0 || y == 0))
830 c = yr / (yr - y) + yl / (yl - y) - 1.;
831 yprime = (yr - yl) / (2. * h);
832 tem = Math.abs(y * y / ((c + 1.) * yprime));
834 if (Double.isNaN(tem))
836 if (Math.abs(tem / eps - 1.) < 1.e-4)
838 if (Math.abs(c) <= epsc) {
839 tem = eps * Math.abs(yprime) / (y * y);
842 xnew = x + y / yprime * Math.log(tem);
844 tem = (1. + c) * eps * Math.abs(yprime) / (y * y);
847 xnew = x + y / (c * yprime) * (Math.pow(tem, c / (1. + c)) - 1.);
851 System.out.printf(
"Cutoff x = %g y = %g c = %g%n", xnew, y, c);
853 if ((Math.abs(xnew - x) <= Math.abs(x) * epsx) || (Math.abs(xnew - x) <= epsx))
865 if (Math.abs(c) > epsc)
874 if (Math.abs(c) > epsc)
878 if (Math.abs(xnew - x) >= range)
883 if ((rc1 == 0 && rc2 == 0 && rc3 == 0)) {
888 if ((lc1 == 0 && lc2 == 0 && lc3 == 0)) {