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

为什么scipy.integrate.solve_ivp(RK45)的精度远低于自制RK4实现?

为什么scipy.integrate.solve_ivp(RK45)的精度远低于自制RK4实现?

嘿,这个问题确实有点反直觉,毕竟按理论阶数来说5阶的RK45怎么也该比4阶的RK4表现更好对吧?我帮你拆解下可能的原因:

1. 自适应步长的“效率优先” vs 固定小步长的“稳定累积”

你自己写的RK4用的是固定步长0.01,每一步都严格按这个间隔计算;但scipy的RK45是自适应步长算法,它会默认用atol=1e-6和rtol=1e-3的误差容差自动调整步长——只要单步误差在容差范围内,就会尽量用大步长来提升效率。

但你的仿真时长长达300秒(差不多48个圆周周期),属于长期保守系统仿真。虽然RK45单步误差阶数更高,但大步长带来的累积误差在长期运行中会被放大,反而超过固定小步长RK4的累积误差。尤其是圆周运动这种需要严格维持速度大小、角动量的系统,步长的波动会让轨迹的偏离越来越明显。

你可以试试给solve_ivp加更严格的误差限制,比如:

result = solve_ivp(
    fun=get_v_and_a,
    t_span=[0, end_time],
    y0=initial_values,
    method="RK45",
    t_eval=time_points,
    atol=1e-9,
    rtol=1e-12
)

强制RK45用更小的步长,应该能看到它的轨迹贴近圆周了。

2. 插值过程的额外误差

你设置了t_eval=time_points,要求solve_ivp在每个0.01秒的时间点输出结果,但RK45内部是用自适应步长计算的,最终结果是通过插值得到的。如果内部步长比0.01大,插值过程会引入额外误差,这也是它结果不如你自制RK4的原因之一——你的RK4直接在每个时间点计算,没有插值环节。

3. 保守系统的积分特性

你的问题是典型的保守系统(加速度垂直于速度,速度大小始终为10,角动量守恒)。虽然RK4和RK45都不是辛积分方法(专门针对保守系统的积分方法),但固定步长的RK4在长期仿真中对守恒量的保持会更稳定;而自适应步长的RK45因为不断调整步长,相当于频繁改变积分规则,会让守恒量的漂移速度加快,最终轨迹偏离圆周的程度更严重。

如果想让solve_ivp在这类问题上表现更好,除了调小容差,还可以试试用更高阶的自适应步长方法比如DOP853,或者干脆用固定步长的积分实现(不过solve_ivp没有提供固定步长的RK45选项)。

先试试调小atol和rtol,应该就能看到RK45的结果明显改善啦~


备注:内容来源于stack exchange,提问作者平田智剛

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 14:52:57