예제 #1
0
        public void WatsonIntegrals()
        {
            // Watson defined and analytically integrated three complicated triple integrals related to random walks in three dimension
            // See http://mathworld.wolfram.com/WatsonsTripleIntegrals.html

            Interval watsonWidth = Interval.FromEndpoints(0.0, Math.PI);

            Interval[] watsonBox = new Interval[] { watsonWidth, watsonWidth, watsonWidth };

            Assert.IsTrue(
                MultiFunctionMath.Integrate(
                    (IReadOnlyList <double> x) => 1.0 / (1.0 - Math.Cos(x[0]) * Math.Cos(x[1]) * Math.Cos(x[2])), watsonBox
                    ).Estimate.ConfidenceInterval(0.99).ClosedContains(
                    MoreMath.Pow(AdvancedMath.Gamma(1.0 / 4.0), 4) / 4.0
                    )
                );

            Assert.IsTrue(
                MultiFunctionMath.Integrate(
                    (IReadOnlyList <double> x) => 1.0 / (3.0 - Math.Cos(x[0]) * Math.Cos(x[1]) - Math.Cos(x[1]) * Math.Cos(x[2]) - Math.Cos(x[0]) * Math.Cos(x[2])), watsonBox
                    ).Estimate.ConfidenceInterval(0.99).ClosedContains(
                    3.0 * MoreMath.Pow(AdvancedMath.Gamma(1.0 / 3.0), 6) / Math.Pow(2.0, 14.0 / 3.0) / Math.PI
                    )
                );

            Assert.IsTrue(
                MultiFunctionMath.Integrate(
                    (IReadOnlyList <double> x) => 1.0 / (3.0 - Math.Cos(x[0]) - Math.Cos(x[1]) - Math.Cos(x[2])), watsonBox
                    ).Estimate.ConfidenceInterval(0.99).ClosedContains(
                    Math.Sqrt(6.0) / 96.0 * AdvancedMath.Gamma(1.0 / 24.0) * AdvancedMath.Gamma(5.0 / 24.0) * AdvancedMath.Gamma(7.0 / 24.0) * AdvancedMath.Gamma(11.0 / 24.0)
                    )
                );
        }
예제 #2
0
        public void HypergeometricAtOne()
        {
            // A&S 15.1.20
            foreach (double a in abcs)
            {
                foreach (double b in abcs)
                {
                    foreach (double c in abcs)
                    {
                        // Formula only hold for positive real c-a-b
                        if ((c - a - b) <= 0.0)
                        {
                            continue;
                        }

                        // Formula is still right for non-positive c, but to handle it we would need to deal with canceling infinite Gammas
                        if (IsNonpositiveInteger(c))
                        {
                            continue;
                        }

                        Assert.IsTrue(TestUtilities.IsNearlyEqual(
                                          AdvancedMath.Hypergeometric2F1(a, b, c, 1.0),
                                          AdvancedMath.Gamma(c) * AdvancedMath.Gamma(c - a - b) / AdvancedMath.Gamma(c - a) / AdvancedMath.Gamma(c - b)
                                          ));
                    }
                }
            }
        }
예제 #3
0
        public void HypergeometricAtMinusOne()
        {
            foreach (double a in abcs)
            {
                if ((a <= 0.0) && (Math.Round(a) == a))
                {
                    continue;
                }

                Assert.IsTrue(TestUtilities.IsNearlyEqual(
                                  AdvancedMath.Hypergeometric2F1(1.0, a, a + 1.0, -1.0),
                                  a / 2.0 * (AdvancedMath.Psi((a + 1.0) / 2.0) - AdvancedMath.Psi(a / 2.0))
                                  ));

                foreach (double b in abcs)
                {
                    double c = a - b + 1.0;
                    if ((c <= 0.0) && (Math.Round(c) == c))
                    {
                        continue;
                    }

                    // If result vanishes, returned value may just be very small.
                    double R = AdvancedMath.Gamma(a - b + 1.0) * AdvancedMath.Gamma(a / 2.0 + 1.0) / AdvancedMath.Gamma(a + 1.0) / AdvancedMath.Gamma(a / 2.0 - b + 1.0);
                    if (R == 0.0)
                    {
                        Assert.IsTrue(Math.Abs(AdvancedMath.Hypergeometric2F1(a, b, a - b + 1.0, -1.0)) <= 1.0E-14);
                    }
                    else
                    {
                        Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.Hypergeometric2F1(a, b, a - b + 1.0, -1.0), R));
                    }
                }
            }
        }
        public void BesselInflectionValue()
        {
            // Abromowitz derived a series for J_{\nu}(\nu) and Y_{\nu}(\nu),
            // the value at the inflection point.

            // These appear in A&S 9.3.31 - 9.3.34 with numerical values for the coefficients.
            // Symbolic values for the coefficients appear in Jentschura & Loetstedt 2011
            // (https://arxiv.org/abs/1112.0072)

            // This is a fairly onerous test to code, but it is a good one, because
            // the Bessel functions are difficult to calculate in this region.

            double A = Math.Pow(2.0, 1.0 / 3.0) / Math.Pow(3.0, 2.0 / 3.0) / AdvancedMath.Gamma(2.0 / 3.0);

            double B = Math.Pow(2.0, 2.0 / 3.0) / Math.Pow(3.0, 1.0 / 3.0) / AdvancedMath.Gamma(1.0 / 3.0);

            double[] a = new double[] {
                1.0,
                -1.0 / 225.0,
                151439.0 / 218295000.0,
                -887278009.0 / 2504935125000.0,
                1374085664813273149.0 / 3633280647121125000000.0
            };

            double[] b = new double[] {
                1.0 / 70.0,
                -1213.0 / 1023750.0,
                16542537833.0 / 37743205500000.0,
                -9597171184603.0 / 25476663712500000.0,
                53299328587804322691259.0 / 91182706744837207500000000.0
            };

            foreach (double nu in TestUtilities.GenerateRealValues(10.0, 100.0, 8))
            {
                double Af = A / Math.Pow(nu, 1.0 / 3.0);
                double Bf = B / Math.Pow(nu, 5.0 / 3.0);

                double J  = 0.0;
                double dJ = 0.0;

                for (int k = 0; k < Math.Min(a.Length, b.Length); k++)
                {
                    double nuk = MoreMath.Pow(nu, 2 * k);

                    dJ = Af * a[k] / nuk;
                    J += dJ;

                    dJ = Bf * b[k] / nuk;
                    J -= dJ;
                }

                EvaluationSettings e = new EvaluationSettings()
                {
                    RelativePrecision = TestUtilities.TargetPrecision,
                    AbsolutePrecision = Math.Abs(dJ)
                };

                TestUtilities.IsNearlyEqual(AdvancedMath.BesselJ(nu, nu), J, e);
            }
        }
예제 #5
0
        /// <summary>
        /// Initializes a new instance of a Gamma distribution with the given parameters.
        /// </summary>
        /// <param name="shape">The shape parameter, which must be positive.</param>
        /// <param name="scale">The scale parameter, which must be positive.</param>
        public GammaDistribution(double shape, double scale)
        {
            if (shape <= 0.0)
            {
                throw new ArgumentOutOfRangeException("shape");
            }
            if (scale <= 0.0)
            {
                throw new ArgumentOutOfRangeException("scale");
            }
            a = shape;
            s = scale;

            // depending on size of a, store Gamma(a) or -Ln(Gamma(a)) for future use
            if (a < 64.0)
            {
                ga = AdvancedMath.Gamma(a);
            }
            else
            {
                ga = -AdvancedMath.LogGamma(a);
            }

            gammaRng = DeviateGeneratorFactory.GetGammaGenerator(a);
        }
