如何通过Runge-Kutta 4传递硬编码微分方程

我试图在C#中实现Runge-Kutta例如问题dy / dt = y – t ^ 2 + 1和dy / dt = t * y + t ^ 3,我似乎无法获得我期望的输出。 我已将我的程序拆分为几个类,以尝试单独查看工作。 我认为我的主要错误来自于尝试使用委托将一个方法通过Runge-Kutta进程作为变量传递。

方程类:

namespace RK4 { public class Eqn { double t; double y; double dt; double b; public Eqn(double t, double y, double dt, double b) { this.t = t; this.y = y; this.dt = dt; this.b = b; } public void Run1() { double temp; int step = 1; RK4 n = new RK4(); while (t < b) { temp = n.Runge(t, y, dt, FN1); y = temp; Console.WriteLine("At step number {0}, t: {1}, y: {2}", step, t, y); t = t + dt; step++; } } public void Run2() { int step = 1; RK4 m = new RK4(); while (t < b) { y = m.Runge(t, y, dt, FN2); Console.WriteLine("At step number {0}, t: {1}, y: {2}", step, t, y); t = t + dt; step++; } } public static double FN1(double t, double y) { double x = y - Math.Pow(t, 2) + 1; return x; } public static double FN2(double t, double y) { double x = t * y + Math.Pow(t, 3); return x; } } } 

Runge-Kutta 4级:

  namespace RK4 { class RK4 { public delegate double Calc(double t, double y); public double Runge(double t, double y, double dt, Calc yp) { double k1 = dt * yp(t, y); double k2 = dt * yp(t + 0.5 * dt, y + k1 * 0.5 * dt); double k3 = dt * yp(t + 0.5 * dt, y + k2 * 0.5 * dt); double k4 = dt * yp(t + dt, y + k3 * dt); return (y + (1 / 6) * (k1 + 2 * k2 + 2 * k3 + k4)); } } } And my Program Class: namespace RK4 { class Program { static void Main(string[] args) { RunProgram(); } public static void RunProgram() { Console.WriteLine("*******************************************************************************"); Console.WriteLine("************************** Fourth Order Runge-Kutta ***************************"); Console.WriteLine("*******************************************************************************"); Console.WriteLine("\nWould you like to implement the fourth-order Runge-Kutta on:"); string Fn1 = "y' = y - t^2 + 1"; string Fn2 = "y' = t * y + t^3"; Console.WriteLine("1) {0}", Fn1); Console.WriteLine("2) {0}", Fn2); Console.WriteLine("Please enter 1 or 2"); switch (Int32.Parse(Console.ReadLine())) { case 1: Console.WriteLine("\nPlease enter beginning of the interval (a):"); double a = Double.Parse(Console.ReadLine()); Console.WriteLine("Please enter end of the interval (b):"); double b = Double.Parse(Console.ReadLine()); Console.WriteLine("Please enter the step size (h) to be used:"); double h = Double.Parse(Console.ReadLine()); Console.WriteLine("Please enter the inital conditions to satisfy y({0}) = d",a); Console.WriteLine("d = "); double d = Double.Parse(Console.ReadLine()); Console.Clear(); Console.WriteLine("Using the interval [{0},{1}] and step size of {2} and the inital condition of y({3}) = {4}:", a, b, h, a, d); Console.WriteLine("With equation: {0}", Fn1); Eqn One = new Eqn(a, d, h, b); One.Run1(); Console.WriteLine("Press enter to exit."); Console.ReadLine(); Environment.Exit(1); break; case 2: Console.WriteLine("\nPlease enter beginning of the interval (a):"); a = Double.Parse(Console.ReadLine()); Console.WriteLine("Please enter end of the interval (b):"); b = Double.Parse(Console.ReadLine()); Console.WriteLine("Please enter the step size (h) to be used:"); h = Double.Parse(Console.ReadLine()); Console.WriteLine("Please enter the inital conditions to satisfy y({0}) = d",a); Console.WriteLine("d = "); d = Double.Parse(Console.ReadLine()); Console.Clear(); Console.WriteLine("Using the interval [{0},{1}] and step size of {2} and the inital condition of y({3}) = {4}:", a, b, h, a, d); Console.WriteLine("With equation: {0}", Fn1); Eqn Two = new Eqn(a, d, h, b); Two.Run2(); Console.WriteLine("Press enter to exit."); Console.ReadLine(); Environment.Exit(1); break; default: Console.WriteLine("Improper input, please press enter to exit."); Console.ReadLine(); Environment.Exit(1); break; } } } } 

这不是任何方式的优雅编程,但我没有工作知识知道我在这一点上做错了什么。 根据我的阅读,我认为RK4类中的委托将能够通过我的硬编码diff eq。

你在RK4实现中做了一个经典错误:有两个变量来定位乘法和dt可供选择,你使用两者。

它是

 k2 = dt*f(t+0.5*dt, y+0.5*k1) 

要么

 k2 = f(t+0.5*dt, y+0.5*dt*k1) 

并且类似地在算法的其他行中。