Esempio n. 1
0
        public static double[] PExp(double[] xA, double scale = 1.0, bool lowerTail = true, bool logP = false)
        {
            double[] rep = new double[xA.Length];

            for (int i = 0; i < xA.Length; i++)
            {
                double x = xA[i];
                if (double.IsNaN(x) || double.IsNaN(scale))
                {
                    rep[i] = x + scale;
                }

                if (scale < 0)
                {
                    rep[i] = double.NaN;
                }

                if (x <= 0.0)
                {
                    rep[i] = (lowerTail ? (logP ? double.NegativeInfinity : 0.0) : (logP ? 0.0 : 1.0));
                }
                /* same as weibull( shape = 1): */
                x = -(x / scale);
                if (lowerTail)
                {
                    rep[i] = (logP
                    ? (x > -RVaria.M_LN2 ? Math.Log(-RVaria.expm1(x)) : RVaria.log1p(-Math.Exp(x)))
                    : -RVaria.expm1(x));
                }
                /* else:  !lower_tail */
                else
                {
                    rep[i] = (logP ? (x) : Math.Exp(x));
                }
            }

            return(rep);
        }
Esempio n. 2
0
        private static void pnorm_both(double x, ref double cum, ref double ccum, bool i_tail, bool log_p)
        {
            /* i_tail in {0,1,2} means: "lower", "upper", or "both" :
             * if(lower) return  *cum := P[X <= x]
             * if(upper) return *ccum := P[X >  x] = 1 - P[X <= x]
             */

            double xden, xnum, temp, del, eps, xsq, y;
            double min = RVaria.DBL_MIN;

            int  i;
            bool lower, upper;

            if (double.IsNaN(x))
            {
                cum = ccum = x; return;
            }

            /* Consider changing these : */
            eps = RVaria.DBL_EPSILON * 0.5;

            /* i_tail in {0,1,2} =^= {lower, upper, both} */
            lower = !i_tail; //  = i_tail != 1;
            upper = i_tail;  // = i_tail != 0

            y = Math.Abs(x);
            if (y <= 0.67448975)
            { /* qnorm(3/4) = .6744.... -- earlier had 0.66291 */
                if (y > eps)
                {
                    xsq  = x * x;
                    xnum = a[4] * xsq;
                    xden = xsq;
                    for (i = 0; i < 3; ++i)
                    {
                        xnum = (xnum + a[i]) * xsq;
                        xden = (xden + b[i]) * xsq;
                    }
                }
                else
                {
                    xnum = xden = 0.0;
                }

                temp = x * (xnum + a[3]) / (xden + b[3]);
                if (lower)
                {
                    cum = 0.5 + temp;
                }
                if (upper)
                {
                    ccum = 0.5 - temp;
                }
                if (log_p)
                {
                    if (lower)
                    {
                        cum = Math.Log(cum);
                    }
                    if (upper)
                    {
                        ccum = Math.Log(ccum);
                    }
                }
            }
            else if (y <= RVaria.M_SQRT_32)
            {
                /* Evaluate pnorm for 0.674.. = qnorm(3/4) < |x| <= sqrt(32) ~= 5.657 */

                xnum = c[8] * y;
                xden = y;
                for (i = 0; i < 7; ++i)
                {
                    xnum = (xnum + c[i]) * y;
                    xden = (xden + d[i]) * y;
                }
                temp = (xnum + c[7]) / (xden + d[7]);

                xsq = Math.Truncate(y * SIXTEN) / SIXTEN;
                del = (y - xsq) * (y + xsq);
                if (log_p)
                {
                    cum = (-xsq * xsq * 0.5) + (-del * 0.5) + Math.Log(temp);
                    if ((lower && x > 0.0) || (upper && x <= 0.0))
                    {
                        ccum = RVaria.log1p(-Math.Exp(-xsq * xsq * 0.5) *
                                            Math.Exp(-del * 0.5) * temp);
                    }
                }
                else
                {
                    cum  = Math.Exp(-xsq * xsq * 0.5) * Math.Exp(-del * 0.5) * temp;
                    ccum = 1.0 - cum;
                }
                if (x > 0.0)
                {/* swap  ccum <--> cum */
                    temp = cum;
                    if (lower)
                    {
                        cum = ccum;
                    }
                    ccum = temp;
                }
            }

            else if ((log_p && y < 1e170) /* avoid underflow below */

                                          /*  ^^^^^ MM FIXME: can speedup for log_p and much larger |x| !
                                           * Then, make use of  Abramowitz & Stegun, 26.2.13, something like
                                           *
                                           * xsq = x*x;
                                           *
                                           * if(xsq * DBL_EPSILON < 1.)
                                           *  del = (1. - (1. - 5./(xsq+6.)) / (xsq+4.)) / (xsq+2.);
                                           * else
                                           *  del = 0.;
                                           * cum = -.5*xsq - M_LN_SQRT_2PI - log(x) + log1p(-del);
                                           * ccum = log1p(-exp(*cum)); /.* ~ log(1) = 0 *./
                                           *
                                           * swap_tail;
                                           *
                                           * [Yes, but xsq might be infinite.]
                                           *
                                           */
                     || (lower && -37.5193 < x && x < 8.2924) ||
                     (upper && -8.2924 < x && x < 37.5193)
                     )
            {
                /* Evaluate pnorm for x in (-37.5, -5.657) union (5.657, 37.5) */
                xsq  = 1.0 / (x * x); /* (1./x)*(1./x) might be better */
                xnum = p[5] * xsq;
                xden = xsq;
                for (i = 0; i < 4; ++i)
                {
                    xnum = (xnum + p[i]) * xsq;
                    xden = (xden + q[i]) * xsq;
                }
                temp = xsq * (xnum + p[4]) / (xden + q[4]);
                temp = (RVaria.M_1_SQRT_2PI - temp) / y;

                // do_del(x);

                xsq = Math.Truncate(x * SIXTEN) / SIXTEN;
                del = (x - xsq) * (x + xsq);
                if (log_p)
                {
                    cum = (-xsq * xsq * 0.5) + (-del * 0.5) + Math.Log(temp);
                    if ((lower && x > 0.0) || (upper && x <= 0.0))
                    {
                        ccum = RVaria.log1p(-Math.Exp(-xsq * xsq * 0.5) *
                                            Math.Exp(-del * 0.5) * temp);
                    }
                }
                else
                {
                    cum  = Math.Exp(-xsq * xsq * 0.5) * Math.Exp(-del * 0.5) * temp;
                    ccum = 1.0 - cum;
                }
                if (x > 0.0)
                {/* swap  ccum <--> cum */
                    temp = cum;
                    if (lower)
                    {
                        cum = ccum;
                    }
                    ccum = temp;
                }
            }
            else
            { /* large x such that probs are 0 or 1 */
                if (x > 0)
                {
                    cum = (log_p ? 0.0 : 1.0); ccum = (log_p ? double.NegativeInfinity : 0.0);
                }
                else
                {
                    cum = (log_p ? double.NegativeInfinity : 0.0); ccum = (log_p ? 0.0 : 1.0);
                }
            }


            //#ifdef NO_DENORMS
            /* do not return "denormalized" -- we do in R */
            if (log_p)
            {
                if (cum > -min)
                {
                    cum = -0.0;
                }
                if (ccum > -min)
                {
                    ccum = -0.0;
                }
            }
            else
            {
                if (cum < min)
                {
                    cum = 0.0;
                }
                if (ccum < min)
                {
                    ccum = 0.0;
                }
            }
            //#endif
            return;
        }
Esempio n. 3
0
        public static double QExp(double p, double scale = 1.0, bool lowerTail = true, bool logP = false)
        {
            if (double.IsNaN(p) || double.IsNaN(scale))
            {
                return(p + scale);
            }
            if (scale < 0)
            {
                return(double.NaN);           //ML_ERR_return_NAN;
            }
            if ((logP && p > 0) || (!logP && (p < 0 || p > 1)))
            //ML_ERR_return_NAN
            {
                return(RVaria.R_NaN);
            }
            if (p == (lowerTail ? (logP ? double.NegativeInfinity : 0.0) : (logP ? 0.0 : 1.0)))
            {
                return(0);
            }

            return(-scale * (lowerTail ? (logP ? ((p) > -RVaria.M_LN2 ? Math.Log(-RVaria.expm1(p)) : RVaria.log1p(-Math.Exp(p))) : RVaria.log1p(-p)) : (logP ? (p) : Math.Log(p))));
        }