Skip to main content

Efficiently generate samples from the Polya-Gamma distribution using a NumPy/SciPy compatible interface.

Project description

polya-gamma

PyPI - Wheel PyPI PyPI - License CircleCI Codecov PyPI - Downloads

Efficiently generate samples from the Polya-Gamma distribution using a NumPy/SciPy compatible interface.

Features

  • polyagamma is written in C and optimized for performance.
  • Very light and easy to install (pre-built wheels).
  • It is flexible and allows the user to sample using one of 4 available methods.
  • Input parameters can be scalars, arrays or both; allowing for easy generation of multi-dimensional samples without specifying the size.
  • Random number generation is thread safe.
  • The functional API resembles that of common numpy/scipy functions, therefore making it easy to plugin to existing libraries.

Dependencies

  • Numpy >= 1.19.0

Installation

To get the latest version of the package, one can install it by downloading the wheel/source distribution from the releases page, or using pip with the following shell command:

$ pip install polyagamma

To install the latest pre-release version, use:

$ pip install --pre -U polyagamma

Alternatively, once can install from source by cloning the repo. This requires an installation of poetry and the following shell commands:

$ git clone https://github.com/zoj613/polya-gamma.git
$ cd polya-gamma/
$ poetry install
# add package to python's path
$ export PYTHONPATH=$PWD:$PYTHONPATH 

Example

Python

import numpy as np
from polyagamma import polyagamma

# generate a PG(1, 0) sample
o = polyagamma()

# Get a 5 by 10 array of PG(1, 2) variates.
o = polyagamma(z=2, size=(5, 10))

# Pass sequences as input. Numpy's broadcasting rules apply here.
h = [[1.5, 2, 0.75, 4, 5],
     [9.5, 8, 7, 6, 0.9]]
o = polyagamma(h, -2.5)

# Pass an output array
out = np.empty(5)
polyagamma(out=out)
print(out)

# one can choose a sampling method from {devroye, alternate, gamma, saddle}.
# If not given, the default behaviour is a hybrid sampler that picks a method
# based on the parameter values.
o = polyagamma(method="saddle")

# one can also use an existing instance of `numpy.random.Generator` as a parameter.
# This is useful to reproduce samples generated via a given seed.
rng = np.random.default_rng(12345)
o = polyagamma(random_state=rng)

# If one is using a `numpy.random.RandomState` instance instead of the `Generator`
# class, the object's underlying bitgenerator can be passed as the value of random_state
bit_gen = np.random.RandomState(12345)._bit_generator
o = polyagamma(random_state=bit_gen)

# When passing a large input array for the shape parameter `h`, parameter value
# validation checks can be disabled to avoid some overhead, which may boost performance.
large_h = np.ones(1000000)
o = polyagamma(large_h, disable_checks=True)

C

For an example of how to use polyagamma in a C program, see here.

Benchmarks

Below are runtime plots of 20000 samples generated for various values of h and z, using each method. We restrict h to integer values to accomodate the devroye method, which cannot be used for non-integer h. The version of the package used to generate them is v1.1.1.

Generally:

  • The gamma method is slowest and should be avoided in cases where speed is paramount.
  • For h > 25, the saddle method is the fastest for any value of z.
  • For 0 <= z <= 2 and integer h < 15, the devroye method should be preferred.
  • For z > 2 and integer/non-integer h <= 25, the alternate method is the most efficient.
  • For h > 50 (or any value large enough), the normal approximation to the distribution is fastest (not reported in the above plot but it is around 10 times faster than the saddle method and also equally accurate).

Therefore, we devise a "hybrid/default" sampler that picks a sampler based on the above guidelines.

We also benchmark the hybrid sampler runtime with the sampler found in the pypolyagamma package (version 1.2.3). The version of NumPy we use is 1.19.0. We use the pgdrawv function which takes arrays as input. Below are runtime plots of 20000 samples for each value of h and z. Values of h range from 0.1 to 60, while z is set to 0, 2.5, 5, and 10.

It can be seen that when generating many samples at once for any given combination of parameters, polyagamma outperforms the pypolyagamma package. The exception is when very small (e.g h < 1). Although not shown here, for values of h larger than 50, we use the normal approximation method. It is also worth noting that the pypolygamma package is on average faster than ours at generating exactly one sample from the distribution. This is mainly due to the overhead introduced by creating the bitgenerator + acquiring/releasing the thread lock + doing parameter validation checks at every call to the function. This overhead can somewhat be mitigated by passing in a random generator instance at every call to the polyagamma function. For example, on an iPython session:

In [4]: %timeit polyagamma()
83.2 µs ± 1.02 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [5]: %timeit polyagamma(random_state=rng)
2.68 µs ± 29.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [6]: %timeit polyagamma(random_state=rng, disable_checks=True)
2.58 µs ± 22.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

To generate the above plots locally, run python scripts/benchmark.py --size=<some size> --z=<z value>. Note that the runtimes may differ than the ones reported here, depending on the machine this script is ran on.

Density Plots

