Skip to content

GBarnsley/DiscretizeDistributions.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DiscretizeDistributions.jl

Build Status codecov

Aqua QA

A Julia package for discretising continuous and discrete probability distributions into interval-based discrete representations with flexible alignment options.

Overview

DiscretizeDistributions.jl provides functionality to convert probability distributions into discrete forms using a robust two-stage approach:

  1. Backend discretisation: Creates discrete distributions with IntervalArithmetic.Interval support representing probability masses over intervals
  2. Alignment utilities: Convert interval-based distributions to point-based distributions for final output, if needed

Key Features

  • Interval-based backend: Uses IntervalArithmetic.jl for 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

Installation

using Pkg
Pkg.add("DiscretizeDistributions")

Quick Start

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 points

Unbiased Discretization Method

The 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)))

Related Packages

Packages

 
 
 

Contributors

Languages