Euler 方法:解 ODE 的简单利器

在研究常微分方程(Ordinary Differential Equation, ODE)时,我们常常需要数值方法来求解,因为许多 ODE 无法直接得到解析解。Euler 方法(Euler Method)是最简单、最直观的数值解法之一,属于一阶方法,特别适合初学者理解。本篇博客将面向深度学习研究者,介绍 Euler 方法的原理、推导及其应用,并提供 Python 代码实现,帮助你在实践中快速上手。


什么是 Euler 方法?

Euler 方法是一种用于求解初值问题的数值方法。给定一个一阶 ODE:
d x ( t ) d t = f ( t , x ) , x ( t 0 ) = x 0 \frac{dx(t)}{dt} = f(t, x), \quad x(t_0) = x_0 dtdx(t)=f(t,x),x(t0)=x0
其中:

  • ( x ( t ) x(t) x(t) ) 是待求解的函数。
  • ( f ( t , x ) f(t, x) f(t,x) ) 是导数函数。
  • ( x 0 x_0 x0 ) 是初始条件。

Euler 方法通过离散化时间,将连续的变化近似为一系列小步迭代:
x i + 1 = x i + α ⋅ f ( t i , x i ) , i = 0 , 1 , … , N − 1 x_{i+1} = x_i + \alpha \cdot f(t_i, x_i), \quad i = 0, 1, \dots, N-1 xi+1=xi+αf(ti,xi),i=0,1,,N1

  • ( α \alpha α ):步长(step size),控制每次迭代的时间增量。
  • ( t i = t 0 + i α t_i = t_0 + i \alpha ti=t0+iα ):离散时间点。
  • ( x i x_i xi ):( t i t_i ti ) 时刻的近似解。

原理:从导数到离散
导数的定义

导数的本质是变化率:
d x ( t ) d t = lim ⁡ Δ t → 0 x ( t + Δ t ) − x ( t ) Δ t \frac{dx(t)}{dt} = \lim_{\Delta t \to 0} \frac{x(t + \Delta t) - x(t)}{\Delta t} dtdx(t)=Δt0limΔtx(t+Δt)x(t)
Euler 方法假设 ( Δ t = α \Delta t = \alpha Δt=α) 是一个有限小步长,近似为:
x ( t + α ) − x ( t ) α ≈ f ( t , x ( t ) ) \frac{x(t + \alpha) - x(t)}{\alpha} \approx f(t, x(t)) αx(t+α)x(t)f(t,x(t))
两边乘以 ( α \alpha α):
x ( t + α ) ≈ x ( t ) + α f ( t , x ( t ) ) x(t + \alpha) \approx x(t) + \alpha f(t, x(t)) x(t+α)x(t)+αf(t,x(t))
这正是 Euler 方法的迭代公式,用当前点的斜率 ( f ( t , x ) f(t, x) f(t,x) ) 预测下一步的位置。

几何直觉

想象 ( x ( t ) x(t) x(t) ) 是一条曲线,( f ( t , x ) f(t, x) f(t,x) ) 是曲线的切线斜率。Euler 方法沿着切线走一小步 ( α \alpha α),然后在新的位置重新计算斜率,继续前进。虽然简单,但这种“直线逼近”在步长足够小时能很好地追踪曲线。


示例:用 Euler 方法解 ODE

考虑一个具体的 ODE:
d x ( t ) d t = x ( t ) + t 2 − 2 t + 1 , x ( 0 ) = x 0 \frac{dx(t)}{dt} = \frac{x(t) + t^2 - 2}{t + 1}, \quad x(0) = x_0 dtdx(t)=t+1x(t)+t22,x(0)=x0
对应的 ( f ( t , x ) = x + t 2 − 2 t + 1 f(t, x) = \frac{x + t^2 - 2}{t + 1} f(t,x)=t+1x+t22 )。用 Euler 方法迭代:
x i + 1 = x i + α ⋅ x i + t i 2 − 2 t i + 1 x_{i+1} = x_i + \alpha \cdot \frac{x_i + t_i^2 - 2}{t_i + 1} xi+1=xi+αti+1xi+ti22

  • ( t i = i α t_i = i \alpha ti=iα )(从 ( t 0 = 0 t_0 = 0 t0=0 ) 开始)。
  • 每次用当前 ( x i x_i xi ) 和 ( t i t_i ti ) 计算斜率,更新 ( x i + 1 x_{i+1} xi+1 )。

