Ejemplo n.º 1
0
        static ScalarValue Psi0asymptotic(ScalarValue z)
        {
            /* coefficients in the asymptotic expansion for large z;
             * let w = z^(-2) and write the expression in the form
             *
             *   ln(z) - 1/(2z) - 1/12 w (1 + c1 w + c2 w + c3 w + ... )
             */
            const double c1 = -0.1;
            const double c2 = 1.0 / 21.0;
            const double c3 = -0.05;
            const double c4 = -1.0 / 12.0;

            var zi = 1.0 / z;
            var w  = zi * zi;

            /* Horner method evaluation of term in parentheses */
            var sum = (w * (c3 / c2)) + 1.0;

            sum  = sum * (c2 / c1);
            sum  = ((sum * w) + 1.0) * c1 * w;
            sum += 1.0;

            /* correction added to log(z) */
            var cs = sum * w;

            cs = cs * c4;
            cs = cs + (zi * (-0.5));

            return(z.Log() + cs);
        }
Ejemplo n.º 2
0
        public static ScalarValue HurwitzZeta(ScalarValue s, ScalarValue q)
        {
            if (s.Re <= 1.0)
                throw new YAMPArgumentRangeException("s", 1.0);

            if (q.Re <= 0.0)
                throw new YAMPArgumentRangeException("q", 0.0);

            var max_bits = 54.0;
            var ln_term0 = -s * q.Log();
            var qabs = q.Abs();
            var sabs = s.Abs();
            var ss = s;

            if ((sabs > max_bits && qabs < 1.0) || (sabs > 0.5 * max_bits && qabs < 0.25))
            {
                return q.Pow(-ss);
            }
            else if (sabs > 0.5 * max_bits && qabs < 1.0)
            {
                var p1 = q.Pow(-ss);
                var p2 = (q / (1.0 + q)).Pow(ss);
                var p3 = (q / (2.0 + q)).Pow(ss);
                return p1 * (1.0 + p2 + p3);
            }

            /* Euler-Maclaurin summation formula
             * [Moshier, p. 400, with several typo corrections]
             */
            const int jmax = 12;
            const int kmax = 10;

            var pmax = (kmax + q).Pow(-ss);
            var scp = s;
            var pcp = pmax / (kmax + q);
            var ans = pmax * ((kmax + q) / (s - 1.0) + 0.5);

            for (var k = 0; k < kmax; k++)
            {
                ans += (k + q).Pow(-ss);
            }

            for (var j = 0; j <= jmax; j++)
            {
                var delta = COEFFICIENTS[j + 1] * scp * pcp;
                ans += delta;

                if ((delta / ans).Abs() < 0.5 * Double.Epsilon)
                {
                    break;
                }

                scp *= (s + 2 * j + 1) * (s + 2 * j + 2);
                pcp /= (kmax + q) * (kmax + q);
            }

            return ans;
        }
Ejemplo n.º 3
0
        public static ScalarValue Polylog(int n, ScalarValue z)
        {
            if (n == 2)
            {
                return(SpenceFunction.DiLog(z));
            }

            if (n == -1)
            {
                return(PolylogNeg1(z));
            }

            if (n == 0)
            {
                return(PolylogZero(z));
            }

            if (n == 1)
            {
                return(PolylogPos1(z));
            }

            if (n == -2)
            {
                return(PolylogNeg2(z));
            }

            if (n == -3)
            {
                return(PolylogNeg3(z));
            }

            if (n == -4)
            {
                return(PolylogNeg4(z));
            }

            if (n < -4)
            {
                return(PolylogNegative(n, z));
            }

            if (z == ScalarValue.One && n > 1)
            {
                return(PolylogZetaPositive(n));
            }

            if (-z == ScalarValue.One && n > 1)
            {
                return(PolylogZetaNegative(n));
            }

            /*  This recurrence provides formulas for n < 2.
             *
             *   d                 1
             *   --   Li (x)  =   ---  Li   (x)  .
             *   dx     n          x     n-1
             *
             */
            var s = ScalarValue.Zero;
            var ah = Math.Abs(z.Re) + Math.Abs(z.Im);
            int i, j;

            if (ah > 3.0)
            {
                return(PolylogInversion(n, z));
            }
            else if (ah >= 0.75)
            {
                var ad = 0.0;
                var x  = z.Log();
                var h  = -((-x).Log());

                for (i = 1; i < n; i++)
                {
                    h += 1.0 / i;
                }

                var p = ScalarValue.One;
                s = PolylogZetaPositive(n);

                for (j = 1; j <= n + 1; j++)
                {
                    p = p * x / j;

                    if (j == n - 1)
                    {
                        s += h * p;
                    }
                    else
                    {
                        s += PolylogZetaPositive(n - j) * p;
                    }
                }

                j = n + 3;
                x = x * x;

                for (; ;)
                {
                    p  = p * x / ((j - 1) * j);
                    h  = PolylogZetaPositive(n - j);
                    h  = h * p;
                    s += h;
                    ah = Math.Abs(h.Re) + Math.Abs(h.Im);
                    ad = Math.Abs(s.Re) + Math.Abs(s.Im);

                    if (ah < ad * double.Epsilon)
                    {
                        break;
                    }

                    j += 2;
                }

                return(s);
            }
            else if (ah >= 1e-6)
            {
                var p  = z * z * z;
                var ad = 0.0;
                var k  = 3.0;
                var h  = ScalarValue.Zero;

                do
                {
                    p  = p * z;
                    k += 1.0;
                    h  = p / Math.Pow(k, n);
                    s += h;
                    ah = Math.Abs(h.Re) + Math.Abs(h.Im);
                    ad = Math.Abs(s.Re) + Math.Abs(s.Im);
                }while (ah > ad * 1.1e-16);
            }

            s += z * z * z / Math.Pow(3.0, n);
            s += z * z / Math.Pow(2.0, n);
            return(s + z);
        }
