<img src="docs/source/_static/cartoon.svg" alt="projnormal logo" width="500"/>
`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"](https://arxiv.org/abs/2506.17461),
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`.
```python
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.
```python
# 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](https://docs.anaconda.com/miniconda/install/#quick-command-line-install)),
and then create a virtual environment with Python 3.11 using the following
shell command:
```bash
conda create -n my-projnormal python=3.11
```
You can then activate the virtual environment with the following command:
```bash
conda activate my-projnormal
```
You should activate the `my-sqfa` environment to install the package, and every
time you want to use it.
### Install package
To install the package, you can clone the GitHub
repository and install in editable mode using `pip`:
```bash
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"](https://arxiv.org/abs/2506.17461):
```bibtex
@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},
}
```
Raw data
{
"_id": null,
"home_page": null,
"name": "projnormal",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "Angular statistics, Geometry, Hypersphere, PyTorch, Sphere, Statistics",
"author": null,
"author_email": "Daniel Herrera-Esposito <dherrera1911@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/55/3f/f8920c7d392dcdc090790ed69df51543d5714158ca6b9df1500284aa47e9/projnormal-0.1.tar.gz",
"platform": null,
"description": "<img src=\"docs/source/_static/cartoon.svg\" alt=\"projnormal logo\" width=\"500\"/>\n\n`projnormal` is a Python package for working with the\nprojected normal and related distributions. It uses a\nPyTorch backend to provide efficient computations and\nfitting procedures.\n\nGiven an $n$-dimensional variable\n$\\mathbf{x} \\sim \\mathcal{N}(\\boldsymbol{\\mu}, \\Sigma)$,\nthe variable obtained by radially projecting\n$\\mathbf{x}$ onto the unit sphere,\n$\\mathbf{y} = \\frac{\\mathbf{x}}{||\\mathbf{x}||}$,\nfollows a projected normal distribution, denoted\nas $\\mathbf{y} \\sim \\mathcal{PN}(\\boldsymbol{\\mu}, \\Sigma)$.\n\nThe package was introduced in the preprint\n[\"Projected Normal Distribution: Moment Approximations and Generalizations\"](https://arxiv.org/abs/2506.17461),\nwhich presents the implemented formulas.\n\n\n## Projected Normal Distribution\n\n`projnormal` implements the following functionalities for\nthe projected normal distribution (and related distributions):\n* PDF and log-PDF formulas\n* Maximum-likelihood parameter estimation\n* Distribution sampling\n* Approximations of the first and second moments\n* Moment matching routines\n\nIn the example code below, we generate samples from\n$\\mathcal{PN}(\\boldsymbol{\\mu}, \\Sigma)$ and compute their\nPDF. The necessary formulas are implemented in the\nsubmodule `projnormal.formulas.projected_normal`.\n\n```python\nimport torch\nimport projnormal\nimport projnormal.formulas.projected_normal as pn_dist\n\n# Sample distribution parameters\n\nN_DIM = 3 # The package work with any dimension\nmean_x = projnormal.param_sampling.make_mean(N_DIM)\ncovariance_x = projnormal.param_sampling.make_spdm(N_DIM)\n\n# Generate distribution samples\nsamples = pn_dist.sample(\n mean_x=mean_x, covariance_x=covariance_x, n_samples=2000\n)\n\n# Compute samples PDF\npdf_values = pn_dist.pdf(\n mean_x=mean_x, covariance_x=covariance_x, y=samples\n)\n```\n\nNext, we initialize a `ProjNormal` object and use it\nto fit the distribution parameters to the samples.\n\n```python\n# Initialize a ProjNormal object to fit\npn_fit = projnormal.classes.ProjNormal(n_dim=N_DIM)\n\n# Fit the parameters of the projected normal distribution\npn_fit.max_likelihood(y=samples)\n\n# Check the fitted parameters against the original parameters\nprint(\"Fitted mean vector:\", pn_fit.mean_x.detach()) \nprint(\"True mean vector:\", mean_x)\n\nprint(\"Fitted covariance matrix: \\n\", pn_fit.covariance_x.detach())\nprint(\"True covariance matrix: \\n\", covariance_x)\n```\n \n## Installation\n\n### Virtual environment\n\nWe recommend installing the package in a virtual environment. For this,\nyou can first install `miniconda` \n([install instructions link](https://docs.anaconda.com/miniconda/install/#quick-command-line-install)),\nand then create a virtual environment with Python 3.11 using the following\nshell command:\n\n```bash\nconda create -n my-projnormal python=3.11\n```\n\nYou can then activate the virtual environment with the following command:\n\n```bash\nconda activate my-projnormal\n```\n\nYou should activate the `my-sqfa` environment to install the package, and every\ntime you want to use it.\n\n\n### Install package\n\nTo install the package, you can clone the GitHub\nrepository and install in editable mode using `pip`:\n\n```bash\ngit clone https://github.com/dherrera1911/projnormal.git\ncd projnormal\npip install -e \".\"\n```\n\n## Citation\n\nIf you use `projnormal` in your research, please cite the\npreprint [\"Projected Normal Distribution: Moment Approximations and Generalizations\"](https://arxiv.org/abs/2506.17461):\n\n```bibtex\n@misc{herreraesposito2025projected,\n title={Projected Normal Distribution: Moment Approximations and Generalizations},\n author={Daniel Herrera-Esposito and Johannes Burge},\n year={2025},\n eprint={2506.17461},\n archivePrefix={arXiv},\n url={https://arxiv.org/abs/2506.17461}, \n}\n```\n\n",
"bugtrack_url": null,
"license": "MIT License",
"summary": "A PyTorch implementation of the Projected Normal distribution with fitting capabilities.",
"version": "0.1",
"project_urls": {
"Bug Reports": "https://github.com/dherrera1911/projnormal/issues",
"Repository": "https://github.com/dherrera1911/projnormal",
"Source": "https://github.com/dherrera1911/projnormal"
},
"split_keywords": [
"angular statistics",
" geometry",
" hypersphere",
" pytorch",
" sphere",
" statistics"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "22aba314b5040c638251dc39e297639c4b3c4b17dd0a565d577fb57f9e772e1c",
"md5": "bc0f4e928c1a3839a654cae23a36730f",
"sha256": "3e789a16d1e7d2e4b58083e1d6dff3ce9e7a7cb0fe907491949ffd35b1bde87f"
},
"downloads": -1,
"filename": "projnormal-0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "bc0f4e928c1a3839a654cae23a36730f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 42044,
"upload_time": "2025-07-11T19:12:42",
"upload_time_iso_8601": "2025-07-11T19:12:42.913248Z",
"url": "https://files.pythonhosted.org/packages/22/ab/a314b5040c638251dc39e297639c4b3c4b17dd0a565d577fb57f9e772e1c/projnormal-0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "553ff8920c7d392dcdc090790ed69df51543d5714158ca6b9df1500284aa47e9",
"md5": "0ae47c94ac4cd6067739ef0084a7c0ca",
"sha256": "5bd7ec24c8b9e6c2c6ca9446d534d2a7acee51f5859811ace71516697616c343"
},
"downloads": -1,
"filename": "projnormal-0.1.tar.gz",
"has_sig": false,
"md5_digest": "0ae47c94ac4cd6067739ef0084a7c0ca",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 110553,
"upload_time": "2025-07-11T19:12:44",
"upload_time_iso_8601": "2025-07-11T19:12:44.493851Z",
"url": "https://files.pythonhosted.org/packages/55/3f/f8920c7d392dcdc090790ed69df51543d5714158ca6b9df1500284aa47e9/projnormal-0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-11 19:12:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "dherrera1911",
"github_project": "projnormal",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "projnormal"
}