MonteCarloMeasurements.jl
Documentation for MonteCarloMeasurements.jl ↗
MonteCarloMeasurements.jl is a package that lets you treat probability distributions as first-class numbers. FlexiChains contains an extension which allows you to directly convert a FlexiChain into a collection of MonteCarloMeasurements.Particles objects, in essence creating Particles from the distribution which the chain represents.
using FlexiChains, DynamicPPL, Distributions, LinearAlgebra
@model function f()
x ~ Normal()
y ~ Poisson(3.0)
v ~ MvNormal(zeros(2), I)
nt ~ product_distribution((a=Normal(), b=Normal()))
end
chn = FlexiChains._make_prior_chain(f(), 1000, 3)╭─FlexiChain (1000 iterations, 3 chains) ──────────────────────────────────────╮
│ ↓ iter = 1:1000 │
│ → chain = 1:3 │
│ │
│ Parameters (4) ── VarName │
│ Float64 x │
│ Int64 y │
│ Vector{Float64} v (2,) │
│ @NamedTuple{a::Float64, b::Float64} nt │
│ │
│ Extras (3) │
│ Float64 logprior, loglikelihood, logjoint │
╰──────────────────────────────────────────────────────────────────────────────╯using MonteCarloMeasurements: Particles
pdict = Particles(chn)OrderedCollections.OrderedDict{VarName, Any} with 4 entries:
x => 0.0159 ± 1.0
y => 3.07 ± 1.8
v => Particles{Float64, 3000}[-0.0211 ± 1.0, 0.00925 ± 1.0]
nt => (a = 0.000449 ± 0.97, b = 0.011 ± 0.99)# Calculates the distribution of `x + y` (for example).
pdict[@varname(x)] + pdict[@varname(y)]3.08656 ± 2.06 MonteCarloMeasurements.Particles{Float64, 3000}Notice that pdict[@varname(x)] can be constructed quite trivially without an extension via
Particles(vec(chn[@varname(x)]))0.0158888 ± 1.02 MonteCarloMeasurements.Particles{Float64, 3000}However, FlexiChains' extension additionally handles array- and NamedTuple-valued variables for you, such as v and nt above.
The default output is an OrderedDict, which is not always the most convenient type to work with. If you prefer a NamedTuple, you can pass this as an argument to the constructor:
pnt = Particles(chn, NamedTuple)(x = 0.0159 ± 1.0, y = 3.07 ± 1.8, v = MonteCarloMeasurements.Particles{Float64, 3000}[-0.0211 ± 1.0, 0.00925 ± 1.0], nt = (a = 0.000449 ± 0.97, b = 0.011 ± 0.99))This can be easier to use sometimes but note that since NamedTuple keys are plain Symbols this conversion might be lossy depending on your chain's parameter type.
Unhandled parameter types
Not every parameter can be meaningfully converted into a Particles object. For example, Cholesky factors (x ~ LKJCholesky(...)) are not supported and will error. If you want to convert a chain that contains such a variable into a Particles object, subset the chain first to only include the parameters you want to convert, e.g.
Particles(chn[[param1, param2, param3]])Docstrings
MonteCarloMeasurements.Particles Type
MonteCarloMeasurements.Particles(
chain::FC.FlexiChain{Tparam},
::Type{Tout}=OrderedDict,
) where {Tparam,Tout}Convert a chain into an OrderedDict, mapping parameters in the chain (of type Tparam) to MonteCarloMeasurements.Particles or collections thereof.
Extras in the chain will be dropped.
Scalar-valued parameters will become single Particles; array-valued parameters will become arrays of Particles (as long as all the arrays have the same size).
Note that if parameters have different sizes or types in different samples, this will conservatively throw an error. Suggestions for improvements are very welcome!
Tout can also be:
Dict, in which case the output will beDictrather thanOrderedDict;NamedTuple. Note that this conversion can be lossy ifTparamis a richer type than
Symbol.
source