I'd like to implement Euler's method (the explicit and the implicit one) ( https://en.wikipedia.org/wiki/Euler_method)执行2次连续的onclick操作:
x(t)' = q(x_M -x(t))x(t)
x(0) = x_0
其中q,x_M和x_0是实数。
我已经知道该方法的(理论上)实现。但我无法弄清楚我可以插入/更改模型的位置。 有人可以帮忙吗?
编辑:你是对的。我没理解这个方法。现在,几个小时后,我想我真的明白了!使用显式方法,我很确定(尽管如此:任何人都可以查看我的代码吗?)通过隐式实现,我不太确定它是否正确。可以请任何人看看隐式方法的实现,并给我一个反馈什么是正确/不好?
def explizit_euler():
''' x(t)' = q(xM -x(t))x(t)
x(0) = x0'''
q = 2.
xM = 2
x0 = 0.5
T = 5
dt = 0.01
N = T / dt
x = x0
t = 0.
for i in range (0 , int(N)):
t = t + dt
x = x + dt * (q * (xM - x) * x)
print '%6.3f %6.3f' % (t, x)
def implizit_euler():
''' x(t)' = q(xM -x(t))x(t)
x(0) = x0'''
q = 2.
xM = 2
x0 = 0.5
T = 5
dt = 0.01
N = T / dt
x = x0
t = 0.
for i in range (0 , int(N)):
t = t + dt
x = (1.0 / (1.0 - q *(xM + x) * x))
print '%6.3f %6.3f' % (t, x)
答案 0 :(得分:1)
先发制人注意事项:虽然总体思路应该是正确的,但我在编辑框中完成了所有代数,因此可能存在错误。在使用任何非常重要的东西之前,请自行检查。
我不确定你是如何来到"隐含的"式
x = (1.0 / (1.0 - q *(xM + x) * x))
但这是错误的,你可以通过比较你的"显式"来检查它。并且"隐含"结果:他们应该 稍微 分歧但是使用这个公式他们会大幅度地分歧。
要理解隐式Euler方法,首先应该在显式方法后面获得 idea 。这个想法非常简单,并在维基的Derivation部分进行了解释:由于衍生y'(x)
是(y(x+h) - y(x))/h
的限制,因此您可以将y(x+h)
近似为{{1}假设我们的原始微分方程是
y(x) + h*y'(x)
h
请注意,这只是一个近似值而不是精确值的原因是,即使在小范围内y'(x) = F(x, y(x))
,导数[x, x+h]
也会略有变化。这意味着如果你想得到y'(x)
更好的近似值,你需要更好的逼近"平均值"范围y(x+h)
范围内的衍生y'(x)
。我们称之为近似[x, x+h]
。这种改进的一个想法是同时找到y'
和y'
同时说我们想要找到y(x+h)
和y'
y(x+h)
实际上是y'
(即最后的衍生物)。这导致以下方程组:
y'(x+h)
相当于单个"隐含"方程:
y'(x+h) = F(x+h, y(x+h))
y(x+h) = y(x) + h*y'(x+h)
它被称为"隐含"因为此处目标y(x+h) - y(x) = h * F(x+h, y(x+h))
也是y(x+h)
的一部分。请注意,wiki文章的Modifications and extensions部分提到了非常类似的等式。
所以现在谈谈你的方程式变为
F
或等效
x(t+dt) - x(t) = dt*q*(xM -x(t+dt))*x(t+dt)
这是一个带有两个解的二次方程式:
dt*q*x(t+dt)^2 + (1 - dt*q)*x(t+dt) - x(t) = 0
显然,我们希望解决方案是"关闭"到x(t+dt) = [(dt*q - 1) ± sqrt((dt*q - 1)^2 + 4*dt*q*x(t))]/(2*dt*q)
x(t)
解决方案。所以代码应该是这样的:
+