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

如何在Scipy的solve_ivp中自定义Runge-Kutta每步h后的操作?

在Scipy solve_ivp的步长节点执行自定义操作的实现方法

核心思路

solve_ivp返回的t数组就是求解器自动选择的步长节点(即你提到的[0. 0.11487653 1.26364188 3. ])。如果需要求解过程中实时执行自定义操作,可以利用求解器的events事件机制触发回调;如果仅需求解完成后处理,直接遍历t数组即可。

实时触发的实现示例

下面是用事件函数配合回调,在每个步长节点(除初始点)实时打印hello world的代码:

import numpy as np
from scipy.integrate import solve_ivp

# 定义指数衰减微分方程
def exponential_decay(t, y):
    return -0.5 * y

# 标记步长是否完成
step_finished = False

# 定义事件函数:触发条件为到达非初始步长节点
def step_event(t, y):
    global step_finished
    if t == 0:
        return 1  # 初始点不触发
    step_finished = True
    return 0  # 返回0触发事件

# 配置事件:触发后不终止求解
step_event.terminal = False
step_event.direction = 0

# 自定义操作:打印指定内容
def custom_action(t):
    print(f"hello world at t = {t:.6f}")

# 事件回调函数:触发时执行自定义操作
def event_callback(t, y):
    global step_finished
    if step_finished:
        custom_action(t)
        step_finished = False

# 调用solve_ivp求解
sol = solve_ivp(
    exponential_decay, 
    [0, 3], 
    [1.0], 
    method='DOP853', 
    events=step_event, 
    callback=event_callback
)

# 输出求解器的步长节点
print("求解器实际步长节点:", sol.t)

求解后批量处理的示例

如果不需要实时操作,求解完成后直接遍历步长节点即可:

# 跳过初始点0,遍历其余节点执行操作
for t in sol.t[1:]:
    print(f"hello world at t = {t:.6f}")

关键说明

  • 事件函数的作用是让求解器在每个步长结束时触发回调,terminal=False确保求解过程不会中断。
  • sol.t存储了求解器自动选择的所有步长节点,完全匹配你需要执行操作的目标节点。

内容的提问来源于stack exchange,提问作者eyesight-2020

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:42:49