显式欧拉方法并不像我期望的那样

时间:2017-08-06 21:25:33

标签: 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 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上的文章,我可以绘制函数并验证我得到了相同的情节:Explicit euler。我相信这里我写的方法工作正常。

接下来,我尝试使用它来解决此page上给出的最后一个系统,而不是显示在那里的情节,我得到了这个:

enter image description here

我不确定为什么我的情节与网页上显示的情节不符。当我使用它来解决斜率没有变化的系统时,显式欧拉方法似乎工作正常,但对于振荡函数,它似乎永远不会模仿它。甚至没有显示链接网页上指示的预期错误增益。我不确定我实施的方法有什么问题。

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

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)运行代码,我得到下面的输出,这必须是不正确的。现在使用您提供的更新代码。

enter image description here

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)

1 个答案:

答案 0 :(得分:3)

问题是你错误地提出了函数g,你想解决这个等式:

enter image description here

从我们观察到的地方:

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()

截图:

enter image description here

转储y',右侧的内容是您应该在df函数中放置的内容。

我们将修改变量以保持变量的相同标准,y将成为因变量,t为自变量。

公式2:在这种情况下,公式f'(x)=cos(x)将被重写为:

y'=cos(t)

然后:

def df(t, y):
    return np.cos(t)

enter image description here

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

y' = f(t, y)

然后:

def df(t, y):
    return f(t, y)