繁体   English   中英

Python 中的显式(前向)和隐式(后向)欧拉方法

[英]Explicit (Forward) and Implicit (Backward) Euler Methods in Python

我正在尝试实现显式和隐式 Euler 方法来近似以下 ODE 的解决方案:

dx/dt = -kx ,其中k = cos(2 pi t) ,并且x(0) = 1

Euler 的方法使用有限差分来逼近导数:

dx/dt = (x(t+dt) - x(t)) / dt

forward方法根据先前的解x(t)显式计算x(t+dt ) :

x(t+dt) = x(t) + f(x,t)dt

反向方法是隐式的,通过求解涉及系统x(t)的当前 state 和后一个x(t+dt)的方程来找到解x( t+dt) :

x(t) = x(t+dt) - f(x,(t+dt))dt

我的近似解的代码dx/dt = -kx , x(0) = 1并将其与实际解决方案一起绘制如下:

### Import Necessary Packages
import matplotlib.pyplot as plt
import numpy as np
%config InlineBackend.figure_format = 'retina'
plt.rcParams['figure.figsize'] = (10.0, 6.0)

### Defining Basic Data
t0 = 0                                # initial t
tf = 4*np.pi                          # final t       
N = 1000                              # factor affecting time step size
dt = (4*np.pi)/N                      # time step size (as a factor of N)
t = np.linspace(t0,tf,N)              # defining a vector of t values from t0 to tf  
x0 = 1                                # initial x
x = np.zeros([N])                     # initializing array for x values
f = lambda x,t: -np.cos(2*np.pi*t)*x  # defining f(x,t) on RHS on ODE

### Define a Function for Euler's Forward Method ###
def ForwardEuler(f,x0,t):
    x[0] = x0
    for i in range(1,N-1):
        x[i+1] = x[i] + (f(x[i],t[i]))*dt
    return x

# Plot Solution
forward = ForwardEuler(f,x0,t)
actual = 1/np.exp((1/(2*np.pi))*np.sin(2*np.pi*t))
plt.plot(t,actual,'r-',t,forward,'b-')
plt.legend(['Actual','Backward Euler'])
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title("Solution to $x'=-kx$,   $x$(0)=1")
plt.grid(True);plt.show()

我的问题在于如何调整代码的 for 循环部分以显示后向 Euler 方法而不是前向 Euler 方法。 我遇到了麻烦,因为方程式要求您知道 x[i+1] 才能求解 x[i+1]。

我相信向后的 for 循环将是下面给出的,但我不确定:

def BackwardEuler(f,x0,t):
    x[0] = x0
    for i in range(1,N-1):
        x[i] = x[i+1] - (f(x[i+1],t[i+1]))*dt
    return x

我在网上找到的资源很少,完全不知所措。 对此的任何帮助将不胜感激! 谢谢!

通常,对于反向欧拉和梯形规则,您将表达式写为方程(或方程组),然后求解它(即找到它的零点)。 零表示x[i+1]的值。

例如,对于Backward Euler ,系统为:

x[i+1] = x[i] - (f(x[i+1],t[i+1]))*dt

您可以将其重写为:

x[i+1] - x[i] + dt*f(x[i+1], t[i+1]) = 0

x[i]t[i+1]的值是已知的。 唯一未知的是x[i+1] 你可以用数字方式求解这个系统(使用类似fsolve的东西),解决方案就是你的x[i+1] 当然,您有可能得到不止一种解决方案。 您必须 select 适合您的问题(即x不能是虚数,或者x不能是负数等)

相同的技术可以应用于梯形规则,系统为:

x[i+1] - x[i] - (f(x[i],t[i]) - f(x[i+1],t[i+1]))*(dt/2) = 0

PS :查看计算科学 StackExchange 它更适合与数值和计算方法相关的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM