Skip to content

ReparameterisedDistributions.jl ​

Parameter-convention switches for Distributions.jl.

Why ReparameterisedDistributions? ​

  • A delay can be elicited as a mean and a standard deviation, but Distributions.jl names each family by its native parameters, so those are not the coordinates a model has to be written in.

  • Independent priors on a shape and a scale imply a prior on the mean that was never chosen, and is usually not the one that was meant.

  • reparameterise makes the moments a distribution's parameters, so a prior can be put on the mean directly.

  • The wrapper is an ordinary Distribution and stays differentiable, so the moments can be sampled directly inside a model.

Getting started ​

See the Getting started documentation for every supported parameterisation.

jl
using Pkg
Pkg.add("ReparameterisedDistributions")

reparameterise returns a distribution whose parameters are the moments, so a prior goes on the mean rather than on a shape that only implies one.

julia
using ReparameterisedDistributions, Distributions, Turing, Random

Random.seed!(1)

truth = reparameterise(Gamma; mean = 8.0, sd = 3.0)
y = rand(truth, 200)

@model function delay(y)
    delay_mean ~ truncated(Normal(8.0, 4.0); lower = 0.0)
    delay_sd ~ truncated(Normal(3.0, 2.0); lower = 0.0)
    y .~ reparameterise(Gamma; mean = delay_mean, sd = delay_sd)
end

chain = sample(delay(y), NUTS(), 500; progress = false)

summarystats(chain)
Summary Statistics

  parameters      mean       std      mcse   ess_bulk   ess_tail      rhat   e ⋯
      Symbol   Float64   Float64   Float64    Float64    Float64   Float64     ⋯

  delay_mean    8.0778    0.2407    0.0142   289.8410   329.6722    1.0011     ⋯
    delay_sd    3.2642    0.1846    0.0115   258.2991   247.9024    1.0012     ⋯

                                                                1 column omitted

The chain comes back in a mean and a standard deviation, the coordinates the delay was elicited in, rather than in native parameters that only imply them.

julia
using CairoMakie, AlgebraOfGraphics, DataFramesMeta

CairoMakie.activate!(type = "png", px_per_unit = 2)

draws = DataFrame(
    value = vcat(vec(chain[:delay_mean]), vec(chain[:delay_sd])),
    moment = vcat(fill("mean", length(chain[:delay_mean])),
        fill("sd", length(chain[:delay_sd])))
)
actual = DataFrame(moment = ["mean", "sd"], value = [8.0, 3.0])

draw(
    data(draws) * mapping(:value, layout = :moment) *
    AlgebraOfGraphics.density() +
    data(actual) * mapping(:value, layout = :moment) *
    visual(VLines, color = :black, linestyle = :dash);
    facet = (; linkxaxes = :none)
)

Where to learn more ​

Contributing ​

We welcome contributions and new contributors! Please open an issue or pull request on GitHub. This package follows ColPrac and the SciML style.

How to cite ​

If you use ReparameterisedDistributions in your work, please cite it. Citation metadata lives in CITATION.cff, which GitHub renders as a "Cite this repository" button on the repository page.

Code of conduct ​

Please note that the ReparameterisedDistributions project is released with a Contributor Code of Conduct. By contributing, you agree to abide by its terms.