Skip to content

Commit

Permalink
Draw functions with flexible number of parameters (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
twallema authored Jul 25, 2024
1 parent 09355c1 commit 237940a
Show file tree
Hide file tree
Showing 17 changed files with 413 additions and 226 deletions.
4 changes: 2 additions & 2 deletions docs/enzyme_kinetics.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# A model for the enzymatic esterification of D-glucose and Lauric acid in a continuous-flow reactor

This tutorial is based on: Tijs W. Alleman. (2019). Model-Based Analysis of Enzymatic Reactions in Continuous Flow Reactors (master dissertation). Ghent University, Ghent, BE.
This tutorial is based on: Tijs W. Alleman. (2019). Model-Based Analysis of Enzymatic Reactions in Continuous Flow Reactors (master dissertation). Ghent University, Ghent, BE, and is showcased in our [software paper](https://www.sciencedirect.com/science/article/pii/S1877750323002089).

## Introduction

Expand Down Expand Up @@ -265,7 +265,7 @@ if __name__ == '__main__':
# Update initial condition
model.initial_states.update(initial_states[i])
# Simulate model
out = model.sim(1600, N=n, draw_function=draw_fcn, samples=samples_dict)
out = model.sim(1600, N=n, draw_function=draw_fcn, draw_function_kwargs={'samples': samples_dict})
# Add 4% observational noise
out = add_gaussian_noise(out, 0.04, relative=True)
# Visualize
Expand Down
16 changes: 9 additions & 7 deletions docs/influenza_1718.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# An stochastic jump process model for the 2017-2018 Influenza Season in Belgium

In this tutorial, we'll set up a stochastic age-stratified model for seasonal Influenza in Belgium. First, we'll expand the dynamics of the [simple SIR model](workflow.md) to account for additional charateristics of seasonal Influenza and we'll use the concept of *dimensions* to include four age groups in our model. Opposed to the simple SIR tutorial, where changes in the number of social contacts were not considered, we'll use a *time-dependent parameter function* to include the effects of school closures during school holidays in our Influenza model. Finally, we'll calibrate two of the model's parameters to incrementally larger sets of incidence data and asses how the goodness-of-fit evolves with the amount of knowledge at our disposal. One of the calibrated model parameters is a 1D vector, pySODM allows users to easily calibrate n-dimensional model parameters.
This tutorial is showcased in our [software paper](https://www.sciencedirect.com/science/article/pii/S1877750323002089).

We'll set up a simple stochastic model for Influenza in Belgium. First, we'll expand the dynamics of the [simple SIR model](workflow.md) to account for additional disease charateristics of Influenza, and we'll use the concept of *dimensions* to include four age groups in our model (called 'age strata'). Opposed to the simple SIR tutorial, where changes in the number of social contacts were not considered, we'll demonstrate how to use a *time-dependent parameter function* to include the effects of school closures during school holidays in our Influenza model. Finally, we'll calibrate two of the model's parameters to incrementally larger sets of incidence data and asses how the goodness-of-fit evolves with the amount of knowledge at our disposal. One of the calibrated model parameters will be a 1D vector, pySODM allows users to easily calibrate n-dimensional model parameters.

This tutorial introduces the following concepts,
- Building a stochastic model and simulate it with Gillespie's Tau-Leaping method (which is a form of jump process)
- Adding age groups to a dynamic transmission model of disease
- Calibrating n-D parameters to n-D datasets
1. Building a stochastic model and simulate it with Gillespie's Tau-Leaping method
2. Extending an SIR model with age strata and using a social contact matrix
3. Calibrating an n-D model parameter to an n-D dataset

This tutorial can be replicated by running
```bash
Expand Down Expand Up @@ -301,11 +303,11 @@ if __name__ == '__main__':
data=[df_influenza[start_date:end_calibration], ]
states = ["Im_inc",]
log_likelihood_fnc = [ll_negative_binomial,]
log_likelihood_fnc_args = [5*[0.03,],]
log_likelihood_fnc_args = [4*[0.03,],]
# Calibated parameters and bounds
pars = ['beta', 'f_a']
labels = ['$\\beta$', '$f_a$']
pars = ['beta', 'f_ud']
labels = ['$\\beta$', '$f_{ud}$']
bounds = [(1e-6,0.06), (0,0.99)]
# Setup objective function (no priors --> uniform priors based on bounds)
Expand Down
2 changes: 1 addition & 1 deletion docs/installation.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Installation

### Quick and dirty installation
### Fast & Furious

```
pip install pySODM
Expand Down
6 changes: 3 additions & 3 deletions docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ pip install pySODM

### Resources

Documentation: https://twallema.github.io/pySODM
1. [Documentation website](https://twallema.github.io/pySODM)

Manuscript: https://www.sciencedirect.com/science/article/pii/S1877750323002089
2. [Manuscript](https://www.sciencedirect.com/science/article/pii/S1877750323002089)

pyPI: https://pypi.org/project/pySODM/
3. [pyPI](https://pypi.org/project/pySODM/)

### Aim & Scope

Expand Down
164 changes: 113 additions & 51 deletions docs/models.md

Large diffs are not rendered by default.

22 changes: 10 additions & 12 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,24 +238,24 @@ class SIR(JumpProcess):

### Draw functions

The `sim()` method of the `ODE` and `JumpProcess` classes can be used to perform {math}`N` repeated simulations by using the optional argument `N`. A *draw function* can be used to alter the value of a model parameters during consecutive model runs by drawing them rrandomly from a list of samples, thereby offering a powerful tool for sensitivity analysis and uncertainty propagation.
The simulation functions of the `ODE` and `JumpProcess` classes (`sim()`) can be used to perform {math}`N` repeated simulations by using the optional argument `N`. A *draw function* can be used to instruct the model on how to alter the value of a model parameters during consecutive model runs, thereby offering a powerful tool for sensitivity analysis and uncertainty propagation.

Draw functions **always** take two dictionaries as input: 1) The dictionary of model parameters, 2) A dictionary containing samples of a model parameter. Assuming we have a list containing 100 samples of the parameter `gamma`, drawn randomly from 0 to 5,
Draw functions **always** take the dictionary of model parameters, `parameters` as their first argument, input checks are used to ensure you provide the correct name and type. This can be followed an arbitrary number of user-defined parameters, which are supplied to the `sim()` function by using its `draw_function_kwargs` argument. The output of a draw function is **always** the dictionary of model parameters, without alterations to the dictionaries keys (no new parameters introduced or parameters deleted). In the example below, we attempt to draw a model parameter `gamma` randomly from 0 to 5,

```python
# make an example of a dictionary containing parameter samples
samples_dict = {'gamma': np.random.uniform(low=0, high=5, n=100)}
# make an example of a dictionary containing samples of a parameter `gamma`
samples = np.random.uniform(low=0, high=5, n=100)

# define a 'draw function'
def draw_function(parameters, samples):
""" randomly selects a sample of 'gamma' from the provided dictionary of samples and
assigns it to the dictionary of model parameters
"""
parameters['gamma'] = np.random.choice(samples['gamma'])
parameters['gamma'] = np.random.choice(samples)
return parameters

# simulate 10 trajectories, exploit 10 cores to speed up the computation
out = model.sim(121, N=10, draw_function=draw_function, samples=samples_dict, processes=10)
out = model.sim(121, N=10, draw_function=draw_function, draw_function_kwargs={'samples': samples}, processes=10)
print(out)
```

Expand All @@ -274,20 +274,18 @@ Data variables:
R (draws, age_groups, time) float64 0.0 0.3439 ... 684.0 684.0
```

This example is more easily coded up by drawing the random values within the *draw function*,
This example can also be coded up by drawing the random values within the *draw function*,

```python
# define a 'draw function'
def draw_function(parameters, samples):
def draw_function(parameters):
parameters['gamma'] = np.random.uniform(low=0, high=5)
return parameters

# simulate the model
out = model.sim(121, N=10, draw_function=draw_function, samples={})
out = model.sim(121, N=10, draw_function=draw_function)
```
**_NOTE_** Internally, a call to `draw_function` is made within the `sim()` function, where it is given the dictionary of model parameters and the input argument `samples` of the `sim()` function.

**_NOTE:_** Technically, you can supply any input you'd like to a *draw function* by exploiting its `samples` dictionary input. Aside from its name and type, `samples` is not subject to any input checks.
**_NOTE_** Internally, a call to `draw_function` is made within the `sim()` function, where it is given the dictionary of model parameters `parameters`, followed by the `draw_function_kwargs`.

### Time-dependent parameter functions

Expand Down
6 changes: 4 additions & 2 deletions docs/references.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ In addition to the tutorials listed on the documentation website, we've used pyS

- Alleman T.W., Vergeynst J., De Visscher L., Rollier M., Torfs E., Nopens I., Baetens J.M. (2021). Assessing the effects of non-pharmaceutical interventions on SARS-CoV-2 transmission in Belgium by means of an extended SEIQRD model and public mobility data. *Epidemics*, 37(9). https://doi.org/10.1016/j.epidem.2021.100505

- Alleman T.W., Rollier M., Vergeynst J., Baetens J.M. (2022). A Mobility-Driven Spatially Explicit SEIQRD COVID-19 Model with VOCs, vaccines and seasonality. *Accepted for publication in Applied Mathematical Modeling*. https://doi.org/10.48550/ARXIV.2207.03717
- Alleman T.W., Rollier M., Vergeynst J., Baetens J.M. (2023). A Mobility-Driven Spatially Explicit SEIQRD COVID-19 Model with VOCs, vaccines and seasonality. *Applied Mathematical Modeling*, 123, 507:525. https://doi.org/10.1016/j.apm.2023.06.027

- Alleman T.W., Schoors K., Baetens J.M. (2023). Validating a dynamic input-output model for the propagation of supply and demand shocks during the COVID-19 pandemic in Belgium. *arXiv*. https://arxiv.org/abs/2305.16377
- Alleman T.W., Schoors K., Baetens J.M. (2023). Validating a dynamic input-output model for the propagation of supply and demand shocks during the COVID-19 pandemic in Belgium. *arXiv*. https://arxiv.org/abs/2305.16377

- Alleman T.W., Baetens J.M. (2024). Assessing the impact of forced and voluntary behavioral changes on economic-epidemiological co-dynamics: A comparative case study between Belgium and Sweden during the 2020 COVID-19 pandemic. *arXiv*. https://arxiv.org/abs/2401.08442
Loading

0 comments on commit 237940a

Please sign in to comment.