C#,数值计算——Kolmogorov-Smirnov累积分布函数的计算方法与源程序

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// Kolmogorov-Smirnov累积分布函数
    /// Kolmogorov-Smirnov cumulative distribution functions 
    /// and their inverses.
    /// </summary>
    public class KSdist
    {
        public double pks(double z)
        {
            if (z < 0.0)
            {
                throw new Exception("bad z in KSdist");
            }
            if (z < 0.042)
            {
                return 0.0;
            }
            if (z < 1.18)
            {
                double y = Math.Exp(-1.23370055013616983 / Globals.SQR(z));
                return 2.25675833419102515 * Math.Sqrt(-Math.Log(y)) * (y + Math.Pow(y, 9) + Math.Pow(y, 25) + Math.Pow(y, 49));
            }
            else
            {
                double x = Math.Exp(-2.0 * Globals.SQR(z));
                return 1.0 - 2.0 * (x - Math.Pow(x, 4) + Math.Pow(x, 9));
            }
        }

        public double qks(double z)
        {
            if (z < 0.0)
            {
                throw new Exception("bad z in KSdist");
            }
            //if (z == 0.0)
            if (Math.Abs(z) <= float.Epsilon)
            {
                return 1.0;
            }
            if (z < 1.18)
            {
                return 1.0 - pks(z);
            }
            double x = Math.Exp(-2.0 * Globals.SQR(z));
            return 2.0 * (x - Math.Pow(x, 4) + Math.Pow(x, 9));
        }

        public double invqks(double q)
        {
            if (q <= 0.0 || q > 1.0)
            {
                throw new Exception("bad q in KSdist");
            }
            //if (q == 1.0)
            if (Math.Abs(q) <= float.Epsilon)
            {
                return 0.0;
            }
            if (q > 0.3)
            {
                double f = -0.392699081698724155 * Globals.SQR(1.0 - q);
                double y = Integrals.invxlogx(f);
                double t;
                do
                {
                    double yp = y;
                    double logy = Math.Log(y);
                    double ff = f / Globals.SQR(1.0 + Math.Pow(y, 4) + Math.Pow(y, 12));
                    double u = (y * logy - ff) / (1.0 + logy);
                    t = u / Math.Max(0.5, 1.0 - 0.5 * u / (y * (1.0 + logy)));
                    y = y - (t);
                } while (Math.Abs(t / y) > 1.0e-15);
                return 1.57079632679489662 / Math.Sqrt(-Math.Log(y));
            }
            else
            {
                double x = 0.03;
                double xp;
                do
                {
                    xp = x;
                    x = 0.5 * q + Math.Pow(x, 4) - Math.Pow(x, 9);
                    if (x > 0.06)
                    {
                        x += Math.Pow(x, 16) - Math.Pow(x, 25);
                    }
                } while (Math.Abs((xp - x) / x) > 1.0e-15);
                return Math.Sqrt(-0.5 * Math.Log(x));
            }
        }

        public double invpks(double p)
        {
            return invqks(1.0 - p);
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/beijinghorn/article/details/131894088