예제 #6
0
 public override double RawMoment(int r)
 {
     if (r < 0)
     {
         throw new ArgumentOutOfRangeException(nameof(r));
     }
     else if (r == 0)
     {
         return(1.0);
     }
     else if (r == 1)
     {
         return(Global.SqrtHalfPI * (1.0 - 1.0 / 6.0 / sqrt_n));
     }
     else if (r == 3)
     {
         return(Global.SqrtHalfPI * (3.0 / 2.0 * AdvancedMath.Apery - 3.0 / 4.0 / sqrt_n));
     }
     else
     {
         // we needed to handle 1st and 3rd moments specially because \zeta divergences but multiplication by zero gives finite result
         return(AdvancedMath.Gamma(r / 2.0 + 1.0) / Math.Pow(2.0, r / 2.0 - 1.0) *
                ((r - 1) * AdvancedMath.RiemannZeta(r) - (r - 3) * AdvancedMath.RiemannZeta(r - 2) / sqrt_n)
                );
     }
 }
예제 #7
0
 public void GammaRecurrsion()
 {
     // Limit x to avoid overflow.
     foreach (double x in TestUtilities.GenerateRealValues(1.0E-4, 1.0E2, 16))
     {
         Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.Gamma(x + 1.0), x * AdvancedMath.Gamma(x)));
     }
 }
예제 #8
0
 public void GammaAtNegativeIntegers()
 {
     Assert.IsTrue(Double.IsInfinity(AdvancedMath.Gamma(0.0)));
     foreach (int n in TestUtilities.GenerateIntegerValues(1, 100, 4))
     {
         Assert.IsTrue(Double.IsInfinity(AdvancedMath.Gamma(-n)));
     }
 }
예제 #9
0
 public void GammaReflection()
 {
     foreach (double x in TestUtilities.GenerateRealValues(1.0E-4, 1.0E2, 16))
     {
         double GP = AdvancedMath.Gamma(x);
         double GN = AdvancedMath.Gamma(-x);
         Assert.IsTrue(TestUtilities.IsNearlyEqual(-x * GN * GP, Math.PI / MoreMath.SinPi(x)));
     }
 }
예제 #10
0
        public void HypergeometricLinearTransforms()
        {
            foreach (double a in abcs)
            {
                foreach (double b in abcs)
                {
                    foreach (double c in abcs)
                    {
                        if (IsNonpositiveInteger(c))
                        {
                            continue;
                        }
                        foreach (double x in xs)
                        {
                            double F = AdvancedMath.Hypergeometric2F1(a, b, c, x);

                            // A&S 15.3.3
                            Assert.IsTrue(TestUtilities.IsNearlyEqual(F, AdvancedMath.Hypergeometric2F1(c - a, c - b, c, x) * Math.Pow(1.0 - x, c - a - b)));

                            // A&S 15.3.4
                            Assert.IsTrue(TestUtilities.IsNearlyEqual(F, AdvancedMath.Hypergeometric2F1(a, c - b, c, x / (x - 1.0)) * Math.Pow(1.0 - x, -a)));

                            // A&S 15.3.5
                            Assert.IsTrue(TestUtilities.IsNearlyEqual(F, AdvancedMath.Hypergeometric2F1(b, c - a, c, x / (x - 1.0)) * Math.Pow(1.0 - x, -b)));

                            // A&S 15.3.6
                            if (!IsNonpositiveInteger(c - a - b) && !IsNonpositiveInteger(a + b - c) && (x > 0.0))
                            {
                                Assert.IsTrue(TestUtilities.IsSumNearlyEqual(
                                                  new double[] {
                                    AdvancedMath.Gamma(c) * AdvancedMath.Gamma(c - a - b) / AdvancedMath.Gamma(c - a) / AdvancedMath.Gamma(c - b) *
                                    AdvancedMath.Hypergeometric2F1(a, b, a + b - c + 1.0, 1.0 - x),
                                    AdvancedMath.Gamma(c) * AdvancedMath.Gamma(a + b - c) / AdvancedMath.Gamma(a) / AdvancedMath.Gamma(b) *
                                    AdvancedMath.Hypergeometric2F1(c - a, c - b, c - a - b + 1.0, 1.0 - x) *
                                    Math.Pow(1.0 - x, c - a - b)
                                }, F
                                                  ));
                            }

                            // A&S 15.3.7
                            if (!IsNonpositiveInteger(a - b) && !IsNonpositiveInteger(b - a) && (x < 0.0))
                            {
                                Assert.IsTrue(TestUtilities.IsSumNearlyEqual(
                                                  new double[] {
                                    AdvancedMath.Gamma(c) * AdvancedMath.Gamma(b - a) / AdvancedMath.Gamma(b) / AdvancedMath.Gamma(c - a) *
                                    AdvancedMath.Hypergeometric2F1(a, 1.0 - c + a, 1.0 - b + a, 1.0 / x) * Math.Pow(-x, -a),
                                    AdvancedMath.Gamma(c) * AdvancedMath.Gamma(a - b) / AdvancedMath.Gamma(a) / AdvancedMath.Gamma(c - b) *
                                    AdvancedMath.Hypergeometric2F1(b, 1.0 - c + b, 1.0 - a + b, 1.0 / x) * Math.Pow(-x, -b)
                                }, F
                                                  ));
                            }
                        }
                    }
                }
            }
        }
