用欧拉方法处理 ODE 不起作用
crunching a ODE with Euler's Method doesn't work
所以我必须用不同的方法和 Δt 来处理 ODE,但突然间我的函数停止工作,Δt<1。
ODE 是:T(t)'=R*T(t) - K*T(t-δ)
,R 和 K 常量,十进制和小常量。
第一部分是在 δ=0 的情况下处理的,所以它很顺利,没有问题,但现在我在 δ=5 的情况下处理它,突然 ODE 就不起作用了。
当 Δt=1 时,程序可以使用 Euler 方法很好地处理 ODE,但当 Δt=.1 时,它突然停止工作。
它没有崩溃或其他任何事情,但它没有正确计算数字,而是似乎无法识别 δ,或者假定它为零,然后继续这样,直到图形等于δ=0.
我正在使用 Numpy 和 Matplotlib,这是代码:
r = 0.1
R = 0.1
CeCw = 0.27
γ1 = 1
γ2 = 0.164
α = 0.612
δ = 5
Te0 = 1
tf = 240
Δt2 = np.arange(0, tf+.1, .1)
def d(Te, n):
return R*Te[n] - α*γ1*CeCw*Te[n-δ]
Te2 = np.array([Te0])
for n in range(len(Δt2)-1):
if n*.1<=δ:
Te2 = np.append(Te2, 1)
else:
Te2 = np.append(Te2, Te2[n] + .1*d(Te2, n))
如果我将 .1
更改为简单的 1,它会突然再次开始工作(尽管它生成了一个不正确的图形,因为它不是正确的方法)。
我尝试用 Decimal() 包装数字并使用不同的函数,但不知何故 .1 回来删除 δ。
编辑:向前移动并尝试使用 δ=5 实施 Heun 的方法,并且在 Δt=.1 或更低的情况下,它的行为就像 δ=0
这种方程通常称为延迟微分方程并且不是 ODE。专门的求解器通常使用足够高的误差阶插值来获取过去时间的值。
更具体地说,您的代码没有正确实现延迟。 delay δ
是时间差,不是索引差。对于索引差异 m_δ
,您想要 m_δ*h = δ
的实现类型。然后用m_δ
确定初始段的长度和导数函数中的偏移量。
这看起来像
δ = 5
mδ = 50
h = δ/mδ
Te0 = 1
tf = 240
Δt2 = np.arange(0, tf+h, h)
def d(Te, n):
return R*Te[n] - α*γ1*CeCw*Te[n-mδ]
Te2 = np.array(len(Δt2)*[Te0], dtype=float)
for n in range(mδ,len(Δt2)-1):
Te2[n+1] = Te2[n] + h*d(Te2, n)
这确实会产生振荡
使用时间循环的 Heun 方法获得相同的视觉图像
for n in range(mδ,len(Δt2)-1):
k1 = d(Te2, n)
Te2[n+1] = Te2[n] + h*k1
k2 = d(Te2, n+1)
Te2[n+1] = Te2[n] + 0.5*h*(k1+k2)
数值与小数点后第二位不同,正如一阶和二阶方法所预期的那样 h=0.1
。
所以我必须用不同的方法和 Δt 来处理 ODE,但突然间我的函数停止工作,Δt<1。
ODE 是:T(t)'=R*T(t) - K*T(t-δ)
,R 和 K 常量,十进制和小常量。
第一部分是在 δ=0 的情况下处理的,所以它很顺利,没有问题,但现在我在 δ=5 的情况下处理它,突然 ODE 就不起作用了。 当 Δt=1 时,程序可以使用 Euler 方法很好地处理 ODE,但当 Δt=.1 时,它突然停止工作。
它没有崩溃或其他任何事情,但它没有正确计算数字,而是似乎无法识别 δ,或者假定它为零,然后继续这样,直到图形等于δ=0.
我正在使用 Numpy 和 Matplotlib,这是代码:
r = 0.1
R = 0.1
CeCw = 0.27
γ1 = 1
γ2 = 0.164
α = 0.612
δ = 5
Te0 = 1
tf = 240
Δt2 = np.arange(0, tf+.1, .1)
def d(Te, n):
return R*Te[n] - α*γ1*CeCw*Te[n-δ]
Te2 = np.array([Te0])
for n in range(len(Δt2)-1):
if n*.1<=δ:
Te2 = np.append(Te2, 1)
else:
Te2 = np.append(Te2, Te2[n] + .1*d(Te2, n))
如果我将 .1
更改为简单的 1,它会突然再次开始工作(尽管它生成了一个不正确的图形,因为它不是正确的方法)。
我尝试用 Decimal() 包装数字并使用不同的函数,但不知何故 .1 回来删除 δ。
编辑:向前移动并尝试使用 δ=5 实施 Heun 的方法,并且在 Δt=.1 或更低的情况下,它的行为就像 δ=0
这种方程通常称为延迟微分方程并且不是 ODE。专门的求解器通常使用足够高的误差阶插值来获取过去时间的值。
更具体地说,您的代码没有正确实现延迟。 delay δ
是时间差,不是索引差。对于索引差异 m_δ
,您想要 m_δ*h = δ
的实现类型。然后用m_δ
确定初始段的长度和导数函数中的偏移量。
这看起来像
δ = 5
mδ = 50
h = δ/mδ
Te0 = 1
tf = 240
Δt2 = np.arange(0, tf+h, h)
def d(Te, n):
return R*Te[n] - α*γ1*CeCw*Te[n-mδ]
Te2 = np.array(len(Δt2)*[Te0], dtype=float)
for n in range(mδ,len(Δt2)-1):
Te2[n+1] = Te2[n] + h*d(Te2, n)
这确实会产生振荡
使用时间循环的 Heun 方法获得相同的视觉图像
for n in range(mδ,len(Δt2)-1):
k1 = d(Te2, n)
Te2[n+1] = Te2[n] + h*k1
k2 = d(Te2, n+1)
Te2[n+1] = Te2[n] + 0.5*h*(k1+k2)
数值与小数点后第二位不同,正如一阶和二阶方法所预期的那样 h=0.1
。