【问题标题】:Replacing negative values in a model (system of ODEs) with zero用零替换模型(ODE 系统)中的负值
【发布时间】:2021-05-12 01:32:34
【问题描述】:

我目前正在使用deSolve 求解常微分方程组,并且想知道是否有任何方法可以防止微分变量值低于零。我看过其他一些关于在向量、数据框等中将负值设置为零的帖子,但由于这是一个生物模型(T 细胞计数变为负数没有意义),我需要从一开始就阻止它发生,这样这些值就不会扭曲结果,而不仅仅是替换最终输出中的负数。

【问题讨论】:

  • 您在寻找参数约束吗?
  • 这可能会有所帮助——我的主要问题不在于参数,而在于自变量。是否有任何等价物,例如 MATLAB 的非负函数,或者我可以实现的代码使 x[1] 永远不会低于 0?
  • 当 x[1] 达到零时,方程中会发生什么?零是一个稳定的不动点吗?如果是这样,您可以将第一个负值和之后的所有值设置为零。同样在定义 ODE 的函数中,您可以设置 x[1]=max(x[1],0) 然后动态应该是正确的,即使它需要后处理。

标签: r ode negative-number


【解决方案1】:

我的标准方法是将状态变量转换为不受约束的规模。对正变量执行此操作的最明显/标准方法是写下 log(x) 而不是 x 的动力学方程。

例如,对于传染病流行的易感感染恢复 (SIR) 模型,其中方程为 dS/dt = -beta*S*I; dI/dt = beta*S*I-gamma*I; dR/dt = gamma*I,我们会天真地将梯度函数写为

gfun <- function(time, y, params) {
   g <- with(as.list(c(y,params)),
       c(-beta*S*I,
          beta*S*I-gamma*I,
          gamma*I)
       )
   return(list(g))
}

如果我们让log(I) 而不是I 成为状态变量(原则上我们也可以用S 做到这一点,但实际上S 接近边界的可能性要小得多),那么我们有d(log(I))/dt = (dI/dt)/I = beta*S-gamma;其余等式需要使用exp(logI)来引用I。所以:

gfun_log <- function(time, y, params) {
   g <- with(as.list(c(y,params)),
       c(-beta*S*exp(logI),
          beta*S-gamma,
          gamma*exp(logI))
       )
   return(list(g))
}

(计算一次exp(logI) 并存储/重用它会比计算两次更有效...)

【讨论】:

  • 很抱歉恢复这篇古老的帖子,但我喜欢你对状态变量(及其衍生物)进行对数转换以确保它们保持正数的策略。当您的变量和时间数组跨越巨大的动态范围时,您是否认为对数变换也会有所帮助,例如在天体物理学中,假设状态变量预计会在数十亿年内从 ~0 演变到 ~1e10,并在第一时间快速演变 ~十亿年(导致 ODE 求解器在早期采取非常小的时间步长)?还是设置绝对/相对误差容限?
  • 有趣的问题,似乎它可能会有所帮助,但并不真正知道 - 是否有一个足够简单的例子可以变成一个 SO 问题?
  • 应该注意的是,如果您的模型允许动态变量的导数为负(如果动态变量为零),这不会为您节省一点点。在这种情况下,集成将失败,您会得到负溢出或对数的无效参数(无论先发生什么)。
【解决方案2】:

如果某个值在现实中没有变为负值,但在您的模型中变为负值,则您应该更改模型,或者等效地修改微分方程,这样就不可能了。换句话说:不要试图约束你的动态变量,而是它们的导数。 其他一切只会导致你的求解器出现问题,而它不应该关心微分方程的变化。

举个简单的例子,假设:

  • 你有一个一维微分方程ẏ = f(y),
  • y 不会变成负数,
  • 您的初始 y 是肯定的。

在这种情况下,y 只能在 f(0) f em> 使得 f(0) ≥ 0(并且它仍然是平滑的)。

为了证明原理,您可以将 f 与经过适当修改的 sigmoid function 相乘(它允许您用平滑函数组合每个逻辑运算)。这样,y, 的大多数值都不会发生任何变化,并且只有在 y 接近 0 时(即,当您无论如何都要操作事物时)才更改微分方程.

但是,如果不考虑您的模型,我不会真的推荐使用 sigmoid。如果您的模型在 y = 0 附近完全错误,那么它很可能对于附近的值已经无用。如果您的模拟在这种情况下冒险,并且您希望结果有意义,您应该解决这个问题。

【讨论】:

  • 不幸的是,我认为这是不可能的,因为变量会相互影响。例如,来自某种细胞类型的病毒载量方程为 dVB
  • @Dorian:您绝对可以实现这样的约束,即使对于交互变量也是如此:Sigmoids 允许您实现所有逻辑操作。但是,如果您改进我的模型,很可能有一种更合理的方法。我强烈建议考虑这一点,因为如果您的模型在 0 时是虚假的,那么几乎可以肯定它在 0 附近是虚假的,因此您的结果很可能毫无用处。另请参阅我的编辑。
  • @Dorian:另外,如果我正确理解你的模型,dVB 是 x[1](即ẋ[1])的时间导数,而 k_b、x[7] 和 d_vb 是总是积极的。因此,您的方程式已经确保 x[1] 永远不会变为负数,因为对于 x[1]=0,您会自动获得非负 dVB=ẋ[1]。因此,您的模型已经避免了问题——通过成为一个好的模型。
  • @Wrzlprmft:这在数学上是正确的,但不一定在数字上下文中。
  • @BenBolker:是和不是。例如在提问者的例子中,稍微负的值会被“推回”到 0,所以这样的数值错误是没有问题的。大多数模型也应如此(如果不是,您可以再次修改微分方程以解决此问题)。此外,通过良好的积分器和合理选择的参数,您可以完全避免这种情况。使用具有自适应步长的龙格-库塔积分器,提问者的示例永远不会低于 0,其中控制相对误差。
猜你喜欢
  • 2012-07-01
  • 2016-12-23
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
  • 2012-03-15
  • 1970-01-01
  • 1970-01-01
  • 2018-01-05
相关资源
最近更新 更多