防止Gillespie SSA随机模型运行否定

时间:2016-06-10 12:25:37

标签: r modeling stochastic stochastic-process

我使用Gillespie SSA制作了感染的随机模型(寄生虫)。该模型使用了" GillespieSSA"包(https://cran.r-project.org/web/packages/GillespieSSA/index.html)。 简而言之,代码模拟了一群离散的隔间。隔室之间的移动取决于用户定义的速率方程。 SSA算法用于计算给定时间步长(tau)的每个速率方程产生的事件的数量,并相应地更新群体,过程重复到给定的时间点。问题是,事件的数量假设为泊松分布(Poisson(rate [i] * tau)),因此当速率为负时会产生错误,包括当人口数量变为负数时。

# Parameter Values 
sir.parms <- c(deltaHinfinity=0.00299, CHi=0.00586, deltaH0=0.0854, aH=0.5,
               muH=0.02, SigmaW=0.1, SigmaM =0.8, SigmaL=104, phi=1.15, f = 0.6674,
               deltaVo=0.0166, CVo=0.0205, alphaVo=0.5968, beta=52, mbeta=7300 ,muV=52, g=0.0096, N=100)
# Inital Population Values
sir.x0 <- c(W=20,M=10,L=0.02)
# Rate Equations
sir.a <- c("((deltaH0+deltaHinfinity*CHi*mbeta*L)/(1+CHi*mbeta*L))*mbeta*L*N"
           ,"SigmaW*W*N", "muH*W*N", "((1/2)*phi*f)*W*N", "SigmaM*M*N", "muH*M*N",
           "(deltaVo/(1+CVo*M))*beta*M*N", "SigmaL*L*N", "muV*L*N", "alphaVo*M*L*N", "(aH/g)*L*N")
# Population change for even
sir.nu <- matrix(c(+0.01,0,0,
                   -0.01,0,0,
                   -0.01,0,0,
                   0,+0.01,0,
                   0,-0.01,0,
                   0,-0.01,0,
                   0,0,+0.01/230,
                   0,0,-0.01/230,
                   0,0,-0.01/230,
                   0,0,-0.01/230,
                   0,0,-0.01/32),nrow=3,ncol=11,byrow=FALSE)
runs <- 10
set.seed(1)

# Data Frame of output
sir.out <- data.frame(time=numeric(),W=numeric(),M=numeric(),L=numeric())
# Multiple runs and combining data and SSA methods 
for(i in 1:runs){
  sim <- ssa(sir.x0,sir.a,sir.nu,sir.parms, method="ETL", tau=1/12, tf=140, simName="SIR")
  sim.out <- data.frame(time=sim$data[,1],W=sim$data[,2],M=sim$data[,3],L=sim$data[,4])

  sim.out$run <- i
  sir.out <- rbind(sir.out,sim.out)
}

因此,计算费率并且模型更新每个时间步的总体值,数据存储在数据框中,然后与先前的运行一起附加。然而,当群体的水平变得非常低时,可能发生事件,使得减少群体的事件的数量大于隔间中的数量。一种方法是使时间步长非常小,但这会大大增加模拟的长度。

我的问题是有一种方法可以增加代码,以便在每个时间步骤创建/计算数据时,任何负数的人口数值都会转换为0吗?

我已经尝试过解决这个问题,但似乎只能在模拟完成后提出改变值的方法,负值仍会导致运行本身出现问题。 例如
    if(sir.out $ L&lt; 0)sir.out $ L == 0

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:2)

我认为问题是你在ssa函数中设置的方法(&#34; ETL&#34;)。 ETL方法最终会产生负数。你可以试试&#34; OTL&#34;方法,基于 tau-leaping模拟方法的有效步长选择 - 其中还有一些你可以调整的参数,但基本命令是:

ssa(sir.x0,sir.a,sir.nu,sir.parms, method="OTL", tf=140, simName="SIR")

或直接方法,它不会产生任何负数:

ssa(sir.x0,sir.a,sir.nu,sir.parms, method="D", tf=140, simName="SIR")