This python library implements algorithms to simulate and study population processes, to compute their mean-field approximations and refined mean-field approximations for the transient regime and steady-state.
The tool accepts three model types:
- homogeneous population processes (HomPP)
- density dependent population processes (DDPPs)
- heterogeneous population models (HetPP)
In particular, it provides a numerical algorithm to compute the constant of the "refined mean field approximation" provided in the paper A Refined Mean Field Approximation by N. Gast and B. Van Houdt, accepted at SIGMETRICS 2018. And a framework to compute heterogeneous mean field approximations Mean Field and Refined Mean Field Approximations for Heterogeneous Systems: It Works! by N. Gast and S. Allmeier, accepted at SIGMETRICS 2022.
pip install rmftool
Clone the repository. For example by using the termin git client:
git clone https://github.com/ngast/rmf_tool
then manually add the package by using pip in the corresponding folder
pip install .
An extensive description of the supported classes can be found in the publication rmf tool – A library to Compute (Refined) Mean Field Approximation(s) by N. Gast and S. Allmeier. The example given in the publication can be found in the repository https://gitlab.inria.fr/gast/toolpaper_rmf
Homogeneous population model consists of
- (Unilateral) An object in state
$s$ moves to state$s'$ at rate$a_{s,s'}$ . - (Pairwise) A pair of objects in state
$(s,\tilde{s})$ moves to state$(s',\tilde{s}')$ at rate$b_{s,\tilde{s},s',\tilde{s}'}/n$ .
Homogeneous population models is a subclass of density dependent population processes (DDPPs) defined in the following.
A density dependent process is a Markov chain that evolves in a sub-domain of
-
$x \mapsto x + \frac 1N \ell$ at rate$\beta_\ell(x)$
The class DDPP can be used to defined a process, via the functions add_transition(l, beta)
.
As before, the heterogeneous population model consists of
- The object
$k$ moves from state$s$ to state$s'$ at rate$a_{k,s,s'}$ . - The pair
$(k,k')$ moves from states$(s,\tilde{s})$ to states$(s',\tilde{s}')$ at rate$b_{k,k',s,\tilde{s},s',\tilde{s}'}/n$ .
In order to obtain sample trajectories, mean field and refined mean field approximations the following methods can be used.
Description | Function DDPP & HomPP | Function HetPP |
---|---|---|
sample trajectoy | simulate(N, time) |
simulate(time) |
mean-field (or fluid) approximation | ode(time) |
ode(time) |
refined mean-field (transient) | meanFieldExpansionTransient(time) |
meanFieldExpansionTransient(time) |
refined mean-field (steady-state) | meanFieldExpansionSteadyState() |
meanFieldExpansionSteadyState() |
steady-state using simulation | steady_state_simulation(N, time=20000) |
- |
sample Mean trajectory | - | sampleMean(time, samples=1000) |
The functions are documented and their documentation is accessible by the "help" command.
Apart from that, the documentation is mostly contained in the examples below (from basic to more advanced).
The computation of the function meanFieldExpansionSteadyState
grows as symbolic_differentiation=True
(default), it takes about 10 seconds for a 50-dimensional system, about 60 seconds for a 100-dimensional system. Note that for large models, most of the time is taken by the computation of the symbolic derivatives. This time can be reduced when using symbolic_differentiation=False
to approximatively 4 sec for 50-dimensional systems and about 15 seconds for 100-dimensional systems (note: due to limitation of the lambdify function, the symbolic_differentiation=False cannot be used for systems with more than 255 dimensions).
The simulation of the underlying Markov chain is not optimized and therefore might be slow for large models.
The following code illustrates how to define a 2-dimensional model using the DDPP class. It plots the mean-field approximation versus one sample trajectory. It then computes the refined mean-field approximation (in steady-state)
import rmftool as rmf
ddpp = rmf.DDPP()
ddpp.add_transition([-1,1], lambda x : x[0])
ddpp.add_transition([1,-1], lambda x : x[1]+x[0]*x[1])
ddpp.set_initial_state([.5,.5])
ddpp.plot_ODE_vs_simulation(N=100)
One of the simplest examples of population process is the epidemic model called the SIS model. In an SIS model, each object can be in one of the two states
In the following, we illustrate the setup using the different available classes.
With our tool, we define a class called HomPP for which we specify the transition rates and an initial state. For the SIS model above, with
import rmftool as rmf
import numpy as np
model = rmf.HomPP()
d, S, I = 2, 0, 1
A, B = np.zeros((d, d)), np.zeros((d, d, d, d))
A[S, I] = 1 # unil. transitions from S to I (alpha)
A[I, S] = 1 # unil. transitions from I to S (beta)
B[S, I, I, I] = 1 # pairwise transition from S to I (gamma)
model.add_rate_tensors(A, B)
model.set_initial_state([1,0])
Using the class DDPP we can define density dependent population processes directly from their mathematical definition. For the above SIS example, we write:
import rmftool as rmf
model = rmf.DDPP()
alpha, beta, gamma = 1, 1, 1
model.add_transition([-1,1], lambda x: alpha*x[0])
model.add_transition([1,-1], lambda x: beta*x[1])
model.add_transition([-1,1], lambda x: gamma*x[0]*x[1])
model.set_initial_state([1,0])
To set up a heterogeneous version of the previous SIS model we use the HetPP class of the toolbox. In contrast to the HomPP and DDPP class, the model can not be defined independent of the system size, i.e.,
import rmftool as rmf
import numpy as np
model = rmf.HetPP()
N, d = 20, 2
S, I = 0, 1
A, B = np.zeros((N, d, d)), np.zeros((N, N, d, d, d, d))
A[:, S, I] = np.ones((N))
A[:, I, S] = np.random.rand(N) # Hetero. recovery rates
B[:, :, S, I, I, I] = (1/N) * np.ones((N, N))
model.add_rate_tensors(A, B)
model.set_initial_state(np.ones((N,d))*np.array([1,0]))
Following the setup the methods described in the subsection 'available functions' can be used to analyze the model. We point to
for a more detailed discussion on how to use the toolbox.
More examples can be found in the example directory and in the rmf_tool paper repository - https://gitlab.inria.fr/gast/toolpaper_rmf/-/tree/master/code.
This library depends on the following python library:
- numpy
- random
- scipy
- sympy
- matplotlib.pyplot
- jax
- v0.3:
- (New feature) Added two new population classes (HomPP, HetPP) with support for simulation, mean field and first order refined mean field approximation
- v0.2:
- (New feature) Support for multi-class variables
- (Optimization) Addition of an option to use a numerical differentiation
- v0.1: original version
Copyright 2017. Authors : Nicolas Gast, Emmanuel Rodriguez, Sebastian Allmeier