我喜欢解决一个涉及多个阈值的耦合微分方程系统。浏览 R 信息,这使我将 ODE 与根函数和事件函数结合使用。
通过各种示例,即温度模型,第 14 页http://cran.r-project.org/web/packages/diffEq/vignettes/ODEinR.pdf - 粘贴在下面的代码 - 我可以让我的模型行动在一个阈值上,即找到一个变量的根/达到阈值会触发一个事件。
library(deSolve)
yini <- c(temp = 18, heating_on=1)
temp <- function(t,y, parms) {
dy1 <- ifelse(y[2] == 1, 1.0, -0.5)
dy2 <- 0
list(c(dy1, dy2))
}
rootfunc <- function(t,y,parms) c(y[1]-18, y[1]-20)
eventfunc <- function(t,y,parms) {
y[1] <- y[1]
y[2] <- ! y[2]
return(y)
}
times <- seq(from=0, to=20, by=0.1)
out <- lsode(times=times, y=yini, func = temp, parms = NULL,
rootfun = rootfunc, events = list(func=eventfunc, root = TRUE))
plot(out, lwd=2)
attributes(out)$troot
该示例还表明,不同的根可以触发相同的事件函数(y[1] – 18 和 y[1]-20 都触发 eventfunc)。但是,我的问题是,是否也可以让不同的根触发不同的事件函数?换句话说,根据找到哪个root,触发不同的eventfunc?或者,在同一个 eventfunct 中,它是否可以根据找到的根执行不同的操作。
为了简单起见,我首先想看看这是否可以使用相同的示例,例如通过命名根和使用 if 语句?目前这行不通。这个事情谁有经验?如果您查看 attributes(out),ODE 似乎确实记录了遇到 $indroot 的根(但这是在评估之后。)提前谢谢您。
# library(deSolve)
yini <- c(temp = 18, heating_on=1)
temp <- function(t,y, parms) {
dy1 <- ifelse(y[2] == 1, 1.0, -0.5)
dy2 <- 0
list(c(dy1, dy2))
}
rootfunc <- function(t,y,parms) {
yroot <- vector(len = 2)
yroot[1] <- y[1]-18
yroot[2] <- y[1]-20
return(yroot)
}
eventfunc <- function(t,y, parms) {
y[1] <- y[1]
ifelse(yroot[2]==2, y[2] <- y[2], y[2] <- !y[2])
return(y)
}
times <- seq(from=0, to=20,by=0.1)
out <- lsode(times=times, y=yini, func = temp, parms = NULL,
rootfun = rootfunc, events = list(func=eventfunc, root = TRUE))
plot(out, lwd=2)
attributes(out)$troot