Exemplo n.º 1
0
        public void NormalCdfIntegralTest()
        {
            Assert.True(0 <= NormalCdfIntegral(190187183095334850882507750944849586799124505055478568794871547478488387682304.0, -190187183095334850882507750944849586799124505055478568794871547478488387682304.0, -1, 0.817880416082724044547388352452631856079457366800004151664125953519049673808376291470533145141236089924006896061006277409614237094627499958581030715374379576478204968748786874650796450332240045653919846557755590765736997127532958984375e-78).Mantissa);
            Assert.True(0 <= NormalCdfIntegral(213393529.2046706974506378173828125, -213393529.2046706974506378173828125, -1, 0.72893668811495072384656764856902984306419313043079455383121967315673828125e-9).Mantissa);
            Assert.True(0 < NormalCdfIntegral(-0.421468532207607216033551367218024097383022308349609375, 0.42146843802130329326161017888807691633701324462890625, -0.99999999999999989, 0.62292398855983019004972723654291189010479001808562316000461578369140625e-8).Mantissa);

            // Checking all cases takes a long time.
            const int limit = 2_000_000;
            int       count = 0;

            Parallel.ForEach(OperatorTests.Doubles(), x =>
            {
                if (count > limit)
                {
                    return;
                }
                foreach (var y in OperatorTests.Doubles())
                {
                    if (count > limit)
                    {
                        break;
                    }
                    foreach (var r in OperatorTests.Doubles().Where(d => d >= -1 && d <= 1))
                    {
                        if (count > limit)
                        {
                            break;
                        }
                        MMath.NormalCdfIntegral(x, y, r);
                        Interlocked.Add(ref count, 1);
                    }
                }
            });
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
 // Same as MMath.NormalCdfIntegral but avoids inconsistent values of r and sqrtomr2 when using arbitrary precision.
 public static ExtendedDouble NormalCdfIntegral(double x, double y, double r, double sqrtomr2)
 {
     if (sqrtomr2 < 0.618)
     {
         // In this regime, it is more accurate to compute r from sqrtomr2.
         // See NormalCdfRatioLn
         r = System.Math.Sign(r) * System.Math.Sqrt((1 - sqrtomr2) * (1 + sqrtomr2));
     }
     else
     {
         // In this regime, it is more accurate to compute sqrtomr2 from r.
         double omr2 = 1 - r * r;
         sqrtomr2 = System.Math.Sqrt(omr2);
     }
     return(MMath.NormalCdfIntegral(x, y, r, sqrtomr2));
 }
Exemplo n.º 4
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}");
                        }
                    }
                }
            }
        }
Exemplo n.º 5
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));
        }
Exemplo n.º 6
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();
                }
            }
        }