Search code examples
c#.netmathnet-numerics

Solving a system of ordinary differential equations using Math.Net Numerics


I am trying to solve a system of ordinary differential equations using Math.Net Numerics. It is not the mathematics I am having trouble with. The system I want to solve is:

x'(t)=x(t)+2y(t)+2t

y'(t)=3x(t)+2y(t)-4t

x(0)=-7/4, y(0)=55/8

I want to solve this system using the fourth order Runge Kutta ODE solver for the system here: https://numerics.mathdotnet.com/api/MathNet.Numerics.OdeSolvers/RungeKutta.htm

The first parameter it takes in is

Vector<T>y0

What I am having trouble with is when I click on the link for the vector<T>I do not find the basic information. So I am having trouble with understanding this class. Do you understand it and how to use it?

The next parameters are ok until I come to the last one: Func<double, Vector<double>, Vector<double>>, since I do not understand the vector class I do not understand how to make this. Do you see how to create this Func?

The last thing I am having trouble with is the return type. It says that it returns a Vector'1[]. But what is this? I can't find any documentation for it.

Can you please help me? Maybe someone can show how to solve the equation?


Solution

  • I think I solved it. Thanks to Tom W for his help.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using MathNet.Numerics.LinearAlgebra;
    using MathNet.Numerics.OdeSolvers;
    
    namespace Sys
    {
        class Program
        {
            static void Main(string[] args)
            {
                int N = 1000000;
                Vector<double> y0 = Vector<double>.Build.Dense(new[] { -7.0 / 4.0, 55.0 / 8.0 });
                Func<double, Vector<double>, Vector<double>> der = DerivativeMaker();
    
                Vector<double>[] res = RungeKutta.FourthOrder(y0, 0, 10, N, der);
    
                double[] x = new double[N];
                double[] y = new double[N];
                for (int i=0; i <N; i++)
                {
                    double[] temp = res[i].ToArray();
                    x[i] = temp[0];
                    y[i] = temp[1];
                }
    
                //Test
                Console.WriteLine(y[N / 10]); // gives 164,537981852489
                Console.WriteLine(Math.Exp(-1) + 3 * Math.Exp(4) - 5.0 / 2 + 23.0 / 8); //gives 164,537329540604, which is y(1)
    
    
                Console.ReadKey();
    
            }
    
            static Func<double, Vector<double>, Vector<double>> DerivativeMaker()
            {
                return (t, Z) =>
                {
                    double[] A = Z.ToArray();
                    double x = A[0];
                    double y = A[1];
    
                    return Vector<double>.Build.Dense(new[] { x + 2 * y + 2 * t, 3 * x + 2 * y - 4 * t });
    
                };
            }
        }
    }