Python 代码实现

以下是用 Python 实现 Euler 方法的代码,以上述 ODE 为例:

import numpy as np
import matplotlib.pyplot as plt

# 定义导数函数 f(t, x)
def f(t, x):
    return (x + t**2 - 2) / (t + 1)

# Euler 方法求解 ODE
def euler_method(t0, x0, alpha, t_end):
    """
    Args:
        t0: 初始时间
        x0: 初始值 x(t0)
        alpha: 步长
        t_end: 结束时间
    Returns:
        t_values: 时间点数组
        x_values: 解的数组
    """
    # 计算步数
    N = int((t_end - t0) / alpha)
    t_values = np.linspace(t0, t_end, N + 1)
    x_values = np.zeros(N + 1)
    x_values[0] = x0
    
    # Euler 迭代
    for i in range(N):
        t_i = t_values[i]
        x_i = x_values[i]
        x_values[i + 1] = x_i + alpha * f(t_i, x_i)
    
    return t_values, x_values

# 参数设置
t0 = 0.0      # 初始时间
x0 = 1.0      # 初始值
alpha = 0.1   # 步长
t_end = 2.0   # 结束时间

# 运行 Euler 方法
t_values, x_values = euler_method(t0, x0, alpha, t_end)

# 可视化
plt.plot(t_values, x_values, label=f'Euler Method (step size = {alpha})', marker='o')
plt.xlabel('t')
plt.ylabel('x(t)')
plt.title('Euler Method for dx/dt = (x + t^2 - 2) / (t + 1)')
plt.legend()
plt.grid(True)
plt.show()
代码说明
  1. 导数函数f(t, x) 定义了 ODE 的右端。
  2. Euler 方法euler_method 函数实现迭代,从 ( t 0 t_0 t0 ) 到 ( t end t_{\text{end}} tend ) 计算 ( x ( t ) x(t) x(t) )。
  3. 可视化:用 Matplotlib 绘制解的轨迹,步长为 0.1。

运行后,你会看到一条从 ( x ( 0 ) = 1 x(0) = 1 x(0)=1 ) 开始随时间变化的曲线。可以通过调整 ( α \alpha α)(如 0.01 或 0.5)观察步长对精度的影响。

在这里插入图片描述


Euler 方法的优缺点
优点
  • 简单直观:只需当前点的斜率和步长,易于实现。
  • 计算高效:每次迭代仅需一次函数评估。
缺点
  • 一阶精度:误差与 ( α \alpha α) 成正比(全局误差 ( O ( α ) O(\alpha) O(α) )),步长大时可能偏离真实解。
  • 不稳定:对于某些“刚性”(stiff)ODE,Euler 方法可能发散,需要更小步长或更高阶方法(如 Runge-Kutta)。

与深度学习的联系
  • 优化算法:梯度下降可以看作 ODE ( d x d t = − ∇ f ( x ) \frac{dx}{dt} = -\nabla f(x) dtdx=f(x) ) 的 Euler 近似。
  • 扩散模型:DDPM 和 SMLD 的 SDE 求解(如逆向采样)常用 Euler-Maruyama 方法(Euler 方法的随机版本)。

总结

Euler 方法通过:
x i + 1 = x i + α ⋅ f ( t i , x i ) x_{i+1} = x_i + \alpha \cdot f(t_i, x_i) xi+1=xi+αf(ti,xi)
将 ODE 的连续变化离散化为一步步迭代。它简单易用,是理解数值解法的基础。尽管精度有限,但在步长较小时仍能有效逼近解。对于深度学习研究者来说,掌握 Euler 方法不仅有助于理解 ODE 的求解,还为优化和生成模型中的连续方法打下基础。试试上面的代码,调整参数,看看解如何变化吧!


注:本文以直观解释为主,代码可直接运行验证。

后记

2025年3月9日16点54分于上海,在Grok 3大模型辅助下完成。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