Skip to content

dherrera1911/projnormal

Repository files navigation

projnormal logo

Build Status Tests Status Documentation Status License: MIT Python version codecov PyPI version

projnormal is a Python package for working with the projected normal and related distributions. It uses a PyTorch backend to provide efficient computations and fitting procedures.

Given an $n$-dimensional variable $\mathbf{x} \sim \mathcal{N}(\boldsymbol{\mu}, \Sigma)$, the variable obtained by radially projecting $\mathbf{x}$ onto the unit sphere, $\mathbf{y} = \frac{\mathbf{x}}{||\mathbf{x}||}$, follows a projected normal distribution, denoted as $\mathbf{y} \sim \mathcal{PN}(\boldsymbol{\mu}, \Sigma)$.

The package was introduced in the preprint "Projected Normal Distribution: Moment Approximations and Generalizations", which presents the implemented formulas.

Projected Normal Distribution

projnormal implements the following functionalities for the projected normal distribution (and related distributions):

  • PDF and log-PDF formulas
  • Maximum-likelihood parameter estimation
  • Distribution sampling
  • Approximations of the first and second moments
  • Moment matching routines

In the example code below, we generate samples from $\mathcal{PN}(\boldsymbol{\mu}, \Sigma)$ and compute their PDF. The necessary formulas are implemented in the submodule projnormal.formulas.projected_normal.

import torch
import projnormal
import projnormal.formulas.projected_normal as pn_dist

# Sample distribution parameters

N_DIM = 3  # The package work with any dimension
mean_x = projnormal.param_sampling.make_mean(N_DIM)
covariance_x = projnormal.param_sampling.make_spdm(N_DIM)

# Generate distribution samples
samples = pn_dist.sample(
  mean_x=mean_x, covariance_x=covariance_x, n_samples=2000
)

# Compute samples PDF
pdf_values = pn_dist.pdf(
  mean_x=mean_x, covariance_x=covariance_x, y=samples
)

Next, we initialize a ProjNormal object and use it to fit the distribution parameters to the samples.

# Initialize a ProjNormal object to fit
pn_fit = projnormal.classes.ProjNormal(n_dim=N_DIM)

# Fit the parameters of the projected normal distribution
pn_fit.max_likelihood(y=samples)

# Check the fitted parameters against the original parameters
print("Fitted mean vector:", pn_fit.mean_x.detach()) 
print("True mean vector:", mean_x)

print("Fitted covariance matrix: \n", pn_fit.covariance_x.detach())
print("True covariance matrix: \n", covariance_x)

Installation

Virtual environment

We recommend installing the package in a virtual environment. For this, you can first install miniconda (install instructions link), and then create a virtual environment with Python 3.11 using the following shell command:

conda create -n my-projnormal python=3.11

You can then activate the virtual environment with the following command:

conda activate my-projnormal

You should activate the my-projnormal environment to install the package, and every time you want to use it.

Install package from PyPI

The easiest way to install the package is form the PyPI repository, using the following command:

pip install projnormal

Install package from source

To install the package from source (e.g., if you want to edit the code), you can clone the GitHub repository and install in editable mode using the following commands:

git clone https://github.com/dherrera1911/projnormal.git
cd projnormal
pip install -e "."

Citation

If you use projnormal in your research, please cite the preprint "Projected Normal Distribution: Moment Approximations and Generalizations":

@misc{herreraesposito2025projected,
      title={Projected Normal Distribution: Moment Approximations and Generalizations},
      author={Daniel Herrera-Esposito and Johannes Burge},
      year={2025},
      eprint={2506.17461},
      archivePrefix={arXiv},
      url={https://arxiv.org/abs/2506.17461}, 
}

About

PyTorch implementation of the Projected Normal distribution and generalizations

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages