示例#1
0
        public void SeperableIntegrals()
        {
            // Integrates \Pi_{j=0}^{d-1} \int_0^1 \! dx \, x_j^j = \Pi_{j=0}^{d-1} \frac{1}{j+1} = \frac{1}{d!}

            // This is a simple test of a seperable integral

            Func <IList <double>, double> f = delegate(IList <double> x) {
                double y = 1.0;
                for (int j = 0; j < x.Count; j++)
                {
                    y *= MoreMath.Pow(x[j], j);
                }
                return(y);
            };

            for (int d = 1; d <= 10; d++)
            {
                Console.WriteLine(d);
                IntegrationResult r = MultiFunctionMath.Integrate(f, UnitCube(d));
                Console.WriteLine("{0}: {1} ({2}) ?= {3}", r.EvaluationCount, r.Value, r.Precision, 1.0 / AdvancedIntegerMath.Factorial(d));
                Assert.IsTrue(TestUtilities.IsNearlyEqual(
                                  r.Value,
                                  1.0 / AdvancedIntegerMath.Factorial(d),
                                  new EvaluationSettings()
                {
                    AbsolutePrecision = 2.0 * r.Precision
                }
                                  ));
            }
        }
示例#2
0
        public void ZetaIntegrals()
        {
            // By expanding 1/(1-x) = 1 + x + x^2 + ... and integrating term-by-term
            // it's easy to show that this integral is \zeta(d)

            Func <IList <double>, double> f = delegate(IList <double> x) {
                double p = 1.0;
                for (int i = 0; i < x.Count; i++)
                {
                    p *= x[i];
                }
                return(1.0 / (1.0 - p));
            };

            // \zeta(1) is infinite, so skip d=1

            for (int d = 2; d <= 10; d++)
            {
                Console.WriteLine(d);
                IntegrationResult result = MultiFunctionMath.Integrate(f, UnitCube(d));
                Console.WriteLine("{0} ({1}) {2}", result.Value, result.Precision, AdvancedMath.RiemannZeta(d));
                Assert.IsTrue(TestUtilities.IsNearlyEqual(result.Value, AdvancedMath.RiemannZeta(d), new EvaluationSettings()
                {
                    AbsolutePrecision = 2.0 * result.Precision
                }));
            }
        }
示例#3
0
        public void SteinmetzVolume()
        {
            // Steinmetz solid is intersection of unit cylinders along all axes. This is another hard-edged integral. Analytic values are known for d=2-5.
            // http://www.math.illinois.edu/~hildebr/ugresearch/cylinder-spring2013report.pdf
            // http://www.math.uiuc.edu/~hildebr/igl/nvolumes-fall2012report.pdf

            EvaluationSettings settings = new EvaluationSettings()
            {
                EvaluationBudget = 1000000, RelativePrecision = 1.0E-2
            };

            for (int d = 2; d <= 5; d++)
            {
                IntegrationResult v1 = MultiFunctionMath.Integrate((IList <double> x) => {
                    for (int i = 0; i < d; i++)
                    {
                        double s = 0.0;
                        for (int j = 0; j < d; j++)
                        {
                            if (j != i)
                            {
                                s += x[j] * x[j];
                            }
                        }
                        if (s > 1.0)
                        {
                            return(0.0);
                        }
                    }
                    return(1.0);
                }, SymmetricUnitCube(d), settings);

                double v2 = 0.0;
                switch (d)
                {
                case 2:
                    // trivial square
                    v2 = 4.0;
                    break;

                case 3:
                    v2 = 16.0 - 8.0 * Math.Sqrt(2.0);
                    break;

                case 4:
                    v2 = 48.0 * (Math.PI / 4.0 - Math.Atan(Math.Sqrt(2.0)) / Math.Sqrt(2.0));
                    break;

                case 5:
                    v2 = 256.0 * (Math.PI / 12.0 - Math.Atan(1.0 / (2.0 * Math.Sqrt(2.0))) / Math.Sqrt(2.0));
                    break;
                }

                Console.WriteLine("{0} {1} {2}", d, v1.Value, v2);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(v1.Value, v2, new EvaluationSettings()
                {
                    AbsolutePrecision = 4.0 * v1.Precision
                }));
            }
        }
示例#4
0
        public void SeperableIntegrals()
        {
            // Integrates \Pi_{j=0}^{d-1} \int_0^1 \! dx \, x_j^j = \Pi_{j=0}^{d-1} \frac{1}{j+1} = \frac{1}{d!}

            // This is a simple test of a seperable integral

            Func <IReadOnlyList <double>, double> f = delegate(IReadOnlyList <double> x) {
                double y = 1.0;
                for (int j = 0; j < x.Count; j++)
                {
                    y *= MoreMath.Pow(x[j], j);
                }
                return(y);
            };

            for (int d = 1; d <= 10; d++)
            {
                Console.WriteLine(d);
                // Result gets very small, so rely on relative rather than absolute precision.
                IntegrationSettings s = new IntegrationSettings()
                {
                    AbsolutePrecision = 0, RelativePrecision = Math.Pow(10.0, -(6.0 - d / 2.0))
                };
                IntegrationResult r = MultiFunctionMath.Integrate(f, UnitCube(d), s);
                Assert.IsTrue(r.Estimate.ConfidenceInterval(0.95).ClosedContains(1.0 / AdvancedIntegerMath.Factorial(d)));
            }
        }
示例#5
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)
                    )
                );
        }
示例#6
0
 private IntegrationResult RambleIntegral(int d, int s, IntegrationSettings settings)
 {
     return(MultiFunctionMath.Integrate((IReadOnlyList <double> x) => {
         Complex z = 0.0;
         for (int k = 0; k < d; k++)
         {
             z += ComplexMath.Exp(2.0 * Math.PI * Complex.I * x[k]);
         }
         return (MoreMath.Pow(ComplexMath.Abs(z), s));
     }, UnitCube(d), settings));
 }
示例#7
0
 public double BoxIntegralB(int d, int r, IntegrationSettings settings)
 {
     return(MultiFunctionMath.Integrate((IReadOnlyList <double> x) => {
         double s = 0.0;
         for (int k = 0; k < d; k++)
         {
             s += x[k] * x[k];
         }
         return (Math.Pow(s, r / 2.0));
     }, UnitCube(d), settings).Value);
 }
示例#8
0
        public void UnitSquareIntegrals()
        {
            // http://mathworld.wolfram.com/UnitSquareIntegral.html has a long list of integrals over the unit square.

            // Many are taken from Guillera and Sondow,
            // "Double Integrals and Infinite Products for Some Classical Constants Via Analytic Continuations of Lerch's Transcendent.",
            // 16 June 2005. (http://arxiv.org/abs/math.NT/0506319)

            Assert.IsTrue(
                MultiFunctionMath.Integrate(
                    (IReadOnlyList <double> x) => 1.0 / (1.0 - x[0] * x[1]),
                    UnitCube(2)
                    ).Estimate.ConfidenceInterval(0.95).ClosedContains(
                    AdvancedMath.RiemannZeta(2.0)
                    )
                );

            Assert.IsTrue(
                MultiFunctionMath.Integrate(
                    (IReadOnlyList <double> x) => - Math.Log(x[0] * x[1]) / (1.0 - x[0] * x[1]),
                    UnitCube(2)
                    ).Estimate.ConfidenceInterval(0.95).ClosedContains(
                    2.0 * AdvancedMath.RiemannZeta(3.0)
                    )
                );

            Assert.IsTrue(
                MultiFunctionMath.Integrate(
                    (IReadOnlyList <double> x) => (x[0] - 1.0) / (1.0 - x[0] * x[1]) / Math.Log(x[0] * x[1]),
                    UnitCube(2)
                    ).Estimate.ConfidenceInterval(0.95).ClosedContains(
                    AdvancedMath.EulerGamma
                    )
                );

            Assert.IsTrue(
                MultiFunctionMath.Integrate(
                    (IReadOnlyList <double> x) => (x[0] - 1.0) / (1.0 + x[0] * x[1]) / Math.Log(x[0] * x[1]),
                    UnitCube(2)
                    ).Estimate.ConfidenceInterval(0.95).ClosedContains(
                    Math.Log(4.0 / Math.PI)
                    )
                );

            Assert.IsTrue(
                MultiFunctionMath.Integrate(
                    (IReadOnlyList <double> x) => 1.0 / (1.0 + MoreMath.Sqr(x[0] * x[1])),
                    UnitCube(2)
                    ).Estimate.ConfidenceInterval(0.95).ClosedContains(
                    AdvancedMath.Catalan
                    )
                );
        }
