예제 #1
0
        public void OdeErf()
        {
            Func <double, double, double> rhs = (double t, double u) =>
                                                2.0 / Math.Sqrt(Math.PI) * Math.Exp(-t * t);

            OdeResult r = FunctionMath.IntegrateOde(rhs, 0.0, 0.0, 5.0);

            Console.WriteLine(r.Y);
        }
예제 #2
0
        public static void IntegrateOde()
        {
            Func <double, double, double> rhs = (x, y) => - x * y;
            OdeResult sln = FunctionMath.IntegrateOde(rhs, 0.0, 1.0, 2.0);

            Console.WriteLine($"Numeric solution y({sln.X}) = {sln.Y}.");
            Console.WriteLine($"Required {sln.EvaluationCount} evaluations.");
            Console.WriteLine($"Analytic solution y({sln.X}) = {Math.Exp(-MoreMath.Sqr(sln.X) / 2.0)}");

            // Lotka-Volterra equations
            double A = 0.1;
            double B = 0.02;
            double C = 0.4;
            double D = 0.02;
            Func <double, IReadOnlyList <double>, IReadOnlyList <double> > lkRhs = (t, y) => {
                return(new double[] {
                    A *y[0] - B * y[0] * y[1], D *y[0] * y[1] - C * y[1]
                });
            };
            MultiOdeSettings lkSettings = new MultiOdeSettings()
            {
                Listener = r => { Console.WriteLine($"t={r.X} rabbits={r.Y[0]}, foxes={r.Y[1]}"); }
            };

            MultiFunctionMath.IntegrateOde(lkRhs, 0.0, new double[] { 20.0, 10.0 }, 50.0, lkSettings);

            Func <double, IReadOnlyList <double>, IReadOnlyList <double> > rhs1 = (x, u) => {
                return(new double[] { u[1], -u[0] });
            };
            MultiOdeSettings settings1 = new MultiOdeSettings()
            {
                EvaluationBudget = 100000
            };
            MultiOdeResult result1 = MultiFunctionMath.IntegrateOde(
                rhs1, 0.0, new double[] { 0.0, 1.0 }, 500.0, settings1
                );
            double s1 = MoreMath.Sqr(result1.Y[0]) + MoreMath.Sqr(result1.Y[1]);

            Console.WriteLine($"y({result1.X}) = {result1.Y[0]}, (y)^2 + (y')^2 = {s1}");
            Console.WriteLine($"Required {result1.EvaluationCount} evaluations.");

            Func <double, double, double> rhs2 = (x, y) => - y;
            OdeSettings settings2 = new OdeSettings()
            {
                EvaluationBudget = 100000
            };
            OdeResult result2 = FunctionMath.IntegrateConservativeOde(
                rhs2, 0.0, 0.0, 1.0, 500.0, settings2
                );
            double s2 = MoreMath.Sqr(result2.Y) + MoreMath.Sqr(result2.YPrime);

            Console.WriteLine($"y({result2.X}) = {result2.Y}, (y)^2 + (y')^2 = {s2}");
            Console.WriteLine($"Required {result2.EvaluationCount} evaluations");

            Console.WriteLine(MoreMath.Sin(500.0));
        }
예제 #3
0
        public void OdeExponential()
        {
            // The exponential function y = e^x satisfies
            //    y' = y
            // This is perhaps the simplest differential equation.

            Func <double, double, double> f = (double x, double y) => y;

            OdeResult r = FunctionMath.IntegrateOde(f, 0.0, 1.0, 2.0);

            Assert.IsTrue(TestUtilities.IsNearlyEqual(r.Y, MoreMath.Sqr(Math.E)));

            Console.WriteLine(r.EvaluationCount);
        }
예제 #4
0
        public void OdeExample()
        {
            Func <double, double, double> rhs      = (double t, double u) => (1.0 - 2.0 * t) * u;
            Func <double, double, double> solution = (double u0, double t) => u0 *Math.Exp(t - t *t);

            int count = 0;

            foreach (double t in new double[] { 0.5, 0.75, 1.50, 2.25, 3.25 })
            {
                OdeResult r  = FunctionMath.IntegrateOde(rhs, 0.0, 1.0, t);
                double    y1 = r.Y;
                Assert.IsTrue(TestUtilities.IsNearlyEqual(y1, solution(1.0, t)));
                count += r.EvaluationCount;
            }
            Console.WriteLine(count);
        }
예제 #5
0
        public void OdeLogistic()
        {
            // y = \frac{y_0}{y_0 + (1 - y_0) e^{-(x - x_0)}
            Func <double, double, double> rhs      = (double x, double y) => y * (1.0 - y);
            Func <double, double, double> solution = (double y0, double x) => y0 / (y0 + (1.0 - y0) * Math.Exp(-x));

            int count = 0;

            foreach (double y0 in new double[] { -0.1, 0.0, 0.4, 1.0, 1.6 })
            {
                Console.WriteLine(y0);
                Interval  r  = Interval.FromEndpoints(0.0, 2.0);
                OdeResult s  = FunctionMath.IntegrateOde(rhs, 0.0, y0, 2.0);
                double    y1 = s.Y;
                Console.WriteLine(y1);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(y1, solution(y0, 2.0)));
                count += s.EvaluationCount;
            }
            Console.WriteLine(count);
        }
예제 #6
0
        public void OdeNonlinear()
        {
            // y = \frac{y_0}{1 - y_0 (x - x_0)}
            Func <double, double, double> f = (double x, double y) => MoreMath.Sqr(y);

            int         count    = 0;
            OdeSettings settings = new OdeSettings()
            {
                RelativePrecision = 1.0E-8,
                EvaluationBudget  = 1024,
                Listener          = (OdeResult) => count++
            };
            OdeResult result = FunctionMath.IntegrateOde(f, 0.0, 1.0, 0.99, settings);

            Assert.IsTrue(TestUtilities.IsNearlyEqual(result.Y, 1.0 / (1.0 - 1.0 * (0.99 - 0.0)), result.Settings));

            Assert.IsTrue(count > 0);

            Console.WriteLine(result.EvaluationCount);
        }
예제 #7
0
        public void OdeDawson()
        {
            // The Dawson function fulfills a simple ODE.
            //   \frac{dF}{dx} + 2 x F = 1 \qquad F(0) = 0
            // See e.g. https://en.wikipedia.org/wiki/Dawson_function
            // Verify that we get correct values via ODE integration.

            Func <double, double, double> rhs = (double x, double F) => 1.0 - 2.0 * x * F;

            foreach (double x1 in TestUtilities.GenerateRealValues(0.1, 10.0, 8))
            {
                EvaluationSettings s = new EvaluationSettings()
                {
                    RelativePrecision = 1.0E-13,
                    AbsolutePrecision = 0.0
                };
                OdeResult r = FunctionMath.IntegrateOde(rhs, 0.0, 0.0, x1);
                Debug.WriteLine("{0}: {1} {2}: {3}", x1, r.Y, AdvancedMath.Dawson(x1), r.EvaluationCount);
                Assert.IsTrue(TestUtilities.IsNearlyEqual(r.Y, AdvancedMath.Dawson(x1), s));
            }
        }