我喜欢解决一个涉及多个阈值的耦合微分方程系统。通过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)。 我的问题是,是否也可以让不同的根触发不同的事件函数?不同地说,取决于找到哪个根,触发了不同的eventfunc?或者,在同一个事件中,它可以根据找到的根来执行不同的操作。
为了保持简单,我首先想看看这是否可以使用相同的示例,例如通过命名根和使用if语句?目前不起作用。有任何人对此有经验吗?如果你看一下属性(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