Skip to content
Snippets Groups Projects
Commit 66d44c7e authored by Bentriou Mahmoud's avatar Bentriou Mahmoud
Browse files

update of notebooks according to the new simulation methods

parent 920cd91a
No related branches found
No related tags found
No related merge requests found
...@@ -10,7 +10,7 @@ import Distributed: @everywhere, @distributed ...@@ -10,7 +10,7 @@ import Distributed: @everywhere, @distributed
import Distributions: Product, Uniform, Normal import Distributions: Product, Uniform, Normal
import Distributions: Distribution, Univariate, Continuous, UnivariateDistribution, import Distributions: Distribution, Univariate, Continuous, UnivariateDistribution,
MultivariateDistribution, product_distribution MultivariateDistribution, product_distribution
import Distributions: insupport, pdf import Distributions: insupport, isbounded, pdf
import FunctionWrappers: FunctionWrapper import FunctionWrappers: FunctionWrapper
import Random: rand, rand! import Random: rand, rand!
import StaticArrays: SVector, @SVector import StaticArrays: SVector, @SVector
......
...@@ -271,15 +271,15 @@ ...@@ -271,15 +271,15 @@
], ],
"metadata": { "metadata": {
"kernelspec": { "kernelspec": {
"display_name": "Julia 1.4.2", "display_name": "Julia 1.5.3",
"language": "julia", "language": "julia",
"name": "julia-1.4" "name": "julia-1.5"
}, },
"language_info": { "language_info": {
"file_extension": ".jl", "file_extension": ".jl",
"mimetype": "application/julia", "mimetype": "application/julia",
"name": "julia", "name": "julia",
"version": "1.4.2" "version": "1.5.3"
} }
}, },
"nbformat": 4, "nbformat": 4,
......
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# Create a model # Create a model
In this package, probabilistic models are represented by `ContinuousTimeModel` objects. There are several ways to create these kind of objects. In this package, probabilistic models are represented by `ContinuousTimeModel` objects. There are several ways to create these kind of objects.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
using MarkovProcesses using MarkovProcesses
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## 1. With load_model() ## 1. With load_model()
A bunch of models are already available in the package. If `str_model::String` is the name of an implemented model, then `load_model(str_model)` creates a variable with name `str_model`. A bunch of models are already available in the package. If `str_model::String` is the name of an implemented model, then `load_model(str_model)` creates a variable with name `str_model`.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
# Poisson process # Poisson process
load_model("poisson") load_model("poisson")
poisson poisson
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
# Repressilator model # Repressilator model
load_model("repressilator") load_model("repressilator")
repressilator repressilator
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## 2. With @network_model ## 2. With @network_model
A useful feature is avaiable for CTMCs induced by a Chemical Reaction Network. Let's consider the Chemical Reaction Network of the SIR model: A useful feature is avaiable for CTMCs induced by a Chemical Reaction Network. Let's consider the Chemical Reaction Network of the SIR model:
$$ $$
Infection: S + I \xrightarrow{k_i} 2I \\ Infection: S + I \xrightarrow{k_i} 2I \\
Recovery: I \xrightarrow{k_r} R Recovery: I \xrightarrow{k_r} R
$$ $$
The macro `@network_model` creates easily a CTMC stored in a `ContinuousTimeModel` variable based on this formalism. The macro `@network_model` creates easily a CTMC stored in a `ContinuousTimeModel` variable based on this formalism.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
easy_sir = @network_model begin easy_sir = @network_model begin
Infection: (S + I => 2I, ki*I*S) Infection: (S + I => 2I, ki*I*S)
Recovery: (I => R, kr*I) Recovery: (I => R, kr*I)
end "My awesome SIR" end "My awesome SIR"
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
In the first reaction, `ki*I*S` is the reaction rate of the reaction `Infection`. This model is almost ready to use, we have to set the initial state and the parameters. In the first reaction, `ki*I*S` is the reaction rate of the reaction `Infection`. This model is almost ready to use, we have to set the initial state and the parameters.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
set_param!(easy_sir, [0.0012, 0.05]) set_param!(easy_sir, [0.0012, 0.05])
set_x0!(easy_sir, [95, 5, 0]) set_x0!(easy_sir, [95, 5, 0])
using Plots using Plots
σ = simulate(easy_sir) σ = simulate(easy_sir)
plot(times(σ), σ.I, linetype = :steppost) plot(times(σ), σ.I, linetype = :steppost)
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## 3. Manually (advanced) ## 3. Manually (advanced)
When the above cases don't fit your application one can create manually a `ContinuousTimeModel`. Let's take a look about the signature of the constructor method: When the above cases don't fit your application one can create manually a `ContinuousTimeModel`. Let's take a look about the signature of the constructor method:
```julia ```julia
function ContinuousTimeModel(dim_state::Int, dim_params::Int, map_var_idx::Dict{VariableModel,Int}, function ContinuousTimeModel(dim_state::Int, dim_params::Int, map_var_idx::Dict{VariableModel,Int},
map_param_idx::Dict{ParameterModel,Int}, transitions::Vector{<:Transition}, map_param_idx::Dict{ParameterModel,Int}, transitions::Vector{<:Transition},
p::Vector{Float64}, x0::Vector{Int}, t0::Float64, p::Vector{Float64}, x0::Vector{Int}, t0::Float64,
f!::Function, isabsorbing::Function; kwargs) f!::Function, isabsorbing::Function; kwargs)
``` ```
First, one has to specify the dimensions of the state space and the parameter space. First, one has to specify the dimensions of the state space and the parameter space.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
dim_state_sir, dim_params_sir = 3, 2 dim_state_sir, dim_params_sir = 3, 2
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
`map_var_idx` is a dictionary that maps each model variable (represented by a `Symbol`) to an index in the state space. `map_var_idx` is a dictionary that maps each model variable (represented by a `Symbol`) to an index in the state space.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
map_var_idx_sir = Dict(:S => 1, :I => 2, :R => 3) map_var_idx_sir = Dict(:S => 1, :I => 2, :R => 3)
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
`map_var_params` is the equivalent of `map_var_idx` for parameters. `map_var_params` is the equivalent of `map_var_idx` for parameters.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
map_params_idx_sir = Dict(:ki => 1, :kr => 2) map_params_idx_sir = Dict(:ki => 1, :kr => 2)
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
`transitions` are the transitions/reactions of the model (vector of `Symbol`), `p`, `x0` and `t0` are respectively the parameters, the initial state and initial time of the model. `transitions` are the transitions/reactions of the model (vector of `Symbol`), `p`, `x0` and `t0` are respectively the parameters, the initial state and initial time of the model.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
transitions_sir = [:Infection, :Recovery] transitions_sir = [:Infection, :Recovery]
p_sir = [0.0012, 0.05] p_sir = [0.0012, 0.05]
x0_sir = [95, 5, 0] x0_sir = [95, 5, 0]
t0_sir = 0.0 t0_sir = 0.0
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
The two last arguments are functions, the first one, called `f!` must have the signature: The two last arguments are functions, the first one, called `f!` must have the signature:
```julia ```julia
function f!(xnplus1::Vector{Int}, ptr_t::Vector{Float64}, ptr_tr::Vector{Transition}, function f!(xnplus1::Vector{Int}, ptr_t::Vector{Float64}, ptr_tr::Vector{Transition},
xn::Vector{Int}, tn::Float64, p::Vector{Float64}) xn::Vector{Int}, tn::Float64, p::Vector{Float64})
``` ```
It should return nothing. `xnplus1`, `ptr_t` and `ptr_tr` are vectors where the next values are stored. `ptr_t` is of length 1 and stores the next time value (`ptr_t[1] = tn + delta_t`) whereas `ptr_tr` stores the name of the next transition/reaction (`ptr_tr[1] = :Infection` for example). This function is implemented in the package as: It should return nothing. `xnplus1`, `ptr_t` and `ptr_tr` are vectors where the next values are stored. `ptr_t` is of length 1 and stores the next time value (`ptr_t[1] = tn + delta_t`) whereas `ptr_tr` stores the name of the next transition/reaction (`ptr_tr[1] = :Infection` for example). This function is implemented in the package as:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
@everywhere function sir_f!(xnplus1::Vector{Int}, l_t::Vector{Float64}, l_tr::Vector{Transition}, @everywhere function sir_f!(xnplus1::Vector{Int}, l_t::Vector{Float64}, l_tr::Vector{Transition},
xn::Vector{Int}, tn::Float64, p::Vector{Float64}) xn::Vector{Int}, tn::Float64, p::Vector{Float64})
@inbounds a1 = p[1] * xn[1] * xn[2] @inbounds a1 = p[1] * xn[1] * xn[2]
@inbounds a2 = p[2] * xn[2] @inbounds a2 = p[2] * xn[2]
l_a = (a1, a2) l_a = (a1, a2)
asum = sum(l_a) asum = sum(l_a)
if asum == 0.0 if asum == 0.0
copyto!(xnplus1, xn) copyto!(xnplus1, xn)
return nothing return nothing
end end
nu_1 = (-1, 1, 0) nu_1 = (-1, 1, 0)
nu_2 = (0, -1, 1) nu_2 = (0, -1, 1)
l_nu = (nu_1, nu_2) l_nu = (nu_1, nu_2)
l_str_R = (:Infection, :Recovery) l_str_R = (:Infection, :Recovery)
u1 = rand() u1 = rand()
u2 = rand() u2 = rand()
tau = - log(u1) / asum tau = - log(u1) / asum
b_inf = 0.0 b_inf = 0.0
b_sup = a1 b_sup = a1
reaction = 0 reaction = 0
for i = 1:2 for i = 1:2
if b_inf < asum*u2 < b_sup if b_inf < asum*u2 < b_sup
reaction = i reaction = i
break break
end end
@inbounds b_inf += l_a[i] @inbounds b_inf += l_a[i]
@inbounds b_sup += l_a[i+1] @inbounds b_sup += l_a[i+1]
end end
nu = l_nu[reaction] nu = l_nu[reaction]
for i = 1:3 for i = 1:3
@inbounds xnplus1[i] = xn[i]+nu[i] @inbounds xnplus1[i] = xn[i]+nu[i]
end end
@inbounds l_t[1] = tn + tau @inbounds l_t[1] = tn + tau
@inbounds l_tr[1] = l_str_R[reaction] @inbounds l_tr[1] = l_str_R[reaction]
end end
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
The second function called `isaborbing` must have the signature: The second function called `isaborbing` must have the signature:
```julia ```julia
isabsorbing(p::Vector{Float64}, xn::Vector{Int}) isabsorbing(p::Vector{Float64}, xn::Vector{Int})
``` ```
This function checks if the state `xn` is an absorbing state according to the model parametrised by `p`. It has to return true or false. This function checks if the state `xn` is an absorbing state according to the model parametrised by `p`. It has to return true or false.
For a CTMC, a state is an absorbing state if the total exit rate is zero. In the case of the SIR model: For a CTMC, a state is an absorbing state if the total exit rate is zero. In the case of the SIR model:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
@everywhere sir_isabsorbing(p::Vector{Float64}, xn::Vector{Int}) = (p[1]*xn[1]*xn[2] + p[2]*xn[2]) === 0.0 @everywhere sir_isabsorbing(p::Vector{Float64}, xn::Vector{Int}) = (p[1]*xn[1]*xn[2] + p[2]*xn[2]) === 0.0
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Finally one sets the observed variables and the model can be created. Finally one sets the observed variables and the model can be created.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
g_sir = [:I] g_sir = [:I]
tryhard_sir = ContinuousTimeModel(dim_state_sir, dim_params_sir,
# Generates simulate method for the new model
@everywhere @eval $(MarkovProcesses.generate_code_model_type_def(:TryhardSIRModel))
@everywhere @eval $(MarkovProcesses.generate_code_model_type_constructor(:TryhardSIRModel))
@everywhere @eval $(MarkovProcesses.generate_code_simulation(:TryhardSIRModel, :sir_f!, :sir_isabsorbing))
tryhard_sir = TryhardSIRModel(dim_state_sir, dim_params_sir,
map_var_idx_sir, map_params_idx_sir, map_var_idx_sir, map_params_idx_sir,
transitions_sir, p_sir, x0_sir, t0_sir, transitions_sir, p_sir, x0_sir, t0_sir,
getfield(Main, :sir_f!), getfield(Main, :sir_isabsorbing); g = g_sir, name = "Handmade SIR") :sir_f!, :sir_isabsorbing; g = g_sir)
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
using Plots using Plots
σ = simulate(tryhard_sir) σ = simulate(tryhard_sir)
plot(times(σ), σ.I, linetype = :steppost) plot(times(σ), σ.I, linetype = :steppost)
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
``` ```
......
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# ABC-SMC with ContinuousTimeModel # ABC-SMC with ContinuousTimeModel
The package allows the run of ABC-SMC algorithm with models defined by the package. The package allows the run of ABC-SMC algorithm with models defined by the package.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
using MarkovProcesses using MarkovProcesses
using Distributions using Distributions
load_model("SIR") load_model("SIR")
set_time_bound!(SIR, 100.0) set_time_bound!(SIR, 100.0)
parametric_SIR = ParametricModel(SIR, (:ki, Uniform(0.001, 0.0015))) parametric_SIR = ParametricModel(SIR, (:ki, Uniform(0.001, 0.0015)))
vec_observations = [simulate(SIR)] vec_observations = [simulate(SIR)]
function dist_obs(vec_sim::Vector{Trajectory}, vec_observations::Vector{Trajectory}) function dist_obs(vec_sim::Vector{Trajectory}, vec_observations::Vector{Trajectory})
return dist_lp(vec_sim[1], vec_observations[1]; p=2) return dist_lp(vec_sim[1], vec_observations[1]; p=2)
end end
epsilon = 0.5 * dist_obs([simulate(SIR)], vec_observations) epsilon = 0.5 * dist_obs([simulate(SIR)], vec_observations)
@show epsilon @show epsilon
res_abc = abc_smc(parametric_SIR, vec_observations, dist_obs, nbr_particles = 100, tolerance = epsilon) res_abc = abc_smc(parametric_SIR, vec_observations, dist_obs, nbr_particles = 100, tolerance = epsilon)
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
using Plots using Plots
histogram(vec(res_abc.mat_p_end), weights = res_abc.weights) histogram(vec(res_abc.mat_p_end), weights = res_abc.weights)
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` julia ``` julia
``` ```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment