Python 显式欧拉方法不';I don’我没有表现出我所期望的样子

Python 显式欧拉方法不';I don’我没有表现出我所期望的样子,python,numerical-methods,numerical,numerical-integration,Python,Numerical Methods,Numerical,Numerical Integration,我在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 t

我在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
在上的文章之后,我可以绘制函数并验证是否得到相同的绘图:。我相信在这里我写的方法是正确的

接下来,我试图用它来解决最后一个系统,而不是图中所示的,我得到:

我不知道为什么我的绘图与网页上显示的不匹配。当我用显式euler方法求解斜率不变的系统时,它似乎工作得很好,但对于振荡函数,它似乎从来没有模仿过它。甚至没有显示链接网页上显示的预期错误增益。我不确定我实现的方法有什么问题

以下是用于绘图和衍生工具的代码:

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)的代码,我会得到下图所示的输出,这肯定是错误的。现在使用您提供的更新代码


问题是,您错误地提出了函数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))

然后根据欧拉方程:

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)
然后:

总之,如果我们有以下形式的方程:

y' = f(t, y)
然后:


方程式是什么?对不起,现在我的手机上显示的方程式应该显示在第二个链接网页的底部。第三个例子?如果是这样的话,把这个等式放在你的帖子里,链接就会断开,你的帖子对任何人都没有帮助,这是一个社区,答案应该为其他人服务。我已经发现了问题,我马上发布了我的答案。主要的错误是你忽略了等式中的变量y,而不是求解原始等式,已解方程:
y'=-0.5*e^(t/2)*sin(5t)+5e^(t/2)*cos(5t)
我确信它是正确的,但我要到早上才能检查它。谢谢。是的,空间用完了,我正在更新这个问题。我用一个更进一步的例子更新了这个问题,以说明它的行为与我预期的两个例子不同。这可能是因为我对该方法的工作原理有误解。我同意你目前的回答解决了我对一个特定方程的问题,但没有澄清我不理解的部分,以帮助我将该技术应用于其他问题。这就是euler方法的优点,其阶数为O(h^2)。误差不会累积,它取决于时间δ=h
y'=cos(t)
def df(t, y):
    return np.cos(t)
y' = f(t, y)
def df(t, y):
    return f(t, y)