Ejemplo n.º 4
0
        static ScalarValue Psi0asymptotic(ScalarValue z)
        {
            /* coefficients in the asymptotic expansion for large z;
             * let w = z^(-2) and write the expression in the form
             *
             *   ln(z) - 1/(2z) - 1/12 w (1 + c1 w + c2 w + c3 w + ... )
             */
            const double c1 = -0.1;
            const double c2 = 1.0 / 21.0;
            const double c3 = -0.05;
            const double c4 = -1.0 / 12.0;

            var zi = 1.0 / z;
            var w = zi * zi;

            /* Horner method evaluation of term in parentheses */
            var sum = (w * (c3 / c2)) + 1.0;
            sum = sum * (c2 / c1);
            sum = ((sum * w) + 1.0) * c1 * w;
            sum += 1.0;

            /* correction added to log(z) */
            var cs = sum * w;
            cs = cs * c4;
            cs = cs + (zi * (-0.5));

            return z.Log() + cs;
        }
Ejemplo n.º 5
0
        public static ScalarValue HurwitzZeta(ScalarValue s, ScalarValue q)
        {
            if (s.Re <= 1.0)
            {
                throw new YAMPArgumentRangeException("s", 1.0);
            }

            if (q.Re <= 0.0)
            {
                throw new YAMPArgumentRangeException("q", 0.0);
            }

            var max_bits = 54.0;
            var ln_term0 = -s *q.Log();

            var qabs = q.Abs();
            var sabs = s.Abs();
            var ss   = s;

            if ((sabs > max_bits && qabs < 1.0) || (sabs > 0.5 * max_bits && qabs < 0.25))
            {
                return(q.Pow(-ss));
            }
            else if (sabs > 0.5 * max_bits && qabs < 1.0)
            {
                var p1 = q.Pow(-ss);
                var p2 = (q / (1.0 + q)).Pow(ss);
                var p3 = (q / (2.0 + q)).Pow(ss);
                return(p1 * (1.0 + p2 + p3));
            }

            /* Euler-Maclaurin summation formula
             * [Moshier, p. 400, with several typo corrections]
             */
            const int jmax = 12;
            const int kmax = 10;

            var pmax = (kmax + q).Pow(-ss);
            var scp  = s;
            var pcp  = pmax / (kmax + q);
            var ans  = pmax * ((kmax + q) / (s - 1.0) + 0.5);

            for (var k = 0; k < kmax; k++)
            {
                ans += (k + q).Pow(-ss);
            }

            for (var j = 0; j <= jmax; j++)
            {
                var delta = COEFFICIENTS[j + 1] * scp * pcp;
                ans += delta;

                if ((delta / ans).Abs() < 0.5 * Double.Epsilon)
                {
                    break;
                }

                scp *= (s + 2 * j + 1) * (s + 2 * j + 2);
                pcp /= (kmax + q) * (kmax + q);
            }

            return(ans);
        }
Ejemplo n.º 6
0
 protected override ScalarValue GetValue(ScalarValue value)
 {
     return value.Log(2.0);
 }
 protected override ScalarValue GetValue(ScalarValue value)
 {
     return(value.Log(2.0));
 }