使用deSolve中的事件来防止负状态变量,R

时间:2015-12-22 21:29:40

标签: r ode

我使用OD中的ODE和deSolve模拟物种食物网中的种群变化,显然种群不应小于零。因此我添加了一个事件函数并运行如下。虽然答案从我没有使用事件功能时改变,但它仍然产生负值。怎么了?

#using events in a function to distinguish and address the negative abundances
eventfun <- function(t, y, parms){
    y[which(y<0)] <- 0  
    return(y)
}

# =============================== main code
max.time = 100
start.time = 50

initials <- c(N, R)

#parms <- list(webs=webs, a=a, b=b, h=h, m=m, basals=basals, mu=mu, Y=Y, K=K, no.species=no.species, flow=flow,S=S, neighs=neighs$neighs.per, dispers.maps=dispers.maps)
temp.abund <- ode(y=initials, func=solve.model, times=0:max.time, parms=parms, events = list(func = eventfun, time = 0:max.time))   

这是ODE函数(如果它有助于发现问题):

solve.model <- function(t, y, parms){

y <- ifelse(y<1e-6, 0, y)
with(parms,{
    # return from vector form into matrix form for calculations
    (R <- as.matrix(y[(max(no.species)*length(no.species)+1):length(y)]))
    (N <- matrix(y[1:(max(no.species)*length(no.species))], ncol=length(no.species)))

    dy1 <- matrix(nrow=max(no.species), ncol=length(no.species))
    dy2 <- matrix(nrow=length(no.species), ncol=1)

    no.webs <- length(no.species)
    for (i in 1:no.webs){

        species <- no.species[i]
        (abundance <- N[1:species,i])

        adj <- as.matrix(webs[[i]])
        a.temp <- a[1:species, 1:species]*adj
        b.temp <- b[1:species, 1:species]*adj
        h.temp <- h[1:species, 1:species]*adj

        (sum.over.preys <- abundance%*%(a.temp*h.temp))
        (sum.over.predators <- (a.temp*h.temp)%*%abundance)

        #Calculating growth of basal
        (basal.growth <- basals[,i]*N[,i]*(mu*R[i]/(K+R[i])-m))

        # Calculating growth for non-basal species D
        no.basal <- rep(1,len=species)-basals[1:species]

        predator.growth<- rep(0, max(no.species))
        (predator.growth[1:species] <- ((abundance%*%(a.temp*b.temp))/(1+sum.over.preys)-m*no.basal)*abundance)


        predation <- rep(0, max(no.species))
        (predation[1:species] <- (((a.temp*b.temp)%*%abundance)/t(1+sum.over.preys))*abundance)

        (pop <- basal.growth + predator.growth - predation)


        dy1[,i] <- pop

        dy2[i] <- 0.0005 #to consider a nearly constant value for the resource

    }

    #Calculating dispersals .they can be easily replaced
    # by adjacency maps of connections between food webs arbitrarily!
    disp.left <- dy1*d*dispers.maps$left.immig
    disp.left <- disp.left[,neighs[,2]]

    disp.right <- dy1*d*dispers.maps$right.immig
    disp.right <- disp.right[,neighs[,3]]

    emig <- dy1*d*dispers.maps$emigration
    mortality <- m*dy1

    dy1 <- dy1+disp.left+disp.right-emig

    return(list(c(dy1, dy2)))    
})
}

非常感谢你的帮助

2 个答案:

答案 0 :(得分:1)

我正在使用与 jjborrelli 发布的事件函数类似的事件函数。我想指出,对我来说,它仍然显示 ode 函数返回负值。但是,ode 去计算下一步时,使用的是 0,而不是当前步骤显示的负值,因此您基本上可以忽略负值,并在模拟结束时用零替换。

答案 1 :(得分:0)

我使用类似的事件函数成功完成了这个:

eventfun <- function(t, y, parms){
  with(as.list(y), {
    y[y < 1e-6] <- 0
    return(y)
  })
}