Differentiable Critical Bandwidth: Silverman's modality test as a differentiable PyTorch layer with IFT backward pass.
Project description
DCB — Differentiable Critical Bandwidth
A PyTorch package that makes Silverman's critical bandwidth test (1981) fully differentiable, enabling end-to-end gradient-based optimization over the modal structure of continuous distributions.
Overview
The critical bandwidth h_crit is the minimum KDE bandwidth at which a distribution appears to have at most m modes — a classical nonparametric statistic for modality testing. DCB replaces every non-differentiable operation in its computation with a smooth surrogate, then uses the Implicit Function Theorem to compute exact gradients through the root-finding step at O(1) memory cost.
import torch
from dcb import DCBLayer
X = torch.randn(1000, requires_grad=True) # 1D samples
layer = DCBLayer(target_modes=1)
h_crit = layer(X) # differentiable scalar
h_crit.backward() # exact IFT gradients
Installation
pip install diffcb
Or from source:
git clone https://github.com/ryZhangHason/differentiable-critical-bandwidth
cd differentiable-critical-bandwidth
pip install -e ".[dev]"
Accuracy vs R's bw.crit
DCB is validated against R's multimode::bw.crit(data, mod0=1) — the standard reference implementation of Hall & York (2001). On identical data:
| n | DCB vs R (same sample) | DCB vs R (independent samples) |
|---|---|---|
| 100K | 0.004% | ~0.5% (MC noise from independent RNG) |
| 1M | 0.005% | ~0.2% |
| 10M | 0.004% | ~0.1% |
The independent-sample figures reflect natural sampling variability (two unbiased estimators drawing different data), not algorithmic error. On identical data, DCB agrees with R to within 0.005% at all tested n. DCB is 43× faster than R at n=100M (1.1 s vs 50 s) and handles n=2B in 24 s while R OOMs.
Key Parameters
DCBLayer(
target_modes=1, # target number of modes
G=512, # IFT evaluation grid points
use_fft=True, # FFT forward (default); eliminates subsampling bias for n>50K
max_n_exact=1_000_000,# sketch to sketch_size when n exceeds this (None = always exact)
sketch_size=500_000, # sketch target; 500K matches full-n accuracy (O(n^{-2/9}) rate)
safe_backward=False, # clamp IFT denominator near bifurcations
)
Confirmed Experimental Results
All GPU results produced on Kaggle (T4 / P100) — see experiments/ and outputs/.
| Experiment | Result | Criterion |
|---|---|---|
| Accuracy vs R (same data, n=100K) | 0.004% | < 0.01% ✓ |
| Validation (m≥2, Marron-Wand) | R²=0.91, MAE=0.07, ρ=0.89 | R²≥0.85 ✓ |
| Speedup vs scipy (CUDA T4, n=8192) | 10.5× | ≥3× ✓ |
| GAN mode preservation | h_crit=1.232 >> 0.3 | h_crit>0.3 ✓ |
| Anomaly AUC (KDDCup99) | DCB=0.9982 vs IF=0.9867 | DCB≥IF ✓ |
Repository Structure
dcb/ Core PyTorch package
layer.py DCBLayer nn.Module + DCBFunction autograd
solver.py IFT root-finder and backward pass
fft_kde.py FFT-based mode counter (MPS-safe, float64, G=16384)
kde.py Direct KDE derivatives (small-n path)
utils.py Grid, Silverman bandwidth, sg() stabilizer
experiments/ Reproduction scripts for all paper figures and tables
phase1_*.py Validation, speedup, ablation (Figures 1–2, S1–S2)
phase2_gan.py GAN mode-collapse prevention (Figure 3)
phase3_anomaly.py Anomaly detection (Table 2, Figure 5)
round20_*.py Large-n R comparison and streaming benchmarks
round21_*.py Accuracy improvement experiments
tests/ Unit tests (pytest, 45 passed, 1 xfailed)
outputs/ All generated figures and tables (PDFs, PNGs, CSVs)
License
Apache 2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file diffcb-0.1.5.tar.gz.
File metadata
- Download URL: diffcb-0.1.5.tar.gz
- Upload date:
- Size: 40.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09f33c25e64272c3b6e8fec61b31e2ab92c83d87099fc71d46f9333647c8587b
|
|
| MD5 |
0379f8e94944dd934249315bea3456f7
|
|
| BLAKE2b-256 |
934291befe2f598a02d963b853ca729d2c530f3da345f5bf749383c1cfca26bd
|
File details
Details for the file diffcb-0.1.5-py3-none-any.whl.
File metadata
- Download URL: diffcb-0.1.5-py3-none-any.whl
- Upload date:
- Size: 38.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a50b1d58e5424155220c1025f5dfecdf467f4a7e68f23a3b153bcfd300f0424
|
|
| MD5 |
ad76aafc785ee2b3112ea2b93fe1cff0
|
|
| BLAKE2b-256 |
b7f7077b6ca4293acf2bfdd7deb9378e3bfc420a190de614148c4758e9dee54b
|