不同时间步长的 Runge-Kutta 四阶误差近似
Runge-Kutta 4th Order error approximation for varied time-steps
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
def f(x, t): #function
return -x
def exact(t): #exact solution
return np.exp(-t)
def Rk4(x0, t0, dt): #Runge-Kutta Fourth Order Error
t = np.arange(0, 1+dt, dt)
n = len(t)
x = np.array([x0]*n)
x[0],t[0] = x0,t0
for i in range(n-1):
h = t[i+1]-t[i]
k1 = h*f(x[i], t[i])
k2 = h*f(x[i]+0.5*k1, t[i]+0.5*h)
k3 = h*f(x[i]+0.5*k2, t[i]+0.5*h)
k4 = h*f(x[i]+k3, t[i+1])
x[i+1] = x[i]+(k1+2.0*(k2+k3)+k4 )/6.0
E = abs(x[n-1]-exact(1))
return E
vecRk4 = np.vectorize(Rk4)
dt = 10e-4
dtime = []
delta = 10e-4
while dt < 1:
if Rk4(1.0,0.0,dt) < Rk4(1.0,0.0,dt+delta):
dtime.append(dt)
S = vecRk4(1.0,0.0,dtime)
dt = dt + delta
plt.plot(dtime,S)
plt.xlabel("dt (s)")
plt.ylabel("Error")
plt.show()
当我 运行 代码时,它会产生一个锯齿状的图,尖峰在许多 dt 值处产生零误差,中间有正误差。 (抱歉,我无法嵌入图表图像)。这些大的尖峰不应发生,因为随着时间步长 dt 的减小,误差应该会持续减小。但是,我不确定如何解决这个问题,也不知道错误从何而来。我尝试通过添加 while 循环来消除尖峰,希望它只在 dt 处的误差大于 dt+delta 处的误差时才将点添加到我的 dtime 数组,但它产生了完全相同的图形。
一个简短的测试表明
In [104]: import numpy as np
In [105]: dt = 0.6
In [106]: np.arange(0, 1+dt, dt)
Out[106]: array([ 0. , 0.6, 1.2])
因此,要获得有意义的结果,请在开始时设置 t[n-1]=1
或将错误计算为
E = abs(x[n-1]-exact(t[n-1]))
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
def f(x, t): #function
return -x
def exact(t): #exact solution
return np.exp(-t)
def Rk4(x0, t0, dt): #Runge-Kutta Fourth Order Error
t = np.arange(0, 1+dt, dt)
n = len(t)
x = np.array([x0]*n)
x[0],t[0] = x0,t0
for i in range(n-1):
h = t[i+1]-t[i]
k1 = h*f(x[i], t[i])
k2 = h*f(x[i]+0.5*k1, t[i]+0.5*h)
k3 = h*f(x[i]+0.5*k2, t[i]+0.5*h)
k4 = h*f(x[i]+k3, t[i+1])
x[i+1] = x[i]+(k1+2.0*(k2+k3)+k4 )/6.0
E = abs(x[n-1]-exact(1))
return E
vecRk4 = np.vectorize(Rk4)
dt = 10e-4
dtime = []
delta = 10e-4
while dt < 1:
if Rk4(1.0,0.0,dt) < Rk4(1.0,0.0,dt+delta):
dtime.append(dt)
S = vecRk4(1.0,0.0,dtime)
dt = dt + delta
plt.plot(dtime,S)
plt.xlabel("dt (s)")
plt.ylabel("Error")
plt.show()
当我 运行 代码时,它会产生一个锯齿状的图,尖峰在许多 dt 值处产生零误差,中间有正误差。 (抱歉,我无法嵌入图表图像)。这些大的尖峰不应发生,因为随着时间步长 dt 的减小,误差应该会持续减小。但是,我不确定如何解决这个问题,也不知道错误从何而来。我尝试通过添加 while 循环来消除尖峰,希望它只在 dt 处的误差大于 dt+delta 处的误差时才将点添加到我的 dtime 数组,但它产生了完全相同的图形。
一个简短的测试表明
In [104]: import numpy as np
In [105]: dt = 0.6
In [106]: np.arange(0, 1+dt, dt)
Out[106]: array([ 0. , 0.6, 1.2])
因此,要获得有意义的结果,请在开始时设置 t[n-1]=1
或将错误计算为
E = abs(x[n-1]-exact(t[n-1]))