1.用Euler方法和Runge-Kutta法计算下列微分方程的数值解,画出解的图形,改变步长,对结果进行分析比较
时间: 2024-06-04 21:12:33 浏览: 90
微分方程:y'=y-t^2+1,y(0)=0.5
首先我们需要将微分方程转化为差分方程,即:
y[i+1] = y[i] + h*(y[i]-t[i]^2+1)
其中,h为步长,t[i]为第i个时刻的时间,即t[i] = i*h。
使用Euler方法求解:
def euler(f, y0, t, h):
y = np.zeros(len(t))
y[0] = y0
for i in range(1, len(t)):
y[i] = y[i-1] + h*f(y[i-1], t[i-1])
return y
def f(y, t):
return y - t**2 + 1
y0 = 0.5
t = np.linspace(0, 2, 201)
h = 0.01
y_euler = euler(f, y0, t, h)
使用Runge-Kutta方法求解:
def rk4(f, y0, t, h):
y = np.zeros(len(t))
y[0] = y0
for i in range(1, len(t)):
k1 = h*f(y[i-1], t[i-1])
k2 = h*f(y[i-1]+0.5*k1, t[i-1]+0.5*h)
k3 = h*f(y[i-1]+0.5*k2, t[i-1]+0.5*h)
k4 = h*f(y[i-1]+k3, t[i-1]+h)
y[i] = y[i-1] + (k1 + 2*k2 + 2*k3 + k4)/6
return y
y_rk4 = rk4(f, y0, t, h)
绘制解的图形:
import matplotlib.pyplot as plt
plt.figure(figsize=(8,6))
plt.plot(t, y_euler, label='Euler')
plt.plot(t, y_rk4, label='Runge-Kutta')
plt.legend()
plt.xlabel('t')
plt.ylabel('y')
plt.show()
改变步长,对结果进行分析比较:
h = 0.1
y_euler = euler(f, y0, t, h)
y_rk4 = rk4(f, y0, t, h)
plt.figure(figsize=(8,6))
plt.plot(t, y_euler, label='Euler')
plt.plot(t, y_rk4, label='Runge-Kutta')
plt.legend()
plt.xlabel('t')
plt.ylabel('y')
plt.show()
h = 0.001
y_euler = euler(f, y0, t, h)
y_rk4 = rk4(f, y0, t, h)
plt.figure(figsize=(8,6))
plt.plot(t, y_euler, label='Euler')
plt.plot(t, y_rk4, label='Runge-Kutta')
plt.legend()
plt.xlabel('t')
plt.ylabel('y')
plt.show()
从图形可以看出,随着步长的减小,数值解的精度也随之提高,Euler方法的误差比Runge-Kutta方法大很多,步长为0.1时甚至出现了振荡现象。因此,在求解微分方程时,我们应该尽量选择步长较小的方法,以提高数值解的精度。
阅读全文