示例#9
0
 public double BoxIntegralD(int d, int r, EvaluationSettings settings)
 {
     return(MultiFunctionMath.Integrate((IList <double> x) => {
         double s = 0.0;
         for (int k = 0; k < d; k++)
         {
             double z = x[k] - x[k + d];
             s += z * z;
         }
         return (Math.Pow(s, r / 2.0));
     }, UnitCube(2 * d), settings).Value);
 }
示例#10
0
        public void GaussianIntegrals()
        {
            Random rng = new Random(1);

            for (int d = 2; d < 4; d++)
            {
                if (d == 4 || d == 5 || d == 6)
                {
                    continue;
                }
                Console.WriteLine(d);

                // Create a symmetric matrix
                SymmetricMatrix A = new SymmetricMatrix(d);
                for (int r = 0; r < d; r++)
                {
                    for (int c = 0; c < r; c++)
                    {
                        A[r, c] = rng.NextDouble();
                    }
                    // Ensure it is positive definite by diagonal dominance
                    A[r, r] = r + 1.0;
                }

                // Compute its determinant, which appears in the analytic value of the integral
                CholeskyDecomposition CD = A.CholeskyDecomposition();
                double detA = CD.Determinant();

                // Compute the integral
                Func <IList <double>, double> f = (IList <double> x) => {
                    ColumnVector v = new ColumnVector(x);
                    double       s = v.Transpose() * (A * v);
                    return(Math.Exp(-s));
                };

                Interval[] volume = new Interval[d];
                for (int i = 0; i < d; i++)
                {
                    volume[i] = Interval.FromEndpoints(Double.NegativeInfinity, Double.PositiveInfinity);
                }

                IntegrationResult I = MultiFunctionMath.Integrate(f, volume);

                // Compare to the analytic result
                Console.WriteLine("{0} ({1}) {2}", I.Value, I.Precision, Math.Sqrt(MoreMath.Pow(Math.PI, d) / detA));
                Assert.IsTrue(TestUtilities.IsNearlyEqual(I.Value, Math.Sqrt(MoreMath.Pow(Math.PI, d) / detA), new EvaluationSettings()
                {
                    AbsolutePrecision = 2.0 * I.Precision
                }));
            }
        }
