【问题标题】:Solving differential equations with a function called at each time step使用在每个时间步调用的函数求解微分方程
【发布时间】:2021-05-19 14:51:48
【问题描述】:

方程组

def SEIRD_gov(y, t, beta_0, c_1, c_2, sigma, gamma, dr, ro, tg, g_1, g_2, ind):
    S, E, I, R, D = y
    
    dSdt = -beta_gov(t, beta_0, c_1, c_2, tg, g_1, g_2, ind) * S * I/N
    dEdt = beta_gov(t, beta_0, c_1, c_2, tg, g_1, g_2, ind) * I * S/N - sigma * E
    dIdt = sigma * E - (1 - dr) * gamma * I - dr * ro * I
    dRdt = (1 - dr) * gamma * I
    dDdt = dr * ro * I

    return dSdt, dEdt, dIdt, dRdt, dDdt

beta_gov - 这也是一个函数

def beta_gov(t, beta_0, c_1, c_2, tg, g_1, g_2, ind):
    beta_rez = beta_0 * gov(t, tg, g_1, g_2) * c_sig(t, c_1, c_2, ind)
    return beta_rez

但它也调用了两个函数

  1. gov - 功能没问题
def gov(t, tg, g_1, g_2):
    if t > tg:
        alpha = 1 - g_1
    else:
        alpha = 1 - g_2
    return alpha

  1. 我不明白那个。
def c_sig(t, c_1, c_2, ind):
    sig = 1 / (1 + math.exp(c_1*(ind - c_2)))
    return sig

ind - DataSeries,一组数值,其中有很多。当我调用主函数“SEIRD_gov”时,必须将“ind”中的这些值一次加一个来求解方程,然后将结果传递给微分方程组。

ind = df_region['self_isolation'].apply(lambda x: int(x))
ind = ind.values

可能在这里你需要添加类似循环的东西,但是当一个函数被另一个函数调用时,我不明白如何做到这一点。

算法应该如下:

beta_gov - 调用两个函数,从ind依次向c_sig添加一个元素,并返回求解微分方程的值。

以前,我只能传递此列表中的一项,这导致了错误的解决方案。

之前它是 Julia 的模型,这里是带有方程式的代码的一部分。我只需要通过已经存在的参数显示图形,但首先我需要在 python 中重写模型

y0 =  S0, E0, I0, R0, D0
ret = odeint(SEIRD_gov, y0, t, args=(beta_0, c_1, c_2, sigma, gamma, dr, ro, tg, g_1, g_2, ind))
S, E, I, R, D = ret.T
function SEIRD_gov!(du,u, p, t)
    S,E,I,R,D = u
    beta_0, c_1, c_2, sigma, gamma, dr, ro, tg, g_1, g_2 = p
    
    du[1] = -beta_gov(t, beta_0, c_1, c_2, tg, g_1, g_2) * S * I/N
    du[2] = beta_gov(t, beta_0, c_1, c_2, tg, g_1, g_2) * I * S/N - sigma * E
    du[3] = sigma * E - (1 - dr) * gamma * I - dr * ro * I
    du[4]= (1 - dr) * gamma * I 
    du[5] = dr * ro * I
end

function si(t)
    ind = convert(Int, round(t + 1))
    return data.self_isolation[ind]
end

c_lin(t, c_1, c_2) = 1 + c_1*(1 - c_2*si(t))
c_sig(t, c_1, c_2) = 1/(1 + exp(c_1*(si(t) - c_2)))

function gov(t, tg, g_1, g_2) 
    if t > tg
        alpha = 1 - g_1
    else
        alpha = 1 - g_2
    end
    alpha
end

beta_gov(t, beta_0, c_1, c_2, tg, g_1, g_2) = beta_0 * gov(t, tg, g_1, g_2)* c_sig(t, c_1, c_2) 

结果图:

【问题讨论】:

  • 似乎“ind”代表时间......你是从某个地方复制的吗?
  • @Girardi ,这是 Julia 的模特。我将代码添加到问题中,为了更好地了解发生了什么,我只是第一次做这样的转换,经验不足。
  • @Girardi ,如果需要,我可以发笔记本
  • 当你说“它缺少一个循环”时,我猜你的意思可能是你缺少时间循环......你必须随着时间的推移迭代并在每个时间步调用 SEIRD_gov
  • 从你的 julia 代码中,我看到 ind 只是时间......你在某个地方有这个 self_isolation 数据,每个时间步都有一个值,你也想用它作为对您的解决方案的输入...但是它在您的答案中的写法,真的很难确切知道该做什么...请提供一个您想要做什么的示例

标签: python function julia differential-equations


【解决方案1】:

我猜你缺少的是ind 必须是一个函数,因为它是一个与时间相关的系数。

我假设df_region 是来自pandasDataFrame

因此,将代码中的ind 定义修改为:

self_isolation_values = df_region['self_isolation'].to_numpy()
ind = lambda t: self_isolation_values[int(t)]

这使得ind 成为t 的函数,这样ind(t) 将把t 转换为int 并从df_region['self_isolation'] 中的输入数据中返回对应的系数值。这正是 julia 代码中函数 si(t) 的行为。

然后,在c_sig 函数中,调用ind(t) 函数

def c_sig(t, c_1, c_2, ind):
    sig = 1 / (1 + math.exp(c_1*(ind(t) - c_2)))
    return sig

【讨论】:

  • 如果我有办法,我会为你立个纪念。非常感谢,它奏效了。你是最棒的。
猜你喜欢
  • 2019-02-14
  • 2022-11-28
  • 1970-01-01
  • 2021-04-19
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 2018-11-01
相关资源
最近更新 更多