我目前正致力于使用deSolve
解决常微分方程组,并且想知道是否有任何方法可以防止差分变量值低于零。我已经看过其他一些关于在矢量,数据框等中将负值设置为零的帖子,但由于这是一个生物模型(并且它对T细胞计数没有意义)负面),我需要阻止它开始发生,所以这些值不会扭曲结果,而不仅仅是替换最终输出中的底片。
答案 0 :(得分:6)
我的标准方法是将状态变量转换为无约束的比例。对正变量执行此操作的最明显/标准方法是记下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)而不是我是状态变量(原则上我们也可以用S做这个,但实际上S不太可能接近边界),那么我们有{{1} };其余的方程需要使用d(log(I))/dt = (dI/dt)/I = beta-gamma
来引用exp(logI)
。所以:
I
(计算gfun_log <- function(time, y, params) {
g <- with(as.list(c(y,params)),
c(-beta*S*exp(logI),
beta-gamma,
gamma*exp(logI))
)
return(list(g))
}
一次并存储/重新使用它而不是计算它两次会稍微有效......)
答案 1 :(得分:0)
如果某个值在实际中没有变为负值但在模型中变为负值,则应更改模型,或者等效地修改微分方程,使其无法实现。换句话说:不要试图限制你的动力变量,而应该限制它们的衍生物。其他一切只会导致你的求解器出现问题,而它不应该关注微分方程的变化。
举一个简单的例子,假设:
在这种情况下, y 只有在 f (0)&lt;因此,您所要做的就是修改 f ,使 f (0)≥0(并且它仍然是平滑的)。
对于原理证明,您可以将 f 与适当修改的sigmoid function相乘(这允许您使用平滑函数组合每个逻辑运算)。这样,对于 y,的大多数值都没有任何改变,只有当 y 接近0时才改变你的微分方程,也就是说,无论如何你要操纵事物
但是,如果不考虑您的模型,我不会真的建议使用sigmoids。如果您的模型在 y = 0附近完全错误,则很可能已经对附近的值无效。如果您的模拟在这个地形中冒险并且您希望结果有意义,那么您应该解决这个问题。