예제 #11
0
        public void GammaTrottIdentity()
        {
            // http://mathworld.wolfram.com/GammaFunction.html
            double G1  = AdvancedMath.Gamma(1.0 / 24.0);
            double G5  = AdvancedMath.Gamma(5.0 / 24.0);
            double G7  = AdvancedMath.Gamma(7.0 / 24.0);
            double G11 = AdvancedMath.Gamma(11.0 / 24.0);

            Assert.IsTrue(TestUtilities.IsNearlyEqual((G1 * G11) / (G5 * G7), Math.Sqrt(3.0) * Math.Sqrt(2.0 + Math.Sqrt(3.0))));
        }
예제 #12
0
        private double GammaProduct(int r)
        {
            double p = 1.0;

            for (int i = 1; i < r; i++)
            {
                p *= AdvancedMath.Gamma(((double)i) / r);
            }
            return(p);
        }
예제 #13
0
 public void HypergeometricAtOneNinth()
 {
     foreach (double a in abcs)
     {
         Assert.IsTrue(TestUtilities.IsNearlyEqual(
                           AdvancedMath.Hypergeometric2F1(a, a + 0.5, 5.0 / 6.0 + 2.0 / 3.0 * a, 1.0 / 9.0),
                           Math.Sqrt(Math.PI) * Math.Pow(3.0 / 4.0, a) * AdvancedMath.Gamma(5.0 / 6.0 + 2.0 / 3.0 * a) / AdvancedMath.Gamma(1.0 / 2.0 + 1.0 / 3.0 * a) / AdvancedMath.Gamma(5.0 / 6.0 + 1.0 / 3.0 * a)
                           ));
     }
 }
예제 #14
0
 public void HypergeometricAtMinusOneThird()
 {
     foreach (double a in abcs)
     {
         Assert.IsTrue(TestUtilities.IsNearlyEqual(
                           AdvancedMath.Hypergeometric2F1(a, a + 0.5, 1.5 - 2.0 * a, -1.0 / 3.0),
                           Math.Pow(8.0 / 9.0, -2.0 * a) * AdvancedMath.Gamma(4.0 / 3.0) / AdvancedMath.Gamma(3.0 / 2.0) * AdvancedMath.Gamma(3.0 / 2.0 - 2.0 * a) / AdvancedMath.Gamma(4.0 / 3.0 - 2.0 * a)
                           ));
     }
 }
예제 #15
0
 public void GammaDuplication()
 {
     foreach (double x in TestUtilities.GenerateRealValues(1.0E-4, 1.0E2, 16))
     {
         Assert.IsTrue(TestUtilities.IsNearlyEqual(
                           AdvancedMath.Gamma(2.0 * x),
                           AdvancedMath.Gamma(x) * AdvancedMath.Gamma(x + 0.5) * Math.Pow(2.0, 2.0 * x - 1.0) / Math.Sqrt(Math.PI)
                           ));
     }
 }
