# anyHR
A collection of *hit-and-run Markov Chain Monte Carlo* algorithms for sampling of n-dimensional sets defined by arbitrary inequality constraints.
## Introduction
This tool implements some variants of the *hit and run* or *mixing* algorithms.
Let **S** be an open bounded set in n dimensions defined by inequality constraints of the form
f(x<sub>1</sub>,..., x<sub>n</sub>) < g(x<sub>1</sub>,..., x<sub>n</sub>), where f and g are arbitrary functions.
Let all parameters also have parameter ranges defined as intervals, so **S** is a subset of a hyperrectangle.
(As an example, one could impose ``x + y < 1`` in the two dimensional plane, with x in (0,1) and y in (0,1)).
Hit-and-run algorithms can be used to get a sample uniformly at random inside of this set **S**.
**anyHR** parses the parameters and their respective constraints and returns a number of samples that satisfy this spec,
while being distributed uniformly on the set of allowed values.
For more information on mixing algorithms see
## Installation
It is necessary to have a working installation of Python 3,
[pip](https://pip.pypa.io/en/stable/installing/) and [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) for the following installation process.
Open the target installation directory in a terminal and type
```bash
pip install anyHR
```
## Use
A minimal running example for the above specification can be sampled with the following code:
````python
# Import modules
import numpy as np
import matplotlib.pyplot as plt
from anyHR.constraint.Constraint import Constraints
from anyHR.hit_and_run.hit_and_run import HitAndRun
# Define variables to use
var_names = ['x', 'y']
# Define the set of constraint
c = Constraints(var_names)
c.add_constraint('x+y < 1')
# Define the bounding hyperrectangle
x_bound = [0, 1]
y_bound = [0, 1]
bounds = [x_bound, y_bound]
# build hr object
hr = HitAndRun(constraint=c, bounding_box=bounds)
# generate samples
samples = []
total_rejections = 0
nb_samples = 100
mixing = 10
for i in range(nb_samples * mixing):
sample, rejections = hr.next_sample()
# do some mixing in between samples
if i % mixing == 0:
samples.append(sample)
xs = [sample[0] for sample in samples]
ys = [sample[1] for sample in samples]
plt.scatter(xs,ys)
plt.show()
````
## References
For more information about mixing algorithms, see:
- Smith, R. L. (1984). Efficient Monte Carlo procedures for generating points uniformly distributed over bounded regions. Operations Research, 32(6), 1296-1308.
- Kiatsupaibul, S., Smith, R. L., & Zabinsky, Z. B. (2011). An analysis of a variation of hit-and-run for uniform sampling from general regions. ACM Transactions on Modeling and Computer Simulation (TOMACS), 21(3), 1-11.
- Neal, R. M. (2003). Slice sampling. The annals of statistics, 31(3), 705-767.
We also thank Abraham Lee for his implementation of the PSO algorithms which is used here.
See https://github.com/tisimst/pyswarm for more information.