Esempio n. 1
0
        public static ComplexDouble FastGamma(ComplexDouble n)
        {
            if (ComplexDouble.IsNaN(n))
            {
                if (ThrowExceptions)
                {
                    throw new ArgumentException("n is NaN", "n");
                }
                else
                {
                    return(double.NaN);
                }
            }
            if (n.Im.Equals(0d))
            {
                return(FastGamma(n.Re));
            }
            if (ComplexDouble.IsInfinity(n))
            {
                return(0d);
            }
            var q = new ComplexDouble(n.Re % 1d, n.Im);

            if (q.Re < 0d)
            {
                ++q;
            }
            var z = (int)(n.Re - q.Re);

            n = q + 8d;
            return(q.Equals(0d) || q.Equals(1d) ? Pochhammer(q + 1d, z - 1) :
                   q.Equals(0.5d) ? 0.5d * ComplexDouble.SqrtPi * Pochhammer(q + 1d, z - 1) :
                   ComplexDouble.Exp(
                       0.5d * System.Math.Log(2d * ComplexDouble.Pi)
                       + (n - 0.5d) * ComplexDouble.Log(n) - n
                       + Pow(n, -1) / 12d
                       - Pow(n, -3) / 360d
                       + Pow(n, -5) / 1260d
                       - Pow(n, -7) / 1680d
                       + Pow(n, -9) / 1188d
                       - Pow(n, -11) / 360360d * 691d
                       + Pow(n, -13) / 156d
                       ) * Pochhammer(n, z - 8));

            /*
             * n = q + 17d;
             * return
             *      ComplexDouble.Pow(2d * ComplexDouble.Pi * n, 0.5d) * ComplexDouble.Pow(n, n - 1d)
             * ComplexDouble.Exp(-n + 1d / (12d * n) - 1d / (360d * ComplexDouble.Pow(n, 3d))
             + 1d / (1260d * ComplexDouble.Pow(n, 5d)) - 1d / (1686d * ComplexDouble.Pow(n, 7d)))
             * Pochhammer(n, z - 17);
             * //*/
        }
Esempio n. 2
0
        public static ComplexDouble IntegrateComplex(Func <double, ComplexDouble> f, double a, double b, ComplexDouble fa, ComplexDouble fb, Func2 <double> nextPoint, double eps = Eps)
        {
            bool ia = ComplexDouble.IsInfinity(fa) || ComplexDouble.IsNaN(fa),
                 ib = ComplexDouble.IsInfinity(fb) || ComplexDouble.IsNaN(fb);

            if ((ia || ib) && eps <= Eps)
            {
                return(0d);
            }
            double        p  = nextPoint(a, b);
            ComplexDouble fp = f(p),
                          ab = 0.5d * (b - a) * (fa + fb),
                          ap = 0.5d * (p - a) * (fa + fp),
                          pb = 0.5d * (b - p) * (fp + fb),
                          s  = ap + pb;

            if ((ab - s).SqrAbs <= eps * eps * (b - a) * (b - a))
            {
                return(s);
            }
            return(IntegrateComplex(f, a, p, fa, fp, nextPoint, eps)
                   + IntegrateComplex(f, p, b, fp, fb, nextPoint, eps));             //*/
        }
Esempio n. 3
0
        public static ComplexDouble SlowGamma(ComplexDouble n, double eps = Eps)
        {
            if (ComplexDouble.IsNaN(n))
            {
                if (ThrowExceptions)
                {
                    throw new ArgumentException("n is NaN", "n");
                }
                else
                {
                    return(double.NaN);
                }
            }
            if (n.Im.Equals(0d))
            {
                return(SlowGamma(n.Re, eps));
            }
            if (ComplexDouble.IsInfinity(n))
            {
                return(0d);
            }
            var q = new ComplexDouble(n.Re % 1d, n.Im);

            if (q.Re < 0d)
            {
                ++q;
            }
            var z = (int)(n.Re - q.Re);

            n = new ComplexDouble(q.Re + q.Re + 1d, q.Im + q.Im);
            Func <double, ComplexDouble> f = t => ComplexDouble.Exp(n * System.Math.Log(t) - t * t);

            return(2d * (
                       IntegrateComplex(f, 0d, 1d, 0d, 1d / ComplexDouble.E, eps) +
                       IntegrateComplex(f, 1d, 26.641747557046328d, 1d / ComplexDouble.E, 0d, eps)
                       ) * Pochhammer(++q, --z));
        }