You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于显式/隐式欧拉及梯形法求解ODE的Python代码正确性问询

常微分方程数值解法代码问题分析与修正

问题背景

需要数值求解常微分方程:

y′(t)=(0.5−t)(y(t) + 1), y(0) = 1

采用显式欧拉法、隐式欧拉法、梯形法并用Python实现,现有代码结果与同学存在差异,需验证实现正确性。

代码问题分析

  • 隐式欧拉法实现错误
    隐式欧拉法的核心公式是:
    $$y_{n+1} = y_n + h \cdot f(t_{n+1}, y_{n+1})$$
    对于当前线性ODE,可直接推导得到$y_{n+1}$的解析表达式:
    将$f(t_{n+1}, y_{n+1})=(0.5-t_{n+1})(y_{n+1}+1)$代入公式整理得:
    $$y_{n+1} = \frac{y_n + h(0.5-t_{n+1})}{1 - h(0.5-t_{n+1})}$$
    原代码用显式欧拉的预测值代入$f$计算,并非真正的隐式欧拉,属于近似迭代的错误写法。

  • 绘图代码存在未定义变量
    原代码中plt.quiver(T, Y, U, V, angles='xy')一行的T、Y、U、V均未定义,会导致运行报错,需删除该行。

  • 显式欧拉法与梯形法实现正确
    显式欧拉的公式$y_{n+1}=y_n + h\cdot f(t_n,y_n)$、梯形法的公式$y_{n+1}=y_n + \frac{h}{2}[f(t_n,y_n)+f(t_{n+1},y_n+h\cdot f(t_n,y_n))]$均正确实现。

修正后的完整代码

import numpy as np
import matplotlib.pyplot as plt

# 通用求解器
def solveIVP(f, tspan, y0, h, solver):
    t = np.arange(tspan[0], tspan[1]+h, h)
    y = np.zeros(len(t))
    y[0] = y0
    
    for n in range(len(t)-1):
        y[n+1] = solver(f, t[n], y[n], h, t[n+1])  # 传入t_{n+1}给隐式欧拉
    return t, y

# 解析解
def y_function(t):
    return 2 * np.exp(0.5*t - 0.5*t**2) - 1
t_values = np.linspace(-1, 2, 100)
y_analytical = y_function(t_values)

# 显式欧拉法
def explicit_euler(f, tn, yn, h, t_next=None):
    return yn + h * f(tn, yn)

# 隐式欧拉法(修正版)
def implicit_euler(f, tn, yn, h, t_next):
    # 针对当前线性ODE直接求解y_{n+1}
    a = 1 - h*(0.5 - t_next)
    b = yn + h*(0.5 - t_next)
    return b / a

# 梯形法
def trapezoid(f, tn, yn, h, t_next=None):
    k1 = f(tn, yn)
    k2 = f(tn + h, yn + h * k1)
    return yn + h / 2 * (k1 + k2)

# 定义ODE右端函数
def f(t,y):
    return (0.5-t)*(y+1)

# 求解参数
tspan = [0, 1]
y0 = 1
h = 0.2

# 求解各方法
t, y_e = solveIVP(f, tspan, y0, h, explicit_euler)
t, y_i = solveIVP(f, tspan, y0, h, implicit_euler)
t, y_t = solveIVP(f, tspan, y0, h, trapezoid)

# 打印结果表格
print("|   t   | 显式欧拉 | 隐式欧拉 | 梯形法 | 解析解 |")
print("|:-----:|:-------:|:-------:|:-----:|:-----:|")
for n in range(len(t)):
    y_an = y_function(t[n])
    print(f"| {t[n]:0.3f} | {y_e[n]:0.4f} | {y_i[n]:0.4f} | {y_t[n]:0.4f} | {y_an:0.4f} |")

# 绘图
fig, ax = plt.subplots(figsize=(10,6))
plt.plot(t_values, y_analytical, "k-", label="解析解")
plt.plot(t, y_e, "bo-", label="显式欧拉法")
plt.plot(t, y_i, "go-", label="隐式欧拉法")
plt.plot(t, y_t, "ro-", label="梯形法")
plt.xlim(-1, 2)
plt.ylim(-1, 2)
plt.xlabel("$t$", fontsize=16)
plt.ylabel("$y$", fontsize=16)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.legend(fontsize=14)
plt.grid(alpha=0.3)
plt.show()

结果说明

修正后,三种数值方法的结果会与解析解更贴近:

  • 显式欧拉法为向前一步预测,步长较小时误差可控;
  • 隐式欧拉法为向后一步求解,对于该ODE稳定性更好;
  • 梯形法为二阶精度方法,结果最接近解析解。

内容的提问来源于stack exchange,提问作者juzze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:42:31