示例#11
0
        public void DoubleIntegrals()
        {
            // At http://mathworld.wolfram.com/DoubleIntegral.html, Mathworld
            // lists a few double integrals with known values that we take as
            // tests.

            // One of the integrals listed there is just the zeta integral for d=2
            // which we do above, so we omit it here.

            // Because these are non-ocsilatory and have relatively low
            // dimension, we can demand fairly high accuracy.

            IntegrationResult i1 = MultiFunctionMath.Integrate(
                (IList <double> x) => 1.0 / (1.0 - x[0] * x[0] * x[1] * x[1]),
                UnitCube(2)
                );

            Console.WriteLine("{0} ({1})", i1.Value, i1.Precision);
            Assert.IsTrue(TestUtilities.IsNearlyEqual(i1.Value, Math.PI * Math.PI / 8.0, new EvaluationSettings()
            {
                AbsolutePrecision = 2.0 * i1.Precision
            }));
            //Assert.IsTrue(i1.Estimate.ConfidenceInterval(0.99).ClosedContains(Math.PI * Math.PI / 8.0));

            IntegrationResult i2 = MultiFunctionMath.Integrate(
                (IList <double> x) => 1.0 / (x[0] + x[1]) / Math.Sqrt((1.0 - x[0]) * (1.0 - x[1])),
                UnitCube(2),
                new EvaluationSettings()
            {
                RelativePrecision = 1.0E-5, EvaluationBudget = 1000000
            }
                );

            Console.WriteLine("{0} ({1})", i2.Value, i2.Precision);
            Assert.IsTrue(TestUtilities.IsNearlyEqual(i2.Value, 4.0 * AdvancedMath.Catalan, new EvaluationSettings()
            {
                AbsolutePrecision = 2.0 * i2.Precision
            }));
            // For higher precision demands on this integral, we start getting Infinity +/- NaN for estimate and never terminate, look into this.

            IntegrationResult i3 = MultiFunctionMath.Integrate(
                (IList <double> x) => (x[0] - 1.0) / (1.0 - x[0] * x[1]) / Math.Log(x[0] * x[1]),
                UnitCube(2)
                );

            Console.WriteLine("{0} ({1})", i3.Value, i3.Precision);
            Assert.IsTrue(TestUtilities.IsNearlyEqual(i3.Value, AdvancedMath.EulerGamma, new EvaluationSettings()
            {
                AbsolutePrecision = 2.0 * i3.Precision
            }));
        }
示例#12
0
        public void GaussianIntegrals()
        {
            Random rng = new Random(1);

            for (int d = 2; d < 8; d++)
            {
                Console.WriteLine(d);

                // Create a symmetric matrix
                SymmetricMatrix A = new SymmetricMatrix(d);
                for (int r = 0; r < d; r++)
                {
                    for (int c = 0; c < r; c++)
                    {
                        A[r, c] = rng.NextDouble();
                    }
                    // Ensure it is positive definite by diagonal dominance
                    A[r, r] = r + 1.0;
                }

                // Compute its determinant, which appears in the analytic value of the integral
                CholeskyDecomposition CD = A.CholeskyDecomposition();
                double detA = CD.Determinant();

                // Compute the integral
                Func <IReadOnlyList <double>, double> f = (IReadOnlyList <double> x) => {
                    ColumnVector v = new ColumnVector(x);
                    double       s = v.Transpose * (A * v);
                    return(Math.Exp(-s));
                };

                Interval[] volume = new Interval[d];
                for (int i = 0; i < d; i++)
                {
                    volume[i] = Interval.FromEndpoints(Double.NegativeInfinity, Double.PositiveInfinity);
                }

                // These are difficult integrals; demand reduced precision.
                IntegrationSettings settings = new IntegrationSettings()
                {
                    RelativePrecision = Math.Pow(10.0, -(4.0 - d / 2.0))
                };

                IntegrationResult I = MultiFunctionMath.Integrate(f, volume, settings);

                // Compare to the analytic result
                Assert.IsTrue(I.Estimate.ConfidenceInterval(0.95).ClosedContains(Math.Sqrt(MoreMath.Pow(Math.PI, d) / detA)));
            }
        }
示例#13
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
                }));
            }
        }
示例#14
0
        public void ExponentialBox()
        {
            // Mentioned in passing in http://crd-legacy.lbl.gov/~dhbailey/dhbpapers/BoxII.pdf
            // This is easy because the integrand is seperable and smooth.

            for (int d = 2; d <= 10; d++)
            {
                IntegrationResult result = MultiFunctionMath.Integrate((IReadOnlyList <double> r) => {
                    double s = 0.0;
                    foreach (double x in r)
                    {
                        s += x * x;
                    }
                    return(Math.Exp(-s));
                }, UnitCube(d));

                Assert.IsTrue(result.Estimate.ConfidenceInterval(0.95).ClosedContains(
                                  MoreMath.Pow(Math.Sqrt(Math.PI) / 2.0 * AdvancedMath.Erf(1.0), d)
                                  ));
            }
        }
