Esempio n. 1
0
        // Use the large variance approximation to sigma(m,v) = \int N(x;m,v) logistic(x)
        private static void BigvProposal(double m, double v, out double mf, out double vf)
        {
            double v2 = v + Math.PI * Math.PI / 3.0;
            double Z  = MMath.NormalCdf(m / Math.Sqrt(v2));
            double s1 = Math.Exp(Gaussian.GetLogProb(0, m, v2));
            double s2 = -s1 * m / v2;

            mf = m + v * s1 / Z;
            double Ex2 = v + m * m + 2 * m * v * s1 / Z + v * v * s2 / Z;

            vf = Ex2 - mf * mf;
        }
Esempio n. 2
0
        // Helper function for NormalCdfRatioConFrac
        private static double NormalCdfRatioConFracNumer(double x, double y, double r, double scale, double sqrtomr2, double diff, double Rdiff)
        {
            double delta = (1 + r) * (y - x) / sqrtomr2;
            double numer;

            if (Math.Abs(delta) > 0.5)
            {
                numer = scale * r * Rdiff;
                double diffy = (y - r * x) / sqrtomr2;
                if (scale == 1)
                {
                    numer += MMath.NormalCdfRatio(diffy);
                }
                else // this assumes scale = N((y-rx)/sqrt(1-r^2);0,1)
                {
                    numer += MMath.NormalCdf(diffy);
                }
            }
            else
            {
                numer = scale * (NormalCdfRatioDiff(diff, delta) + (1 + r) * Rdiff);
            }
            return(numer);
        }
Esempio n. 3
0
        /// <summary>
        /// Computes the cumulative bivariate normal distribution.
        /// </summary>
        /// <param name="x">First upper limit.</param>
        /// <param name="y">Second upper limit.</param>
        /// <param name="r">Correlation coefficient.</param>
        /// <returns><c>phi(x,y,r)</c></returns>
        /// <remarks>
        /// The cumulative bivariate normal distribution is defined as
        /// <c>int_(-inf)^x int_(-inf)^y N([x;y],[0;0],[1 r; r 1]) dx dy</c>
        /// where <c>N([x;y],[0;0],[1 r; r 1]) = exp(-0.5*(x^2+y^2-2*x*y*r)/(1-r^2))/(2*pi*sqrt(1-r^2))</c>.
        /// </remarks>
        public static double NormalCdf(double x, double y, double r)
        {
            if (Double.IsNegativeInfinity(x) || Double.IsNegativeInfinity(y))
            {
                return(0.0);
            }
            else if (Double.IsPositiveInfinity(x))
            {
                return(NormalCdf(y));
            }
            else if (Double.IsPositiveInfinity(y))
            {
                return(NormalCdf(x));
            }
            else if (r == 0)
            {
                return(NormalCdf(x) * NormalCdf(y));
            }
            else if (r == 1)
            {
                return(NormalCdf(Math.Min(x, y)));
            }
            else if (r == -1)
            {
                return(Math.Max(0.0, NormalCdf(x) + NormalCdf(y) - 1));
            }
            // at this point, both x and y are finite.
            // swap to ensure |x| > |y|
            if (Math.Abs(y) > Math.Abs(x))
            {
                double t = x;
                x = y;
                y = t;
            }
            double offset = 0;
            double scale  = 1;

            // ensure x <= 0
            if (x > 0)
            {
                // phi(x,y,r) = phi(inf,y,r) - phi(-x,y,-r)
                offset = MMath.NormalCdf(y);
                scale  = -1;
                x      = -x;
                r      = -r;
            }
            // ensure r <= 0
            if (r > 0)
            {
                // phi(x,y,r) = phi(x,inf,r) - phi(x,-y,-r)
                offset += scale * MMath.NormalCdf(x);
                scale  *= -1;
                y       = -y;
                r       = -r;
            }
            double omr2 = (1 - r) * (1 + r); // more accurate than 1-r*r
            double ymrx = (y - r * x) / Math.Sqrt(omr2);
            double exponent;
            double result = NormalCdf_Helper(x, y, r, omr2, ymrx, out exponent);

            return(offset + scale * result * Math.Exp(exponent));
        }