Skip to main content

Fast Simulation of Hyperplane-Truncated Multivatiate Normal Distributions

Project description

htnorm

This repo provides a C implementation of a fast and exact sampler from a multivariate normal distribution (MVN) truncated on a hyperplane as described here

this repo implements the following from the paper:

  • efficient Sampling from a MVN truncated on a hyperplane:

    hptrunc

  • efficient sampling from a MVN with a stuctured precision matrix:

    struc

  • efficent sampling frfom a MVN with a structured precision and mean:

    strucmean

The algorithms implemented have the following practical applications:

  • Topic models when unknown parameters can be interpreted as fractions.
  • Admixture models
  • discrete graphical models
  • Sampling from posterior distribution of an Intrinsic Conditional Autoregressive prior icar
  • Sampling from posterior conditional distributions of various bayesian regression problems.

Dependencies

  • a C compiler that supports the C99 standard or later
  • an installation of BLAS and LAPACK that exposes its C interface via the headers <cblas.h> and <lapacke.h> (e.g openBLAS).

Usage

Building a shared library of htnorm can be done with the following:

$ cd src/
# optionally set path to CBLAS and LAPACKE headers using INCLUDE_DIRS environmental variable
$ export INCLUDE_DIRS="some/path/to/headers" 
# optionally set path to BLAS installation shared library
$ export LIBS_DIR="some/path/to/library/"
# optionally set the linker flag for your BLAS installation (e.g -lopenblas)
$ export LIBS=<flag here>
$ make lib

Afterwards the shared library will be found in a lib/ directory of the project root, and the library can be linked dynamically via -lhtnorm.

The puplic API exposes the samplers through the function declarations

  • int htn_hyperplane_truncated_mvn(rng_t* rng, const ht_config_t* conf, double* out)
  • int htn_structured_precision_mvn(rng_t* rng, const sp_config_t* conf, double* out)

The details of the parameters are documented in ther header files "htnorm.h".

Random number generation is done using PCG64 or Xoroshiro128plus bitgenerators. The API allows using a custom generator, and the details are documented in the header file "rng.h".

Examples

#include "htnorm.h"

int main ()
{
    ...

    // instantiate a random number generator
    rng_t* rng = rng_new_pcg64();
    ht_config_t config;
    config.g = ...; // G matrix
    config.gnrow = ...; // number of rows of G
    config.gncol = ...; // number of columns of G
    cofig.r = ...; // r array
    config.mean = ...; // mean array
    config.cov = ...; // the convariance matrix
    confi.diag = ...; // whether covariance is diagonal

    double* samples = ...; // array to store the samples
    // now call the sampler
    int res_info = htn_hyperplane_truncated_mvn(rng, &config, samples);

    // res_info contains a number that indicates whether sampling failed or not.

    ...

    // finally free the RNG pointer at some point
    rng_free(rng);

    ...
    return 0;
}

Python API

A high level python interface to the library is also provided. Linux users can install it using wheels via pip (thus not needing to worry about availability of C libraries),

pip install pyhtnorm

Wheels are not provided for MacOS. To install via pip, one can run the following commands:

#set the path to BLAS installation headers
export INCLUDE_DIR=<path/to/headers>
#set the path to BLAS shared library
export LIBS_DIR=<some directory>
#set the name of the BLAS shared library (e.g. "openblas")
export LIBS=<lib name>
# finally install via pip so the compilation and linking can be done correctly
pip install pyhtnorm

Alternatively, one can install it from source. This requires an installation of poetry and the following shell commands:

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

Below is an example of how to use htnorm in python to sample from a multivariate gaussian truncated on the hyperplane sumzero (i.e. making sure the sampled values sum to zero)

from pyhtnorm import HTNGenerator
import numpy as np

rng = HTNGenerator()

# generate example input
k1 = 1000
k2 = 1
npy_rng = np.random.default_rng()
temp = npy_rng.random((k1, k1))
cov = temp @ temp.T + np.diag(npy_rng.random(k1))
G = np.ones((k2, k1))
r = np.zeros(k2)
mean = npy_rng.random(k1)

samples = rng.hyperplane_truncated_mvnorm(mean, cov, G, r)
# verify if sampled values sum to zero
print(sum(samples))

# alternatively one can pass an array to store the results in
out = np.empty(k1)
rng.hyperplane_truncated_mvnorm(mean, cov, G, r, out=out)
# verify
print(out.sum())

For more details about the parameters of the HTNGenerator and its methods, see the docstrings via python's help function.

The python API also exposes the HTNGenerator class as a Cython extension type that can be "cimported" in a cython script.

