MMSB: Mathematical Modeling in Systems Biology / Apr 30 2021 / Published
Gillespie Algorithm (Julia)
using Random # randexp()
using StatsBase # Weights() and sample()
using Plots
Plots.gr(fmt=:png)
10.3s
Julia
The direct method
#=
Stochastic chemical reaction: Gillespie Algorithm (direct method)
Adapted from: Chemical and Biomedical Enginnering Calculations Using Python Ch.4-3
=#
function ssa_direct(model, u0, tend, p, stoich; tstart=zero(tend))
t = tstart # Current time
ts = [t] # Time points
u = copy(u0) # Current state
us = copy(u) # Record of states
while t < tend
a = model(u, p, t) # propensities
dt = randexp() / sum(a) # Time step
du = sample(stoich, Weights(a)) # Choose the stoichiometry for the next reaction
u .+= du # Update state
t += dt # Update time
us = [us u] # Append state variable to record
push!(ts, t) # Append time point to record
end
# Make column as variables, rows as observations
us = collect(us')
return (t = ts, u = us)
end
2.7s
Julia
#=
Reaction of A <-> B with rate constants k1 & k2
=#
"Propensity model for this reaction"
model(u, p, t) = [p.k1 * u[1], p.k2 * u[2]]
parameters = (k1=1.0, k2=0.5, stoich=[[-1, 1], [1, -1]])
u0 = [200, 0]
tend = 10.0
0.8s
Julia
sol = ssa_direct(model, u0, tend, parameters, parameters.stoich)
2.5s
Julia
plot(sol.t, sol.u, xlabel="time", ylabel="# of molecules", title = "SSA (direct method)", label=["A" "B"])
14.9s
Julia
First reaction method
#=
Stochastic chemical reaction: Gillespie Algorithm (first reaction method)
Adapted from: Chemical and Biomedical Enginnering Calculations Using Python Ch.4-3
=#
function ssa_first(model, u0, tend, p, stoich; tstart=zero(tend))
t = tstart # Current time
ts = [t] # Time points
u = copy(u0) # Current state
us = copy(u) # Record of states
while t < tend
a = model(u, p, t) # propensities of reactions
# dts from all reactions
dts = randexp(length(a)) ./ a
# Choose the reaction
i = argmin(dts)
dt = dts[i]
du = stoich[i]
# Update state and time
u .+= du
t += dt
us = [us u] # Append state variable to record
push!(ts, t) # Append time point to record
end
# Make column as variables, rows as observations
us = collect(us')
return (t = ts, u = us)
end
0.3s
Julia
sol2 = ssa_first(model, u0, tend, parameters, parameters.stoich)
0.5s
Julia
plot(sol2.t, sol2.u, xlabel="time", ylabel="# of molecules", title = "SSA (1st reaction method)", label=["A" "B"])
0.5s
Julia
Ensemble simulation
# Repeated simulations
plot()
for i in 1:50
sol = ssa_direct(model, u0, tend, parameters, parameters.stoich)
plot!(sol.t, sol.u, linecolor=[:blue :red], linealpha=0.1, label=false)
end
plot!(xlabel="time", ylabel="# of molecules", title = "SSA (1st reaction method) ensemble")
2.3s
Julia
See also
Solving Discrete Stochastic (Gillespie) Equations in
DifferentialEquations.jl
.