1.用Euler方法和Runge-Kutta法计算下列微分方程的数值解,画出解的图形,改变步长,对结果进行分析比较; (1)y'=y+2*x,y(0)=1; (2)
时间: 2024-05-20 17:17:56 浏览: 144
基于matlab的微分方程数值解(Euler方法、预估-校正方法、四节龙格-库塔法源码.m
y'=-y+x+1, y(0)=0.5
(1) Euler方法:
设步长为h,则有:
y1 = y0 + h*y0 = (1+h)*y0
y2 = y1 + h*y1 = (1+h)^2*y0
y3 = y2 + h*y2 = (1+h)^3*y0
...
yn = (1+h)^n*y0
代码实现:
import matplotlib.pyplot as plt
def euler(f, y0, x_range, h):
xs = [x_range[0]]
ys = [y0]
x = x_range[0]
y = y0
while x < x_range[1]:
y += h * f(x, y)
x += h
xs.append(x)
ys.append(y)
return xs, ys
def f(x, y):
return y
xs, ys = euler(f, 1, (0, 2), 0.1)
plt.plot(xs, ys, label='Euler, h=0.1')
xs, ys = euler(f, 1, (0, 2), 0.01)
plt.plot(xs, ys, label='Euler, h=0.01')
plt.legend()
plt.show()
Runge-Kutta法:
一阶Runge-Kutta法就是Euler方法,所以考虑二阶Runge-Kutta法:
y1 = y0 + h/2*f(x0,y0)
y2 = y0 + h*f(x0+h/2, y1)
代码实现:
def rk2(f, y0, x_range, h):
xs = [x_range[0]]
ys = [y0]
x = x_range[0]
y = y0
while x < x_range[1]:
k1 = f(x, y)
k2 = f(x+h/2, y+h/2*k1)
y += h * k2
x += h
xs.append(x)
ys.append(y)
return xs, ys
xs, ys = rk2(f, 1, (0, 2), 0.1)
plt.plot(xs, ys, label='RK2, h=0.1')
xs, ys = rk2(f, 1, (0, 2), 0.01)
plt.plot(xs, ys, label='RK2, h=0.01')
plt.legend()
plt.show()
结果与分析:
对于y'=y,解析解为y=e^x。可以看到,随着步长的减小,两种方法的计算结果越来越接近解析解。同时,Euler方法的误差随着步长的减小呈线性下降,而Runge-Kutta法的误差随着步长的减小呈二次下降,这说明Runge-Kutta法的精度更高。
对于y'=-y+x+1,解析解为y=1+x/2-e^(-x/2)/2。可以看到,两种方法的计算结果在步长较小时比较接近解析解,但随着步长的增大,误差也随之增大。此外,与Euler方法相比,Runge-Kutta法的误差更小,精度更高。
阅读全文