Skip to content

Overview ​

FlexiChains.jl provides a rich data structure for storing and analysing Markov chain Monte Carlo (MCMC) output.

julia
using Turing, FlexiChains
@model function f()
    x ~ Normal()
    y ~ Poisson(3.0)
    z ~ MvNormal([x + y, x - y], I)
end
chain = sample(f(), Prior(), MCMCSerial(), 1000, 4)
╭─FlexiChain (1000 iterations, 4 chains) ──────────────────────────────────────╮
│ ↓ iter  = 1:1000                                                             │
│ → chain = 1:4                                                                │
│                                                                              │
│ Parameters (3) ── VarName                                                    │
│  Float64          x                                                          │
│  Int64            y                                                          │
│  Vector{Float64}  z (2,)                                                     │
│                                                                              │
│ Extras (3)                                                                   │
│  Float64  logprior, loglikelihood, logjoint                                  │
╰──────────────────────────────────────────────────────────────────────────────╯

Primary features ​

Type and structure fidelity ​

FlexiChains preserves the original shapes of your samples: all Julia types are faithfully stored without modification. The example Turing.jl model above yields a FlexiChain where each x is a Float64, each y is an Int, and each z is a Vector{Float64}.

This is in contrast to many other representations which flatten all samples into a single Array{Float64}.

Diverse input sources ​

FlexiChains is the default chain type for Turing.jl since v0.45 of Turing.

You can also construct a FlexiChain from a variety of other sources, including ParallelMCMC.jl, Pigeons.jl, Stan CSV files, MCMCChains.jl, or PosteriorDB.jl.

Expressive indexing ​

You can access data stored in chains in a variety of ways, using the full power of DimensionalData.jl selectors.

julia
chain[@varname(x), iter=101:End, chain=2]
┌ 900-element DimArray{Float64, 1} Parameter(x) ┐
├───────────────────────────────────────────────┴────────── dims ┐
  ↓ iter Sampled{Int64} 101:1000 ForwardOrdered Regular Points
└────────────────────────────────────────────────────────────────┘
  101   0.856598
  102  -1.56957
  103  -0.439255
  104  -0.52298
  105   1.33797
    ⋮  
  996  -0.651087
  997   1.49336
  998  -0.894593
  999  -0.202176
 1000  -0.621742

Downstream analysis ​

FlexiChains provides a number of tools for statistical analysis, including:

julia
ss = summarystats(chain)
╭─FlexiSummary (9 statistics) ─────────────────────────────────────────────────╮
│   iter    collapsed                                                          │
│   chain   collapsed                                                          │
│ ↓ stat  = [mean, std, mcse, ess_bulk, ess_tail, rhat, q5, q50, q95]          │
│                                                                              │
│ Parameters (4) ── VarName                                                    │
│  Float64  x, y, z[1], z[2]                                                   │
│                                                                              │
│ Extras (3)                                                                   │
│  Float64  logprior, loglikelihood, logjoint                                  │
│                                                                              │
│ Summary                                                                      │
│  param  mean     std     mcse    …  rhat    q5       q50      q95            │
│  x      0.0024   1.0022  0.0158     1.0000  -1.6426  0.0093   1.6505         │
│  y      2.9987   1.7414  0.0270     1.0005  1.0000   3.0000   6.0000         │
│  z[1]   3.0077   2.2519  0.0348     1.0001  -0.5107  2.9099   6.8194         │
│  z[2]   -2.9961  2.2629  0.0373     1.0004  -6.9224  -2.8814  0.5911         │
╰──────────────────────────────────────────────────────────────────────────────╯
julia
ss[@varname(x), stat=:mean]
0.0024402529856892845

For added versatility you can also convert a FlexiChain into a DimArray or a DataFrame.

Plotting ​

Many visualisation functions with both Makie.jl and Plots.jl backends are provided, along with a PairPlots.jl extension.

julia
using PairPlots, CairoMakie
pairplot(chain)