Accord.Statistics.Distributions.Univariate.KolmogorovSmirnovDistribution.Pomeranz C# (CSharp) Method

Pomeranz() public static method

Pomeranz algorithm.
public static Pomeranz ( int n, double x ) : double
n int
x double
return double
        public static double Pomeranz(int n, double x)
        {
            // The Pomeranz algorithm to compute the KS distribution
            double EPS = 1.0e-15;
            int ENO = 350;
            double RENO = Math.Pow(2, ENO); // for renormalization of V
            int renormalizations;
            double t = n * x;
            double w, sum, minsum;
            int k, s;
            int r1, r2; // Indices i and i-1 for V[i][]
            int jlow, jup, klow, kup, kup0;

            double[] A = new double[2 * n + 3];
            double[] floors = new double[2 * n + 3];
            double[] ceilings = new double[2 * n + 3];

            double[][] V = new double[2][];
            for (int j = 0; j < V.Length; j++)
                V[j] = new double[n + 2];

            double[][] H = new double[4][];     // = pow(w, j) / Factorial(j)
            for (int j = 0; j < H.Length; j++)
                H[j] = new double[n + 2];

            double z = computeLimits(t, floors, ceilings);

            computeA(n, A, z);
            computeH(n, A, H);

            V[1][1] = RENO;
            renormalizations = 1;

            r1 = 0;
            r2 = 1;
            for (int i = 2; i <= 2 * n + 2; i++)
            {
                jlow = (int)(2 + floors[i]);
                if (jlow < 1)
                    jlow = 1;
                jup = (int)(ceilings[i]);
                if (jup > n + 1)
                    jup = n + 1;

                klow = (int)(2 + floors[i - 1]);
                if (klow < 1)
                    klow = 1;
                kup0 = (int)(ceilings[i - 1]);

                // Find to which case it corresponds
                w = (A[i] - A[i - 1]) / n;
                s = -1;
                for (int j = 0; j < 4; j++)
                {
                    if (Math.Abs(w - H[j][1]) <= EPS)
                    {
                        s = j;
                        break;
                    }
                }

                minsum = RENO;
                r1 = (r1 + 1) & 1;          // i - 1
                r2 = (r2 + 1) & 1;          // i

                for (int j = jlow; j <= jup; j++)
                {
                    kup = kup0;
                    if (kup > j)
                        kup = j;
                    sum = 0;
                    for (k = kup; k >= klow; k--)
                        sum += V[r1][k] * H[s][j - k];
                    V[r2][j] = sum;
                    if (sum < minsum)
                        minsum = sum;
                }

                if (minsum < 1.0e-280)
                {
                    // V is too small: renormalize to avoid underflow of probabilities
                    for (int j = jlow; j <= jup; j++)
                        V[r2][j] *= RENO;
                    renormalizations++;              // keep track of log of RENO
                }
            }

            sum = V[r2][n + 1];
            w = Special.LogFactorial(n) - renormalizations * ENO * Constants.Log2 + Math.Log(sum);
            if (w >= 0)
                return 1;
            return Math.Exp(w);
        }