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

solve_ivp运行单函数封装模型时提取中间变量及结果异常问题求助

solve_ivp 单函数内捕获中间变量解决方案

异常原因说明

  • 输出时间点多于预期:solve_ivp默认使用自适应步长求解器,求解过程中会多次调用ODE函数完成步长试探、误差校验等内部操作,并非仅在t_eval指定的时间点调用,无差别追加会记录所有内部调用的中间值。
  • 初始体重数值错误:求解器启动阶段会执行初始步长试探,可能先调用t<0的试算点,无过滤的追加逻辑会把试算值作为第一条记录覆盖真实初始值。

实现思路

通过solve_ivp的args参数传入两个额外参数:目标输出时间点列表、用于存储中间变量的可变容器,在ODE函数内仅当当前调用时间与目标时间点满足浮点数相等判定时,才将中间变量写入容器,既不需要拆分模型函数,也能避免记录试算数据。

可运行完整示例

import numpy as np
from scipy.integrate import solve_ivp

# 模型参数配置字典
params = {
    "initial_weight": 60,  # 初始体重 单位g
    "intake_coef": 0.05,   # 摄食系数
    "metab_coef": 0.02,    # 代谢系数
    "target_t": [1,2,3,4,5]# 目标输出时间点
}

# 单个函数封装所有模型逻辑
def growth_model(t, y, params, storage):
    weight = y[0]
    # 中间变量计算
    daily_intake = params["intake_coef"] * weight  # 日摄食量 中间变量
    daily_metab = params["metab_coef"] * weight    # 日代谢消耗 中间变量
    # 微分方程计算
    dweight_dt = daily_intake - daily_metab
    
    # 仅匹配目标时间点时存储中间变量
    for target in params["target_t"]:
        if np.isclose(t, target, atol=1e-6):
            storage["t"].append(t)
            storage["weight"].append(weight)
            storage["daily_intake"].append(daily_intake)
            storage["daily_metab"].append(daily_metab)
            break
    return [dweight_dt]

if __name__ == "__main__":
    # 初始化中间变量存储容器
    mid_storage = {
        "t": [],
        "weight": [],
        "daily_intake": [],
        "daily_metab": []
    }
    # 求解微分方程
    sol = solve_ivp(
        fun=growth_model,
        t_span=(0, 5),
        y0=[params["initial_weight"]],
        t_eval=params["target_t"],
        args=(params, mid_storage),
        method="RK45"
    )
    # 输出结果验证
    print("求解器返回的体重结果:", sol.y[0])
    print("存储的中间变量时间点:", mid_storage["t"])
    print("存储的对应体重值:", mid_storage["weight"])
    print("存储的日摄食量中间变量:", mid_storage["daily_intake"])

方案验证说明

  • 存储的mid_storage内的所有数据长度均等于目标时间点数量,不会产生多余的试算数据
  • 存储的初始时间点对应的体重值与solve_ivp返回的结果完全一致,初始设定的60g会作为求解的初始状态正确参与计算,t=0的状态可直接从params["initial_weight"]获取,也可将0加入target_t列表直接存储
  • 所有模型计算逻辑均封装在growth_model单个函数内,无需拆分实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:12:03