TODO

  • Add an R interface to the library.

Licensing

htnorm is free software made available under the BSD-3 License. For details see the LICENSE file.

References

  • Cong, Yulai; Chen, Bo; Zhou, Mingyuan. Fast Simulation of Hyperplane-Truncated Multivariate Normal Distributions. Bayesian Anal. 12 (2017), no. 4, 1017--1037. doi:10.1214/17-BA1052.
  • Bhattacharya, A., Chakraborty, A., and Mallick, B. K. (2016). “Fast sampling with Gaussian scale mixture priors in high-dimensional regression.” Biometrika, 103(4):985.

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

pyhtnorm-0.1.1.tar.gz (144.7 kB view details)

Uploaded Source

Built Distributions

pyhtnorm-0.1.1-cp38-cp38-manylinux2014_x86_64.whl (11.0 MB view details)

Uploaded CPython 3.8

pyhtnorm-0.1.1-cp38-cp38-manylinux2010_x86_64.whl (10.0 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.12+ x86-64

pyhtnorm-0.1.1-cp38-cp38-manylinux1_x86_64.whl (14.1 MB view details)

Uploaded CPython 3.8

pyhtnorm-0.1.1-cp37-cp37m-manylinux2014_x86_64.whl (10.9 MB view details)

Uploaded CPython 3.7m

pyhtnorm-0.1.1-cp37-cp37m-manylinux2010_x86_64.whl (9.9 MB view details)

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

pyhtnorm-0.1.1-cp37-cp37m-manylinux1_x86_64.whl (14.1 MB view details)

Uploaded CPython 3.7m

pyhtnorm-0.1.1-cp36-cp36m-manylinux2014_x86_64.whl (10.9 MB view details)

Uploaded CPython 3.6m

pyhtnorm-0.1.1-cp36-cp36m-manylinux2010_x86_64.whl (9.9 MB view details)

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

pyhtnorm-0.1.1-cp36-cp36m-manylinux1_x86_64.whl (14.1 MB view details)

Uploaded CPython 3.6m

File details

Details for the file pyhtnorm-0.1.1.tar.gz.

File metadata

  • Download URL: pyhtnorm-0.1.1.tar.gz
  • Upload date:
  • Size: 144.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.9

File hashes

Hashes for pyhtnorm-0.1.1.tar.gz
Algorithm Hash digest
SHA256 3ea000c11a535858e176cc137d524404d97849211959e2b8388bf57670e40bbb
MD5 2ebceac41617c3b8058a74994148dbc3
BLAKE2b-256 50a2f08e4a26a356ea8ce45425ee87834305878f139443943770bb4f725ac2e0

See more details on using hashes here.

File details

Details for the file pyhtnorm-0.1.1-cp38-cp38-manylinux2014_x86_64.whl.

File metadata

  • Download URL: pyhtnorm-0.1.1-cp38-cp38-manylinux2014_x86_64.whl
  • Upload date:
  • Size: 11.0 MB
  • Tags: CPython 3.8
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.9

File hashes

Hashes for pyhtnorm-0.1.1-cp38-cp38-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ba21100298d9d0c805337e801be227bc07e5604e15b2e526167bfc20de59a3cb
MD5 f66f95867c8b75ffd5af010a3d785ed1
BLAKE2b-256 b19ed8df33ce10c26464f075f0126eec06f3d09055d89f5307792ca994d287cd

See more details on using hashes here.

File details

Details for the file pyhtnorm-0.1.1-cp38-cp38-manylinux2010_x86_64.whl.

File metadata

  • Download URL: pyhtnorm-0.1.1-cp38-cp38-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 10.0 MB
  • Tags: CPython 3.8, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.9

File hashes

Hashes for pyhtnorm-0.1.1-cp38-cp38-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 55adbef96e9608f27358481649aa740cecd0b7a44c448e29f51d7fda810874d8
MD5 ebb5f3bbf6bd87af9c4b04ed6182c97a
BLAKE2b-256 6224a0d89e5c8fba30340594b7433ed4aff320537beb5530006406372103e3ba

See more details on using hashes here.

File details

Details for the file pyhtnorm-0.1.1-cp38-cp38-manylinux1_x86_64.whl.

File metadata

  • Download URL: pyhtnorm-0.1.1-cp38-cp38-manylinux1_x86_64.whl
  • Upload date:
  • Size: 14.1 MB
  • Tags: CPython 3.8
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.9

File hashes

Hashes for pyhtnorm-0.1.1-cp38-cp38-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 a8b30d0424913ab1fd8efcb3ef0b44eae77c85c5aa7db1ebddc7dbfa4d16a820
MD5 857abab3bd99344f1bd45b01b3a14ae6
BLAKE2b-256 3da13c565348b4c3a6db0d41a66ee20e6ecde254280a9747d5d63ffd72902a34

See more details on using hashes here.

File details

Details for the file pyhtnorm-0.1.1-cp37-cp37m-manylinux2014_x86_64.whl.

File metadata

  • Download URL: pyhtnorm-0.1.1-cp37-cp37m-manylinux2014_x86_64.whl
  • Upload date:
  • Size: 10.9 MB
  • Tags: CPython 3.7m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.9

File hashes

Hashes for pyhtnorm-0.1.1-cp37-cp37m-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f14cfecbeeace02c1b855ff2d3d2b6bd586d4b05e9e919435ba0864cbe5377d7
MD5 699f55c32dc1df37f557c95685d3c3da
BLAKE2b-256 05be79bbc4734f4efb0b975f14b08e7ffb71f3d0e3d5d69ab1653a6580c22fca

See more details on using hashes here.

File details

Details for the file pyhtnorm-0.1.1-cp37-cp37m-manylinux2010_x86_64.whl.

File metadata

  • Download URL: pyhtnorm-0.1.1-cp37-cp37m-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 9.9 MB
  • Tags: CPython 3.7m, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.9

File hashes

Hashes for pyhtnorm-0.1.1-cp37-cp37m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 ad52245f7b488748d33e8b98e112044df9d8234e35b8d75c481209e78f7d11ff
MD5 664dcd6e8adc6387fe0c0f417eaae2e3
BLAKE2b-256 debb2ed7f0587856378f872c04b1c2d9b5b91cbe8931ff16d41c95f22b1c0ba0

See more details on using hashes here.

File details

Details for the file pyhtnorm-0.1.1-cp37-cp37m-manylinux1_x86_64.whl.

File metadata

  • Download URL: pyhtnorm-0.1.1-cp37-cp37m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 14.1 MB
  • Tags: CPython 3.7m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.9

File hashes

Hashes for pyhtnorm-0.1.1-cp37-cp37m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 55c0d8d3c5f30658e2c0a549dda012a2671f125c1610a0b040027aa9dcd3a0a9
MD5 9490ae5d847f8d7dd373794c4e07c187
BLAKE2b-256 7759b0638083aab8c5e1d2b8a874afb3bf43df060f0c4f5889326b197af565cf

See more details on using hashes here.

File details

Details for the file pyhtnorm-0.1.1-cp36-cp36m-manylinux2014_x86_64.whl.

File metadata

  • Download URL: pyhtnorm-0.1.1-cp36-cp36m-manylinux2014_x86_64.whl
  • Upload date:
  • Size: 10.9 MB
  • Tags: CPython 3.6m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.9

File hashes

Hashes for pyhtnorm-0.1.1-cp36-cp36m-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 70f34c5c763e577f4b02cd0c15df80a0749da36f666f826b0a2a44db86225ccf
MD5 d9bd9eda5e4ac28d5d5c3a62bf744dc4
BLAKE2b-256 d6fd33155c9df4db82552a9876e2b40269b5871d7249a4dcdba412b159b97130

See more details on using hashes here.

File details

Details for the file pyhtnorm-0.1.1-cp36-cp36m-manylinux2010_x86_64.whl.

File metadata

  • Download URL: pyhtnorm-0.1.1-cp36-cp36m-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 9.9 MB
  • Tags: CPython 3.6m, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.9

File hashes

Hashes for pyhtnorm-0.1.1-cp36-cp36m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 f9afc2bb4a4fa442d27c1a59838d7c90e188d07fc4335e4a1eabd2a7ddfc0c54
MD5 722bb9b04eb7249d3041d28eb4014622
BLAKE2b-256 4614233f2e0b1b76adabb6326a47bbf86c723dc6595aed8d8dd5c6320ea6f67a

See more details on using hashes here.

File details

Details for the file pyhtnorm-0.1.1-cp36-cp36m-manylinux1_x86_64.whl.

File metadata

  • Download URL: pyhtnorm-0.1.1-cp36-cp36m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 14.1 MB
  • Tags: CPython 3.6m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.9

File hashes

Hashes for pyhtnorm-0.1.1-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 27105fb53652b26f64ee28831b54adac7ad18582ae0b51d00f121eb85bab12cf
MD5 c0b39d8b72c6b677a1f254058622ae84
BLAKE2b-256 100e4dbc2d0208f0bba741ad23cbac8b5e34fb5a75ecd1e785c1917f438b859c

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