コード例 #1
0
        private static double GetGaussianQuantileRank(double x, double x0, double p0, double x1, double p1)
        {
            double mean, stddev;

            GetGaussianFromQuantiles(x0, p0, x1, p1, out mean, out stddev);
            return(MMath.NormalCdf((x - mean) / stddev));
        }
コード例 #2
0
        public void NormalCdf2Test()
        {
            double x = 1.2, y = 1.3;
            double xy1 = System.Math.Max(0.0, MMath.NormalCdf(x) + MMath.NormalCdf(y) - 1);

            Assert.True(0 < MMath.NormalCdf(6.8419544775976187E-08, -5.2647906596206016E-08, -1, 3.1873689658872377E-10).Mantissa);

            // In sage:
            // integral(1/(2*pi*sqrt(1-t*t))*exp(-(x*x+y*y-2*t*x*y)/(2*(1-t*t))),t,-1,r).n(digits=200);
            double[,] normalcdf2_pairs = ReadPairs(Path.Combine(TestUtils.DataFolderPath, "SpecialFunctionsValues", "NormalCdf2.csv"));
            CheckFunctionValues("NormalCdf2", new MathFcn3(MMath.NormalCdf), normalcdf2_pairs);

            // using wolfram alpha:  (for cases where r=-1 returns zero)
            // log(integrate(1/(2*pi*sqrt(1-t*t))*exp(-(2*0.1*0.1 - 2*t*0.1*0.1)/(2*(1-t*t))),t,-1,-0.9999))
            // log(integrate(1/(2*pi*sqrt(1-t*t))*exp(-(2*1.5*1.5 + 2*t*1.5*1.5)/(2*(1-t*t))),t,-1,-0.5))
            double[,] normalcdfln2_pairs = ReadPairs(Path.Combine(TestUtils.DataFolderPath, "SpecialFunctionsValues", "NormalCdfLn2.csv"));
            CheckFunctionValues("NormalCdfLn2", new MathFcn3(MMath.NormalCdfLn), normalcdfln2_pairs);

            double[,] normalcdfRatioLn2_pairs = ReadPairs(Path.Combine(TestUtils.DataFolderPath, "SpecialFunctionsValues", "NormalCdfRatioLn2.csv"));
            CheckFunctionValues("NormalCdfRatioLn2", new MathFcn4(NormalCdfRatioLn), normalcdfRatioLn2_pairs);

            // The true values are computed using
            // x * MMath.NormalCdf(x, y, r) + System.Math.Exp(Gaussian.GetLogProb(x, 0, 1) + MMath.NormalCdfLn(ymrx)) + r * System.Math.Exp(Gaussian.GetLogProb(y, 0, 1) + MMath.NormalCdfLn(xmry))
            // where
            // ymrx = (y - r * x) / sqrt(1-r*r)
            // xmry = (x - r * y) / sqrt(1-r*r)
            double[,] normalcdfIntegral_pairs = ReadPairs(Path.Combine(TestUtils.DataFolderPath, "SpecialFunctionsValues", "NormalCdfIntegral.csv"));
            CheckFunctionValues("NormalCdfIntegral", new MathFcn3(MMath.NormalCdfIntegral), normalcdfIntegral_pairs);

            double[,] normalcdfIntegralRatio_pairs = ReadPairs(Path.Combine(TestUtils.DataFolderPath, "SpecialFunctionsValues", "NormalCdfIntegralRatio.csv"));
            CheckFunctionValues("NormalCdfIntegralRatio", new MathFcn3(MMath.NormalCdfIntegralRatio), normalcdfIntegralRatio_pairs);
        }
コード例 #3
0
ファイル: Range.cs プロジェクト: liux3260/5092-1-HW
        public double[] getbsdelta(double strike, double under, double volatility, double t, double rate)//calculate delta
        {
            double d1;

            double[] delta = new double[2];
            d1       = (Math.Log(under / strike) + (rate + Math.Pow(volatility, 2) / 2) * t) / (volatility * Math.Sqrt(t));
            delta[0] = MMath.NormalCdf(d1); //call delta
            delta[1] = delta[0] - 1;        //put delta
            return(delta);
        }
