Slice Sampling
SliceSampling.jl provides a family of derivative-free slice samplers. Once using SliceSampling, they can sample any compiled BUGSModel, so you get gradient-free inference without configuring an AD backend. This is handy for models with awkward geometry, non-differentiable pieces, or as a robust component sampler inside JuliaBUGS.Gibbs.
Slice samplers are used two ways:
- Standalone — pass a slice sampler to
AbstractMCMC.sampleto update the whole model. - Inside
JuliaBUGS.Gibbs— assign a slice sampler to one or more variable groups in thesampler_map; JuliaBUGS drives it through the Gibbs sweep.
Setup
using JuliaBUGS
using JuliaBUGS: Gibbs
using SliceSampling
using AbstractMCMC
using MCMCChains
using OrderedCollections: OrderedDict
model_def = @bugs begin
mu ~ dnorm(0, 0.0001)
y ~ dnorm(mu, 1)
end
model = model_def((; y = 1.5))BUGSModel (parameters are in transformed (unconstrained) space, with dimension 1):
Model parameters:
mu
Variable sizes and types:
y: type = Float64
mu: type = Float64
Standalone sampling
Univariate slice samplers such as SliceSteppingOut and SliceDoublingOut update one coordinate at a time. On a single-parameter model you can pass one directly:
chain = AbstractMCMC.sample(
model,
SliceSteppingOut(1.0), # 1.0 is the initial slice window width
500;
chain_type = Chains,
progress = false,
)
summarystats(chain)Summary Statistics
parameters mean std mcse ess_bulk ess_tail rhat e ⋯
Symbol Float64 Float64 Float64 Real Float64 Float64 ⋯
mu 1.5285 1.0151 0.0505 439.6037 241.0086 1.0040 ⋯
1 column omitted
No initial_params is required: the extension implements SliceSampling.initial_sample, which seeds the sampler from the model's current parameter values.
For a model with more than one parameter, wrap a univariate sampler in a multivariate strategy (e.g. RandPermGibbs, which cycles through coordinates in a random order), or use a genuinely multivariate slice sampler:
multi_def = @bugs begin
a ~ dnorm(0, 1)
b ~ dnorm(0, 1)
y ~ dnorm(a + b, 1)
end
multi_model = multi_def((; y = 0.5))
multi_chain = AbstractMCMC.sample(
multi_model,
RandPermGibbs(SliceSteppingOut(1.0)),
500;
chain_type = Chains,
progress = false,
)
summarystats(multi_chain)Summary Statistics
parameters mean std mcse ess_bulk ess_tail rhat e ⋯
Symbol Float64 Float64 Float64 Real Float64 Float64 ⋯
b 0.2469 0.8238 0.0559 218.1688 258.3042 1.0003 ⋯
a 0.1394 0.8125 0.0530 244.3861 324.8920 1.0005 ⋯
1 column omitted
Inside Gibbs
Because each single-site conditional in JuliaBUGS.Gibbs is univariate, a bare univariate slice sampler works per site — no multivariate wrapper needed. Map variable groups to samplers in an OrderedDict:
sampler_map = OrderedDict(
@varname(a) => SliceSteppingOut(1.0),
@varname(b) => SliceSteppingOut(1.0),
)
gibbs = Gibbs(multi_model, sampler_map)
gibbs_chain = AbstractMCMC.sample(
multi_model,
gibbs,
500;
chain_type = Chains,
progress = false,
)
summarystats(gibbs_chain)Summary Statistics
parameters mean std mcse ess_bulk ess_tail rhat e ⋯
Symbol Float64 Float64 Float64 Real Float64 Float64 ⋯
b 0.2019 0.8415 0.0659 171.3296 244.3924 1.0092 ⋯
a 0.1376 0.8778 0.0530 276.1364 275.9140 1.0040 ⋯
1 column omitted
Slice samplers can be freely mixed with HMC and AdvancedMH samplers in the same sampler_map. They update continuous blocks. Gibbs updates finite discrete blocks exactly by enumerating and normalizing their full conditional, without invoking SliceSampling or AdvancedMH.
Output formats and statistics
Both chain backends are supported:
chain_type = Chainsreturns anMCMCChains.Chains(shown above).chain_type = VNChainreturns aFlexiChains.FlexiChainkeyed byVarName(requiresusing FlexiChains):
using FlexiChains
chain = AbstractMCMC.sample(model, SliceSteppingOut(1.0), 500; chain_type = VNChain, progress = false)In either case the sampler's own statistics are recorded alongside the draws: the log density lp and num_proposals (the number of proposals the slice sampler evaluated per step). Under MCMCChains these appear as internals; under FlexiChains they are FlexiChains.Extra entries. For a multivariate sampler the per-coordinate num_proposals is flattened into num_proposals[i] columns for MCMCChains.