A Julia package for discretising continuous and discrete probability distributions into interval-based discrete representations with flexible alignment options.
DiscretizeDistributions.jl provides functionality to convert probability distributions into discrete forms using a robust two-stage approach:
- Backend discretisation: Creates discrete distributions with
IntervalArithmetic.Intervalsupport representing probability masses over intervals - Alignment utilities: Convert interval-based distributions to point-based distributions for final output, if needed
- Interval-based backend: Uses
IntervalArithmetic.jlfor precise interval representation - Flexible output formats: Convert to left-aligned, centered, or right-aligned point distributions
- Support for both continuous and discrete input distributions
- Custom or uniform interval spacing
- Automatic handling of infinite bounds using quantiles
using Pkg
Pkg.add("DiscretizeDistributions")We recommend using rational numbers for interval definitions to maintain precision:
using Distributions, IntervalArithmetic
using DiscretizeDistributions
# Discretize a continuous distribution (returns interval-based distribution)
normal_dist = Normal(0.0, 1.0)
discrete_intervals = discretize(normal_dist, 1//10) # Returns intervals like [0.0, 0.1), [0.1, 0.2), etc.
# Convert to different point-based alignments using post-processing
left_aligned = left_align_distribution(discrete_intervals) # Uses interval start points
centered = centred_distribution(discrete_intervals) # Uses interval midpoints
right_aligned = right_align_distribution(discrete_intervals) # Uses interval end points
# Or use direct method specification for one-step processing
left_direct = discretize(normal_dist, 1//10; method=:left_aligned)
centered_direct = discretize(normal_dist, 1//10; method=:centred)
right_direct = discretize(normal_dist, 1//10; method=:right_aligned)
# Use custom intervals
custom_intervals = [-3.0, -1.0, 0.0, 1.0, 3.0]
discrete_custom = discretize(normal_dist, custom_intervals)
# For unbounded distributions, bounds are set using quantiles (customizable)
# Default: 0.1% and 99.9% quantiles
println("Automatic bounds: ", minimum(discrete_intervals.support), " to ", maximum(discrete_intervals.support))
# You can also use truncation for explicit bounds
discrete_truncated = discretize(truncated(Normal(), -1.1, 5.13), 1//10)
println("Truncated bounds: ", minimum(discrete_truncated.support), " to ", maximum(discrete_truncated.support))
# Discretize a discrete distribution
poisson_dist = Poisson(3.0)
discrete_poisson = discretize(poisson_dist, 2) # Group into intervals of width 2
# The backend maintains interval structure - convert to points as needed
println("Interval support: ", support(discrete_intervals)[1:5]) # Shows first 5 intervals
println("Left-aligned: ", support(left_aligned)[1:5]) # Shows first 5 pointsThe unbiased method provides mean-preserving discretization by computing probabilities that ensure the discrete distribution's mean matches the original distribution as closely as possible:
# Note: Unbiased method requires equal interval widths
normal_dist = Gamma(2, 10)
unbiased_discrete = discretize(normal_dist, 0.6; method=:unbiased)
# Compare means
println("Original mean: ", mean(normal_dist))
println("Unbiased discrete mean: ", mean(unbiased_discrete))
println("Centered discrete mean: ", mean(discretize(normal_dist, 0.6; method=:centred)))- Distributions.jl - Foundation for probability distributions in Julia
- IntervalArithmetic.jl - Interval arithmetic backend