示例#15
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));
            }
        }
示例#16
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

            // These integrals are difficult, so up the budget to about 1,000,000 and reduce the target accuracy to about 10^{-4}
            EvaluationSettings settings = new EvaluationSettings()
            {
                RelativePrecision = 1.0E-4, EvaluationBudget = 1000000
            };

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

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

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

            Assert.IsTrue(
                MultiFunctionMath.Integrate(
                    (IList <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, settings
                    ).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(
                    (IList <double> x) => 1.0 / (3.0 - Math.Cos(x[0]) - Math.Cos(x[1]) - Math.Cos(x[2])), watsonBox, settings
                    ).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)
                    )
                );
        }
示例#17
0
        public void ZetaIntegrals()
        {
            // By expanding 1/(1-x) = 1 + x + x^2 + ... and integrating term-by-term
            // it's easy to show that this integral is \zeta(d)

            Func <IReadOnlyList <double>, double> f = delegate(IReadOnlyList <double> x) {
                double p = 1.0;
                for (int i = 0; i < x.Count; i++)
                {
                    p *= x[i];
                }
                return(1.0 / (1.0 - p));
            };

            // \zeta(1) is infinite, so skip d=1
            for (int d = 2; d <= 15; d++)
            {
                Console.WriteLine(d);
                IntegrationResult result = MultiFunctionMath.Integrate(f, UnitCube(d));
                Assert.IsTrue(result.Estimate.ConfidenceInterval(0.95).ClosedContains(AdvancedMath.RiemannZeta(d)));
            }
        }
示例#18
0
        public void DoubleIntegrals()
        {
            // At http://mathworld.wolfram.com/DoubleIntegral.html, Mathworld
            // lists a few double integrals with known values that we take as
            // tests.

            // One of the integrals listed there is just the zeta integral for d=2
            // which we do above, so we omit it here.

            // Because these are non-ocsilatory and have relatively low
            // dimension, we can demand fairly high accuracy.

            IntegrationResult i1 = MultiFunctionMath.Integrate(
                (IReadOnlyList <double> x) => 1.0 / (1.0 - x[0] * x[0] * x[1] * x[1]),
                UnitCube(2)
                );

            Assert.IsTrue(i1.Estimate.ConfidenceInterval(0.95).ClosedContains(Math.PI * Math.PI / 8.0));

            IntegrationResult i2 = MultiFunctionMath.Integrate(
                (IReadOnlyList <double> x) => 1.0 / (x[0] + x[1]) / Math.Sqrt((1.0 - x[0]) * (1.0 - x[1])),
                UnitCube(2),
                new IntegrationSettings()
            {
                RelativePrecision = 1.0E-6
            }
                );

            Assert.IsTrue(i2.Estimate.ConfidenceInterval(0.95).ClosedContains(4.0 * AdvancedMath.Catalan));
            // For higher precision demands on this integral, we start getting Infinity +/- NaN for estimate and never terminate, look into this.

            IntegrationResult i3 = MultiFunctionMath.Integrate(
                (IReadOnlyList <double> x) => (x[0] - 1.0) / (1.0 - x[0] * x[1]) / Math.Log(x[0] * x[1]),
                UnitCube(2)
                );

            Assert.IsTrue(i3.Estimate.ConfidenceInterval(0.95).ClosedContains(AdvancedMath.EulerGamma));
        }
