# Contains functions for creating stochastic chemical kinetic models or systems
# Creates a test system for use in testing functions
test.system = function(i=1)
{
foundi = FALSE
switch(i,
{ # Constitutive production
X = c(0)
Pre = matrix(0,1,1)
Post = matrix(1,1,1)
s = length(X)
r = nrow(Pre)
theta = rgamma(r, 100, 100)
stoich = t(Post-Pre)
mult = rep(1,r)
foundi = TRUE
},
{
X = c(0,1,2)
Pre = rbind(c(0,0,0),c(1,0,0),c(0,1,0),c(0,0,1),c(1,1,0),c(1,0,1),c(0,1,1),c(1,1,1))
s = length(X)
r = nrow(Pre)
theta = rgamma(r, 100, 100)
Post = matrix(1,nrow=r,ncol=s)
stoich = t(Post-Pre)
mult = rep(1,r)
foundi = TRUE
})
# Used in place of a default switch case
if (!foundi) stop("Test system doesn't exist.")
sys = list(r=r,s=s,Pre=Pre,Post=Post,stoich=stoich,theta=theta,X=X,mult=mult)
check.system(sys)
return(sys)
}
null.system = function(r=2,s=3)
{
Pre = matrix(0,r,s)
Post = matrix(0,r,s)
stoich = t(Post-Pre)
theta = rep(0,r)
X = rep(0,s)
mult = rep(1,r)
sys = list(r=r,s=s,Pre=Pre,Post=Post,stoich=stoich,theta=theta,X=X,mult=mult)
check.system(sys)
return(sys)
}
#
random.system = function(seed=1,r=NULL,s=NULL)
{
set.seed(seed)
if (is.null(r)) r = rpois(1,2)+1
if (is.null(s)) s = rpois(1,3)+1
Pre = matrix(rpois(r*s, 1),r,s)
Post = matrix(rpois(r*s, 1),r,s)
stoich = t(Post-Pre)
theta = rgamma(r,100,100)
X = rpois(s,10)+1
mult = rep(1,r)
sys = list(r=r,s=s,Pre=Pre,Post=Post,stoich=stoich,theta=theta,X=X,mult=mult)
check.system(sys)
return(sys)
}
check.system = function(sys) {
stopifnot(sys$s == ncol( sys$Pre),
sys$s == ncol( sys$Post),
sys$s == nrow( sys$stoich),
sys$s == length(sys$X),
sys$r == nrow( sys$Pre),
sys$r == nrow( sys$Post),
sys$r == ncol( sys$stoich),
sys$r == length(sys$theta),
sys$r == length(sys$mult),
all(sys$theta>=0),
all(sys$X >=0),
all(sys$Pre >=0),
all(sys$Post >=0),
all(sys$mult >=0))
if (!all.equal(sys$stoich,t(sys$Post-sys$Pre))) warning("sys$stoich!=t(sys$Post-sys$Pre))")
}
#' A convenience function to create a variety of stochastic chemical kinetic models.
#'
#' @param system a character string indicating the type of system to create, currently implemented models are sir and seir
#' @param ... other parameters sent on to the system construction, e.g. the state of the system X and the rate parameters theta
#' @return an sckm system
#' @author Jarad Niemi \email{niemi@@iastate.edu}
#' @export sckm
sckm = function(system, ...) {
do.call(tolower(system), list(...))
}
sir = function(X=c(1000,10,0),theta=c(0.5,0.25)) {
# SIR model:
# rxn 1: S + I -> 2I
# rxn 2: I -> R
# S I R
Pre = rbind(c(1,1,0), # S + I
c(0,1,0)) # I
# S I R
Post = rbind(c(0,2,0), # 2I
c(0,0,1)) # R
stoich = t(Post-Pre)
mult = c(1/sum(X), 1)
states = c("S","I","R")
reactions = c("S+I->2I","I->R")
sys = list(r=2, s=3, Pre=Pre, Post=Post, stoich=stoich, theta=theta, X=X, mult=mult, states=states, reactions=reactions)
check.system(sys)
return(sys)
}
#updated seir function, now takes n argument, which is a named vector
#ne is number of exposed states
#ni is number of infected states
seir = function(X=c(16000,0,100,0), theta=c(.5,2/3,2/3), n=c(ne=1,ni=1)) {
ni <- n[["ni"]]
ne <- n[["ne"]]
#make sure X and Theta are the right length, initialize them if not.
if(length(X)!=(ni+ne+2)){
X=c(16000,rep(0,ne),100,rep(0,ni))
}
if(length(theta)!=(ni+ni+ne)){
theta=theta=c(rep(.5,ni),rep((ne/3),ne),rep(ni/3,ni))
}
#create Pre matrix:
#will consist of two submatrices
#first will be all ways of getting infected, i.e., rows
#with a 1 in the S column and a 1 in an infected state column for different infected states.
#One row for each infected state.
m11 <- matrix(1,nrow=ni,ncol=1)
m12 <- matrix(0, nrow=ni, ncol=ne)
m13 <- diag(ni)
m14 <- matrix(0,nrow=ni,ncol=1)
M1 <- cbind(m11,m12,m13,m14)
#next is a submatrix for trasitioning from either: Ei -> E(i+1), Ei -> I1, Ii -> I(i+1), or Ii -> R
m21 <- matrix(0,nrow=ne+ni,ncol=1)
m22 <- diag(ne+ni)
m23 <- matrix(0,nrow=ne+ni,ncol=1)
M2 <- cbind(m21,m22,m23)
Pre = rbind(M1, M2)
#create Pre matrix:
#will consist of two submatrices
#first will be result of infection from each different I state, i.e.
#rows with a 1 in the E1 column (or I1 column if no exposed state) and a 1 in an infected state column.
#One row for each infected state.
if(ne>0){
m31 <- matrix(0,nrow=ni,ncol=1)
m32 <- matrix(1,nrow=ni,ncol=1)
m33 <- matrix(0, nrow=ni,ncol=ne-1)
m34 <- diag(ni)
m35 <- matrix(0, nrow=ni, ncol=1)
M3 <- cbind(m31,m32,m33,m34,m35)
}
if(ne==0){
m31 <- matrix(0,nrow=ni,ncol=1)
m32 <- matrix(c(2,rep(1,ni-1)),nrow=ni,ncol=1)
m33 <- rbind(rep(0,ni-1),diag(ni-1))
m34 <- matrix(0, nrow=ni, ncol=1)
M3 <- cbind(m31,m32,m33,m34)
}
#next submatrix shows results of moving either E-> E, E->I, I->I, or I-> R
m41<- matrix(0,nrow=ne+ni,ncol=2)
m42 <- diag(ne+ni)
M4 <- cbind(m41,m42)
Post <- rbind(M3,M4)
stoich = t(Post-Pre)
mult = c(rep(1/sum(X),ni),rep(1,ne+ni))
#Create list of different states, and then combine them into different reactions.
if(ne>0){
numbers<-c(seq(1,ne),seq(1,ni))
letters<-c(rep("E",ne), rep("I",ni))
}
if(ne==0){
numbers<-c(seq(1,ni))
letters<-c(rep("I",ni))
}
states<-c("S",paste(letters, numbers,sep=""),"R")
nreactions <- dim(Pre)[1]
reactions <- rep(0,nreactions)
for(i in 1:nreactions){
reactions[i] <- paste(paste( states[which(Pre[i,]!=0)],collapse="+"),"->",paste( states[which(Post[i,]!=0)],collapse="+"),sep="")
}
sys = list(r=nreactions, s=length(states), Pre=Pre, Post=Post, stoich=stoich, theta=theta, X=X, mult=mult, states=states, reactions=reactions)
check.system(sys)
return(sys)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.