我正在尝试使用deSolve
来解决R中的ODE。使用以下代码,我期望参数gamma0
在时间步0,1,2,3,4,5,6,7,8,9和10取值5,否则取0。但是,print(gamma0)
表示gamma0
保持为0.
这是我的ODE:
library(deSolve)
param <- c(a = 0.1, b = 1)
yini <- c(alpha0 = 6, beta0 = 2)
mod <- function(times, yini, param) {
with(as.list(c(yini, param)), {
gamma0 <- ifelse(times %in% seq(0,10,1), 5, 0)
## print(gamma0)
dalpha0 <- - a*alpha0 + gamma0
dbeta0 <- a*alpha0 - b*beta0
return(list(c(dalpha0, dbeta0)))
})}
times <- seq(from = 0, to = 10, by = 1/24)
out <- ode(func = mod, times = times, y = yini, parms = param)
plot(out, lwd = 2, xlab = "day")
我做错了什么?
答案 0 :(得分:4)
我得到的结果略有不同。如果我取消注释print(gamma0)
它打印5次,然后输出513个零。尽管你可能想要的比我在这里提供的更多,但要用一种肤浅的方式来追踪它们并不难。
如果您有(注释掉)声明print(gamma0)
,请填写以下行:
cat("g:", gamma0, " t:", times, "\n")
并运行代码。您将看到它显示的前两次是0.因为这些在您的列表中seq(0,10,1)
,gamma0是5.之后,显示的时间值会发生变化。请注意,打印的其中没有来自您原始的时间列表seq(from = 0, to = 10, by = 1/24)
,并且它们都不是整数,因此没有符合条件将gamma0设置为5. ode
是用时间做某事(插值?)但它不是简单地使用你提供的值。实际上,它不会打印出gamma0和次数的241个值。它打印出515个这样的值。我注意到结果out
确实有241个值。
我认为,根据您的问题,您认为ode
实际上会评估您times
的功能。它不是。它将times
视为连续变量。但是你的情况
gamma0 <- ifelse(times %in% seq(0,10,1), 5, 0)
仅测试11个特定值 - 而不是值范围。连续变量不太可能完全达到这些值。
答案 1 :(得分:4)
这是对您的功能的一个非常简单的修改。如果您对了解自己的错误感兴趣,可以查看以下内容。
mod <- function(times, yini, param) {
dt = times[2] - times[1]
with(as.list(c(yini, param)), {
gamma0 <- ifelse(times <= 10*dt, 5, 0)
## print(gamma0)
dalpha0 <- - a*alpha0 + gamma0
dbeta0 <- a*alpha0 - b*beta0
return(list(c(dalpha0, dbeta0)))
})}
修改强>
与G5W的回答相同,问题在于您将times
与times %in% seq(0,10,1)
进行比较。
写作时
times
你不是指时间步骤。您只需引用dt
。
因此,如果您想在前10个步骤中使用它,您只需要使用我的代码或任何考虑gamma0
的内容。
但是这里有一个问题:
如果您不需要times
根据times
进行更改,并希望在前11(10)个时间步长为5,那么为什么要将其与{{1}}进行比较?为什么不简单地将它设置为5用于那些时间步骤?
答案 2 :(得分:1)
M--的答案对我不起作用,如果您只是尝试这样做呢?
mod <- function(times, yini, param) {
with(as.list(c(yini, param)), {
if (times < 10) {
gamma0 = 5
} else if (times >= 10) {
gamma0 = 0
}
dalpha0 <- -a * alpha0 + gamma0
dbeta0 <- a * alpha0 - b * beta0
return(list(c(dalpha0, dbeta0)))
})
}
这可以用作Headvise类型的功能