我正在尝试使用基于LV模型的微分方程对猎物 - 食饵 - 捕食者系统进行建模。为了精确,我需要使用runge-kutta4方法。 但考虑到这些方程式,一些人群很快变得消极。
所以我尝试使用ODE的事件/根系统,但似乎rk4和rootfun不兼容......
eventFunc <- function(t, y, p){
if (y["N1"] < 0) { y["N1"] = 0 }
if (y["N2"] < 0) { y["N2"] = 0 }
if (y["P"] < 0) { y["P"] = 0 }
return(y)
}
rootFunction <- function(t, y, p){
if (y["P"] < 0) {y["P"] = 0}
if (y["N1"] < 0) {y["N1"] = 0}
if (y["N2"] < 0) {y["N2"] = 0}
return(y)
}
out <- ode(func=Model_T2.2,
method="rk4",
y=state,
parms=parameters,
times=times,
events = list(func = eventFunc,
root = TRUE),
rootfun = rootFunction
)
此代码给出了以下错误:
checkevents(事件,时间,Ynames,dllname)出错: 如果指定'events $ func'并且没有root函数或你的求解器不支持根函数,则应该给出'events $ time'并包含事件的时间
有没有解决方案使用rk4并禁止函数低于0?
提前致谢。
对于那些可能会问的人,这是有效的:
if(!require(ggplot2)) {
install.packages("ggplot2"); require(ggplot2)}
if(!require(deSolve)) {
install.packages("deSolve"); require(deSolve)}
Model_T2.2 <- function(t, state, par){
with(as.list(c(state, par)), {
response1 <- (a1 * N1)/(1+(a1*h1*N1)+(a2*h2*N2))
response2 <- (a2 * N2)/(1+(a1*h1*N1)+(a2*h2*N2))
dN1 = r1*N1 * (1 - ((N1 + A12 * N2)/K1)) - response1 * P
dN2 = r2*N2 * (1 - ((N1 + A21 * N2)/K2)) - response2 * P
dP = ((E1 * response1) + (E2 * response2)) * P - Mp
return(list(c(dN1, dN2, dP)))
})
}
parameters<-c(
r1=1.42, r2=0.9,
A12=0.6, A21=0.5,
K1=50, K2=50,
a1=0.77, a2=0.77,
b1 = 1, b2=1,
h1=1.04, h2=1.04,
o1=0, o2=0,
Mp=0.22,
E1=0.36, E2=0.36
)
## inital states
state<-c(
P=10,
N1=30,
N2=30
)
times <- seq(0, 30, by=0.5)
out <- ode(func=Model_T2.2,
method="rk4",
y=state,
parms=parameters,
times=times,
events = list(func = eventFunc,
root = TRUE),
rootfun = rootFunction
)
md <- melt(as.data.frame(out), id.vars=1, measure.vars = c("N1", "N2", "P"))
pl <- ggplot(md, aes(x=time, y=value, colour=variable))
pl <- pl + geom_line() + geom_point() + scale_color_discrete(name="Population")
pl
图表中的结果: Evolution of prey1, prey2 and predator populations 正如你所看到的,掠食者的数量变为负数,这在现实世界中显然是不可能的。
编辑:缺少变量,对不起。
答案 0 :(得分:1)
对于像rk4这样的所有显式求解器,这是一个问题。减少时间步骤将有助于达到一定程度。更好地使用具有隐式方法的求解器,lsoda
似乎以一种或另一种形式普遍可用。
明确强制正值的另一种方法是将它们作为指数参数化。设置N1=exp(U1)
,N2=exp(U2)
然后ODE功能代码转换为(dN = exp(U)*dU = N*dU
)
N1 <- exp(U1)
N2 <- exp(U2)
response1 <- (a1)/(1+(a1*h1*N1)+(a2*h2*N2))
response2 <- (a2)/(1+(a1*h1*N1)+(a2*h2*N2))
dU1 = r1 * (1 - ((N1 + A12 * N2)/K1)) - response1 * P
dU2 = r2 * (1 - ((N1 + A21 * N2)/K2)) - response2 * P
dP = ((E1 * response1*N1) + (E2 * response2*N2)) * P - Mp
对于输出,您当然可以从解决方案N1, N2
重建U1, U2
。
答案 1 :(得分:1)