예제 #16
0
 public void GammaIntegral()
 {
     foreach (double x in TestUtilities.GenerateRealValues(1.0, 1.0E2, 4))
     {
         Func <double, double> f = delegate(double t) {
             return(Math.Pow(t, x - 1.0) * Math.Exp(-t));
         };
         Interval r = Interval.FromEndpoints(0.0, Double.PositiveInfinity);
         Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.Gamma(x), FunctionMath.Integrate(f, r)));
     }
 }
 /// <inheritdoc />
 public override double RawMoment(int r)
 {
     if (r < 0)
     {
         throw new ArgumentOutOfRangeException(nameof(r));
     }
     else
     {
         return(Math.Pow(2.0, r / 2.0) * AdvancedMath.Gamma(1.0 + r / 2.0) * MoreMath.Pow(s, r));
     }
 }
예제 #18
0
 public void GammaInequality()
 {
     foreach (double x in TestUtilities.GenerateRealValues(2.0, 1.0E2, 16))
     {
         // for x >= 2
         double lower = Math.Pow(x / Math.E, x - 1.0);
         double upper = Math.Pow(x / 2.0, x - 1.0);
         double value = AdvancedMath.Gamma(x);
         Assert.IsTrue((lower <= value) && (value <= upper));
     }
 }
예제 #19
0
 public void GammaSpecialCases()
 {
     // It would be nice to be able to make more of these comparisons exact.
     Assert.IsTrue(Double.IsPositiveInfinity(AdvancedMath.Gamma(0.0)));
     Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.Gamma(0.5), Math.Sqrt(Math.PI)));
     Assert.IsTrue(AdvancedMath.Gamma(1.0) == 1.0);
     Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.Gamma(1.5), Math.Sqrt(Math.PI) / 2.0));
     Assert.IsTrue(AdvancedMath.Gamma(2.0) == 1.0);
     Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.Gamma(3.0), 2.0));
     Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.Gamma(4.0), 6.0));
     Assert.IsTrue(Double.IsPositiveInfinity(AdvancedMath.Gamma(Double.PositiveInfinity)));
 }
예제 #20
0
        public void EllipticESPecialCases()
        {
            Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.EllipticE(0.0), Math.PI / 2.0));
            Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.EllipticE(1.0), 1.0));

            double g2 = Math.Pow(AdvancedMath.Gamma(1.0 / 4.0), 2.0);

            Assert.IsTrue(TestUtilities.IsNearlyEqual(
                              AdvancedMath.EllipticE(1.0 / Math.Sqrt(2.0)),
                              Math.Pow(Math.PI, 3.0 / 2.0) / g2 + g2 / 8.0 / Math.Sqrt(Math.PI)
                              ));
        }
        // standard deviation inherits from base; nothing special to say about it

        /// <inheritdoc />
        public override double RawMoment(int r)
        {
            if (r < 0.0)
            {
                throw new ArgumentOutOfRangeException(nameof(r));
            }
            else if (r == 0)
            {
                return(1.0);
            }
            else
            {
                return(Math.Pow(scale, r) * AdvancedMath.Gamma(1.0 + r / shape));
            }
        }
        public void AssociatedLaguerreOrthonormality()
        {
            // don't let orders get too big, or (1) the Gamma function will overflow and (2) our integral will become highly oscilatory
            foreach (int n in TestUtilities.GenerateIntegerValues(1, 10, 3))
            {
                foreach (int m in TestUtilities.GenerateIntegerValues(1, 10, 3))
                {
                    foreach (double a in TestUtilities.GenerateRealValues(0.1, 10.0, 5))
                    {
                        //int n = 2;
                        //int m = 4;
                        //double a = 3.5;

                        Console.WriteLine("n={0} m={1} a={2}", n, m, a);

                        // evaluate the orthonormal integral
                        Func <double, double> f = delegate(double x) {
                            return(Math.Pow(x, a) * Math.Exp(-x) *
                                   OrthogonalPolynomials.LaguerreL(m, a, x) *
                                   OrthogonalPolynomials.LaguerreL(n, a, x)
                                   );
                        };
                        Interval r = Interval.FromEndpoints(0.0, Double.PositiveInfinity);

                        // need to loosen default evaluation settings in order to get convergence in some of these cases
                        // seems to have most convergence problems for large a
                        IntegrationSettings e = new IntegrationSettings();
                        e.AbsolutePrecision = TestUtilities.TargetPrecision;
                        e.RelativePrecision = TestUtilities.TargetPrecision;

                        double I = FunctionMath.Integrate(f, r, e).Value;
                        Console.WriteLine(I);

                        // test for orthonormality
                        if (n == m)
                        {
                            Assert.IsTrue(TestUtilities.IsNearlyEqual(
                                              I, AdvancedMath.Gamma(n + a + 1) / AdvancedIntegerMath.Factorial(n)
                                              ));
                        }
                        else
                        {
                            Assert.IsTrue(Math.Abs(I) < TestUtilities.TargetPrecision);
                        }
                    }
                }
            }
        }
