Density Transform Estimation with PyTorch
torchdensityestimation is a package that provides implementations of algorithms for the estimation of density transforms (ratio, difference, etc.) using PyTorch and following a functional paradigm. The package currently implements
- Relative unconstrained Least-Squares Importance Fitting (RuLSIF), for the estimation of ratio of probability densities (or density ratios) [1,2,3]
- Least-Squares Density-Difference (LSDD) for density differences [4]
Installation
Using torchdensityestimation
You can use pip to install torchdensityestimation with the command
pip install torchdensityestimation
torchdensityestimation has the following dependencies
- Python 3.10 or higher
- PyTorch
Using source code
If you'd like to play around with the source code instead, run
git clone https://github.com/FilippoAiraldi/torch-density-estimation.git
You can then install the package to edit it as you wish as
pip install -e /path/to/torch-density-estimation
Getting started
Here we provide a compact example on how torchdensityestimation can be employed to estimate the ratio of two probability density functions (PDFs) without the need to explicitly estimate the PDFs themselves. This can be done with different methods, but this package implements the relative unconstrained least squares importance fitting (RuLSIF) algorithm [1,2,3].
We start by generating some data from two different multivariate Gaussian distributions:
import numpy as np
import torch
from scipy.stats import multivariate_normal as mvnorm
# define the two multivariate normal distributions
n_dim = 2
mean = np.ones(n_dim)
cov_x = np.eye(n_dim) / 8
cov_y = np.eye(n_dim) / 2
# generate samples from the two distributions
n_samples = 3000
rng = np.random.default_rng(0)
x = torch.from_numpy(mvnorm.rvs(size=n_samples, mean=mean, cov=cov_x, random_state=rng))
y = torch.from_numpy(mvnorm.rvs(size=n_samples, mean=mean, cov=cov_y, random_state=rng))
We can then use the torchdensityestimation package to estimate the ratio of the two
PDFs using the RuLSIF algorithm as follows:
from torchdensityestimation.ratio import rulsif_fit, rulsif_predict
alpha = 0.1
sigmas = torch.as_tensor([0.1, 0.3, 0.5, 0.7, 1.0], dtype=x.dtype)
lambdas = torch.as_tensor([0.01, 0.02, 0.03, 0.04, 0.05], dtype=x.dtype)
mdl = rulsif_fit(x, y, alpha, sigmas, lambdas, seed=int(rng.integers(0, 2**32)))
For reproducibility, we can set the seed argument to a fixed value. In this way,
results are consistent across runs. Then, we evaluate the predicted density ratio on a
grid of points, and compute also the true one for comparison:
n_vals = 200
vals = torch.linspace(0, 2, n_vals, dtype=x.dtype)
grid = torch.dstack(torch.meshgrid(vals, vals, indexing="xy")).reshape(-1, 2)
predicted = rulsif_predict(mdl, grid).reshape(n_vals, n_vals)
grid_np = grid.numpy()
pdf_x = mvnorm.pdf(grid_np, mean, cov_x)
target = pdf_x / (alpha * pdf_x + (1 - alpha) * mvnorm.pdf(grid_np, mean, cov_y))
target = target.reshape(n_vals, n_vals)
Finally, we can visualize the results using matplotlib:
from matplotlib import pyplot as plt
vals_np = vals.numpy()
levels = [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4.5]
_, axs = plt.subplots(1, 2, constrained_layout=True)
axs[0].contourf(vals_np, vals_np, target, levels=levels)
axs[0].set_title("True density ratio")
axs[1].contourf(vals_np, vals_np, predicted.numpy(), levels=levels)
axs[1].set_title("RuLSIF density ratio")
plt.show()
This code produces the following image:
Examples
Our examples subdirectory contains other example applications of this library.
License
The repository is provided under the MIT License. See the LICENSE file included with this repository.
Author
Filippo Airaldi, PhD Candidate [f.airaldi@tudelft.nl | filippoairaldi@gmail.com]
Delft Center for Systems and Control in Delft University of Technology
Copyright (c) 2025 Filippo Airaldi.
Copyright notice: Technische Universiteit Delft hereby disclaims all copyright interest in the program “csnlp” (Nonlinear Progamming with CasADi) written by the Author(s). Prof. Dr. Ir. Fred van Keulen, Dean of ME.
Thanks
This repository is heavily inspired by hoxo-m/densratio_py and JohnYKiyo/density_ratio_estimation, please visit their repositories and star them if you find them useful! Also, noteworthy is this large repository of algorithms.
References
[1] Yamada, M., Suzuki, T., Kanamori, T., Hachiya, H. and Sugiyama, M., 2013. Relative density-ratio estimation for robust distribution comparison. Neural computation, 25(5), pp.1324-1370.
[2] Liu, S., Yamada, M., Collier, N. and Sugiyama, M., 2013. Change-point detection in time-series data by relative density-ratio estimation. Neural Networks, 43, pp.72-83.
[3] Kanamori, T., Hido, S. and Sugiyama, M., 2009. A least-squares approach to direct importance estimation. The Journal of Machine Learning Research, 10, pp.1391-1445
[4] Sugiyama, M., Suzuki, T., Kanamori, T., Du Plessis, M. C., Liu, S., & Takeuchi, I., 2013. Density-difference estimation. Neural Computation, 25(10), pp.2734-2775.
Metadata
Release files for torchdensityestimation 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| torchdensityestimation-1.0.0.tar.gz | 13.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| torchdensityestimation-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.8 kB
Release files / torchdensityestimation-1.0.0.tar.gz
| Download URL | torchdensityestimation-1.0.0.tar.gz |
|---|---|
| Size | 13.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
78d5e8ac5c607cb9aa4ab5562c22011e5fa8b064e1ed066963fb5f6c0737a45b
|
|
BLAKE2b-256 checksum How to use checksums |
b804fa5aaf073aee8c927c0e5f8d834d32e25d8efb2b613e4a611a6ebf4db254
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.9.22
|
Release files / torchdensityestimation-1.0.0-py3-none-any.whl
| Download URL | torchdensityestimation-1.0.0-py3-none-any.whl |
|---|---|
| Size | 12.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bc513e176c42558883a77adda8434ceaaf71270ed4dbae6b872923fd74fb026a
|
|
BLAKE2b-256 checksum How to use checksums |
e5d07a36c408a965d0f95d3581b6dcee50b172a98a67e6df38e599d2488bee05
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.9.22
|