コード例 #4
0
        public void NormalCdfTest()
        {
            /* In python mpmath:
             * from mpmath import *
             * mp.dps = 500
             * mp.pretty = True
             * ncdf(-12.2)
             */
            // In wolfram alpha: (not always accurate)
            // http://www.wolframalpha.com/input/?i=erfc%2813%2Fsqrt%282%29%29%2F2
            // In xcas: (not always accurate)
            // Digits := 30
            // phi(x) := evalf(erfc(-x/sqrt(2))/2);
            double[,] normcdf_pairs = ReadPairs(Path.Combine(TestUtils.DataFolderPath, "SpecialFunctionsValues", "NormalCdf.csv"));
            CheckFunctionValues("NormalCdf", new MathFcn(MMath.NormalCdf), normcdf_pairs);

            Assert.Equal(0.5, MMath.NormalCdf(0));
            Assert.True(MMath.NormalCdf(7.9) <= 1);
            Assert.True(MMath.NormalCdf(-40) >= 0);
            Assert.True(MMath.NormalCdf(-80) >= 0);

            double[,] erfc_pairs = new double[normcdf_pairs.GetLength(0), normcdf_pairs.GetLength(1)];
            for (int i = 0; i < normcdf_pairs.GetLength(0); i++)
            {
                double input  = normcdf_pairs[i, 0];
                double output = normcdf_pairs[i, 1];
                erfc_pairs[i, 0] = -input / MMath.Sqrt2;
                erfc_pairs[i, 1] = 2 * output;
            }
            CheckFunctionValues("Erfc", new MathFcn(MMath.Erfc), erfc_pairs);

            double[,] normcdfinv_pairs = new double[normcdf_pairs.GetLength(0), 2];
            for (int i = 0; i < normcdfinv_pairs.GetLength(0); i++)
            {
                double input  = normcdf_pairs[i, 0];
                double output = normcdf_pairs[i, 1];
                if (!(Double.IsPositiveInfinity(input) || Double.IsNegativeInfinity(input)) && (input <= -10 || input >= 6))
                {
                    normcdfinv_pairs[i, 0] = 0.5;
                    normcdfinv_pairs[i, 1] = 0;
                }
                else
                {
                    normcdfinv_pairs[i, 0] = output;
                    normcdfinv_pairs[i, 1] = input;
                }
            }
            CheckFunctionValues("NormalCdfInv", new MathFcn(MMath.NormalCdfInv), normcdfinv_pairs);

            double[,] normcdfln_pairs = ReadPairs(Path.Combine(TestUtils.DataFolderPath, "SpecialFunctionsValues", "NormalCdfLn.csv"));
            CheckFunctionValues("NormalCdfLn", new MathFcn(MMath.NormalCdfLn), normcdfln_pairs);

            double[,] normcdflogit_pairs = ReadPairs(Path.Combine(TestUtils.DataFolderPath, "SpecialFunctionsValues", "NormalCdfLogit.csv"));
            CheckFunctionValues("NormalCdfLogit", new MathFcn(MMath.NormalCdfLogit), normcdflogit_pairs);
        }
コード例 #5
0
        private double NormalCdfIntegralTaylor(double x, double y, double r)
        {
            double omr2     = 1 - r * r;
            double sqrtomr2 = System.Math.Sqrt(omr2);
            double ymrx     = y / sqrtomr2;
            double dx0      = MMath.NormalCdf(0, y, r);
            double ddx0     = System.Math.Exp(Gaussian.GetLogProb(0, 0, 1) + MMath.NormalCdfLn(ymrx));
            // \phi_{xx} &= -x \phi_x - r \phi_r
            double dddx0 = -r *System.Math.Exp(Gaussian.GetLogProb(0, 0, 1) + Gaussian.GetLogProb(ymrx, 0, 1));

            Trace.WriteLine($"dx0 = {dx0} {ddx0} {dddx0}");
            return(MMath.NormalCdfIntegral(0, y, r) + x * dx0 + 0.5 * x * x * ddx0 + 1.0 / 6 * x * x * x * dddx0);
        }
コード例 #6
0
        public static double NormalCdfMomentRecurrence(int n, double m, double v)
        {
            double prev = Math.Exp(-MMath.LnSqrt2PI - 0.5 * Math.Log(v) - 0.5 * m * m / v);
            double cur  = MMath.NormalCdf(m / Math.Sqrt(v));

            for (int i = 0; i < n; i++)
            {
                double next = (m * cur + v * prev) / (i + 1);
                prev = cur;
                cur  = next;
            }
            return(cur);
        }
