欧拉数值方法(lesson 2)
一种一阶数值方法,用以对给定初值的常微分方程求解
对于一阶常系数微分方程 y ′ = f ( x , y ) y'=f(x,y) y′=f(x,y)
理论推导:
二元函数
f
(
x
,
y
)
f(x,y)
f(x,y)可以看做y的斜率
给定初始值
y
(
a
)
=
b
y(a) = b
y(a)=b ,即
(
a
,
b
)
(a,b)
(a,b), 步长
h
h
h,可以求出下一临近点的位置
用公式表示:
x n + 1 = x n + h x_{n+1}=x_{n}+h xn+1=xn+h
y n + 1 = y n + h ∗ A n y_{n+1}=y_{n}+h*An yn+1=yn+h∗An
A n = f ( x n , y n ) An=f(x_{n},y_{n}) An=f(xn,yn)
不断进行迭代就可以汇出
y
y
y的图像
此时的图像误差较大
当
y
′
′
<
0
y''<0
y′′<0时欧拉数值法的结果会偏大
当
y
′
′
>
0
y''>0
y′′>0时欧拉数值法的结果会偏小
优化欧拉数值法
- 减小步长 h h h
- 采用更高阶(这里以四阶为例)
x n + 1 = x n + h x_{n+1}=x_{n}+h xn+1=xn+h
y n + 1 = y n + h ∗ ( A n + 2 B n + 2 C n + D n ) ∗ 1 / 6 y_{n+1}=y_{n}+h*(An+2Bn+2Cn+Dn)*1/6 yn+1=yn+h∗(An+2Bn+2Cn+Dn)∗1/6
A n = f ( x n , y n ) An=f(x_{n},y_{n}) An=f(xn,yn)
B n = f ( x n + h , h ∗ A n ) Bn=f(x_{n}+h,h*An) Bn=f(xn+h,h∗An)
C n = f ( x n + 2 h , h ∗ ( A n + B n ) ) Cn=f(x_{n}+2h,h*(An+Bn)) Cn=f(xn+2h,h∗(An+Bn))
D n = f ( x n + 3 h , h ∗ ( A n + B n + C n ) ) Dn=f(x_{n}+3h,h*(An+Bn+Cn)) Dn=f(xn+3h,h∗(An+Bn+Cn))
import matplotlib.pyplot as plt
#y' = x^2 - y^2
#f(x, y)=x^2 - y^2
def An(x, y):
return x**2 - y**2
def Bn(x, y, h):
return (x + h)**2 - (y + h*An(x, y))**2
def Cn(x, y, h):
return (x + 2*h)**2 - (y + h*(An(x, y) + Bn(x, y, h)))**2
def Dn(x, y, h):
return (x + 3*h)**2 - (y + h*(An(x, y) + Bn(x, y, h) + Cn(x, y, h)))**2
def One():
X = []
Y = []
x0, y0 = 0, 1
iteration = 10000
h = 0.0002
for i in range(iteration):
x1 = x0 + h
y1 = y0 + h*An(x0, y0)
X.append(x1)
Y.append(y1)
x0, y0 = x1, y1
plt.plot(X, Y)
plt.title('One')
plt.show()
def Two():
X = []
Y = []
x0, y0 = 0, 1
iteration = 10000
h = 0.0002
for i in range(iteration):
x1 = x0 + h
y1 = y0 + h*(An(x0, y0) + Bn(x0, y0, h))*.5
X.append(x1)
Y.append(y1)
x0, y0 = x1, y1
plt.plot(X, Y)
plt.title('Two')
plt.show()
def Four():
X, Y = [], []
x0, y0 = 0, 1
iteration = 10000
h = .0002
for i in range(iteration):
x1 = x0 + h
y1 = y0 + h*(An(x0,y0) + 2*Bn(x0,y0,h)
+ 2*Cn(x0,y0,h) + Dn(x0,y0,h))*(1/6)
X.append(x1)
Y.append(y1)
x0, y0 = x1, y1
plt.plot(X, Y)
plt.title('Four')
plt.show()
if __name__ == '__main__' :
One();
Two();
Four();