是否可以在ode(包deSolve)中使用rk4和rootfun
我正试图用基于LV模型的微分方程来模拟一个食饵-捕食者系统。为了精确起见,我需要使用runge-kutta4方法。 但根据这些方程式,一些人口很快就会变成负数 所以我尝试使用ODE的事件/根系统,但似乎rk4和rootfun不兼容是否可以在ode(包deSolve)中使用rk4和rootfun,r,modeling,ode,R,Modeling,Ode,我正试图用基于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) {
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
)
eventFunc这是所有显式解算器(如rk4)都会遇到的问题。在一定程度上,缩短时间步长会有所帮助。最好使用隐式方法的解算器,lsoda
似乎以某种形式普遍可用
另一种显式强制正值的方法是将它们参数化为指数。设置N1=exp(U1)
,N2=exp(U2)
,然后ODE函数代码转换为(asdN=exp(U)*dU=N*dU
)
N1多亏了,我现在可以运行我的L-V模型了
radau
(而不是您提到的randau
)函数确实接受根函数,而events ans隐式实现了runge-kutta方法
再次感谢,希望这将对将来的人有所帮助。状态
,参数
和时间
在您的“工作示例”(第二个代码段)中缺失。尝试deSolve
文档中的一些示例确实表明method=“rk4”
和根事件不兼容。但是如何使用函数randau
?此函数支持事件
和根
。我添加了参数
、时间
和状态
变量。我将尝试randau
功能,并在测试后尽快更新此帖子。谢谢您的快速回复。您确定型号正确吗?即使对于P=0
您也会得到dP=-Mp
。对于正P
这意味着与种群大小无关的不断移除/收获,但如果没有种群,就无法再移除任何东西。真是太遗憾了!卢兹尔发现了真正的问题:我数学不好。。。谢谢。
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
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