我在python中实现了以下显式euler方法:
def explicit_euler(df, x0, h, N):
"""Solves an ODE IVP using the Explicit Euler method.
Keyword arguments:
df - The derivative of the system you wish to solve.
x0 - The initial value of the system you wish to solve.
h - The step size.
N - The number off steps.
"""
x = np.zeros(N)
x[0] = x0
for i in range(0, N-1):
x[i+1] = x[i] + h * df(x[i])
return x
关于wikipedia上的文章,我可以绘制函数并验证我得到了相同的情节:。我相信这里我写的方法工作正常。
接下来,我尝试使用它来解决此page上给出的最后一个系统,而不是显示在那里的情节,我得到了这个:
我不确定为什么我的情节与网页上显示的情节不符。当我使用它来解决斜率没有变化的系统时,显式欧拉方法似乎工作正常,但对于振荡函数,它似乎永远不会模仿它。甚至没有显示链接网页上指示的预期错误增益。我不确定我实施的方法有什么问题。
以下是用于绘图和衍生的代码:
def g(t):
return -0.5 * np.exp(t * 0.5) * np.sin(5 * t) + 5 * np.exp(t * 0.5)
* np.cos(5 * t)
h = 0.001
x0 = 0
tn = 4
N = int(tn / h)
x = ee.explicit_euler(f, x0, h, N)
t = np.arange(0, tn, h)
fig = plt.figure()
plt.plot(t, x, label="Explicit Euler")
plt.plot(t, (np.exp(0.5 * t) * np.sin(5 * t)), label="Analytical
solution")
#plt.plot(t, np.exp(0.5 * t), label="Analytical solution")
plt.xlabel('Timesteps t')
plt.ylabel('x(t)=e^(0.5*t) * sin(5*t)')
plt.legend()
plt.grid()
plt.show()
编辑:
这里要求的是我正在应用该方法的当前等式:
y'-y=-0.5*e^(t/2)*sin(5t)+5e^(t/2)*cos(5t)
其中y(0)= 0。
我想明确指出,这种行为并不仅仅发生在这个方程中,而是所有斜率都有符号变化或振荡行为的方程式。
编辑2: 好,谢谢。是的,下面的代码确实有效。但我还有一个问题。在我用于指数函数的简单示例中,我定义了一个方法:
def f(x):
return x
系统f'(x)= x。这给出了我的第一张图表的输出,看起来是正确的。然后我定义了另一个函数:
def k(x):
return cos(x)
对于系统f'(x)= cos(x),这不会给出预期的输出。但是当我将函数定义更改为
时def k(t, x):
return cos(t)
我得到了预期的输出。如果我改变我的功能
def f(t, x):
return t
输出错误。我是否总是在一个时间步骤中实际评估函数,并且只是偶然的系统x' = x在每个时间步,该值只是x的值?
我已经理解,Euler方法使用先前计算的值的值来获得下一个值。但是如果我为我的函数k(x)= cos(x)运行代码,我得到下面的输出,这必须是不正确的。现在使用您提供的更新代码。
def k(t, x):
return np.cos(x)
h = 0.1 # Step size
x0 = (0, 0) # Initial point of iteration
tn = 10 # Time step to iterate to
N = int(tn / h) # Number of steps
x = ee.explicit_euler(k, x0, h, N)
t = np.arange(0, tn, h)
答案 0 :(得分:3)
问题是你错误地提出了函数g,你想解决这个等式:
从我们观察到的地方:
y' = y -0.5*e^(t/2)*sin(5t)+5e^(t/2)*cos(5t)
然后我们将函数f(t, y) = y -0.5*e^(t/2)*sin(5t)+5e^(t/2)*cos(5t)
定义为:
def f(t, y):
return y -0.5 * np.exp(t * 0.5) * np.sin(5 * t) + 5 * np.exp(t * 0.5) * np.cos(5 * t)
迭代的初始点是f0=(t(0), y(0))
:
f0 = (0, 0)
然后来自欧拉方程:
def explicit_euler(df, x0, h, N):
"""Solves an ODE IVP using the Explicit Euler method.
Keyword arguments:
df - The derivative of the system you wish to solve.
x0 - The initial value of the system you wish to solve.
h - The step size.
N - The number off steps.
"""
x = np.zeros(N)
t, x[0] = x0
for i in range(0, N-1):
x[i+1] = x[i] + h * df(t ,x[i])
t += h
return x
完整代码:
def explicit_euler(df, x0, h, N):
"""Solves an ODE IVP using the Explicit Euler method.
Keyword arguments:
df - The derivative of the system you wish to solve.
x0 - The initial value of the system you wish to solve.
h - The step size.
N - The number off steps.
"""
x = np.zeros(N)
t, x[0] = x0
for i in range(0, N-1):
x[i+1] = x[i] + h * df(t ,x[i])
t += h
return x
def df(t, y):
return -0.5 * np.exp(t * 0.5) * np.sin(5 * t) + 5 * np.exp(t * 0.5) * np.cos(5 * t) + y
h = 0.001
f0 = (0, 0)
tn = 4
N = int(tn / h)
x = explicit_euler(df, f0, h, N)
t = np.arange(0, tn, h)
fig = plt.figure()
plt.plot(t, x, label="Explicit Euler")
plt.plot(t, (np.exp(0.5 * t) * np.sin(5 * t)), label="Analytical solution")
#plt.plot(t, np.exp(0.5 * t), label="Analytical solution")
plt.xlabel('Timesteps t')
plt.ylabel('x(t)=e^(0.5*t) * sin(5*t)')
plt.legend()
plt.grid()
plt.show()
截图:
转储y'
,右侧的内容是您应该在df函数中放置的内容。
我们将修改变量以保持变量的相同标准,y
将成为因变量,t
为自变量。
公式2:在这种情况下,公式f'(x)=cos(x)
将被重写为:
y'=cos(t)
然后:
def df(t, y):
return np.cos(t)
总之,如果我们有以下形式的等式:
y' = f(t, y)
然后:
def df(t, y):
return f(t, y)