示例#19
0
        public void IsingIntegrals()
        {
            // See http://www.davidhbailey.com/dhbpapers/ising.pdf.

            IntegrationSettings settings = new IntegrationSettings()
            {
                RelativePrecision = 1.0E-3, EvaluationBudget = 1000000
            };

            int d = 4;

            Interval[] volume = new Interval[d];
            for (int i = 0; i < volume.Length; i++)
            {
                volume[i] = Interval.FromEndpoints(0.0, Double.PositiveInfinity);
            }

            IntegrationResult r = MultiFunctionMath.Integrate((IReadOnlyList <double> x) => {
                double p = 1.0;
                double q = 0.0;
                for (int i = 0; i < x.Count; i++)
                {
                    double u = x[i];
                    double v = 1.0 / u;
                    q       += (u + v);
                    p       *= v;
                }
                return(p / MoreMath.Sqr(q));
            }, volume, settings);
            double c = 4.0 / AdvancedIntegerMath.Factorial(d);

            Console.WriteLine("{0} {1}", c * r.Estimate, r.EvaluationCount);

            Console.WriteLine(7.0 * AdvancedMath.RiemannZeta(3.0) / 12.0);

            Assert.IsTrue((c * r.Estimate).ConfidenceInterval(0.99).ClosedContains(7.0 * AdvancedMath.RiemannZeta(3.0) / 12.0));
        }
示例#20
0
        public static void Integration()
        {
            // This is the area of the upper half-circle, so the value should be pi/2.
            IntegrationResult i = FunctionMath.Integrate(x => Math.Sqrt(1.0 - x * x), -1.0, +1.0);

            Console.WriteLine($"i = {i.Estimate} after {i.EvaluationCount} evaluations.");

            Interval          zeroToPi = Interval.FromEndpoints(0.0, Math.PI);
            IntegrationResult watson   = MultiFunctionMath.Integrate(
                x => 1.0 / (1.0 - Math.Cos(x[0]) * Math.Cos(x[1]) * Math.Cos(x[2])),
                new Interval[] { zeroToPi, zeroToPi, zeroToPi }
                );

            IntegrationResult i2 = FunctionMath.Integrate(
                x => Math.Sqrt(1.0 - x * x), -1.0, +1.0,
                new IntegrationSettings()
            {
                RelativePrecision = 1.0E-4
            }
                );

            // This integrand has a log singularity at x = 0.
            // The value of this integral is the Catalan constant.
            IntegrationResult soft = FunctionMath.Integrate(
                x => - Math.Log(x) / (1.0 + x * x), 0.0, 1.0
                );

            // This integral has a power law singularity at x = 0.
            // The value of this integral is 4.
            IntegrationResult hard = FunctionMath.Integrate(
                x => Math.Pow(x, -3.0 / 4.0), 0.0, 1.0,
                new IntegrationSettings()
            {
                RelativePrecision = 1.0E-6
            }
                );

            // The value of this infinite integral is sqrt(pi)
            IntegrationResult infinite = FunctionMath.Integrate(
                x => Math.Exp(-x * x), Double.NegativeInfinity, Double.PositiveInfinity
                );

            Func <IReadOnlyList <double>, double> distance = z => {
                ColumnVector x = new ColumnVector(z[0], z[1], z[2]);
                ColumnVector y = new ColumnVector(z[3], z[4], z[5]);
                ColumnVector d = x - y;
                return(d.Norm());
            };

            Interval oneBox = Interval.FromEndpoints(0.0, 1.0);

            Interval[] sixBox = new Interval[] { oneBox, oneBox, oneBox, oneBox, oneBox, oneBox };

            IntegrationSettings settings = new IntegrationSettings()
            {
                RelativePrecision = 1.0E-4,
                AbsolutePrecision = 0.0,
                Listener          = r => {
                    Console.WriteLine($"Estimate {r.Estimate} after {r.EvaluationCount} evaluations.");
                }
            };

            IntegrationResult numeric = MultiFunctionMath.Integrate(distance, sixBox, settings);

            Console.WriteLine($"The numeric result is {numeric.Estimate}.");

            double analytic = 4.0 / 105.0 + 17.0 / 105.0 * Math.Sqrt(2.0) - 2.0 / 35.0 * Math.Sqrt(3.0)
                              + Math.Log(1.0 + Math.Sqrt(2.0)) / 5.0 + 2.0 / 5.0 * Math.Log(2.0 + Math.Sqrt(3.0))
                              - Math.PI / 15.0;

            Console.WriteLine($"The analytic result is {analytic}.");
        }