# simulate an SIR model using the Gillespie method
# the population size
N = 10000
# the initial number of infectious agents
I0 = 10
# the transmission rate
beta = 0.4
# the recovery rate
gamma = 0.2
# an waiting time egenerator that handles 0 rate properly
wait.exp = function(rate) {
if (rate == 0) Inf else rexp(1, rate)
}
# this is a function that rescheduled all the events. When the
# state changed, the old events are invalid because they are
# calculated from the old state. This is possible because the
# waiting times are exponentially distributed
reschedule = function(time, agent, state) {
clearEvents(agent)
t.inf = time + wait.exp(beta*state$I*state$S/N)
schedule(agent, newEvent(t.inf, handler.infect))
t.rec = time + wait.exp(gamma*state$I)
schedule(agent, newEvent(t.rec, handler.recover))
}
# The infection event handler
# an event handler take 3 arguments
# time is the current simulation time
# sim is an external pointer to the Simulation object.
# agent is the agent that the event is scheduled to
handler.infect = function(time, sim, agent) {
x = getState(agent)
x$S = x$S - 1
x$I = x$I + 1
setState(agent, x)
reschedule(time, agent, x)
}
# The recovery event handler
handler.recover = function(time, sim, agent) {
x = getState(agent)
x$R = x$R + 1
x$I = x$I - 1
setState(agent, x)
reschedule(time, agent, x)
}
# create a new simulation with no agent in it.
# note that the simulation object itself is an agent
sim = Simulation$new()
# the initial state
x = list(S=N-I0, I=I0, R=0)
sim$state = x
# schedule an infection event and a recovery event
reschedule(0, sim$get, sim$state)
# add state loggers that saves the S, I, and R states
sim$addLogger(newStateLogger("S", NULL, "S"))
sim$addLogger(newStateLogger("I", NULL, "I"))
sim$addLogger(newStateLogger("R", sim$get, "R"))
# now the simulation is setup, and is ready to run
result = sim$run(0:100)
# the result is a data.frame object
print(result)
# simulate an agent based SEIR model
# specify an exponential waiting time for recovery
gamma = newExpWaitingTime(0.2)
# specify a tansmission rate
beta = 0.4
# specify a exponentially distributed latent period
sigma =newExpWaitingTime(0.5)
# the population size
N = 10000
# create a simulation with N agents, initialize the first 5 with a state "I"
# and the remaining with "S".
sim = Simulation$new(N, function(i) if (i <= 5) "I" else "S")
# add event loggers that counts the individuals in each state.
# the first variable is the name of the counter, the second is
# the state for counting. States should be lists. However, for
# simplicity, if the state has a single value, then we
# can specify the list as the value, e.g., "S", and the state
# is equivalent to list("S")
sim$addLogger(newCounter("S", "S"))
sim$addLogger(newCounter("E", "E"))
sim$addLogger(newCounter("I", "I"))
sim$addLogger(newCounter("R", "R"))
# create a random mixing contact pattern and attach it to sim
m = newRandomMixing()
sim$addContact(m)
# the transition for leaving latent state anbd becoming infectious
sim$addTransition("E"->"I", sigma)
# the transition for recovery
sim$addTransition("I"->"R", gamma)
# the transition for tranmission, which is caused by the contact m
# also note that the waiting time can be a number, which is the same
# as newExpWaitingTime(beta)
sim$addTransition("I" + "S" -> "I" + "E" ~ m, beta)
# run the simulation, and get a data.frame object
result = sim$run(0:100)
print(result)
Run the code above in your browser using DataLab