首页 > 解决方案 > scipy中具有时变系数的ODE

问题描述

我正在评估一组具有时变系数的 ODE

def deriv(y, t, N, coefficients):
    S, I, R = y
    dSdt = coefficients['beta'](t) * S * I / N * -1
    dIdt = coefficients['beta'](t) * S * I / N - coefficients['gamma']* I
    dRdt = coefficients['gamma'] * I
    return dSdt, dIdt, dRdt

特别是,我在预先计算的数组中有“beta”值,其大小等于 int(max(t))。

coefficients = {'beta' : beta_f,'gamma':0.1}
def beta_f(t):
     return  mybetas.iloc[int(t)]

# Initial conditions vector
y0 = (S0, I0, R0)
# Integrate the SIR equations over the time grid, t.
ret = odeint(deriv,y0,t,args=(N,coefficients))

当我运行 odeint 时,它还会评估超出 max(t) 的值,从而在 beta_f 中引发索引越界错误。如何限制 odeint 的评估跨度?

标签: pythonnumpyscipyode

解决方案


由于len(mybetas) == int(max(t)),即使 t 的值不超过 max(t),您也会得到越界错误。例如mybetas.iloc[int(max(t))],即使int(max(t)) <= max(t)对于t.

但就您而言,odeint确实确实检查了集成领域之外的一些值。就在几周前,我不得不处理与您类似的问题,以下关于 stackoverflow 的两次讨论非常有帮助:

integration.ode 将 t0 值设置在我的数据范围之外

求解具有不连续输入/强制数据的 ODE

第二个链接解释了为什么在循环odeint中一个接一个地在每个单独的整数时间步上求解 ODE 在计算上可能会更快,而不是让处理由 beta 值的跳跃引起的导数的不连续性。forodeint

否则,如果这适合您的研究案例,您可以插值您的 beta,并让函数beta_f返回 beta 的插值。当然,您必须将插值域稍微扩展到积分域之外,因为odeint可能想要评估一些t大于的导数max(t)


推荐阅读