Runge-Kutta 4

The RungeKutta4 class provides support for solving differential equations using the fourth-order, Runge-Kutta method.

Overview

Suppose we want to solve the second-order, ordinary differential equation (ODE),

12d2xdt2+2dxdt+12x=sint\begin{align} \frac{1}{2}\frac{\mathrm{d}^2x}{\mathrm{d}t^2}+2\dv{x}{t}+\frac{1}{2}x=\sin{t} \end{align}

with the initial conditions x(0)=1.23x(0)=1.23 and x(0)=2.34x'(0)=2.34. We start by multiplying both sides by two and setting u=dx/dtu=\dd{x}/\dd{t} so that we obtain

dudt+4u+x=2sint.\begin{align} \dv{u}{t}+4u+x=2\sin{t}. \end{align}

This lets us write the first equation as

ddt(ux)+(4110)(ux)=(2sint0).\begin{align} \dv{}{t}\begin{pmatrix}u \\ x\end{pmatrix}+\begin{pmatrix}4 & 1 \\ -1 & 0\end{pmatrix}\begin{pmatrix}u \\ x\end{pmatrix}=\begin{pmatrix}2\sin{t} \\ 0\end{pmatrix}. \end{align}

To solve this with Mathematics.NET, use RungeKutta4 with X1=uu and X2=xx, then write the following:

using Mathematics.NET.Core;
using Mathematics.NET.LinearAlgebra;
using Mathematics.NET.Solvers;
using Plotly.NET.CSharp;
using Chart = Plotly.NET.CSharp.Chart;

State<Vector2<Real>, Real> state = new(new Vector2<Real>[] { new(2.34, 1.23) }, 0);
RungeKutta4<Vector2<Real>, Real> rk4 = new((t, x) => new(2 * Real.Sin(t) - 4 * x.X1 - x.X2, x.X1));

var count = 200;
Vector2<Real>[] points = new Vector2<Real>[count];

for (int i = 0; i < count; i++)
{
  rk4.Integrate(state, 0.1);

  points[i].X1 = state.Time;
  points[i].X2 = state.System.Span[0].X2;
}

var chart = Chart.Line<double, double, string>(
  x: points.Select(x => x.X1.AsDouble()),
  y: points.Select(x => x.X2.AsDouble()),
  Name: "X(t)",
  ShowLegend: true);
chart.Show();

The state of the system is tracked by State, which contains information about the initial conditions. We have also chosen Δt=0.1\Delta t=0.1 and the number of points to be 200. The solution is then plotted using Plotly.NET.