R simecol和稳态:rootfun无法访问SimObj插槽
我使用包模拟生态模型(作为ODE系统) 使生态模型的使用和共享变得非常容易的框架 通过对象类SimObj() 我想实现一个稳态,一旦导数变得很低,它就会停止模拟 据此, 这样,您就可以轻松地实现它 您只需提供一个自定义解算器来检查导数的值。 问题在于,自定义解算器看起来无法到达目标R simecol和稳态:rootfun无法访问SimObj插槽,r,functional-programming,simulation,ode,R,Functional Programming,Simulation,Ode,我使用包模拟生态模型(作为ODE系统) 使生态模型的使用和共享变得非常容易的框架 通过对象类SimObj() 我想实现一个稳态,一旦导数变得很低,它就会停止模拟 据此, 这样,您就可以轻松地实现它 您只需提供一个自定义解算器来检查导数的值。 问题在于,自定义解算器看起来无法到达目标 方程式SimObj插槽 我想保留等式槽的这个不错的功能来切换 容易区分不同类型的功能反应 以下是可复制的示例: 1.定义模型 我们看到,模拟已提前停止(100而不是300),它已停止,因为稳定 已到达该国 我的问题
方程式
SimObj插槽
我想保留等式槽的这个不错的功能来切换
容易区分不同类型的功能反应
以下是可复制的示例:
1.定义模型
我们看到,模拟已提前停止(100而不是300),它已停止,因为稳定
已到达该国
我的问题是:我怎样才能让用户访问equations插槽
自定义解算器
lsodar
?查看您的示例后,我发现您自己的解算器有些“有线”,即不必要的复杂。sim函数调用解算器并获取它所需的内容,因此不需要在其中调用upca_ode。此外,您调用该函数的外部版本,而不是对象,因此它当然无法访问“方程式”
(希望如此)好消息是,rootSolve包已经包含了稳态解算器,您可以使用它
见下面的例子。下面的示例还显示,定义自己的解算器非常容易。请使用正确的参数顺序
希望有帮助
托马斯
library(simecol)
library(rootSolve)
upca <- new("odeModel",
main = function(time, init, parms) {
u <- init[1]
v <- init[2]
w <- init[3]
with(as.list(parms), {
du <- a * u - alpha1 * f(u, v, k1)
dv <- -b * v + alpha1 * f(u, v, k1) +
- alpha2 * f(v, w, k2)
dw <- -c * (w - wstar) + alpha2 * f(v, w, k2)
list(c(du, dv, dw))
})
},
equations = list(
f1 = function(x, y, k){x*y}, # Lotka-Volterra
f2 = function(x, y, k){x*y / (1+k*x)} # Holling II
),
times = c(from=0, to=300, by=0.1),
parms = c(a=1, b=1, c=10, alpha1=0.2, alpha2=1,
k1=0.05, k2=0, wstar=0.1),
init = c(u=10, v=5, w=0.1),
solver = "lsoda"
)
upca@equations$f <- upca@equations$f2
plotupca <- function(obj, ...) {
o <- out(obj)
matplot(o[, 1], o[, -1], type = "l", ...)
legend("topright", legend = c("u", "v", "w"), lty = 1:3, bg = "white", col = 1:3)
}
test <- sim(upca)
plotupca(test)
upca@equations$f <- upca@equations$f1
test <- sim(upca)
plotupca(test)
steady_state <- function(y, times, func, parms, steady.method) {
time <- if (steady.method == "stode") {
0
} else {
c(times[1], Inf)
}
steady(y, time, func, parms, method=steady.method)$y
}
equations(upca)$f <- equations(upca)$f1
solver(upca) <- steady_state
# fast direct approach, does not work with all models
test <- sim(upca, steady.method="stode")
out(test)
## slower, simulates model until approx. steady
test <- sim(upca, steady.method="runsteady")
out(test)
库(simecol)
库(rootSolve)
upca
upca_ode <- function(time, init, parms) {
u <- init["u"]
v <- init["v"]
w <- init["w"]
with(as.list(parms), {
du <- a * u - alpha1 * f(u, v, k1)
dv <- -b * v + alpha1 * f(u, v, k1) - alpha2 * f(v, w, k2)
dw <- -c * (w - wstar) + alpha2 * f(v, w, k2)
list(c(du, dv, dw))
})
}
upca <- upca_model()
equations(upca)$f <- equations(upca)$f2
test <- sim(upca)
plotupca <- function(obj, ...) {
o <- out(obj)
matplot(o[, 1], o[, -1], type = "l", ...)
legend("topright", legend = c("u", "v", "w"), lty = 1:3,, bg = "white",
col = 1:3)
}
plotupca(test)
equations(upca)$f <- equations(upca)$f1
test <- sim(upca)
plotupca(test)
steady_state_upca <- function(time, init, func, parms) {
root <- function(time, init, parms) {
dstate <- unlist(upca_ode(time, init, parms))
return(sum(abs(dstate)) - 1e-4)
}
lsodar(time, init, func, parms, rootfun = root)
}
equations(upca)$f <- equations(upca)$f1
solver(upca) <- steady_state_upca
test <- sim(upca)
#> Error in f(u, v, k1) : impossible de trouver la fonction "f"
upca_ode <- function(time, init, parms) {
u <- init["u"]
v <- init["v"]
w <- init["w"]
#Â Definition of the function f:
f <- function(x, y, k){x * y}
with(as.list(parms), {
du <- a * u - alpha1 * f(u, v, k1)
dv <- -b * v + alpha1 * f(u, v, k1) - alpha2 * f(v, w, k2)
dw <- -c * (w - wstar) + alpha2 * f(v, w, k2)
list(c(du, dv, dw))
})
}
upca <- upca_model()
equations(upca)$f <- equations(upca)$f1
solver(upca) <- steady_state_upca
test <- sim(upca)
plotupca(test)
library(simecol)
library(rootSolve)
upca <- new("odeModel",
main = function(time, init, parms) {
u <- init[1]
v <- init[2]
w <- init[3]
with(as.list(parms), {
du <- a * u - alpha1 * f(u, v, k1)
dv <- -b * v + alpha1 * f(u, v, k1) +
- alpha2 * f(v, w, k2)
dw <- -c * (w - wstar) + alpha2 * f(v, w, k2)
list(c(du, dv, dw))
})
},
equations = list(
f1 = function(x, y, k){x*y}, # Lotka-Volterra
f2 = function(x, y, k){x*y / (1+k*x)} # Holling II
),
times = c(from=0, to=300, by=0.1),
parms = c(a=1, b=1, c=10, alpha1=0.2, alpha2=1,
k1=0.05, k2=0, wstar=0.1),
init = c(u=10, v=5, w=0.1),
solver = "lsoda"
)
upca@equations$f <- upca@equations$f2
plotupca <- function(obj, ...) {
o <- out(obj)
matplot(o[, 1], o[, -1], type = "l", ...)
legend("topright", legend = c("u", "v", "w"), lty = 1:3, bg = "white", col = 1:3)
}
test <- sim(upca)
plotupca(test)
upca@equations$f <- upca@equations$f1
test <- sim(upca)
plotupca(test)
steady_state <- function(y, times, func, parms, steady.method) {
time <- if (steady.method == "stode") {
0
} else {
c(times[1], Inf)
}
steady(y, time, func, parms, method=steady.method)$y
}
equations(upca)$f <- equations(upca)$f1
solver(upca) <- steady_state
# fast direct approach, does not work with all models
test <- sim(upca, steady.method="stode")
out(test)
## slower, simulates model until approx. steady
test <- sim(upca, steady.method="runsteady")
out(test)