コード例 #7
0
 /// <summary>
 /// Gets the log of the normalizer for the Gaussian density function
 /// </summary>
 /// <returns></returns>
 public double GetLogNormalizer()
 {
     if (IsProper())
     {
         // need to check this handles no truncation correctly
         double m = Gaussian.MeanTimesPrecision / Gaussian.Precision;
         double s = Math.Sqrt(1 / Gaussian.Precision);
         double Z = MMath.NormalCdf((UpperBound - m) / s)
                    - MMath.NormalCdf((LowerBound - m) / s);
         return(MMath.LnSqrt2PI + 0.5 * (Gaussian.MeanTimesPrecision * Gaussian.MeanTimesPrecision / Gaussian.Precision - Math.Log(Gaussian.Precision)) + Math.Log(Z));
     }
     else
     {
         return(0.0);
     }
 }
コード例 #8
0
 /// <summary>
 /// Compute the probability that a sample from this distribution is less than x.
 /// </summary>
 /// <param name="x">Any real number.</param>
 /// <returns>The cumulative gaussian distribution at <paramref name="x"/></returns>
 public double GetProbLessThan(double x)
 {
     if (this.IsPointMass)
     {
         return((this.Point < x) ? 1.0 : 0.0);
     }
     else if (Precision <= 0.0)
     {
         throw new ImproperDistributionException(this);
     }
     else
     {
         double sqrtPrec = Math.Sqrt(Precision);
         // (x - m)/sqrt(v) = x/sqrt(v) - m/v * sqrt(v)
         return(MMath.NormalCdf(x * sqrtPrec - MeanTimesPrecision / sqrtPrec));
     }
 }
コード例 #9
0
ファイル: QuantileTests.cs プロジェクト: woooodbond/infer
        public void QuantileTest()
        {
            // draw many samples from N(m,v)
            Rand.Restart(0);
            int           n      = 10000;
            double        m      = 2;
            double        stddev = 3;
            Gaussian      prior  = new Gaussian(m, stddev * stddev);
            List <double> x      = new List <double>();

            for (int i = 0; i < n; i++)
            {
                x.Add(prior.Sample());
            }
            x.Sort();
            var sortedData = new OuterQuantiles(x.ToArray());

            // compute quantiles
            var quantiles = InnerQuantiles.FromDistribution(100, sortedData);

            // loop over x's and compare true quantile rank
            var    testPoints = EpTests.linspace(MMath.Min(x) - stddev, MMath.Max(x) + stddev, 100);
            double maxError   = 0;

            foreach (var testPoint in testPoints)
            {
                var trueRank = MMath.NormalCdf((testPoint - m) / stddev);
                var estRank  = quantiles.GetProbLessThan(testPoint);
                var error    = System.Math.Abs(trueRank - estRank);
                //Trace.WriteLine($"{testPoint} trueRank={trueRank} estRank={estRank} error={error}");
                Assert.True(error < 0.02);
                maxError = System.Math.Max(maxError, error);

                double estQuantile = quantiles.GetQuantile(estRank);
                error = MMath.AbsDiff(estQuantile, testPoint, 1e-8);
                //Trace.WriteLine($"{testPoint} estRank={estRank} estQuantile={estQuantile} error={error}");
                Assert.True(error < 1e-8);

                estRank = sortedData.GetProbLessThan(testPoint);
                error   = System.Math.Abs(trueRank - estRank);
                //Trace.WriteLine($"{testPoint} trueRank={trueRank} estRank={estRank} error={error}");
                Assert.True(error < 0.02);
            }
            //Trace.WriteLine($"max rank error = {maxError}");
        }
