我一直在使用方法deSolve::ode45
,该方法一直有效,直到对方程式做了一些必要的更改。有谁知道为什么ODE求解器不起作用?我尝试使用ode45
和默认的ode
方法运行,但都无法正常工作。请让我知道是否有进一步的解释会有所帮助。
我已经检查了微分方程,我相信它们是正确的。
使用的公式如下:
CCHFModel = function(t,x,params)
{
# get SIR values
SH <- x[1]
EH <- x[2]
IA <- x[3]
IS <- x[4]
RH <- x[5]
ST <- x[6]
IT <- x[7]
SC <- x[9]
IC <- x[10]
RC <- x[11]
# Load values ----
# Beta values
betaHHA = params["betaHHA"]
betaHHS = params["betaHHS"]
betaTH = params["betaTH"]
betaCH = params["betaCH"]
betaTC = params["betaTC"]
betaCT = params["betaCT"]
betaTT = params["betaTT"]
# Gamma value
gamma = params["gamma"]
# death rates
muH = params["muH"]
muT = params["muT"]
muC = params["muC"]
# birth rates
piH = params["piH"]
piT = params["piT"]
piC = params["piC"]
# incubation
deltaHS = params["deltaHS"]
deltaHA = params["deltaHA"]
# recovery rate
alphaA = params["alphaA"]
alphaS = params["alphaS"]
alphaC = params["alphaC"]
# total population
NH = (SH + IA + IS + EH + RH) + (piH * SH) - (muH * SH)
NT = (ST + IT) + (piT * ST) - (muT * ST)
NC = (SC + IC + RC) + (piC * SC) - (muH * SC)
# tick carrying Capacity
# KT = NC * 130 # 130 ticks per carrier max
#computations ----
dSHdt <- (piH * NH) - (betaHHA * IA + betaHHS * IS + betaCH * IC + betaTH * IT)*(SH/NH) - (muH * SH)
dEHdt <- (betaHHA * IA + betaHHS * IS + betaCH * IC + betaTH * IT)*(SH/NH) - ((deltaHA + muH)*EH)
dIAdt <- (deltaHA * EH) - ((alphaA + muH + deltaHS) * IA)
dISdt <- (deltaHS * IA) - ((alphaS + muH + gamma) * IS)
dRHdt <- alphaA * IA + alphaS * IS - muH*RH
dSTdt <- (piT * NT) - (betaTT * IT + betaCT * IC)*(ST/NT) - (muT * ST)
dITdt <- (betaTT * IT + betaCT * IC)*(ST/NT) - (muT * IT)
dSCdt <- (piC * NC) - (betaTC * IT)*(SC/NC) - (muC * SC)
dICdt <- (betaTC * IT)*(SC/NC) - ((alphaC +muC) * IC)
dRCdt <- (alphaC * IC) - (muC * RC)
# return results
list(c(dSHdt, dEHdt, dIAdt, dISdt, dRHdt, dSTdt, dITdt, dSCdt, dICdt, dRCdt))
}
我使用以下命令运行ODE求解器:
defaultParms = c(betaHHA = .0413,
betaHHS = .0413,
betaTH = .2891,
betaCH = .0826,
betaTC = (1/365),
betaCT = 59/365,
betaTT = ((1/(365 * 2)) * .04) * 280,
gamma = 1/10,
muH = (1/(365 * 73)),
muT = (1/(365 * 2)),
muC = (1/(11 * 365)),
piH = 1.25/(73 * 365),
piT = 4.5/730,
piC = 1/(11 * 365),
deltaHS = 1/3,
deltaHA = 1/2,
alphaA = 1/17,
alphaS = 1/17,
alphaC = 1/7)
# time to start solution
t = seq(from = 0, to = 365, by = 0.1)
#initialize initial conditions
initialConditions = c(SH = 10000, EH = 5, IA = 5, IS = 10, RH = 2, ST = 80000, IT = 50, SC = 30000, IC = 5, RC = 1)
dataSet = ode(y = initialConditions, times = t, func = CCHFModel, parms = defaultParms)%>%
as.data.frame()
运行此命令后,所有符合初始条件的输出均为NA。
答案 0 :(得分:3)
这是由于输入错误造成的-您在代码的第一部分中对输入值的转换输入了错误的编号(即,您跳过了x[8]
。我将进行两次(希望如此)有用的练习,首先说明如何调试此功能,然后显示如何重写函数以使其不那么容易出错...
t=0
,x=<initial conditions>
运行梯度函数:CCHFModel(0,initialConditions, defaultParms)
## piH betaHHA deltaHA deltaHS alphaA piT
## -15.02882327 12.62349834 0.53902803 0.07805607 0.88227788 385.31052332
## betaTT piC betaTC alphaC
## 0.85526763 NA NA NA
嗯,我们已经看到了问题。为什么计算得出的梯度的最后三个元素为NA
?
在函数末尾(在browser()
行之前)添加dsCdt <- ...
,以便我们仔细看一下。重新定义函数,然后尝试再次计算梯度。
当我们到达那里并打印出一些计算量时,我们发现NC
和RC
都是NA
……我们还可以看到NA
的{{1}}值将导致RC
为NC
,所以让我们检查NA
的定义...
啊哈! RC
被定义为RC
,但是x[11]
只有10...。仔细观察表明,我们错过了length(initialConditions)
。重新定义适当地会始终给出非{x[8]
的值(我不知道它们是否正确,但至少它们不是NA
)。
尽管使用NA
或[]
提取向量元素通常会给出相同的答案,但当要提取单个元素(标量)时,应始终使用[[]]
来自矢量。原因如下:
[[]]
如果您使用initialConditions[11] ## NA
initialConditions[[11]] ## Error in x[[11]] : subscript out of bounds
,则[]
会在您的代码中传播,因此您必须寻找原始源代码。如果您使用NA
,则R会立即失败并告诉您问题出在哪里。另一个好处是[[]]
以通常没有意义的方式传播矢量元素的名称(看一下上面“ debugging / 1”中输出的名称...)>
通过用以下代码代替拆包代码(计算总人口之前的所有内容),可以避免对参数和状态向量进行所有繁琐且容易出错的拆包
[]
提供了正确的参数和状态向量名称(它们之间没有名称重叠),这将创建一个命名列表,并允许在函数中按名称查找元素; comb <- c(as.list(x), as.list(params))
attach(comb)
on.exit(detach(comb))
确保最后一切都正确清理。 (您会看到建议使用on.exit(detach(comb))
来执行此操作;在这里我更喜欢这种策略,因为它使[如有必要]在函数中的调试更加容易。但是正如@tpetzoldt在注释中指出的,您应该始终将with()
与attach(...)
配对;否则情况会变得非常混乱和混乱……)
在函数结尾处我将使用
on.exit(detach(...))
确保正确标记了梯度矢量,这使故障排除更加容易。