예제 #23
0
 /// <inheritdoc/>
 public override double RawMoment(int r)
 {
     if (r < 0)
     {
         throw new ArgumentOutOfRangeException(nameof(r));
     }
     else if (r < a)
     {
         // This only works for m = 0
         return(MoreMath.Pow(s, r) * AdvancedMath.Gamma(1.0 - r / a));
     }
     else
     {
         return(Double.PositiveInfinity);
     }
 }
예제 #24
0
 public void GammaMultiplication()
 {
     foreach (int k in new int[] { 2, 3, 4 })
     {
         foreach (double z in TestUtilities.GenerateRealValues(1.0E-2, 10.0, 4))
         {
             double p = AdvancedMath.Gamma(z);
             for (int i = 1; i < k; i++)
             {
                 p *= AdvancedMath.Gamma(z + ((double)i) / k);
             }
             Assert.IsTrue(TestUtilities.IsNearlyEqual(
                               p, Math.Pow(2.0 * Math.PI, (k - 1) / 2.0) * Math.Pow(k, 0.5 - k * z) * AdvancedMath.Gamma(k * z)
                               ));
         }
     }
 }
예제 #25
0
        public static void ComputeSpecialFunctions()
        {
            // Compute the value x at which erf(x) is just 10^{-15} from 1.
            double x = AdvancedMath.InverseErfc(1.0E-15);

            // The Gamma function at 1/2 is sqrt(pi)
            double y = AdvancedMath.Gamma(0.5);

            // Compute a Coulomb Wave Function in the quantum tunneling region
            SolutionPair s = AdvancedMath.Coulomb(2, 4.5, 3.0);

            // Compute the Reimann Zeta function at a complex value
            Complex z = AdvancedComplexMath.RiemannZeta(new Complex(0.75, 6.0));

            // Compute the 100th central binomial coefficient
            double c = AdvancedIntegerMath.BinomialCoefficient(100, 50);
        }
예제 #26
0
        /*
         * public override double Variance {
         *  get {
         *      return (Global.HalfPI * (Math.PI / 6.0 - Global.LogTwo * Global.LogTwo) - Global.SqrtHalfPI * Global.LogTwo / 12.0 / Math.Sqrt(n));
         *  }
         * }
         */

        public override double Moment(int r)
        {
            if (r < 0)
            {
                throw new ArgumentOutOfRangeException("r");
            }
            else if (r == 0)
            {
                return(1.0);
            }
            else
            {
                // we can get these expressions just by integrating Q_0' and Q_1' term by term
                double M0 = AdvancedMath.DirichletEta(r) * AdvancedMath.Gamma(r / 2.0 + 1.0) / Math.Pow(2.0, r / 2.0 - 1.0);
                double M1 = -2.0 / 3.0 * AdvancedMath.DirichletEta(r - 1) * AdvancedMath.Gamma((r + 1) / 2.0) / Math.Pow(2.0, (r + 1) / 2.0) * r;
                return(M0 + M1 / Math.Sqrt(n));
            }
        }