コード例 #10
0
        private double NormalCdfIntegralBasic(double x, double y, double r)
        {
            double omr2     = 1 - r * r;
            double sqrtomr2 = System.Math.Sqrt(omr2);
            double ymrx     = (y - r * x) / sqrtomr2;
            double xmry     = (x - r * y) / sqrtomr2;
            // should use this whenever x > 0 and Rymrx >= Rxmry (y-r*x >= x-r*y implies y*(1+r) >= x*(1+r) therefore y >= x)
            // we need a special routine to compute 2nd half without cancellation and without dividing by phir
            // what about x > y > 0?
            //double t = MMath.NormalCdfIntegral(-x, y, -r) + x * MMath.NormalCdf(y) + r * System.Math.Exp(Gaussian.GetLogProb(y, 0, 1));
            //Console.WriteLine(t);
            double phix = System.Math.Exp(Gaussian.GetLogProb(x, 0, 1) + MMath.NormalCdfLn(ymrx));
            double phiy = System.Math.Exp(Gaussian.GetLogProb(y, 0, 1) + MMath.NormalCdfLn(xmry));

            //Trace.WriteLine($"phix = {phix} phiy = {phiy}");
            return(x * MMath.NormalCdf(x, y, r) + phix + r * phiy);
            //return y * MMath.NormalCdf(x, y, r) + r * System.Math.Exp(Gaussian.GetLogProb(x, 0, 1) + MMath.NormalCdfLn(ymrx)) + System.Math.Exp(Gaussian.GetLogProb(y, 0, 1) + MMath.NormalCdfLn(xmry));
        }
コード例 #11
0
        internal void NormalCdfSpeedTest()
        {
            // current results:
            // NormalCdf(0.5): 28ms
            // NormalCdf2: 1974ms
            MMath.NormalCdf(0.5);
            double x = 1.5;

            MMath.NormalCdf(x, 0.5, 0.95);
            Stopwatch watch = new Stopwatch();

            watch.Start();
            for (int i = 0; i < 100000; i++)
            {
                MMath.NormalCdf(0.5);
            }
            watch.Stop();
            Console.WriteLine("NormalCdf(0.5): " + watch.ElapsedMilliseconds + "ms");
            watch.Restart();
            for (int i = 0; i < 100000; i++)
            {
                NormalCdf_Quadrature(x, 0.5, 0.1);
            }
            watch.Stop();
            Console.WriteLine("NormalCdf2Quad: " + watch.ElapsedMilliseconds + "ms");
            watch.Restart();
            for (int i = 0; i < 100000; i++)
            {
                NormalCdfAlt(x, 0.5, 0.1);
            }
            watch.Stop();
            Console.WriteLine("NormalCdf2Alt: " + watch.ElapsedMilliseconds + "ms");
            watch.Restart();
            for (int i = 0; i < 100000; i++)
            {
                MMath.NormalCdf(x, 0.5, 0.95);
            }
            watch.Stop();
            Console.WriteLine("NormalCdf2: " + watch.ElapsedMilliseconds + "ms");
        }
コード例 #12
0
        /// <summary>
        /// Compute int_0^Inf x^n N(x;m,v) dx for all integer n from 0 to nMax.  Loses accuracy if m &lt; -1.
        /// </summary>
        /// <param name="nMax"></param>
        /// <param name="m"></param>
        /// <param name="v"></param>
        /// <returns></returns>
        public static double[] NormalCdfMoments(int nMax, double m, double v)
        {
            double[] result = new double[nMax + 1];
            double   sqrtV  = Math.Sqrt(v);
            double   cur    = MMath.NormalCdf(m / sqrtV);

            result[0] = cur;
            if (nMax > 0)
            {
                double prev = cur;
                cur       = m * prev + sqrtV * Math.Exp(-MMath.LnSqrt2PI - 0.5 * m * m / v);
                result[1] = cur;
                for (int i = 1; i < nMax; i++)
                {
                    double next = m * cur + v * prev * i;
                    prev          = cur;
                    cur           = next;
                    result[i + 1] = cur;
                }
            }
            return(result);
        }
