Wes*_*hem 8 c# numerical-analysis
我试图在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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这不是任何方式的优雅编程,但我没有工作知识知道我在这一点上做错了什么.从我正在阅读的内容中我认为RK4类中的委托将能够通过我的硬编码diff eq.
您在 RK4 实现中犯了一个经典错误:有两种变体可供选择来定位乘法dt,您同时使用这两种变体。
它是
k2 = dt*f(t+0.5*dt, y+0.5*k1)
Run Code Online (Sandbox Code Playgroud)
或者
k2 = f(t+0.5*dt, y+0.5*dt*k1)
Run Code Online (Sandbox Code Playgroud)
算法的其他行也类似。
| 归档时间: |
|
| 查看次数: |
841 次 |
| 最近记录: |