KolmogorovSmirnovDistribution.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.statistics.inference;

  18. import java.util.Arrays;
  19. import org.apache.commons.numbers.combinatorics.Factorial;
  20. import org.apache.commons.numbers.combinatorics.LogFactorial;
  21. import org.apache.commons.numbers.core.DD;
  22. import org.apache.commons.numbers.core.DDMath;
  23. import org.apache.commons.numbers.core.Sum;
  24. import org.apache.commons.statistics.inference.SquareMatrixSupport.RealSquareMatrix;

  25. /**
  26.  * Computes the complementary probability for the one-sample Kolmogorov-Smirnov distribution.
  27.  *
  28.  * @since 1.1
  29.  */
  30. final class KolmogorovSmirnovDistribution {
  31.     /** pi^2. */
  32.     private static final double PI2 = 9.8696044010893586188344909;
  33.     /** sqrt(2*pi). */
  34.     private static final double ROOT_TWO_PI = 2.5066282746310005024157652;
  35.     /** Value of x when the KS sum is 0.5. */
  36.     private static final double X_KS_HALF = 0.8275735551899077;
  37.     /** Value of x when the KS sum is 1.0. */
  38.     private static final double X_KS_ONE = 0.1754243674345323;
  39.     /** Machine epsilon, 2^-52. */
  40.     private static final double EPS = 0x1.0p-52;

  41.     /** No instances. */
  42.     private KolmogorovSmirnovDistribution() {}

  43.     /**
  44.      * Computes the complementary probability {@code P[D_n >= x]}, or survival function (SF),
  45.      * for the two-sided one-sample Kolmogorov-Smirnov distribution.
  46.      *
  47.      * <pre>
  48.      * D_n = sup_x |F(x) - CDF_n(x)|
  49.      * </pre>
  50.      *
  51.      * <p>where {@code n} is the sample size; {@code CDF_n(x)} is an empirical
  52.      * cumulative distribution function; and {@code F(x)} is the expected
  53.      * distribution.
  54.      *
  55.      * <p>
  56.      * References:
  57.      * <ol>
  58.      * <li>Simard, R., &amp; L’Ecuyer, P. (2011).
  59.      * <a href="https://doi.org/10.18637/jss.v039.i11">Computing the Two-Sided Kolmogorov-Smirnov Distribution.</a>
  60.      * Journal of Statistical Software, 39(11), 1–18.
  61.      * <li>
  62.      * Marsaglia, G., Tsang, W. W., &amp; Wang, J. (2003).
  63.      * <a href="https://doi.org/10.18637/jss.v008.i18">Evaluating Kolmogorov's Distribution.</a>
  64.      * Journal of Statistical Software, 8(18), 1–4.
  65.      * </ol>
  66.      *
  67.      * <p>Note that [2] contains an error in computing h, refer to <a
  68.      * href="https://issues.apache.org/jira/browse/MATH-437">MATH-437</a> for details.
  69.      *
  70.      * @since 1.1
  71.      */
  72.     static final class Two {
  73.         /** pi^2. */
  74.         private static final double PI2 = 9.8696044010893586188344909;
  75.         /** pi^4. */
  76.         private static final double PI4 = 97.409091034002437236440332;
  77.         /** pi^6. */
  78.         private static final double PI6 = 961.38919357530443703021944;
  79.         /** sqrt(2*pi). */
  80.         private static final double ROOT_TWO_PI = 2.5066282746310005024157652;
  81.         /** sqrt(pi/2). */
  82.         private static final double ROOT_HALF_PI = 1.2533141373155002512078826;
  83.         /** Threshold for Pelz-Good where the 1 - CDF == 1.
  84.          * Occurs when sqrt(2pi/z) exp(-pi^2 / (8 z^2)) is far below 2^-53.
  85.          * Threshold set at exp(-pi^2 / (8 z^2)) = 2^-80. */
  86.         private static final double LOG_PG_MIN = -55.451774444795625;
  87.         /** Factor 4a in the quadratic equation to solve max k: log(2^-52) * 8. */
  88.         private static final double FOUR_A = -288.3492271129372;
  89.         /** The scaling threshold in the MTW algorithm. Marsaglia used 1e-140. This uses 2^-400 ~ 3.87e-121. */
  90.         private static final double MTW_SCALE_THRESHOLD = 0x1.0p-400;
  91.         /** The up-scaling factor in the MTW algorithm. Marsaglia used 1e140. This uses 2^400 ~ 2.58e120. */
  92.         private static final double MTW_UP_SCALE = 0x1.0p400;
  93.         /** The power-of-2 of the up-scaling factor in the MTW algorithm, n if the up-scale factor is 2^n. */
  94.         private static final int MTW_UP_SCALE_POWER = 400;
  95.         /** The scaling threshold in the Pomeranz algorithm.  */
  96.         private static final double P_DOWN_SCALE = 0x1.0p-128;
  97.         /** The up-scaling factor in the Pomeranz algorithm. */
  98.         private static final double P_UP_SCALE = 0x1.0p128;
  99.         /** The power-of-2 of the up-scaling factor in the Pomeranz algorithm, n if the up-scale factor is 2^n. */
  100.         private static final int P_SCALE_POWER = 128;
  101.         /** Maximum finite factorial. */
  102.         private static final int MAX_FACTORIAL = 170;
  103.         /** Approximate threshold for ln(MIN_NORMAL). */
  104.         private static final int LOG_MIN_NORMAL = -708;
  105.         /** 140, n threshold for small n for the sf computation.*/
  106.         private static final int N140 = 140;
  107.         /** 0.754693, nxx threshold for small n Durbin matrix sf computation. */
  108.         private static final double NXX_0_754693 = 0.754693;
  109.         /** 4, nxx threshold for small n Pomeranz sf computation. */
  110.         private static final int NXX_4 = 4;
  111.         /** 2.2, nxx threshold for large n Miller approximation sf computation. */
  112.         private static final double NXX_2_2 = 2.2;
  113.         /** 100000, n threshold for large n Durbin matrix sf computation. */
  114.         private static final int N_100000 = 100000;
  115.         /** 1.4, nx^(3/2) threshold for large n Durbin matrix sf computation. */
  116.         private static final double NX32_1_4 = 1.4;
  117.         /** 1/2. */
  118.         private static final double HALF = 0.5;

  119.         /** No instances. */
  120.         private Two() {}

  121.         /**
  122.          * Calculates complementary probability {@code P[D_n >= x]} for the two-sided
  123.          * one-sample Kolmogorov-Smirnov distribution.
  124.          *
  125.          * @param x Statistic.
  126.          * @param n Sample size (assumed to be positive).
  127.          * @return \(P(D_n &ge; x)\)
  128.          */
  129.         static double sf(double x, int n) {
  130.             final double p = sfExact(x, n);
  131.             if (p >= 0) {
  132.                 return p;
  133.             }

  134.             // The computation is divided based on the x-n plane.
  135.             final double nxx = n * x * x;
  136.             if (n <= N140) {
  137.                 // 10 decimal digits of precision

  138.                 // nx^2 < 4 use 1 - CDF(x).
  139.                 if (nxx < NXX_0_754693) {
  140.                     // Durbin matrix (MTW)
  141.                     return 1 - durbinMTW(x, n);
  142.                 }
  143.                 if (nxx < NXX_4) {
  144.                     // Pomeranz
  145.                     return 1 - pomeranz(x, n);
  146.                 }
  147.                 // Miller approximation: 2 * one-sided D+ computation
  148.                 return 2 * One.sf(x, n);
  149.             }
  150.             // n > 140
  151.             if (nxx >= NXX_2_2) {
  152.                 // 6 decimal digits of precision

  153.                 // Miller approximation: 2 * one-sided D+ computation
  154.                 return 2 * One.sf(x, n);
  155.             }
  156.             // nx^2 < 2.2 use 1 - CDF(x).
  157.             // 5 decimal digits of precision (for n < 200000)

  158.             // nx^1.5 <= 1.4
  159.             if (n <= N_100000 && n * Math.pow(x, 1.5) < NX32_1_4) {
  160.                 // Durbin matrix (MTW)
  161.                 return 1 - durbinMTW(x, n);
  162.             }
  163.             // Pelz-Good, algorithm modified to sum negative terms from 1 for the SF.
  164.             // (precision increases with n)
  165.             return pelzGood(x, n);
  166.         }

  167.         /**
  168.          * Calculates exact cases for the complementary probability
  169.          * {@code P[D_n >= x]} the two-sided one-sample Kolmogorov-Smirnov distribution.
  170.          *
  171.          * <p>Exact cases handle x not in [0, 1]. It is assumed n is positive.
  172.          *
  173.          * @param x Statistic.
  174.          * @param n Sample size (assumed to be positive).
  175.          * @return \(P(D_n &ge; x)\)
  176.          */
  177.         private static double sfExact(double x, int n) {
  178.             if (n * x * x >= 370 || x >= 1) {
  179.                 // p would underflow, or x is out of the domain
  180.                 return 0;
  181.             }
  182.             final double nx = x * n;
  183.             if (nx <= 1) {
  184.                 // x <= 1/(2n)
  185.                 if (nx <= HALF) {
  186.                     // Also detects x <= 0 (iff n is positive)
  187.                     return 1;
  188.                 }
  189.                 if (n == 1) {
  190.                     // Simplification of:
  191.                     // 1 - (n! (2x - 1/n)^n) == 1 - (2x - 1)
  192.                     return 2.0 - 2.0 * x;
  193.                 }
  194.                 // 1/(2n) < x <= 1/n
  195.                 // 1 - (n! (2x - 1/n)^n)
  196.                 final double f = 2 * x - 1.0 / n;
  197.                 // Switch threshold where (2x - 1/n)^n is sub-normal
  198.                 // Max factorial threshold is n=170
  199.                 final double logf = Math.log(f);
  200.                 if (n <= MAX_FACTORIAL && n * logf > LOG_MIN_NORMAL) {
  201.                     return 1 - Factorial.doubleValue(n) * Math.pow(f, n);
  202.                 }
  203.                 return -Math.expm1(LogFactorial.create().value(n) + n * logf);
  204.             }
  205.             // 1 - 1/n <= x < 1
  206.             if (n - 1 <= nx) {
  207.                 // 2 * (1-x)^n
  208.                 return 2 * Math.pow(1 - x, n);
  209.             }

  210.             return -1;
  211.         }

  212.         /**
  213.          * Computes the Durbin matrix approximation for {@code P(D_n < d)} using the method
  214.          * of Marsaglia, Tsang and Wang (2003).
  215.          *
  216.          * @param x Statistic.
  217.          * @param n Sample size (assumed to be positive).
  218.          * @return \(P(D_n &lt; x)\)
  219.          */
  220.         private static double durbinMTW(double x, int n) {
  221.             final int k = (int) Math.ceil(n * x);
  222.             final RealSquareMatrix h = createH(x, n).power(n);

  223.             // Use scaling as per Marsaglia's code to avoid underflow.
  224.             double pFrac = h.get(k - 1, k - 1);
  225.             int scale = h.scale();
  226.             // Omit i == n as this is a no-op
  227.             for (int i = 1; i < n; ++i) {
  228.                 pFrac *= (double) i / n;
  229.                 if (pFrac < MTW_SCALE_THRESHOLD) {
  230.                     pFrac *= MTW_UP_SCALE;
  231.                     scale -= MTW_UP_SCALE_POWER;
  232.                 }
  233.             }
  234.             // Return the CDF
  235.             return clipProbability(Math.scalb(pFrac, scale));
  236.         }

  237.         /***
  238.          * Creates {@code H} of size {@code m x m} as described in [1].
  239.          *
  240.          * @param x Statistic.
  241.          * @param n Sample size (assumed to be positive).
  242.          * @return H matrix
  243.          */
  244.         private static RealSquareMatrix createH(double x, int n) {
  245.             // MATH-437:
  246.             // This is *not* (int) (n * x) + 1.
  247.             // This is only ever called when 1/n < x < 1 - 1/n.
  248.             // => h cannot be >= 1 when using ceil. h can be 0 if nx is integral.
  249.             final int k = (int) Math.ceil(n * x);
  250.             final double h = k - n * x;

  251.             final int m = 2 * k - 1;
  252.             final double[] data = new double[m * m];
  253.             // Start by filling everything with either 0 or 1.
  254.             for (int i = 0; i < m; ++i) {
  255.                 // h[i][j] = i - j + 1 < 0 ? 0 : 1
  256.                 // => h[i][j<=i+1] = 1
  257.                 final int jend = Math.min(m - 1, i + 1);
  258.                 for (int j = i * m; j <= i * m + jend; j++) {
  259.                     data[j] = 1;
  260.                 }
  261.             }

  262.             // Setting up power-array to avoid calculating the same value twice:
  263.             // hp[0] = h^1, ..., hp[m-1] = h^m
  264.             final double[] hp = new double[m];
  265.             hp[0] = h;
  266.             for (int i = 1; i < m; ++i) {
  267.                 // Avoid compound rounding errors using h * hp[i - 1]
  268.                 // with Math.pow as it is within 1 ulp of the exact result
  269.                 hp[i] = Math.pow(h, i + 1);
  270.             }

  271.             // First column and last row has special values (each other reversed).
  272.             for (int i = 0; i < m; ++i) {
  273.                 data[i * m] -= hp[i];
  274.                 data[(m - 1) * m + i] -= hp[m - i - 1];
  275.             }

  276.             // [1] states: "For 1/2 < h < 1 the bottom left element of the matrix should be
  277.             // (1 - 2*h^m + (2h - 1)^m )/m!"
  278.             if (2 * h - 1 > 0) {
  279.                 data[(m - 1) * m] += Math.pow(2 * h - 1, m);
  280.             }

  281.             // Aside from the first column and last row, the (i, j)-th element is 1/(i - j + 1)! if i -
  282.             // j + 1 >= 0, else 0. 1's and 0's are already put, so only division with (i - j + 1)! is
  283.             // needed in the elements that have 1's. Note that i - j + 1 > 0 <=> i + 1 > j instead of
  284.             // j'ing all the way to m. Also note that we can use pre-computed factorials given
  285.             // the limits where this method is called.
  286.             for (int i = 0; i < m; ++i) {
  287.                 final int im = i * m;
  288.                 for (int j = 0; j < i + 1; ++j) {
  289.                     // Here (i - j + 1 > 0)
  290.                     // Divide by (i - j + 1)!
  291.                     // Note: This method is used when:
  292.                     // n <= 140; nxx < 0.754693
  293.                     // n <= 100000; n x^1.5 < 1.4
  294.                     // max m ~ 2nx ~ (1.4/1e5)^(2/3) * 2e5 = 116
  295.                     // Use a tabulated factorial
  296.                     data[im + j] /= Factorial.doubleValue(i - j + 1);
  297.                 }
  298.             }
  299.             return SquareMatrixSupport.create(m, data);
  300.         }

  301.         /**
  302.          * Computes the Pomeranz approximation for {@code P(D_n < d)} using the method
  303.          * as described in Simard and L’Ecuyer (2011).
  304.          *
  305.          * <p>Modifications have been made to the scaling of the intermediate values.
  306.          *
  307.          * @param x Statistic.
  308.          * @param n Sample size (assumed to be positive).
  309.          * @return \(P(D_n &lt; x)\)
  310.          */
  311.         private static double pomeranz(double x, int n) {
  312.             final double t = n * x;
  313.             // Store floor(A-t) and ceil(A+t). This does not require computing A.
  314.             final int[] amt = new int[2 * n + 3];
  315.             final int[] apt = new int[2 * n + 3];
  316.             computeA(n, t, amt, apt);
  317.             // Precompute ((A[i] - A[i-1])/n)^(j-k) / (j-k)!
  318.             // A[i] - A[i-1] has 4 possible values (based on multiples of A2)
  319.             // A1 - A0 = 0 - 0                               = 0
  320.             // A2 - A1 = A2 - 0                              = A2
  321.             // A3 - A2 = (1 - A2) - A2                       = 1 - 2 * A2
  322.             // A4 - A3 = (A2 + 1) - (1 - A2)                 = 2 * A2
  323.             // A5 - A4 = (1 - A2 + 1) - (A2 + 1)             = 1 - 2 * A2
  324.             // A6 - A5 = (A2 + 1 + 1) - (1 - A2 + 1)         = 2 * A2
  325.             // A7 - A6 = (1 - A2 + 1 + 1) - (A2 + 1 + 1)     = 1 - 2 * A2
  326.             // A8 - A7 = (A2 + 1 + 1 + 1) - (1 - A2 + 1 + 1) = 2 * A2
  327.             // ...
  328.             // Ai - Ai-1 = ((i-1)/2 - A2) - (A2 + (i-2)/2)   = 1 - 2 * A2 ; i = odd
  329.             // Ai - Ai-1 = (A2 + (i-1)/2) - ((i-2)/2 - A2)   = 2 * A2     ; i = even
  330.             // ...
  331.             // A2n+2 - A2n+1 = n - (n - A2)                  = A2

  332.             // ap[][j - k] = ((A[i] - A[i-1])/n)^(j-k) / (j-k)!
  333.             // for each case: A[i] - A[i-1] in [A2, 1 - 2 * A2, 2 * A2]
  334.             // Ignore case 0 as this is not used. Factors are ap[0] = 1, else 0.
  335.             // If A2==0.5 then this is computed as a no-op due to multiplication by zero.
  336.             final int n2 = n + 2;
  337.             final double[][] ap = new double[3][n2];
  338.             final double a2 = Math.min(t - Math.floor(t), Math.ceil(t) - t);
  339.             computeAP(ap[0], a2 / n);
  340.             computeAP(ap[1], (1 - 2 * a2) / n);
  341.             computeAP(ap[2], (2 * a2) / n);

  342.             // Current and previous V
  343.             double[] vc = new double[n2];
  344.             double[] vp = new double[n2];
  345.             // Count of re-scaling
  346.             int scale = 0;

  347.             // V_1,1 = 1
  348.             vc[1] = 1;

  349.             for (int i = 2; i <= 2 * n + 2; i++) {
  350.                 final double[] v = vc;
  351.                 vc = vp;
  352.                 vp = v;
  353.                 // This is useful for following current values of vc
  354.                 Arrays.fill(vc, 0);

  355.                 // Select (A[i] - A[i-1]) factor
  356.                 final double[] p;
  357.                 if (i == 2 || i == 2 * n + 2) {
  358.                     // First or last
  359.                     p = ap[0];
  360.                 } else {
  361.                     // odd:  [1] 1 - 2 * 2A
  362.                     // even: [2] 2 * A2
  363.                     p = ap[2 - (i & 1)];
  364.                 }

  365.                 // Set limits.
  366.                 // j is the ultimate bound for k and should be in [1, n+1]
  367.                 final int jmin = Math.max(1, amt[i] + 2);
  368.                 final int jmax = Math.min(n + 1, apt[i]);
  369.                 final int k1 = Math.max(1, amt[i - 1] + 2);

  370.                 // All numbers will reduce in size.
  371.                 // Maintain the largest close to 1.0.
  372.                 // This is a change from Simard and L’Ecuyer which scaled based on the smallest.
  373.                 double max = 0;
  374.                 for (int j = jmin; j <= jmax; j++) {
  375.                     final int k2 = Math.min(j, apt[i - 1]);
  376.                     // Accurate sum.
  377.                     // vp[high] is smaller
  378.                     // p[high] is smaller
  379.                     // Sum ascending has smaller products first.
  380.                     double sum = 0;
  381.                     for (int k = k1; k <= k2; k++) {
  382.                         sum += vp[k] * p[j - k];
  383.                     }
  384.                     vc[j] = sum;
  385.                     if (max < sum) {
  386.                         // Note: max *may* always be the first sum: vc[jmin]
  387.                         max = sum;
  388.                     }
  389.                 }

  390.                 // Rescale if too small
  391.                 if (max < P_DOWN_SCALE) {
  392.                     // Only scale in current range from V
  393.                     for (int j = jmin; j <= jmax; j++) {
  394.                         vc[j] *= P_UP_SCALE;
  395.                     }
  396.                     scale -= P_SCALE_POWER;
  397.                 }
  398.             }

  399.             // F_n(x) = n! V_{2n+2,n+1}
  400.             double v = vc[n + 1];

  401.             // This method is used when n < 140 where all n! are finite.
  402.             // v is below 1 so we can directly compute the result without using logs.
  403.             v *= Factorial.doubleValue(n);
  404.             // Return the CDF (rescaling as required)
  405.             return Math.scalb(v, scale);
  406.         }

  407.         /**
  408.          * Compute the power factors.
  409.          * <pre>
  410.          * factor[j] = z^j / j!
  411.          * </pre>
  412.          *
  413.          * @param p Power factors.
  414.          * @param z (A[i] - A[i-1]) / n
  415.          */
  416.         private static void computeAP(double[] p, double z) {
  417.             // Note z^0 / 0! = 1 for any z
  418.             p[0] = 1;
  419.             p[1] = z;
  420.             for (int j = 2; j < p.length; j++) {
  421.                 // Only used when n <= 140 and can use the tabulated values of n!
  422.                 // This avoids using recursion: p[j] = z * p[j-1] / j.
  423.                 // Direct computation more closely agrees with the recursion using BigDecimal
  424.                 // with 200 digits of precision.
  425.                 p[j] = Math.pow(z, j) / Factorial.doubleValue(j);
  426.             }
  427.         }

  428.         /**
  429.          * Compute the factors floor(A-t) and ceil(A+t).
  430.          * Arrays should have length 2n+3.
  431.          *
  432.          * @param n Sample size.
  433.          * @param t Statistic x multiplied by n.
  434.          * @param amt floor(A-t)
  435.          * @param apt ceil(A+t)
  436.          */
  437.         // package-private for testing
  438.         static void computeA(int n, double t, int[] amt, int[] apt) {
  439.             final int l = (int) Math.floor(t);
  440.             final double f = t - l;
  441.             final int limit = 2 * n + 2;

  442.             // 3-cases
  443.             if (f > HALF) {
  444.                 // Case (iii): 1/2 < f < 1
  445.                 // for i = 1, 2, ...
  446.                 for (int j = 2; j <= limit; j += 2) {
  447.                     final int i = j >>> 1;
  448.                     amt[j] = i - 2 - l;
  449.                     apt[j] = i + l;
  450.                 }
  451.                 // for i = 0, 1, 2, ...
  452.                 for (int j = 1; j <= limit; j += 2) {
  453.                     final int i = j >>> 1;
  454.                     amt[j] = i - 1 - l;
  455.                     apt[j] = i + 1 + l;
  456.                 }
  457.             } else if (f > 0) {
  458.                 // Case (ii): 0 < f <= 1/2
  459.                 amt[1] = -l - 1;
  460.                 apt[1] = l + 1;
  461.                 // for i = 1, 2, ...
  462.                 for (int j = 2; j <= limit; j++) {
  463.                     final int i = j >>> 1;
  464.                     amt[j] = i - 1 - l;
  465.                     apt[j] = i + l;
  466.                 }
  467.             } else {
  468.                 // Case (i): f = 0
  469.                 // for i = 1, 2, ...
  470.                 for (int j = 2; j <= limit; j += 2) {
  471.                     final int i = j >>> 1;
  472.                     amt[j] = i - 1 - l;
  473.                     apt[j] = i - 1 + l;
  474.                 }
  475.                 // for i = 0, 1, 2, ...
  476.                 for (int j = 1; j <= limit; j += 2) {
  477.                     final int i = j >>> 1;
  478.                     amt[j] = i - l;
  479.                     apt[j] = i + l;
  480.                 }
  481.             }
  482.         }

  483.         /**
  484.          * Computes the Pelz-Good approximation for {@code P(D_n >= d)} as described in
  485.          * Simard and L’Ecuyer (2011).
  486.          *
  487.          * <p>This has been modified to compute the complementary CDF by subtracting the
  488.          * terms k0, k1, k2, k3 from 1. For use in computing the CDF the method should
  489.          * be updated to return the sum of k0 ... k3.
  490.          *
  491.          * @param x Statistic.
  492.          * @param n Sample size (assumed to be positive).
  493.          * @return \(P(D_n &ge; x)\)
  494.          * @throws ArithmeticException if the series does not converge
  495.          */
  496.         // package-private for testing
  497.         static double pelzGood(double x, int n) {
  498.             // Change the variable to z since approximation is for the distribution evaluated at d / sqrt(n)
  499.             final double z2 = x * x * n;

  500.             double lne = -PI2 / (8 * z2);
  501.             // Final result is ~ (1 - K0) ~ 1 - sqrt(2pi/z) exp(-pi^2 / (8 z^2))
  502.             // Do not compute when the exp value is far below eps.
  503.             if (lne < LOG_PG_MIN) {
  504.                 // z ~ sqrt(-pi^2/(8*min)) ~ 0.1491
  505.                 return 1;
  506.             }
  507.             // Note that summing K1, ..., K3 over all k with factor
  508.             // (k + 1/2) is equivalent to summing over all k with
  509.             // 2 (k - 1/2) / 2 == (2k - 1) / 2
  510.             // This is the form for K0.
  511.             // Compute all together over odd integers and divide factors
  512.             // of (k + 1/2)^b by 2^b.
  513.             double k0 = 0;
  514.             double k1 = 0;
  515.             double k2 = 0;
  516.             double k3 = 0;

  517.             final double rootN = Math.sqrt(n);
  518.             final double z = x * rootN;
  519.             final double z3 = z * z2;
  520.             final double z4 = z2 * z2;
  521.             final double z6 = Math.pow(z2, 3);
  522.             final double z7 = Math.pow(z2, 3.5);
  523.             final double z8 = Math.pow(z2, 4);
  524.             final double z10 = Math.pow(z2, 5);

  525.             final double a1 = PI2 / 4;

  526.             final double a2 = 6 * z6 + 2 * z4;
  527.             final double b2 = (PI2 * (2 * z4 - 5 * z2)) / 4;
  528.             final double c2 = (PI4 * (1 - 2 * z2)) / 16;

  529.             final double a3 = (PI6 * (5 - 30 * z2)) / 64;
  530.             final double b3 = (PI4 * (-60 * z2 + 212 * z4)) / 16;
  531.             final double c3 = (PI2 * (135 * z4 - 96 * z6)) / 4;
  532.             final double d3 = -(30 * z6 + 90 * z8);

  533.             // Iterate j=(2k - 1) for k=1, 2, ...
  534.             // Terms reduce in size. Stop when:
  535.             // exp(-pi^2 / 8z^2) * eps = exp((2k-1)^2 * -pi^2 / 8z^2)
  536.             // (2k-1)^2 = 1 - log(eps) * 8z^2 / pi^2
  537.             // 0 = k^2 - k + log(eps) * 2z^2 / pi^2
  538.             // Solve using quadratic equation and eps = ulp(1.0): 4a ~ -288
  539.             final int max = (int) Math.ceil((1 + Math.sqrt(1 - FOUR_A * z2 / PI2)) / 2);
  540.             // Sum smallest terms first
  541.             for (int k = max; k > 0; k--) {
  542.                 final int j = 2 * k - 1;
  543.                 // Create (2k-1)^2; (2k-1)^4; (2k-1)^6
  544.                 final double j2 = (double) j * j;
  545.                 final double j4 = Math.pow(j, 4);
  546.                 final double j6 = Math.pow(j, 6);
  547.                 // exp(-pi^2 * (2k-1)^2 / 8z^2)
  548.                 final double e = Math.exp(lne * j2);
  549.                 k0 += e;
  550.                 k1 += (a1 * j2 - z2) * e;
  551.                 k2 += (a2 + b2 * j2 + c2 * j4) * e;
  552.                 k3 += (a3 * j6 + b3 * j4 + c3 * j2 + d3) * e;
  553.             }
  554.             k0 *= ROOT_TWO_PI / z;
  555.             // Factors are halved as the sum is for k in -inf to +inf
  556.             k1 *= ROOT_HALF_PI / (3 * z4);
  557.             k2 *= ROOT_HALF_PI / (36 * z7);
  558.             k3 *= ROOT_HALF_PI / (3240 * z10);

  559.             // Compute additional K2,K3 terms
  560.             double k2b = 0;
  561.             double k3b = 0;

  562.             // -pi^2 / (2z^2)
  563.             lne *= 4;

  564.             final double a3b = 3 * PI2 * z2;

  565.             // Iterate for j=1, 2, ...
  566.             // Note: Here max = sqrt(1 - FOUR_A z^2 / (4 pi^2)).
  567.             // This is marginally smaller so we reuse the same value.
  568.             for (int j = max; j > 0; j--) {
  569.                 final double j2 = (double) j * j;
  570.                 final double j4 = Math.pow(j, 4);
  571.                 // exp(-pi^2 * k^2 / 2z^2)
  572.                 final double e = Math.exp(lne * j2);
  573.                 k2b += PI2 * j2 * e;
  574.                 k3b += (-PI4 * j4 + a3b * j2) * e;
  575.             }
  576.             // Factors are halved as the sum is for k in -inf to +inf
  577.             k2b *= ROOT_HALF_PI / (18 * z3);
  578.             k3b *= ROOT_HALF_PI / (108 * z6);

  579.             // Series: K0(z) + K1(z)/n^0.5 + K2(z)/n + K3(z)/n^1.5 + O(1/n^2)
  580.             k1 /= rootN;
  581.             k2 /= n;
  582.             k3 /= n * rootN;
  583.             k2b /= n;
  584.             k3b /= n * rootN;

  585.             // Return (1 - CDF) with an extended precision sum in order of descending magnitude
  586.             return clipProbability(Sum.of(1, -k0, -k1, -k2, -k3, +k2b, -k3b).getAsDouble());
  587.         }
  588.     }

  589.     /**
  590.      * Computes the complementary probability {@code P[D_n^+ >= x]} for the one-sided
  591.      * one-sample Kolmogorov-Smirnov distribution.
  592.      *
  593.      * <pre>
  594.      * D_n^+ = sup_x {CDF_n(x) - F(x)}
  595.      * </pre>
  596.      *
  597.      * <p>where {@code n} is the sample size; {@code CDF_n(x)} is an empirical
  598.      * cumulative distribution function; and {@code F(x)} is the expected
  599.      * distribution. The computation uses Smirnov's stable formula:
  600.      *
  601.      * <pre>
  602.      *                   floor(n(1-x)) (n) ( j     ) (j-1)  (         j ) (n-j)
  603.      * P[D_n^+ >= x] = x     Sum       ( ) ( - + x )        ( 1 - x - - )
  604.      *                       j=0       (j) ( n     )        (         n )
  605.      * </pre>
  606.      *
  607.      * <p>Computing using logs is not as accurate as direct multiplication when n is large.
  608.      * However the terms are very large and small. Multiplication uses a scaled representation
  609.      * with a separate exponent term to support the extreme range. Extended precision
  610.      * representation of the numbers reduces the error in the power terms. Details in
  611.      * van Mulbregt (2018).
  612.      *
  613.      * <p>
  614.      * References:
  615.      * <ol>
  616.      * <li>
  617.      * van Mulbregt, P. (2018).
  618.      * <a href="https://doi.org/10.48550/arxiv.1802.06966">Computing the Cumulative Distribution Function and Quantiles of the One-sided Kolmogorov-Smirnov Statistic</a>
  619.      * arxiv:1802.06966.
  620.      * <li>Magg &amp; Dicaire (1971).
  621.      * <a href="https://doi.org/10.1093/biomet/58.3.653">On Kolmogorov-Smirnov Type One-Sample Statistics</a>
  622.      * Biometrika 58.3 pp. 653–656.
  623.      * </ol>
  624.      *
  625.      * @since 1.1
  626.      */
  627.     static final class One {
  628.         /** "Very large" n to use a asymptotic limiting form.
  629.          * [1] suggests 1e12 but this is reduced to avoid excess
  630.          * computation time. */
  631.         private static final int VERY_LARGE_N = 1000000;
  632.         /** Maximum number of term for the Smirnov-Dwass algorithm. */
  633.         private static final int SD_MAX_TERMS = 3;
  634.         /** Minimum sample size for the Smirnov-Dwass algorithm. */
  635.         private static final int SD_MIN_N = 8;
  636.         /** Number of bits of precision in the sum of terms Aj.
  637.          * This does not have to be the full 106 bits of a double-double as the final result
  638.          * is used as a double. The terms are represented as fractions with an exponent:
  639.          * <pre>
  640.          *  Aj = 2^b * f
  641.          *  f of sum(A) in [0.5, 1)
  642.          *  f of Aj in [0.25, 2]
  643.          * </pre>
  644.          * <p>The terms can be added if their exponents overlap. The bits of precision must
  645.          * account for the extra range of the fractional part of Aj by 1 bit. Note that
  646.          * additional bits are added to this dynamically based on the number of terms. */
  647.         private static final int SUM_PRECISION_BITS = 53;
  648.         /** Number of bits of precision in the sum of terms Aj.
  649.          * For Smirnov-Dwass we use the full 106 bits of a double-double due to the summation
  650.          * of terms that cancel. Account for the extra range of the fractional part of Aj by 1 bit. */
  651.         private static final int SD_SUM_PRECISION_BITS = 107;
  652.         /** Proxy for the default choice of the scaled power function.
  653.          * The actual choice is based on the chosen algorithm. */
  654.         private static final ScaledPower POWER_DEFAULT = null;

  655.         /**
  656.          * Defines a scaled power function.
  657.          * Package-private to allow the main sf method to be called direct in testing.
  658.          */
  659.         interface ScaledPower {
  660.             /**
  661.              * Compute the number {@code x} raised to the power {@code n}.
  662.              *
  663.              * <p>The value is returned as fractional {@code f} and integral
  664.              * {@code 2^exp} components.
  665.              * <pre>
  666.              * (x+xx)^n = (f+ff) * 2^exp
  667.              * </pre>
  668.              *
  669.              * @param x x.
  670.              * @param n Power.
  671.              * @param exp Result power of two scale factor (integral exponent).
  672.              * @return Fraction part.
  673.              * @see DD#frexp(int[])
  674.              * @see DD#pow(int, long[])
  675.              * @see DDMath#pow(DD, int, long[])
  676.              */
  677.             DD pow(DD x, int n, long[] exp);
  678.         }

  679.         /** No instances. */
  680.         private One() {}

  681.         /**
  682.          * Calculates complementary probability {@code P[D_n^+ >= x]}, or survival
  683.          * function (SF), for the one-sided one-sample Kolmogorov-Smirnov distribution.
  684.          *
  685.          * @param x Statistic.
  686.          * @param n Sample size (assumed to be positive).
  687.          * @return \(P(D_n^+ &ge; x)\)
  688.          */
  689.         static double sf(double x, int n) {
  690.             final double p = sfExact(x, n);
  691.             if (p >= 0) {
  692.                 return p;
  693.             }
  694.             // Note: This is not referring to N = floor(n*x).
  695.             // Here n is the sample size and a suggested limit 10^12 is noted on pp.15 in [1].
  696.             // This uses a lower threshold where the full computation takes ~ 1 second.
  697.             if (n > VERY_LARGE_N) {
  698.                 return sfAsymptotic(x, n);
  699.             }
  700.             return sf(x, n, POWER_DEFAULT);
  701.         }

  702.         /**
  703.          * Calculates exact cases for the complementary probability
  704.          * {@code P[D_n^+ >= x]} the one-sided one-sample Kolmogorov-Smirnov distribution.
  705.          *
  706.          * <p>Exact cases handle x not in [0, 1]. It is assumed n is positive.
  707.          *
  708.          * @param x Statistic.
  709.          * @param n Sample size (assumed to be positive).
  710.          * @return \(P(D_n^+ &ge; x)\)
  711.          */
  712.         private static double sfExact(double x, int n) {
  713.             if (n * x * x >= 372.5 || x >= 1) {
  714.                 // p would underflow, or x is out of the domain
  715.                 return 0;
  716.             }
  717.             if (x <= 0) {
  718.                 // edge-of, or out-of, the domain
  719.                 return 1;
  720.             }
  721.             if (n == 1) {
  722.                 return x;
  723.             }
  724.             // x <= 1/n
  725.             // [1] Equation (33)
  726.             final double nx = n * x;
  727.             if (nx <= 1) {
  728.                 // 1 - x (1+x)^(n-1): here x may be small so use log1p
  729.                 return 1 - x * Math.exp((n - 1) * Math.log1p(x));
  730.             }
  731.             // 1 - 1/n <= x < 1
  732.             // [1] Equation (16)
  733.             if (n - 1 <= nx) {
  734.                 // (1-x)^n: here x > 0.5 and 1-x is exact
  735.                 return Math.pow(1 - x, n);
  736.             }
  737.             return -1;
  738.         }

  739.         /**
  740.          * Calculates complementary probability {@code P[D_n^+ >= x]}, or survival
  741.          * function (SF), for the one-sided one-sample Kolmogorov-Smirnov distribution.
  742.          *
  743.          * <p>Computes the result using the asymptotic formula Eq 5 in [1].
  744.          *
  745.          * @param x Statistic.
  746.          * @param n Sample size (assumed to be positive).
  747.          * @return \(P(D_n^+ &ge; x)\)
  748.          */
  749.         private static double sfAsymptotic(double x, int n) {
  750.             // Magg & Dicaire (1971) limiting form
  751.             return Math.exp(-Math.pow(6.0 * n * x + 1, 2) / (18.0 * n));
  752.         }

  753.         /**
  754.          * Calculates complementary probability {@code P[D_n^+ >= x]}, or survival
  755.          * function (SF), for the one-sided one-sample Kolmogorov-Smirnov distribution.
  756.          *
  757.          * <p>Computes the result using double-double arithmetic. The power function
  758.          * can use a fast approximation or a full power computation.
  759.          *
  760.          * <p>This function is safe for {@code x > 1/n}. When {@code x} approaches
  761.          * sub-normal then division or multiplication by x can under/overflow. The
  762.          * case of {@code x < 1/n} can be computed in {@code sfExact}.
  763.          *
  764.          * @param x Statistic (typically in (1/n, 1 - 1/n)).
  765.          * @param n Sample size (assumed to be positive).
  766.          * @param power Function to compute the scaled power (can be null).
  767.          * @return \(P(D_n^+ &ge; x)\)
  768.          * @see DD#pow(int, long[])
  769.          * @see DDMath#pow(DD, int, long[])
  770.          */
  771.         static double sf(double x, int n, ScaledPower power) {
  772.             // Compute only the SF using Algorithm 1 pp 12.

  773.             // Compute: k = floor(n*x), alpha = nx - k; x = (k+alpha)/n with 0 <= alpha < 1
  774.             final double[] alpha = {0};
  775.             final int k = splitX(n, x, alpha);

  776.             // Choose the algorithm:
  777.             // Eq (13) Smirnov/Birnbaum-Tingey; or Smirnov/Dwass Eq (31)
  778.             // Eq. 13 sums j = 0 : floor( n(1-x) )  = n - 1 - floor(nx) iff alpha != 0; else n - floor(nx)
  779.             // Eq. 31 sums j = ceil( n(1-x) ) : n   = n - floor(nx)
  780.             // Drop a term term if x = (n-j)/n. Equates to shifting the floor* down and ceil* up:
  781.             // Eq. 13 N = floor*( n(1-x) ) = n - k - ((alpha!=0) ? 1 : 0) - ((alpha==0) ? 1 : 0)
  782.             // Eq. 31 N = n - ceil*( n(1-x) ) = k - ((alpha==0) ? 1 : 0)
  783.             // Where N is the number of terms - 1. This differs from Algorithm 1 by dropping
  784.             // a SD term when it should be zero (to working precision).
  785.             final int regN = n - k - 1;
  786.             final int sdN = k - ((alpha[0] == 0) ? 1 : 0);

  787.             // SD : Figure 3 (c) (pp. 6)
  788.             // Terms Aj (j = n -> 0) have alternating signs through the range and may involve
  789.             // numbers much bigger than 1 causing cancellation; magnitudes increase then decrease.
  790.             // Section 3.3: Extra digits of precision required
  791.             // grows like Order(sqrt(n)). E.g. sf=0.7 (x ~ 0.4/sqrt(n)) loses 8 digits.
  792.             //
  793.             // Regular : Figure 3 (a, b)
  794.             // Terms Aj can have similar magnitude through the range; when x >= 1/sqrt(n)
  795.             // the final few terms can be magnitudes smaller and could be ignored.
  796.             // Section 3.4: As x increases the magnitude of terms becomes more peaked,
  797.             // centred at j = (n-nx)/2, i.e. 50% of the terms.
  798.             //
  799.             // As n -> inf the sf for x = k/n agrees with the asymptote Eq 5 in log2(n) bits.
  800.             //
  801.             // Figure 4 has lines at x = 1/n and x = 3/sqrt(n).
  802.             // Point between is approximately x = 4/n, i.e. nx < 4 : k <= 3.
  803.             // If faster when x < 0.5 and requiring nx ~ 4 then requires n >= 8.
  804.             //
  805.             // Note: If SD accuracy scales with sqrt(n) then we could use 1 / sqrt(n).
  806.             // That threshold is always above 4 / n when n is 16 (4/n = 1/sqrt(n) : n = 4^2).
  807.             // So the current thresholds are conservative.
  808.             boolean sd = false;
  809.             if (sdN < regN) {
  810.                 // Here x < 0.5 and SD has fewer terms
  811.                 // Always choose when we only have one additional term (i.e x < 2/n)
  812.                 sd = sdN <= 1;
  813.                 // Otherwise when x < 4 / n
  814.                 sd |= sdN <= SD_MAX_TERMS && n >= SD_MIN_N;
  815.             }

  816.             final int maxN = sd ? sdN : regN;

  817.             // Note: if N > "very large" use the asymptotic approximation.
  818.             // Currently this check is done on n (sample size) in the calling function.
  819.             // This provides a monotonic p-value for all x with the same n.

  820.             // Configure the algorithm.
  821.             // The error of double-double addition and multiplication is low (< 2^-102).
  822.             // The error in Aj is mainly from the power function.
  823.             // fastPow error is around 2^-52, pow error is ~ 2^-70 or lower.
  824.             // Smirnoff-Dwass has a sum of terms that cancel and requires higher precision.
  825.             // The power can optionally be specified.
  826.             final ScaledPower fpow;
  827.             if (power == POWER_DEFAULT) {
  828.                 // SD has only a few terms. Use a high accuracy power.
  829.                 fpow = sd ? DDMath::pow : DD::pow;
  830.             } else {
  831.                 fpow = power;
  832.             }
  833.             // For the regular summation we must sum at least 50% of the terms. The number
  834.             // of required bits to sum remaining terms of the same magnitude is log2(N/2).
  835.             // These guards bits are conservative and > ~99% of terms are typically used.
  836.             final int sumBits = sd ? SD_SUM_PRECISION_BITS : SUM_PRECISION_BITS + log2(maxN >> 1);

  837.             // Working variable for the exponent of scaled values
  838.             final int[] ie = {0};
  839.             final long[] le = {0};

  840.             // The terms Aj may over/underflow.
  841.             // This is handled by maintaining the sum(Aj) using a fractional representation.
  842.             // sum(Aj) maintained as 2^e * f with f in [0.5, 1)
  843.             DD sum;
  844.             long esum;

  845.             // Compute A0
  846.             if (sd) {
  847.                 // A0 = (1+x)^(n-1)
  848.                 sum = fpow.pow(DD.ofSum(1, x), n - 1, le);
  849.                 esum = le[0];
  850.             } else {
  851.                 // A0 = (1-x)^n / x
  852.                 sum = fpow.pow(DD.ofDifference(1, x), n, le);
  853.                 esum = le[0];
  854.                 // x in (1/n, 1 - 1/n) so the divide of the fraction is safe
  855.                 sum = sum.divide(x).frexp(ie);
  856.                 esum += ie[0];
  857.             }

  858.             // Binomial coefficient c(n, j) maintained as 2^e * f with f in [1, 2)
  859.             // This value is integral but maintained to limited precision
  860.             DD c = DD.ONE;
  861.             long ec = 0;
  862.             for (int i = 1; i <= maxN; i++) {
  863.                 // c(n, j) = c(n, j-1) * (n-j+1) / j
  864.                 c = c.multiply(DD.fromQuotient(n - i + 1, i));
  865.                 // Here we maintain c in [1, 2) to restrict the scaled Aj term to [0.25, 2].
  866.                 final int b = Math.getExponent(c.hi());
  867.                 if (b != 0) {
  868.                     c = c.scalb(-b);
  869.                     ec += b;
  870.                 }
  871.                 // Compute Aj
  872.                 final int j = sd ? n - i : i;
  873.                 // Algorithm 4 pp. 27
  874.                 // S = ((j/n) + x)^(j-1)
  875.                 // T = ((n-j)/n - x)^(n-j)
  876.                 final DD s = fpow.pow(DD.fromQuotient(j, n).add(x), j - 1, le);
  877.                 final long es = le[0];
  878.                 final DD t = fpow.pow(DD.fromQuotient(n - j, n).subtract(x), n - j, le);
  879.                 final long et = le[0];
  880.                 // Aj = C(n, j) * T * S
  881.                 //    = 2^e * [1, 2] * [0.5, 1] * [0.5, 1]
  882.                 //    = 2^e * [0.25, 2]
  883.                 final long eaj = ec + es + et;
  884.                 // Only compute and add to the sum when the exponents overlap by n-bits.
  885.                 if (eaj > esum - sumBits) {
  886.                     DD aj = c.multiply(t).multiply(s);
  887.                     // Scaling must offset by the scale of the sum
  888.                     aj = aj.scalb((int) (eaj - esum));
  889.                     sum = sum.add(aj);
  890.                 } else {
  891.                     // Terms are expected to increase in magnitude then reduce.
  892.                     // Here the terms are insignificant and we can stop.
  893.                     // Effectively Aj -> eps * sum, and most of the computation is done.
  894.                     break;
  895.                 }

  896.                 // Re-scale the sum
  897.                 sum = sum.frexp(ie);
  898.                 esum += ie[0];
  899.             }

  900.             // p = x * sum(Ai). Since the sum is normalised
  901.             // this is safe as long as x does not approach a sub-normal.
  902.             // Typically x in (1/n, 1 - 1/n).
  903.             sum = sum.multiply(x);
  904.             // Rescale the result
  905.             sum = sum.scalb((int) esum);
  906.             if (sd) {
  907.                 // SF = 1 - CDF
  908.                 sum = sum.negate().add(1);
  909.             }
  910.             return clipProbability(sum.doubleValue());
  911.         }

  912.         /**
  913.          * Compute exactly {@code x = (k + alpha) / n} with {@code k} an integer and
  914.          * {@code alpha in [0, 1)}. Note that {@code k ~ floor(nx)} but may be rounded up
  915.          * if {@code alpha -> 1} within working precision.
  916.          *
  917.          * <p>This computation is a significant source of increased error if performed in
  918.          * 64-bit arithmetic. Although the value alpha is only used for the PDF computation
  919.          * a value of {@code alpha == 0} indicates the final term of the SF summation can be
  920.          * dropped due to the cancellation of a power term {@code (x + j/n)} to zero with
  921.          * {@code x = (n-j)/n}. That is if {@code alpha == 0} then x is the fraction {@code k/n}
  922.          * and one Aj term is zero.
  923.          *
  924.          * @param n Sample size.
  925.          * @param x Statistic.
  926.          * @param alpha Output alpha.
  927.          * @return k
  928.          */
  929.         static int splitX(int n, double x, double[] alpha) {
  930.             // Described on page 14 in van Mulbregt [1].
  931.             // nx = U+V (exact)
  932.             DD z = DD.ofProduct(n, x);
  933.             // Integer part of nx is *almost* the integer part of U.
  934.             // Compute k = floor((U,V)) (changed from the listing of floor(U)).
  935.             int k = (int) z.floor().hi();
  936.             // nx = k + ((U - k) + V) = k + (U1 + V1)
  937.             // alpha = (U1, V1) = z - k
  938.             z = z.subtract(k);
  939.             // alpha is in [0, 1) in double-double precision.
  940.             // Ensure the high part is in [0, 1) (i.e. in double precision).
  941.             if (z.hi() == 1) {
  942.                 // Here alpha is ~ 1.0-eps.
  943.                 // This occurs when x ~ j/n and n is large.
  944.                 k += 1;
  945.                 alpha[0] = 0;
  946.             } else {
  947.                 alpha[0] = z.hi();
  948.             }
  949.             return k;
  950.         }

  951.         /**
  952.          * Returns {@code floor(log2(n))}.
  953.          *
  954.          * @param n Value.
  955.          * @return approximate log2(n)
  956.          */
  957.         private static int log2(int n) {
  958.             return 31 - Integer.numberOfLeadingZeros(n);
  959.         }
  960.     }

  961.     /**
  962.      * Computes {@code P(sqrt(n) D_n > x)}, the limiting form for the distribution of
  963.      * Kolmogorov's D_n as described in Simard and L’Ecuyer (2011) (Eq. 5, or K0 Eq. 6).
  964.      *
  965.      * <p>Computes \( 2 \sum_{i=1}^\infty (-1)^(i-1) e^{-2 i^2 x^2} \), or
  966.      * \( 1 - (\sqrt{2 \pi} / x) * \sum_{i=1}^\infty { e^{-(2i-1)^2 \pi^2 / (8x^2) } } \)
  967.      * when x is small.
  968.      *
  969.      * <p>Note: This computes the upper Kolmogorov sum.
  970.      *
  971.      * @param x Argument x = sqrt(n) * d
  972.      * @return Upper Kolmogorov sum evaluated at x
  973.      */
  974.     static double ksSum(double x) {
  975.         // Switch computation when p ~ 0.5
  976.         if (x < X_KS_HALF) {
  977.             // When x -> 0 the result is 1
  978.             if (x < X_KS_ONE) {
  979.                 return 1;
  980.             }

  981.             // t = exp(-pi^2/8x^2)
  982.             // p = 1 - sqrt(2pi)/x * (t + t^9 + t^25 + t^49 + t^81 + ...)
  983.             //   = 1 - sqrt(2pi)/x * t * (1 + t^8 + t^24 + t^48 + t^80 + ...)

  984.             final double logt = -PI2 / (8 * x * x);
  985.             final double t = Math.exp(logt);
  986.             final double s = ROOT_TWO_PI / x;

  987.             final double t8 = Math.pow(t, 8);
  988.             if (t8 < EPS) {
  989.                 // Cannot compute 1 + t^8.
  990.                 // 1 - sqrt(2pi)/x * exp(-pi^2/8x^2)
  991.                 // 1 - exp(log(sqrt(2pi)/x) - pi^2/8x^2)
  992.                 return -Math.expm1(Math.log(s) + logt);
  993.             }

  994.             // sum = t^((2i-1)^2 - 1), i=1, 2, 3, 4, 5, ...
  995.             //     = 1 + t^8 + t^24 + t^48 + t^80 + ...
  996.             // With x = 0.82757... the smallest terms cannot be added when i==5
  997.             // i.e. t^48 + t^80 == t^48
  998.             // sum = 1 + (t^8 * (1 + t^16 * (1 + t^24)))
  999.             final double sum = 1 + (t8 * (1 + t8 * t8 * (1 + t8 * t8 * t8)));
  1000.             return 1 - s * t * sum;
  1001.         }

  1002.         // t = exp(-2 x^2)
  1003.         // p = 2 * (t - t^4 + t^9 - t^16 + ...)
  1004.         // sum = -1^(i-1) t^(i^2), i=i, 2, 3, ...

  1005.         // Sum of alternating terms of reducing magnitude:
  1006.         // Will converge when exp(-2x^2) * eps >= exp(-2x^2)^(i^2)
  1007.         // When x = 0.82757... this requires max i==5
  1008.         // i.e. t * eps >= t^36 (i=6)
  1009.         final double t = Math.exp(-2 * x * x);

  1010.         // (t - t^4 + t^9 - t^16 + t^25)
  1011.         // t * (1 - t^3 * (1 - t^5 * (1 - t^7 * (1 - t^9))))
  1012.         final double t2 = t * t;
  1013.         final double t3 = t * t * t;
  1014.         final double t4 = t2 * t2;
  1015.         final double sum = t * (1 - t3 * (1 - t2 * t3 * (1 - t3 * t4 * (1 - t2 * t3 * t4))));
  1016.         return clipProbability(2 * sum);
  1017.     }

  1018.     /**
  1019.      * Clip the probability to the range [0, 1].
  1020.      *
  1021.      * @param p Probability.
  1022.      * @return p in [0, 1]
  1023.      */
  1024.     static double clipProbability(double p) {
  1025.         return Math.min(1, Math.max(0, p));
  1026.     }
  1027. }