コード例 #13
0
        internal void NormalCdfIntegralTest2()
        {
            double x = 0.0093132267868981222;
            double y = -0.0093132247056551785;
            double r = -1;

            y = -2499147.006377392;
            x = 2499147.273918618;
            //MMath.TraceConFrac = true;
            //MMath.TraceConFrac2 = true;
            for (int i = 0; i < 100; i++)
            {
                //x = 2.1 * (i + 1);
                //y = -2 * (i + 1);
                //x = -2 * (i + 1);
                //y = 2.1 * (i + 1);
                //x = -System.Math.Pow(10, -i);
                //y = -x * 1.1;
                x = -0.33333333333333331;
                y = -1.5;
                r = 0.16666666666666666;
                x = -0.4999;
                y = 0.5;
                x = -0.1;
                y = 0.5;
                r = -0.1;

                x = -824.43680216388009;
                y = -23300.713731480908;
                r = -0.99915764591723821;
                x = -0.94102098773740084;
                x = 1 + i * 0.01;
                y = 2;
                r = 1;

                x = 0.021034851174404436;
                y = -0.37961242087533614;
                //x = -0.02;
                //y += -1;
                //x -= -1;
                r = -1 + System.Math.Pow(10, -i);

                //x = i * 0.01;
                //y = -1;
                //r = -1 + 1e-8;

                // 1.81377005549484E-40 with exponent
                // flipped is 1.70330340479022E-40
                //x = -1;
                //y = -8.9473684210526319;
                //x = System.Math.Pow(10, -i);
                //y = x;
                //r = -0.999999999999999;

                //x = -0.94102098773740084;
                //y = -1.2461486442846208;
                //r = 0.5240076921033775;

                x = 790.80368892437889;
                y = -1081776354979.6719;
                y = -System.Math.Pow(10, i);
                r = -0.94587440643473975;

                x = -39062.492380206008;
                y = 39062.501110681893;
                r = -0.99999983334056686;

                //x = -2;
                //y = 1.5789473684210522;
                //r = -0.78947368421052622;

                //x = -1.1;
                //y = -1.1;
                //r = 0.052631578947368474;

                //x = 0.001;
                //y = -0.0016842105263157896;
                //r = -0.4;

                //x = 0.1;
                //x = 2000;
                //y = -2000;
                //r = -0.99999999999999989;

                x = double.MinValue;
                y = double.MinValue;
                r = 0.1;


                Trace.WriteLine($"(x,y,r) = {x:g17}, {y:g17}, {r:g17}");

                double intZOverZ;
                try
                {
                    intZOverZ = MMath.NormalCdfIntegralRatio(x, y, r);
                }
                catch
                {
                    intZOverZ = double.NaN;
                }
                Trace.WriteLine($"intZOverZ = {intZOverZ:g17}");

                double         intZ0 = NormalCdfIntegralBasic(x, y, r);
                double         intZ1 = 0; // NormalCdfIntegralFlip(x, y, r);
                double         intZr = 0; // NormalCdfIntegralBasic2(x, y, r);
                ExtendedDouble intZ;
                double         sqrtomr2 = System.Math.Sqrt((1 - r) * (1 + r));
                try
                {
                    intZ = MMath.NormalCdfIntegral(x, y, r, sqrtomr2);
                }
                catch
                {
                    intZ = ExtendedDouble.NaN();
                }
                //double intZ = intZ0;
                Trace.WriteLine($"intZ = {intZ:g17} {intZ.ToDouble():g17} {intZ0:g17} {intZ1:g17} {intZr:g17}");
                if (intZ.Mantissa < 0)
                {
                    throw new Exception();
                }
                //double intZ2 = NormalCdfIntegralBasic(y, x, r);
                //Trace.WriteLine($"intZ2 = {intZ2} {r*intZ}");
                double Z = MMath.NormalCdf(x, y, r);
                if (Z < 0)
                {
                    throw new Exception();
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// Used to tune MMath.NormalCdfLn.  The best tuning minimizes the number of messages printed.
        /// </summary>
        internal void NormalCdf2Test2()
        {
            // Call both routines now to speed up later calls.
            MMath.NormalCdf(-2, -2, -0.5);
            NormalCdf_Quadrature(-2, -2, -0.5);
            Stopwatch watch = new Stopwatch();
            double    xmin  = 0.1;
            double    xmax  = 0.1;
            double    n     = 20;
            double    xinc  = (xmax - xmin) / (n - 1);

            for (int xi = 0; xi < n; xi++)
            {
                if (xinc == 0 && xi > 0)
                {
                    break;
                }
                double x    = xmin + xi * xinc;
                double ymin = -System.Math.Abs(x) * 10;
                double ymax = -ymin;
                double yinc = (ymax - ymin) / (n - 1);
                for (int yi = 0; yi < n; yi++)
                {
                    double y    = ymin + yi * yinc;
                    double rmin = -0.999999;
                    double rmax = -0.000001;
                    rmin = MMath.NextDouble(-1);
                    rmax = -1 + 1e-6;
                    //rmax = -0.5;
                    //rmax = 0.1;
                    //rmax = -0.58;
                    //rmax = -0.9;
                    //rmin = -0.5;
                    rmax = 1;
                    double rinc = (rmax - rmin) / (n - 1);
                    for (int ri = 0; ri < n; ri++)
                    {
                        double r    = rmin + ri * rinc;
                        string good = "good";
                        watch.Restart();
                        double result1 = double.NaN;
                        try
                        {
                            result1 = MMath.NormalCdfIntegral(x, y, r);
                        }
                        catch
                        {
                            good = "bad";
                            //throw;
                        }
                        watch.Stop();
                        long ticks = watch.ElapsedTicks;
                        watch.Restart();
                        double result2 = double.NaN;
                        try
                        {
                            result2 = NormalCdfLn_Quadrature(x, y, r);
                        }
                        catch
                        {
                        }
                        long ticks2   = watch.ElapsedTicks;
                        bool overtime = ticks > 10 * ticks2;
                        if (double.IsNaN(result1) /*|| overtime*/)
                        {
                            Trace.WriteLine($"({x:g17},{y:g17},{r:g17},{x - r * y}): {good} {ticks} {ticks2} {result1} {result2}");
                        }
                    }
                }
            }
        }
コード例 #15
0
        /// <summary>
        /// Computes the cumulative bivariate normal distribution.
        /// </summary>
        /// <param name="x">First upper limit.  Must be finite.</param>
        /// <param name="y">Second upper limit.  Must be finite.</param>
        /// <param name="r">Correlation coefficient.</param>
        /// <returns><c>phi(x,y,r)</c></returns>
        /// <remarks>
        /// The double integral is transformed into a single integral which is approximated by quadrature.
        /// Reference:
        /// "Numerical Computation of Rectangular Bivariate and Trivariate Normal and t Probabilities"
        /// Alan Genz, Statistics and Computing, 14 (2004), pp. 151-160
        /// http://www.math.wsu.edu/faculty/genz/genzhome/research.html
        /// </remarks>
        private static double NormalCdf_Quadrature(double x, double y, double r)
        {
            double absr = System.Math.Abs(r);
            Vector nodes, weights;
            int    count = 20;

            if (absr < 0.3)
            {
                count = 6;
            }
            else if (absr < 0.75)
            {
                count = 12;
            }
            nodes   = Vector.Zero(count);
            weights = Vector.Zero(count);
            double result = 0.0;

            if (absr < 0.925)
            {
                // use equation (3)
                double asinr = System.Math.Asin(r);
                Quadrature.UniformNodesAndWeights(0, asinr, nodes, weights);
                double sq = 0.5 * (x * x + y * y), xy = x * y;
                for (int i = 0; i < nodes.Count; i++)
                {
                    double sin  = System.Math.Sin(nodes[i]);
                    double cos2 = 1 - sin * sin;
                    result += weights[i] * System.Math.Exp((xy * sin - sq) / cos2);
                }
                result /= 2 * System.Math.PI;
                result += MMath.NormalCdf(x, y, 0);
            }
            else
            {
                double sy = (r < 0) ? -y : y;
                if (absr < 1)
                {
                    // use equation (6) modified by (7)
                    // quadrature part
                    double cos2asinr = (1 - r) * (1 + r), sqrt1mrr = System.Math.Sqrt(cos2asinr);
                    Quadrature.UniformNodesAndWeights(0, sqrt1mrr, nodes, weights);
                    double sxy = x * sy;
                    double diff2 = (x - sy) * (x - sy);
                    double c = (4 - sxy) / 8, d = (12 - sxy) / 16;
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        double cos2     = nodes[i] * nodes[i];
                        double sin      = System.Math.Sqrt(1 - cos2);
                        double series   = 1 + c * cos2 * (1 + d * cos2);
                        double exponent = -0.5 * (diff2 / cos2 + sxy);
                        double f        = System.Math.Exp(-0.5 * sxy * (1 - sin) / (1 + sin)) / sin;
                        result += weights[i] * System.Math.Exp(exponent) * (f - series);
                    }
                    // Taylor expansion part
                    double exponentr = -0.5 * (diff2 / cos2asinr + sxy);
                    double absdiff   = System.Math.Sqrt(diff2);
                    if (exponentr > -800)
                    {
                        // avoid 0*Inf problems
                        result += sqrt1mrr * System.Math.Exp(exponentr) * (1 - c * (diff2 - cos2asinr) * (1 - d * diff2 / 5) / 3 + c * d * cos2asinr * cos2asinr / 5);
                        // for large absdiff, NormalCdfLn(-absdiff / sqrt1mrr) =approx -0.5*diff2/cos2asinr
                        // so (-0.5*sxy + NormalCdfLn) =approx exponentr
                        result -= System.Math.Exp(-0.5 * sxy + MMath.NormalCdfLn(-absdiff / sqrt1mrr)) * absdiff * (1 - c * diff2 * (1 - d * diff2 / 5) / 3) * MMath.Sqrt2PI;
                    }
                    result /= -2 * System.Math.PI;
                }
                if (r > 0)
                {
                    // exact value for r=1
                    result += MMath.NormalCdf(x, y, 1);
                }
                else
                {
                    // exact value for r=-1
                    result  = -result;
                    result += MMath.NormalCdf(x, y, -1);
                }
            }
            if (result < 0)
            {
                result = 0.0;
            }
            else if (result > 1)
            {
                result = 1.0;
            }
            return(result);
        }
コード例 #16
0
        // Used to debug MMath.NormalCdf
        internal void NormalCdf2Test3()
        {
            double x, y, r;
            bool   first = true;

            if (first)
            {
                // x=-2, y=-10, r=0.9 is dominated by additive part of numerator - poor convergence
                // -2,-2,-0.5
                x = -1.0058535005109381;
                y = -0.11890687017604007;
                r = -0.79846947062734286;
                x = -63;
                y = 63;
                r = -0.4637494637494638;

                x = -1.0329769464004883E-08;
                y = 1.0329769464004876E-08;
                r = -0.99999999999999512;

                x = 0;
                y = 0;
                r = -0.6;

                x = -1.15950886531361;
                y = 0.989626418003324;
                r = -0.626095038754337;

                x = -1.5;
                y = 1.5;
                r = -0.49;

                x = -1.6450031341281908;
                y = 1.2645625117080999;
                r = -0.054054238344620031;

                x = -0.5;
                y = -0.5;
                r = 0.001;

                Console.WriteLine(1 - r * r);

                Console.WriteLine("NormalCdfBrute: {0}", NormalCdfBrute(0, x, y, r));
                Console.WriteLine("NormalCdf_Quadrature: {0}", NormalCdf_Quadrature(x, y, r));
                //Console.WriteLine("{0}", NormalCdfAlt2(x, y, r));
                //Console.WriteLine("NormalCdfAlt: {0}", NormalCdfAlt(x, y, r));
                //Console.WriteLine("NormalCdfTaylor: {0}", MMath.NormalCdfRatioTaylor(x, y, r));
                //Console.WriteLine("NormalCdfConFrac3: {0}", NormalCdfConFrac3(x, y, r));
                //Console.WriteLine("NormalCdfConFrac4: {0}", NormalCdfConFrac4(x, y, r));
                //Console.WriteLine("NormalCdfConFrac5: {0}", NormalCdfConFrac5(x, y, r));
                Console.WriteLine("MMath.NormalCdf: {0}", MMath.NormalCdf(x, y, r));
                Console.WriteLine("MMath.NormalCdfLn: {0}", MMath.NormalCdfLn(x, y, r));
                for (int i = 1; i < 50; i++)
                {
                    //Console.WriteLine("{0}: {1}", i, NormalCdfBrute(i, x, y, r));
                }
                //x = 0;
                //y = 0;
                //r2 = -0.7;
                //r2 = -0.999;
            }
            else
            {
                // x=-2, y=-10, r=0.9 is dominated by additive part of numerator - poor convergence
                // -2,-2,-0.5
                x = -0.1;
                y = -0.1;
                r = -0.999999;
                Console.WriteLine("{0}", MMath.NormalCdfLn(x, y, r));
                //x = 0;
                //y = 0;
                //r2 = -0.7;
                //r2 = -0.999;
            }
        }
コード例 #17
0
        private double NormalCdfIntegralFlip(double x, double y, double r)
        {
            double logProbX = Gaussian.GetLogProb(x, 0, 1);

            return(-MMath.NormalCdfIntegral(x, -y, -r) + x * MMath.NormalCdf(x) + System.Math.Exp(logProbX));
        }