Below are density plots of the PG(h, 0) distribution using each of the available methods. A plot generated using the pypolyagamma package is used for comparison.

Contributing

All contributions, bug reports, bug fixes, documentation improvements, enhancements, and ideas are welcome.

To submit a PR, follow the steps below:

  1. Fork the repo.
  2. Setup the dev environment with poetry install. All dependencies will be installed.
  3. Start writing your changes, including unittests.
  4. Once finished, run make install to build the project with the new changes.
  5. Once build is successful, run tests to make sure they all pass with make test.
  6. Once finished, you can submit a PR for review.

References

  • Luc Devroye. "On exact simulation algorithms for some distributions related to Jacobi theta functions." Statistics & Probability Letters, Volume 79, Issue 21, (2009): 2251-2259.
  • Polson, Nicholas G., James G. Scott, and Jesse Windle. "Bayesian inference for logistic models using Pólya–Gamma latent variables." Journal of the American statistical Association 108.504 (2013): 1339-1349.
  • J. Windle, N. G. Polson, and J. G. Scott. "Improved Polya-gamma sampling". Technical Report, University of Texas at Austin, 2013b.
  • Windle, Jesse, Nicholas G. Polson, and James G. Scott. "Sampling Polya-Gamma random variates: alternate and approximate techniques." arXiv preprint arXiv:1405.0506 (2014)
  • Windle, J. (2013). Forecasting high-dimensional, time-varying variance-covariance matrices with high-frequency data and sampling Pólya-Gamma random variates for posterior distributions derived from logistic likelihoods.(PhD thesis). Retrieved from http://hdl.handle.net/2152/21842 .

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

polyagamma-1.1.1.tar.gz (151.8 kB view details)

Uploaded Source

Built Distributions

polyagamma-1.1.1-cp39-cp39-manylinux2014_x86_64.whl (580.6 kB view details)

Uploaded CPython 3.9

