在 deSolve 中的时间步更改参数值
Change parameter values at time step in deSolve
我正在尝试使用 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")
我做错了什么?
我得到的结果与您略有不同。如果我取消注释 print(gamma0)
它打印出 5 两次然后打印出 513 个零。不难从表面上追溯原因,尽管您想要的可能比我在这里提供的要多。
在您有(注释掉的)语句 print(gamma0)
的地方,输入以下行:
cat("g:", gamma0, " t:", times, "\n")
和 运行 代码。您会看到它显示的前两次是 0。因为那些在您的列表中 seq(0,10,1)
gamma0 是 5。之后,显示的时间值会发生变化。请注意,打印的 none 来自您的原始时间列表 seq(from = 0, to = 10, by = 1/24)
并且其中 none 是整数,因此 none满足将 gamma0 设置为 5 的条件。ode
正在对时间做一些事情(插值?),但它不仅仅是使用您提供的值。事实上,它并没有打印出 241 个 gamma0 和 times 的值。它打印出 515 个这样的值。我注意到结果 out
确实有 241 个值。
根据你的问题,我认为你假设 ode
实际上会在你的 times
处计算函数。它不是。它将 times
视为连续变量。但是你的情况
gamma0 <- ifelse(times %in% seq(0,10,1), 5, 0)
仅测试 11 个特定值 - 不是值范围。连续变量不太可能恰好达到这些值。
这是对您的函数的一个非常简单的修改。如果您有兴趣知道自己做错了什么,可以看下面。
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
.
的值
因此,如果您想在前 10 个时间步使用它,您只需要使用我的代码或任何考虑 dt
.
的代码即可
但是这里有一个问题要问你:
如果您不需要 gamma0
根据 times
进行更改并希望它在前 11 (10) 个时间步长为 5,那么为什么要将它与 times
?为什么不简单地将这些时间步长设置为 5?
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 类型的函数
我正在尝试使用 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")
我做错了什么?
我得到的结果与您略有不同。如果我取消注释 print(gamma0)
它打印出 5 两次然后打印出 513 个零。不难从表面上追溯原因,尽管您想要的可能比我在这里提供的要多。
在您有(注释掉的)语句 print(gamma0)
的地方,输入以下行:
cat("g:", gamma0, " t:", times, "\n")
和 运行 代码。您会看到它显示的前两次是 0。因为那些在您的列表中 seq(0,10,1)
gamma0 是 5。之后,显示的时间值会发生变化。请注意,打印的 none 来自您的原始时间列表 seq(from = 0, to = 10, by = 1/24)
并且其中 none 是整数,因此 none满足将 gamma0 设置为 5 的条件。ode
正在对时间做一些事情(插值?),但它不仅仅是使用您提供的值。事实上,它并没有打印出 241 个 gamma0 和 times 的值。它打印出 515 个这样的值。我注意到结果 out
确实有 241 个值。
根据你的问题,我认为你假设 ode
实际上会在你的 times
处计算函数。它不是。它将 times
视为连续变量。但是你的情况
gamma0 <- ifelse(times %in% seq(0,10,1), 5, 0)
仅测试 11 个特定值 - 不是值范围。连续变量不太可能恰好达到这些值。
这是对您的函数的一个非常简单的修改。如果您有兴趣知道自己做错了什么,可以看下面。
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
.
因此,如果您想在前 10 个时间步使用它,您只需要使用我的代码或任何考虑 dt
.
但是这里有一个问题要问你:
如果您不需要 gamma0
根据 times
进行更改并希望它在前 11 (10) 个时间步长为 5,那么为什么要将它与 times
?为什么不简单地将这些时间步长设置为 5?
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 类型的函数