Skip to content

Commit

Permalink
Merge pull request #17 from TomMonks/dev
Browse files Browse the repository at this point in the history
README: added online docs link for v0.3.0
  • Loading branch information
TomMonks authored Feb 6, 2024
2 parents b12d27d + 1419837 commit bfd7afe
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 28 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/TomMonks/sim-tools/HEAD)
[![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/)
[![Read the Docs](https://readthedocs.org/projects/pip/badge/?version=latest)](https://tommonks.github.io/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)
Expand All @@ -19,11 +20,13 @@ sim-tools is being developed to support simulation education and applied simulat

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
## Three 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.
3. Oneline documentation: https://tommonks.github.io/sim-tools

## Citation

Expand All @@ -42,7 +45,7 @@ If you use sim0tools for research, a practical report, education or any reason p
}
```

# Examples
# Online Tutorials

* 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)

Expand Down
55 changes: 29 additions & 26 deletions sim_tools/time_dependent.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
"""
Classes and functions to support time dependent sampling
in DES models.
Classes and functions to support time dependent samplingm in DES models.
"""

import itertools
import pandas as pd
import numpy as np

from typing import Optional


class NSPPThinning:
"""
Non Stationary Poisson Process via Thinning.
Thinning is an acceptance-rejection approach to sampling
inter-arrival times (IAT) from a time dependent distribution
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.
There are two random variables employed in sampling: an exponential
Expand All @@ -23,43 +22,48 @@ class NSPPThinning:
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
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.
"""
def __init__(self, data, random_seed1: Optional[int]=None, random_seed2: Optional[int]=None):
'''

def __init__(
self,
data,
random_seed1: Optional[int] = None,
random_seed2: Optional[int] = None,
):
"""
Non Stationary Poisson Process via Thinning.
Time dependency is handled for a single table
consisting of equally spaced intervals.
consisting of equally spaced intervals.
Params:
------
data: pandas.DataFrame
list of time points during a period for transition between rates
and list arrival rates in that period. Labels should be "t"
and "arrival_rate" respectively.
and "arrival_rate" respectively.
random_seed1: int, optional (default=None)
Random seed for exponential distribution
random_seed2: int
Random seed for the uniform distribution used
for acceptance/rejection sampling.
'''

"""
self.data = data
self.arr_rng = np.random.default_rng(random_seed1)
self.thinning_rng = np.random.default_rng(random_seed2)
self.lambda_max = data['arrival_rate'].max()
self.lambda_max = data["arrival_rate"].max()
# assumes all other intervals are equal in length.
self.interval = int(data.iloc[1]['t'] - data.iloc[0]['t'])
self.interval = int(data.iloc[1]["t"] - data.iloc[0]["t"])
self.rejects_last_sample = None

def sample(self, simulation_time: float) -> float:
'''
"""
Run a single iteration of acceptance-rejection
thinning alg to sample the next inter-arrival time
Expand All @@ -73,25 +77,24 @@ def sample(self, simulation_time: float) -> float:
-------
float
The inter-arrival time
'''
"""
for _ in itertools.count():

# this gives us the index of dataframe to use
t = int(simulation_time // self.interval) % len(self.data)
lambda_t = self.data['arrival_rate'].iloc[t]
lambda_t = self.data["arrival_rate"].iloc[t]

# set to a large number so that at least 1 sample taken!
u = np.Inf

# included for audit and tracking purposes.
self.rejects_last_sample = 0.0

interarrival_time = 0.0

# reject samples if u >= lambda_t / lambda_max
while u >= (lambda_t / self.lambda_max):
self.rejects_last_sample += 1
interarrival_time += self.arr_rng.exponential(1/self.lambda_max)
interarrival_time += self.arr_rng.exponential(1 / self.lambda_max)
u = self.thinning_rng.uniform(0.0, 1.0)
return interarrival_time

return interarrival_time

0 comments on commit bfd7afe

Please sign in to comment.