예제 #27
0
 /// <inheritdoc />
 public override double RawMoment(int r)
 {
     if (r < 0)
     {
         throw new ArgumentOutOfRangeException(nameof(r));
     }
     else if (r == 0)
     {
         return(1.0);
     }
     else if (r == 1)
     {
         return(Mean);
     }
     else
     {
         return(AdvancedMath.Gamma(r / 2.0 + 1.0) * AdvancedMath.DirichletEta(r) / Math.Pow(2.0, r / 2.0 - 1.0));
     }
 }
예제 #28
0
        public void BallVolumeIntegrals()
        {
            // The volume of a d-sphere is \frac{\pi^{d/2}}{\Gamma(d/2 + 1)}
            // and the fraction in the first quadrant is 1/2^d of that

            // This is a simple test of the integration of a discontinuous function

            Func <IList <double>, double> f = delegate(IList <double> x) {
                double r2 = 0.0;
                for (int j = 0; j < x.Count; j++)
                {
                    r2 += x[j] * x[j];
                }
                if (r2 <= 1.0)
                {
                    return(1.0);
                }
                else
                {
                    return(0.0);
                }
            };

            for (int d = 1; d <= 8; d++)
            {
                if (d == 6)
                {
                    continue;         //. For d=6, integral returns after just ~300 evaluation with an underestimated error; look into this
                }
                Console.WriteLine(d);
                IntegrationResult result = MultiFunctionMath.Integrate(f, UnitCube(d), new EvaluationSettings()
                {
                    AbsolutePrecision = 0.0, RelativePrecision = 5.0E-3, EvaluationBudget = 1000000
                });
                double V = Math.Pow(Math.PI, d / 2.0) / AdvancedMath.Gamma(d / 2.0 + 1.0) * MoreMath.Pow(2.0, -d);
                Console.WriteLine("{0} ({1}) {2}: {3}", result.Value, result.Precision, result.Value - V, result.EvaluationCount);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(result.Value, V, new EvaluationSettings()
                {
                    AbsolutePrecision = 4.0 * result.Precision
                }));
            }
        }
예제 #29
0
        private double ProbabilityDensity_Series(double x)
        {
            double z      = lambda * x / 4.0;
            double halfNu = nu / 2.0;

            double t = 1.0 / AdvancedMath.Gamma(halfNu);
            double s = t;

            for (int k = 1; k < Global.SeriesMax; k++)
            {
                double s_old = s;
                t *= z / k / (k - 1 + halfNu);
                s += t;
                if (s == s_old)
                {
                    return(s);
                }
            }
            throw new NonconvergenceException();
        }
예제 #30
0
        public void BallVolumeIntegrals()
        {
            // The volume of a d-sphere is \frac{\pi^{d/2}}{\Gamma(d/2 + 1)}
            // and the fraction in the first quadrant is 1/2^d of that.

            // This is a simple test of the integration of a discontinuous function.

            Func <IReadOnlyList <double>, double> f = delegate(IReadOnlyList <double> x) {
                double r2 = 0.0;
                for (int j = 0; j < x.Count; j++)
                {
                    r2 += x[j] * x[j];
                }
                if (r2 <= 1.0)
                {
                    return(1.0);
                }
                else
                {
                    return(0.0);
                }
            };

            for (int d = 1; d <= 8; d++)
            {
                if (d == 6)
                {
                    continue;         //. For d=6, integral returns after just ~300 evaluation with an underestimated error; look into this
                }
                Console.WriteLine(d);
                IntegrationSettings settings = new IntegrationSettings()
                {
                    AbsolutePrecision = 0.0, RelativePrecision = 1.0E-2
                };
                IntegrationResult result = MultiFunctionMath.Integrate(f, UnitCube(d), settings);
                double            V      = Math.Pow(Math.PI, d / 2.0) / AdvancedMath.Gamma(d / 2.0 + 1.0) * MoreMath.Pow(2.0, -d);
                Assert.IsTrue(result.Estimate.ConfidenceInterval(0.95).ClosedContains(V));
            }
        }