Esempio n. 1
0
        /// <summary>
        ///   Computes Owen's T function for arbitrary H and A.
        /// </summary>
        ///
        /// <param name="h">Owen's T function argument H.</param>
        /// <param name="a">Owen's T function argument A.</param>
        ///
        /// <returns>The value of Owen's T function.</returns>
        ///
        public static double Function(double h, double a)
        {
            double       absa;
            double       absh;
            double       ah;
            const double cut = 0.67;
            double       normah;
            double       normh;
            double       value;

            absh = Math.Abs(h);
            absa = Math.Abs(a);
            ah   = absa * absh;

            if (absa <= 1.0)
            {
                value = Function(absh, absa, ah);
            }
            else if (absh <= cut)
            {
                value = 0.25 - (-0.5 + Normal.Function(absh)) * (-0.5 + Normal.Function(ah))
                        - Function(ah, 1.0 / absa, absh);
            }
            else
            {
                normh  = Normal.Complemented(absh);
                normah = Normal.Complemented(ah);
                value  = 0.5 * (normh + normah) - normh * normah
                         - Function(ah, 1.0 / absa, absh);
            }

            if (a < 0.0)
            {
                value = -value;
            }

            return(value);
        }
Esempio n. 2
0
        /// <summary>
        ///   Owen's T function for a restricted range of parameters.
        /// </summary>
        ///
        /// <param name="h">Owen's T function argument H (where 0 &lt;= H).</param>
        /// <param name="a">Owen's T function argument A (where 0 &lt;= A &lt;= 1).</param>
        /// <param name="ah">The value of A*H.</param>
        ///
        /// <returns>The value of Owen's T function.</returns>
        ///
        public static double Function(double h, double a, double ah)
        {
            double ai;
            double aj;
            double AS;
            double dhs;
            double dj;
            double gj;

            double hs;
            int    i;
            int    iaint;
            int    icode;
            int    ihint;
            int    ii;
            int    j;
            int    jj;
            int    m;
            int    maxii;
            double normh;

            double       r;
            const double rrtpi  = 0.39894228040143267794;
            const double rtwopi = 0.15915494309189533577;

            double y;
            double yi;
            double z;
            double zi;

            double value = 0;
            double vi;

            /*
             * Determine appropriate method from t1...t6
             */
            ihint = 15;

            for (i = 1; i <= 14; i++)
            {
                if (h <= hrange[i - 1])
                {
                    ihint = i;
                    break;
                }
            }

            iaint = 8;

            for (i = 1; i <= 7; i++)
            {
                if (a <= arange[i - 1])
                {
                    iaint = i;
                    break;
                }
            }

            icode = select[ihint - 1 + (iaint - 1) * 15];
            m     = ord[icode - 1];

            /*
             * t1(h, a, m) ; m = 2, 3, 4, 5, 7, 10, 12 or 18
             * jj = 2j - 1 ; gj = exp(-h*h/2) * (-h*h/2)**j / j
             * aj = a**(2j-1) / (2*pi)
             */

            if (meth[icode - 1] == 1)
            {
                hs    = -0.5 * h * h;
                dhs   = Math.Exp(hs);
                AS    = a * a;
                j     = 1;
                jj    = 1;
                aj    = rtwopi * a;
                value = rtwopi * Math.Atan(a);
                dj    = dhs - 1.0;
                gj    = hs * dhs;

                for (; ;)
                {
                    value = value + dj * aj / jj;

                    if (m <= j)
                    {
                        return(value);
                    }
                    j  = j + 1;
                    jj = jj + 2;
                    aj = aj * AS;
                    dj = gj - dj;
                    gj = gj * hs / j;
                }
            }

            /*
             * t2(h, a, m) ; m = 10, 20 or 30
             * z = (-1)^(i-1) * zi ; ii = 2i - 1
             * vi = (-1)^(i-1) * a^(2i-1) * exp[-(a*h)^2/2] / sqrt(2*pi)
             */
            else if (meth[icode - 1] == 2)
            {
                maxii = m + m + 1;
                ii    = 1;
                value = 0.0;
                hs    = h * h;
                AS    = -a * a;
                vi    = rrtpi * a * Math.Exp(-0.5 * ah * ah);
                z     = 0.5 * (-0.5 + Normal.Function(ah)) / h;
                y     = 1.0 / hs;

                for (; ;)
                {
                    value = value + z;

                    if (maxii <= ii)
                    {
                        value = value * rrtpi * Math.Exp(-0.5 * hs);
                        return(value);
                    }
                    z  = y * (vi - ii * z);
                    vi = AS * vi;
                    ii = ii + 2;
                }
            }

            /*
             * t3(h, a, m) ; m = 20
             * ii = 2i - 1
             * vi = a**(2i-1) * exp[-(a*h)**2/2] / sqrt(2*pi)
             */
            else if (meth[icode - 1] == 3)
            {
                i     = 1;
                ii    = 1;
                value = 0.0;
                hs    = h * h;
                AS    = a * a;
                vi    = rrtpi * a * Math.Exp(-0.5 * ah * ah);
                zi    = 0.5 * (-0.5 + Normal.Function(ah)) / h;
                y     = 1.0 / hs;

                for (; ;)
                {
                    value = value + zi * c2[i - 1];

                    if (m < i)
                    {
                        value = value * rrtpi * Math.Exp(-0.5 * hs);
                        return(value);
                    }
                    zi = y * (ii * zi - vi);
                    vi = AS * vi;
                    i  = i + 1;
                    ii = ii + 2;
                }
            }

            /*
             * t4(h, a, m) ; m = 4, 7, 8 or 20;  ii = 2i + 1
             * ai = a * exp[-h*h*(1+a*a)/2] * (-a*a)**i / (2*pi)
             */
            else if (meth[icode - 1] == 4)
            {
                maxii = m + m + 1;
                ii    = 1;
                hs    = h * h;
                AS    = -a * a;
                value = 0.0;
                ai    = rtwopi * a * Math.Exp(-0.5 * hs * (1.0 - AS));
                yi    = 1.0;

                for (; ;)
                {
                    value = value + ai * yi;

                    if (maxii <= ii)
                    {
                        return(value);
                    }

                    ii = ii + 2;
                    yi = (1.0 - hs * yi) / ii;
                    ai = ai * AS;
                }
            }

            /*
             * t5(h, a, m) ; m = 13
             * 2m - point gaussian quadrature
             */
            else if (meth[icode - 1] == 5)
            {
                value = 0.0;
                AS    = a * a;
                hs    = -0.5 * h * h;
                for (i = 1; i <= m; i++)
                {
                    r     = 1.0 + AS * pts[i - 1];
                    value = value + wts[i - 1] * Math.Exp(hs * r) / r;
                }
                value = a * value;
            }

            /*
             * t6(h, a);  approximation for a near 1, (a<=1)
             */
            else if (meth[icode - 1] == 6)
            {
                normh = Normal.Complemented(h);
                value = 0.5 * normh * (1.0 - normh);
                y     = 1.0 - a;
                r     = Math.Atan(y / (1.0 + a));

                if (r != 0.0)
                {
                    value = value - rtwopi * r * Math.Exp(-0.5 * y * h * h / r);
                }
            }

            return(value);
        }