polyagamma-1.1.1-cp39-cp39-manylinux2010_x86_64.whl (544.4 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.12+ x86-64

polyagamma-1.1.1-cp39-cp39-manylinux2010_x86_64.manylinux1_x86_64.whl (543.5 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.12+ x86-64

polyagamma-1.1.1-cp39-cp39-manylinux1_x86_64.manylinux2010_x86_64.whl (544.4 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.12+ x86-64

polyagamma-1.1.1-cp38-cp38-manylinux2014_x86_64.whl (571.0 kB view details)

Uploaded CPython 3.8

polyagamma-1.1.1-cp38-cp38-manylinux2010_x86_64.whl (561.1 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.12+ x86-64

polyagamma-1.1.1-cp38-cp38-manylinux1_x86_64.manylinux2010_x86_64.whl (561.1 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.12+ x86-64

polyagamma-1.1.1-cp37-cp37m-manylinux2014_x86_64.whl (554.7 kB view details)

Uploaded CPython 3.7m

polyagamma-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl (518.7 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.12+ x86-64

polyagamma-1.1.1-cp37-cp37m-manylinux1_x86_64.manylinux2010_x86_64.whl (518.7 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.12+ x86-64

File details

Details for the file polyagamma-1.1.1.tar.gz.

File metadata

  • Download URL: polyagamma-1.1.1.tar.gz
  • Upload date:
  • Size: 151.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.25.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.55.0 CPython/3.8.6

File hashes

Hashes for polyagamma-1.1.1.tar.gz
Algorithm Hash digest
SHA256 493c0a12c0c9aaa2369dfb5be355ddb3aa030819fba7b1ed86531fe378da744f
MD5 04fa67658ae83d3f938864c24ee2c304
BLAKE2b-256 347a993056e5183a2411d8b97ba5c18c699f6b7179bb6aae4d4e0aec443fb30e

See more details on using hashes here.

File details

Details for the file polyagamma-1.1.1-cp39-cp39-manylinux2014_x86_64.whl.

File metadata

  • Download URL: polyagamma-1.1.1-cp39-cp39-manylinux2014_x86_64.whl
  • Upload date:
  • Size: 580.6 kB
  • Tags: CPython 3.9
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.25.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.55.0 CPython/3.8.6

File hashes

Hashes for polyagamma-1.1.1-cp39-cp39-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2b3a43d0dc6ee85be9b1b75f76318749235915f462f66b1a3219b2608de64579
MD5 a919c70f1dd0280ddc9ac07ed5668e6c
BLAKE2b-256 6101f491dcb940c317b3586ec2a45f79da475b8b348bb8e4adf53c5748c69430

See more details on using hashes here.

File details

Details for the file polyagamma-1.1.1-cp39-cp39-manylinux2010_x86_64.whl.

File metadata

  • Download URL: polyagamma-1.1.1-cp39-cp39-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 544.4 kB
  • Tags: CPython 3.9, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.25.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.55.0 CPython/3.8.6

File hashes

Hashes for polyagamma-1.1.1-cp39-cp39-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 1ca1954cb0cd9e4b70c5338438bf5c662e719080a0ce541ea43d90201b7e6539
MD5 51a3723ac044a0b19e6865ded45f93e2
BLAKE2b-256 e72ebb728cd93f948ecf2c941bec1bfef800bc71bed5ed60825f7c69b6f912d0

See more details on using hashes here.

File details

Details for the file polyagamma-1.1.1-cp39-cp39-manylinux2010_x86_64.manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for polyagamma-1.1.1-cp39-cp39-manylinux2010_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 ba96f7053d3d27224a4e250cfbf01fbc2fc374dfdbe93373745a9d712b5fa804
MD5 ee5b64a6b2b694c492055117b1c2dd3d
BLAKE2b-256 d121807cc4a2846362e12caf4b8ddf33b4b9227c5877e806c8ea812de7ce1d0b

See more details on using hashes here.

File details

Details for the file polyagamma-1.1.1-cp39-cp39-manylinux1_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for polyagamma-1.1.1-cp39-cp39-manylinux1_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 57972b6922897bdda5077ff594c53d8867dcdcbc3b728d072067188b4ac28dda
MD5 38ff85e253b53f49654deb22d8f4751c
BLAKE2b-256 2656eaf9a88bdf7f70b40eb93f0905746c9b7e0f66f5a6f753047d5e92bc2986

See more details on using hashes here.

File details

Details for the file polyagamma-1.1.1-cp38-cp38-manylinux2014_x86_64.whl.

File metadata

  • Download URL: polyagamma-1.1.1-cp38-cp38-manylinux2014_x86_64.whl
  • Upload date:
  • Size: 571.0 kB
  • Tags: CPython 3.8
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.25.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.55.0 CPython/3.8.6

File hashes

Hashes for polyagamma-1.1.1-cp38-cp38-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 16224a9756d0e112f43018ef293cad1e0039f7ecfc494751e8bb1d210ead3026
MD5 2e6b4e5644dafe76dff02423648a3019
BLAKE2b-256 12c0c05b7293adb69269cbf911e0c0902326eb283be0c49c04159b921f94f119

See more details on using hashes here.

File details

Details for the file polyagamma-1.1.1-cp38-cp38-manylinux2010_x86_64.whl.

File metadata

  • Download URL: polyagamma-1.1.1-cp38-cp38-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 561.1 kB
  • Tags: CPython 3.8, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.25.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.55.0 CPython/3.8.6

File hashes

Hashes for polyagamma-1.1.1-cp38-cp38-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 9e03ece0b390b525cff14163bd265a2f0ff354c6cdfb2ac1f88d09ff29d72bcd
MD5 3a8bb9bc9eb77e97e014e0820649b94e
BLAKE2b-256 6a7553c1350a66df5797c360511c031fc34802012b21d86ffe588cbf8a8cfd99

See more details on using hashes here.

File details

Details for the file polyagamma-1.1.1-cp38-cp38-manylinux1_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for polyagamma-1.1.1-cp38-cp38-manylinux1_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 670d9569f8419a8fc24025c989f233e3cc167247e54e4fe0f02d099c63ff9269
MD5 580843ad7fb57acb96b5f215fbd90308
BLAKE2b-256 f911462785645c14a7b8027e86e497e858845208ed82ba3696f0f4f772ed7a83

See more details on using hashes here.

File details

Details for the file polyagamma-1.1.1-cp37-cp37m-manylinux2014_x86_64.whl.

File metadata

  • Download URL: polyagamma-1.1.1-cp37-cp37m-manylinux2014_x86_64.whl
  • Upload date:
  • Size: 554.7 kB
  • Tags: CPython 3.7m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.25.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.55.0 CPython/3.8.6

File hashes

Hashes for polyagamma-1.1.1-cp37-cp37m-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0e4e0e9a782f20e73e1ef1343bc43fbbee729443a367c2b5c84d74830b37e338
MD5 91b8e61cc396382e549610733fae65a2
BLAKE2b-256 f3f1dfa5e5aea0e60930d843a5ad598c1d3d666b578607880b72d0b20fea5b3c

See more details on using hashes here.

File details

Details for the file polyagamma-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl.

File metadata

  • Download URL: polyagamma-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 518.7 kB
  • Tags: CPython 3.7m, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.25.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.55.0 CPython/3.8.6

File hashes

Hashes for polyagamma-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 7c887b28a95db6596519c17c96043fb03cf96ae5a805d344d01bc9c527c7b9de
MD5 9f434e804fd3eae114555175ea9c3b4a
BLAKE2b-256 231ef9053ca31113f460f9382468c5afe372cbe199e9b0d4661ee06d98c6c503

See more details on using hashes here.

File details

Details for the file polyagamma-1.1.1-cp37-cp37m-manylinux1_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for polyagamma-1.1.1-cp37-cp37m-manylinux1_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 83761729650ba0976fe3a17d94b97add9f98eb3eb81ef362052e09e9bf27ab55
MD5 c4d768a956f49cf40bdae50a8340704a
BLAKE2b-256 9489b9388b1c7b11ed7c9a41024da28a227a7e90355186bab6d8ea22b54b185f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page