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

scipy库solve_ivp无法完成tspan全区间积分问题求助

问题原因分析
  • 微分方程在t < 5区间无正实平衡点:该区间内所有初值对应的导数dudt恒为负,u会快速下跌到0以下,之后导数绝对值持续为负,解快速趋向负无穷。
  • solve_ivp默认使用自适应步长的RK45求解器,为了保证计算精度会持续缩小步长匹配解的变化速率,当步长低于求解器最小步长阈值时,会提前终止全区间积分,导致返回的sol.t无法覆盖0到10的完整区间。
  • 你编写的绘图代码手动过滤了所有y < 0的结果,即便求解器完成了全区间积分,也只会绘制u首次变负之前的部分,进一步放大了“积分提前停止”的观感。
解决方案

方案1:修改微分方程避免非物理负值

调整导数计算逻辑,限制u<=0时导数为0,避免解爆炸触发步长过小问题,修改后的dudt如下:

def dudt(t, u):
    du = u*(1-u/12) - 4*np.heaviside(-(t-5), 1)
    # 当u小于等于0时强制导数为0,避免解趋向负无穷
    du[u <= 0] = 0
    return du

修改后直接运行即可完成全区间积分,绘图时无需手动过滤负值也能得到正确结果。

方案2:调整求解器参数适配带负值的解

如果业务需要保留负值的计算结果,可以更换适配刚性求解器,同时放宽精度阈值,避免步长提前收缩过小:

sol = solve_ivp(
    dudt, (0, 10), ic, 
    t_eval=np.linspace(0, 10, 10000),
    method='Radau', # 更换为适合刚性问题的求解器
    atol=1e-6,
    rtol=1e-3
)

绘图时删除手动过滤负值的逻辑,即可看到完整区间的解曲线。

方案3:添加事件触发终止(可选)

如果需要在u降到0时就终止积分,可以添加事件函数:

def cross_zero(t, u):
    return u.min() # 任意分量降到0时触发事件
cross_zero.terminal = True
cross_zero.direction = -1

sol = solve_ivp(dudt, (0, 10), ic, t_eval=np.linspace(0, 10, 10000), events=cross_zero)

内容的提问来源于stack exchange,提问作者An Ignorant Wanderer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 07:18:06