Skip to content

Commit

Permalink
Merge pull request #16 from TomMonks/dev
Browse files Browse the repository at this point in the history
Updates for v0.3.0
  • Loading branch information
TomMonks authored Feb 6, 2024
2 parents 0d86caa + dad7949 commit b12d27d
Show file tree
Hide file tree
Showing 18 changed files with 3,155 additions and 32 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# jupyter-book build folder for docs
docs/_build/*

# vscode
.vscode/

Expand Down
24 changes: 24 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# Change log

## v0.3.0

* Distributions classes now have python type hints.
* Added distributions and time dependent arrivals via thinning example notebooks.
* Added `datasets` module and function to load example NSPP dataset.
* Distributions added
* Erlang (mean and stdev parameters)
* ErlangK (k and theta parameters)
* Poisson
* Beta
* Gamma
* Weibull
* PearsonV
* PearsonVI
* Discrete (values and observed frequency parameters)
* ContinuousEmpirical (linear interpolation between groups)
* RawEmpirical (resample with replacement from individual X's)
* TruncatedDistribution (arbitrary truncation of any distribution)
* Added sim_tools.time_dependent module that contains `NSPPThinning` class for modelling time dependent arrival processes.
* Updated test suite for distributions and thinning
* Basic Jupyterbook of documentation.



## v0.2.0

* Added `sim_tools.distribution` module. This contains classes representing popular sampling distributions for Discrete-event simulation. All classes encapsulate a `numpy.random.Generator` object, a random seed, and the parameters of a sampling distribution.
Expand Down
2 changes: 2 additions & 0 deletions binder/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ dependencies:
- scipy=1.11.3
- scikit-learn=1.3.2
- pip:
- jupyter-book==1.0.0
- sim-tools

58 changes: 58 additions & 0 deletions docs/00_front_page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
![DOI](https://zenodo.org/badge/225608065.svg)](https://zenodo.org/badge/latestdoi/225608065)
[![PyPI version fury.io](https://badge.fury.io/py/sim-tools.svg)](https://pypi.python.org/pypi/sim-tools/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/release/python-360+/)
[![License: MIT](https://img.shields.io/badge/ORCID-0000--0003--2631--4481-brightgreen)](https://orcid.org/0000-0003-2631-4481)

sim-tools is being developed to support simulation education and applied simulation research. It is MIT licensed and freely available to practitioners, students and researchers via PyPi. There is a longer term plan to make sim-tools available via conda-forge.

# Vision for sim-tools

1. Deliver high quality reliable code for simulation education and practice with full documentation.
2. Provide a simple to use pythonic interface.
3. To improve the quality of simulation education and encourage the use of best practice.

# Features:

1. Implementation of classic optimisation via Simulation procedures such as KN, KN++, OBCA and OBCA-m
2. Distributions module that includes classes that encapsulate a random number stream, seed, and distribution parameters.
3. Implementation of Thinning to sample from Non-stationary poisson processes in a discrete-event simulation

## Two simple ways to explore sim-tools

1. `pip install sim-tools`
2. Click on the launch-binder at the top of this readme. This will open example Jupyter notebooks in the cloud via Binder.

## Citation

If you use sim0tools for research, a practical report, education or any reason please include the following citation.

> Monks, Thomas. (2021). sim-tools: tools to support the forecasting process in python. Zenodo. http://doi.org/10.5281/zenodo.4553642
```tex
@software{sim_tools,
author = {Thomas Monks},
title = {sim-tools: fundamental tools to support the simulation process in python},
year = {2021},
publisher = {Zenodo},
doi = {10.5281/zenodo.4553642},
url = {http://doi.org/10.5281/zenodo.4553642}
}
```

# Examples

* Optimisation Via Simulation [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/TomMonks/sim-tools/blob/master/examples/sw21_tutorial.ipynb)


## Contributing to sim-tools

Please fork Dev, make your modifications, run the unit tests and submit a pull request for review.

Development environment:

* `conda env create -f binder/environment.yml`

* `conda activate sim_tools`

**All contributions are welcome!**
381 changes: 381 additions & 0 deletions docs/01_sampling/01_distributions_examples.ipynb

Large diffs are not rendered by default.

256 changes: 256 additions & 0 deletions docs/01_sampling/02_time_dependent_examples.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Time dependent arrivals via thinning\n",
"\n",
"This notebook provides an overview of how to use the `time_dependent.NSPPThinning` class. \n",
"\n",
"Thinning is an acceptance-rejection approach to sampling inter-arrival times (IAT) from a time dependent distribution where each time period follows its own exponential distribution.\n",
"\n",
"There are two random variables employed in sampling: an exponential distribution (used to sample IAT) and a uniform distibution (used to accept/reject samples).\n",
"\n",
"All IATs are sampled from an Exponential distribution with the highest arrival rate (most frequent). These arrivals are then rejected (thinned) proportional to the ratio of the current arrival rate to the maximum arrival rate. The algorithm executes until a sample is accepted. The IAT returned is the sum of all the IATs that were sampled.\n",
"\n",
"## The thinning algorithm\n",
"\n",
"A NSPP has arrival rate $\\lambda(t)$ where $0 \\leq t \\leq T$\n",
"\n",
"Here $i$ is the arrival number and $\\mathcal{T_i}$ is its arrival time.\n",
"\n",
"1. Let $\\lambda^* = \\max_{0 \\leq t \\leq T}\\lambda(t)$ be the maximum of the arrival rate function and set $t = 0$ and $i=1$\n",
"\n",
"2. Generate $e$ from the exponential distribution with rate $\\lambda^*$ and let $t = t + e$ (this is the time of the next entity will arrive)\n",
"\n",
"3. Generate $u$ from the $U(0,1)$ distribution. If $u \\leq \\dfrac{\\lambda(t)}{\\lambda^*}$ then $\\mathcal{T_i} =t$ and $i = i + 1$\n",
"\n",
"4. Go to Step 2."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## `sim-tools` imports"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from sim_tools.datasets import load_banks_et_al_nspp\n",
"from sim_tools.time_dependent import NSPPThinning"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example from Banks et al.\n",
"\n",
"We will illustrate the use of `NSPPThinning` using an example from Banks et al. \n",
"\n",
"The table below breaks an arrival process down into 60 minutes intervals.\n",
"\n",
"\n",
"| t(min) | Mean time between arrivals (min) | Arrival Rate $\\lambda(t)$ (arrivals/min) |\n",
"|:------:|:--------------------------------:|:--------------------------------------:|\n",
"| 0 | 15 | 1/15 |\n",
"| 60 | 12 | 1/12 |\n",
"| 120 | 7 | 1/7 |\n",
"| 180 | 5 | 1/5 |\n",
"| 240 | 8 | 1/8 |\n",
"| 300 | 10 | 1/10 |\n",
"| 360 | 15 | 1/15 |\n",
"| 420 | 20 | 1/20 |\n",
"| 480 | 20 | 1/20 |\n",
"\n",
"\n",
"> **Interpretation**: In the table above the fastest arrival rate is 1/5 customers per minute or 5 minutes between customer arrivals."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>t</th>\n",
" <th>mean_iat</th>\n",
" <th>arrival_rate</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0</td>\n",
" <td>15</td>\n",
" <td>0.066667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>60</td>\n",
" <td>12</td>\n",
" <td>0.083333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>120</td>\n",
" <td>7</td>\n",
" <td>0.142857</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>180</td>\n",
" <td>5</td>\n",
" <td>0.200000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>240</td>\n",
" <td>8</td>\n",
" <td>0.125000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>300</td>\n",
" <td>10</td>\n",
" <td>0.100000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>360</td>\n",
" <td>15</td>\n",
" <td>0.066667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>420</td>\n",
" <td>20</td>\n",
" <td>0.050000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>480</td>\n",
" <td>20</td>\n",
" <td>0.050000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" t mean_iat arrival_rate\n",
"0 0 15 0.066667\n",
"1 60 12 0.083333\n",
"2 120 7 0.142857\n",
"3 180 5 0.200000\n",
"4 240 8 0.125000\n",
"5 300 10 0.100000\n",
"6 360 15 0.066667\n",
"7 420 20 0.050000\n",
"8 480 20 0.050000"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = load_banks_et_al_nspp()\n",
"data"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"37.46 Patient arrival (IAT=37.46)\n",
"73.02 Patient arrival (IAT=35.56)\n",
"89.41 Patient arrival (IAT=16.39)\n",
"96.79 Patient arrival (IAT=7.38)\n",
"98.37 Patient arrival (IAT=1.58)\n",
"104.94 Patient arrival (IAT=6.57)\n",
"112.30 Patient arrival (IAT=7.35)\n",
"121.49 Patient arrival (IAT=9.19)\n",
"127.62 Patient arrival (IAT=6.14)\n",
"135.25 Patient arrival (IAT=7.63)\n",
"135.64 Patient arrival (IAT=0.39)\n",
"141.91 Patient arrival (IAT=6.27)\n",
"148.23 Patient arrival (IAT=6.32)\n",
"155.26 Patient arrival (IAT=7.04)\n",
"158.47 Patient arrival (IAT=3.21)\n"
]
}
],
"source": [
"# create arrivals and set random number seeds\n",
"SEED_1 = 42\n",
"SEED_2 = 101\n",
"arrivals = NSPPThinning(data, SEED_1, SEED_2)\n",
"\n",
"# number of arrivals to simulate\n",
"n_arrivals = 15\n",
"\n",
"# run simulation\n",
"simulation_time = 0.0\n",
"for _ in range(n_arrivals):\n",
" iat = arrivals.sample(simulation_time)\n",
" simulation_time += iat\n",
" print(f'{simulation_time:.2f} Patient arrival (IAT={iat:.2f})')\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "sim_tools",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading

0 comments on commit b12d27d

Please sign in to comment.