De-heaping density estimation with adheaping

Heaping and the identifiability limit

Heaped and rounded data concentrate on a coarse grid of round numbers and defeat kernel density estimation, which renders the rounding marks as spurious modes. Rounding to a grid of width D is exactly convolution of the density with a width-D box followed by lattice sampling, so in the characteristic-function domain the density is recovered by dividing out the known box (a continuous generalization of Sheppard’s correction) inside the grid-Nyquist band |w| < pi/D. Beyond that band the density is not identifiable from the heaped data alone.

A worked example

We draw a bimodal sample, round it to a grid of 0.5, and compare the naive kernel estimate with the tuning-free combined de-heaping estimator.

set.seed(20260627)
n <- 4000
x <- ifelse(runif(n) < 0.5, rnorm(n, -1.2, 0.5), rnorm(n, 1.2, 0.5))
D <- 0.5
y <- D * round(x / D)
grid <- seq(-6, 6, length.out = 2048)

f_true  <- 0.5 * dnorm(grid, -1.2, 0.5) + 0.5 * dnorm(grid, 1.2, 0.5)
f_naive <- naive_kde(y, grid)
f_adk   <- adkde(y, D, grid)
attr(f_adk, "pick")   # which component the band-capacity gate selected
#> [1] "deheap"

The naive estimate carries the rounding comb; the combined estimator recovers the smooth bimodal density.

Reading the grid and the heaped fraction

The grid and the fraction of a sample that is heaped are read directly from the rounding comb, and the grid is detected blind as a group-matched atom in the spectral basis.

heap_grid(y, grid, near = D)                 # locate the grid from the comb tooth
#> [1] 0.5002443
heap_detect(y = D * round(x / D), span = c(-12.8, 12.8))$D_hat  # blind spectral detection
#> [1] NA

Baselines

Faithful base-R replicas of the measurement-error deconvolution and Heitjan-Rubin multiple-imputation methods are provided (deconv_kde, heitjan_mi), and the real Kernelheaping stochastic EM is wrapped by sem_kde when that package is installed.