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:

# 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.

R API

One can also access the API in R. To install the package, use:

devtools::install_github("zoj613/htnorm")

Note that you must have the cblas and lapacke headers available before installation.

Below is an R translation of the above python example:

library(htnorm)

# make dummy data
mean <- rnorm(1000)
cov <- matrix(rnorm(1000 * 1000), ncol=1000)
cov <- cov %*% t(cov)
G <- matrix(rep(1, 1000), ncol=1000)
r <- c(0)
# initialize the Generator instance
rng <- HTNGenerator(seed=12345, gen="pcg64")
samples <- rng$hyperplane_truncated_mvnorm(mean, cov, G, r)
#verify if sampled values sum to zero
sum(samples)

# alternatively one can pass a vector to store the results in
out <- rep(0, 1000)
rng$hyperplane_truncated_mvnorm(mean, cov, G, r, out = out)
#verify
sum(out)

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.2.0.tar.gz (158.2 kB view details)

Uploaded Source

Built Distributions

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

Uploaded CPython 3.8

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

Uploaded CPython 3.8 manylinux: glibc 2.12+ x86-64

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

Uploaded CPython 3.8

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

Uploaded CPython 3.7m

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

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

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

Uploaded CPython 3.7m

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

Uploaded CPython 3.6m

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

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

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

Uploaded CPython 3.6m

File details

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

File metadata

  • Download URL: pyhtnorm-0.2.0.tar.gz
  • Upload date:
  • Size: 158.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for pyhtnorm-0.2.0.tar.gz
Algorithm Hash digest
SHA256 1a9a00796587bba859cef07cc2347cfc4c798d27a9352acf399ca8d45a95de2e
MD5 56ace13d5ad08f7a84d5c976e7d52664
BLAKE2b-256 4a513f78fd7d536660ca4dd60b95762c7728c0567e5c839cb1d665e6f82386ae

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyhtnorm-0.2.0-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.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for pyhtnorm-0.2.0-cp38-cp38-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e5c75e01900ce3ab990e76bf9315f5c018f4d31a3d361d0dba1bc0d0fe56f725
MD5 cb9bba727263fb88b7570dd84e59a5ba
BLAKE2b-256 0437905d09d0ffcf25f1334fc81051b26f2c0845b35bb7eb1b2ffc53aeae9560

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyhtnorm-0.2.0-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.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for pyhtnorm-0.2.0-cp38-cp38-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 f3b4e4bbcc91bbddca041e9a6a29f6e88069f38e69bdb7c37fdae1bfb631a711
MD5 8641ec8152d0067a1f88b55d9a3fd846
BLAKE2b-256 8f78c10c16a2809c61371ef32999562cef420fa1c1bcdeb88aab957ea3ad6bc8

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyhtnorm-0.2.0-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.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for pyhtnorm-0.2.0-cp38-cp38-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 2797eafef8cea01a2b66782c0a07c975ff339a54102cd21b419a6a5efcca89b6
MD5 b436bf869a3b870ae70500d2f2cf1839
BLAKE2b-256 c979591e20a25a6937cc704a2944bda7f9c88f25b89a8a61f4c37c286a886cf0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyhtnorm-0.2.0-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.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for pyhtnorm-0.2.0-cp37-cp37m-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0174db278ea27c475afceb36033bb4c5f12d52e4d0b2eda2af64cf796740213a
MD5 fd9f8129fd48eb08208b09afec9f4b75
BLAKE2b-256 e6ae358262f253482da4c7a9a637cc0ee6c43b6cb9b89178fb54a3bf63cb0f77

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyhtnorm-0.2.0-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.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for pyhtnorm-0.2.0-cp37-cp37m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 8781ed7b6ce531226f3c460ae6de566dca57d49540f85aa44260a816cdd89c63
MD5 499a20a5d0762d448602d84d992176aa
BLAKE2b-256 a145c105cc1aab8f857f20a8cf49de3573e8503c6f6fcb09d2d0e287d9c53165

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyhtnorm-0.2.0-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.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for pyhtnorm-0.2.0-cp37-cp37m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 b6378235acb4e459b80ad6adadf4cda2b61f4faa965b20ba2a852cab95aecdf9
MD5 a513f697467cf53c63fe8d1a9f5e9ee2
BLAKE2b-256 12ed1faa477e80fe2e492989a77065bf010fdb4d7464c1678d57732612e303f1

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyhtnorm-0.2.0-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.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for pyhtnorm-0.2.0-cp36-cp36m-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f3f38a7f9e8021c73e95cc9b94b638d89b51a8574ada87e4e7ba4c7109e75f63
MD5 eebc47c21a8f8880d3b28578cf81d08a
BLAKE2b-256 6a7f2bfe045502da4997a0dd9d02fe88f1167bce190ad4ba81df530f08f30672

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyhtnorm-0.2.0-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.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for pyhtnorm-0.2.0-cp36-cp36m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 d319593cd6775f1a3852e0c192e11ae02b04ea852d8702e0120445e602bb235a
MD5 b66e2006f4cf8ba519a6ba8c84559897
BLAKE2b-256 b37de20b5cd983ef76978c1575d1cf31948ab92b19d26470c8868c4ad897d03b

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyhtnorm-0.2.0-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.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for pyhtnorm-0.2.0-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 ca9331bf3570bf4ffe4552ff450edd31be366abd2e340b8ad0c9f089efd18a78
MD5 5811634b48f192ae2f5598a5157be633
BLAKE2b-256 eed9b47fe213b899a5acadc19623f48a300dcae49b0251b774759fe061596aac

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