Skip to main content

DEFER

DEnsity Function Estimation using Recursive partitioning

Approximate any black-box unnormalised density from point evaluations alone, and get samples, the normalising constant, and more. Runs on PyTorch or NumPy.

Python License Lint

DEFER samples recovering a 3-D spiral density

200k samples drawn from a DEFER approximation of a density concentrated on a 3-D spiral.

Overview

DEFER approximates an arbitrary unnormalised (log-)density over a bounded box using only pointwise evaluations: no gradients, no closed form, no conjugacy. It recursively partitions the domain, spending evaluations where probability mass concentrates, and returns a single object that provides:

  • fast, constant-time sampling (via the alias method),
  • the normalising constant Z, i.e. the model evidence, which DEFER approximates,
  • closed-form expectations under the approximation, including the mean, variance, and differential entropy.

It is robust and fast, and applies to problems of up to around 20 dimensions. The budget is a number of function evaluations: each evaluation adds one partition, so an approximation with N partitions costs N evaluations of your density and takes O(N log N) time and O(N) space. Every numerical step runs through a PyTorch backend (on a chosen device) or NumPy. The method is described in Black-box density function estimation using recursive partitioning (arXiv:2010.13632, ICML 2021).

Install

Managed with uv (Python 3.13):

uv sync

Quickstart

import numpy as np
from defer import defer

# Any unnormalised log-density you can evaluate pointwise (here a 2-D Gaussian).
def log_density(x):
    return -0.5 * (x**2).sum(-1)

approx = defer(
    log_density,
    lower=np.array([-5.0, -5.0]),
    upper=np.array([5.0, 5.0]),
    num_fn_calls=2000,       # density evaluations; one partition is added per evaluation
    use_numpy=True,          # or use_numpy=False, device="cpu" / "cuda"
)

approx.log_z                 # log normalising constant (the evidence)
approx.mean()                # posterior mean
samples = approx.sampler()(10_000)   # (10000, 2) samples, O(1) each

Set use_numpy=False, device="cuda" to run the same code on a GPU with PyTorch.

Examples

Runnable notebooks live in examples/ (uv sync installs the plotting extras):

Gaussian-process kernel selection

Infer each kernel's hyperparameter posterior and use the evidence log Z to choose between a Matérn-3/2 and a sum of two Matérn-3/2. The data is generated from the sum kernel, and the evidence prefers it.

GP hyperparameter posterior

Black-box Gibbs density on a spiral

A density concentrated on a 3-D spiral, defined only by distance to the curve. DEFER recovers a sampler, the normalising constant, and the shape itself.

Spiral density corner plot

Development

make lint        # ruff check + format
make typecheck   # pyright
make test        # pytest (numpy and torch backends)

License

MIT, see LICENSE.

Metadata

Release files for deference 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for deference 0.2.0
File Size Uploaded Provenance Actions
deference-0.2.0.tar.gz 2.1 MB Without provenance Details for deference-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for deference 0.2.0
File Interpreter ABI Platform Actions
deference-0.2.0-py3-none-any.whl Python 3 none any Details for deference-0.2.0-py3-none-any.whl

Total release size: 2.2 MB

Release files / deference-0.2.0.tar.gz

Download URL deference-0.2.0.tar.gz
Size 2.1 MB
Tags Source
SHA-256 checksum
How to use checksums
541a3e979b766deb3741f50f674c4e21cb507c788488a63088d54fa1c642c712
BLAKE2b-256 checksum
How to use checksums
a40da3430cd3ca7ca025b65a19a59fb4bfc869eb1a8bd8960ecd0eefb8b731eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / deference-0.2.0-py3-none-any.whl

Download URL deference-0.2.0-py3-none-any.whl
Size 20.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2977d464b7d55abe1aff4efdd40568bca13cc0e1bdb5df098961a10b35aab27d
BLAKE2b-256 checksum
How to use checksums
ad57f497e4b200e9179e3ce4cd7a9cf86175299540ac829c8171ec025a3c20fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for deference 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page