API
Temper samplers
MCMCTempering.tempered
— Functiontempered(sampler, inverse_temperatures; kwargs...)
OR
tempered(sampler, num_temps; swap_strategy=ReversibleSwap(), kwargs...)
Return a tempered version of sampler
using the provided inverse_temperatures
or inverse temperatures generated from num_temps
and the swap_strategy
.
Arguments
sampler
is an algorithm or sampler object to be used for underlying sampling and to apply tempering to- The temperature schedule can be defined either explicitly or just as an integer number of temperatures, i.e. as:
inverse_temperatures
containing a sequence of 'inverse temperatures' {β₀, ..., βₙ} where 0 ≤ βₙ < ... < β₁ < β₀ = 1 ORnum_temps
, specifying the integer number of inverse temperatures to include in a generatedinverse_temperatures
Keyword arguments
swap_strategy::AbstractSwapStrategy
specifies the method for swapping inverse temperatures between chainssteps_per_swap::Integer
steps are carried out between each attempt at a swap
See also
TemperedSampler
- For more on the swap strategies:
MCMCTempering.TemperedSampler
— TypeTemperedSampler <: AbstractMCMC.AbstractSampler
A TemperedSampler
struct wraps a sampler upon which to apply the Parallel Tempering algorithm.
Fields
sampler
: sampler(s) used to target the tempered distributionschain_to_beta
: collection of inverse temperatures β; β[i] correponds i-th tempered modelswapstrategy
: strategy to use for swappingadapt
: boolean flag specifying whether or not to adaptadaptation_states
: adaptation parameters
Under the hood, MCMCTempering.TemperedSampler
is actually just a "fancy" representation of a composition (represented using a MCMCTempering.CompositionSampler
) of a MCMCTempering.MultiSampler
and a MCMCTempering.SwapSampler
.
Roughly speaking, the implementation of AbstractMCMC.step
for MCMCTempering.TemperedSampler
is basically
# 1. Construct the tempered models.
multimodel = MultiModel([make_tempered_model(model, β) for β in tempered_sampler.chain_to_beta])
# 2. Construct the samplers (can be the same one repeated multiple times or different ones)
multisampler = MultiSampler([getsampler(tempered_sampler, i) for i = 1:numtemps])
# 3. Step targeting `multimodel` using a compositoin of `multisampler` and `swapsampler`.
AbstractMCMC.step(rng, multimodel, multisampler ∘ swapsampler, state; kwargs...)
which in this case is provided by repeated calls to MCMCTempering.make_tempered_model
.
MCMCTempering.make_tempered_model
— Functionmake_tempered_model([sampler, ]model, beta)
Return an instance representing a model
tempered with beta
.
The return-type depends on its usage in compute_logdensities
.
This should be overloaded if you have some custom model-type that does not support the LogDensityProblems.jl-interface. In the case where the model does support the LogDensityProblems.jl-interface, then the following will automatically be constructed
MCMCTempering.TemperedLogDensityProblem
— TypeTemperedLogDensityProblem
A tempered log density function implementing the LogDensityProblem.jl interface.
Fields
logdensity
: underlying log density; assumed to implement LogDensityProblems.jl interfacebeta
In addition, for computation of the tempered logdensities, we have
MCMCTempering.compute_logdensities
— Functioncompute_logdensities(model[, model_other], state, state_other)
Return (logdensity(model, state), logdensity(model, state_other))
.
The default implementation extracts the parameters from the transitions using MCMCTempering.getparams
.
model_other
can be provided to allow specializations that might be more efficient if we know that state_other
is from model_other
, e.g. in the case where the log-probability field is already present in state
and state_other
, and the only difference between logdensity(model, state_other)
and logdensity(model_other, state_other)
is an easily computable factor, then this can be exploited instead of re-computing the log-densities for both.
Swapping
Swapping is implemented using the somewhat special MCMCTempering.SwapSampler
MCMCTempering.SwapSampler
— TypeSwapSampler <: AbstractMCMC.AbstractSampler
Fields
strategy
: swap strategy to use
MCMCTempering.swapstrategy
— Functionswapstrategy(sampler::SwapSampler)
Return the swap-strategy used by sampler
.
This is a rather special sampler because, unlike most other implementations of AbstractMCMC.AbstractSampler
, this is not a valid sampler on its own; for this to be sensible it needs to be part of composition (see MCMCTempering.CompositionSampler
) with at least one other type of (an actually valid) sampler.
Different swap-strategies
A MCMCTempering.SwapSampler
can be defined with different swapping strategies:
MCMCTempering.AbstractSwapStrategy
— TypeAbstractSwapStrategy
Represents a strategy for swapping between parallel chains.
A concrete subtype is expected to implement the method swap_step
.
MCMCTempering.ReversibleSwap
— TypeReversibleSwap <: AbstractSwapStrategy
Stochastically attempt either even- or odd-indexed swap moves between chains.
See [SYED19] for more on this approach, referred to as SEO in their paper.
MCMCTempering.NonReversibleSwap
— TypeNonReversibleSwap <: AbstractSwapStrategy
At every swap step taken, this strategy deterministically traverses first the odd chain indices, proposing swaps between neighbors, and then in the next swap step taken traverses even chain indices, proposing swaps between neighbors.
See [SYED19] for more on this approach, referred to as DEO in their paper.
MCMCTempering.SingleSwap
— TypeSingleSwap <: AbstractSwapStrategy
At every swap step taken, this strategy samples a single chain index i
and proposes a swap between chains i
and i + 1
.
This approach goes under a number of names, e.g. Parallel Tempering (PT) MCMC and Replica-Exchange MCMC.[PTPH05]
MCMCTempering.SingleRandomSwap
— TypeSingleRandomSwap <: AbstractSwapStrategy
At every swap step taken, this strategy samples two chain indices i
and 'j' and proposes a swap between the two corresponding chains.
This approach is shown to be effective for certain models in [1].
MCMCTempering.RandomSwap
— TypeRandomSwap <: AbstractSwapStrategy
This strategy randomly shuffles all the chain indices to produce floor(numptemps(sampler)/2)
pairs of random (not necessarily neighbouring) chain indices to attempt to swap
MCMCTempering.NoSwap
— TypeNoSwap <: AbstractSwapStrategy
Mainly useful for debugging or observing each chain independently, this overrides and disables all swapping functionality.
MCMCTempering.swap_step
— Functionswap_step([strategy::AbstractSwapStrategy, ]rng, model, sampler, state)
Return a new state
, with temperatures possibly swapped according to strategy
.
If no strategy
is provided, the return-value of swapstrategy
called on sampler
is used.
Other samplers
To make a sampler work with MCMCTempering.jl, the sampler needs to implement a few methods:
MCMCTempering.getparams
— Functiongetparams([model, ]state)
Get the parameters from the state
.
Default implementation uses getparams_and_logprob
.
MCMCTempering.getlogprob
— Functiongetlogprob([model, ]state)
Get the log probability of the state
.
Default implementation uses getparams_and_logprob
.
MCMCTempering.getparams_and_logprob
— Functiongetparams_and_logprob([model, ]state)
Return a vector of parameters from the state
.
See also: setparams_and_logprob!!
.
MCMCTempering.setparams_and_logprob!!
— Functionsetparams_and_logprob!!([model, ]state, params)
Set the parameters in the state to params
, possibly mutating if it makes sense.
See also: getparams_and_logprob
.
Other useful methods are:
MCMCTempering.saveall
— Functionsaveall(sampler)
Return whether the sampler saves all the transitions or just the last one.
Compositions of samplers
MCMCTempering.CompositionSampler
— TypeCompositionSampler <: AbstractMCMC.AbstractSampler
A CompositionSampler
is a container for a sequence of samplers.
Fields
sampler_outer
: The outer samplersampler_inner
: The inner samplersaveall
: Whether to save all the transitions or just the last one
Examples
composed_sampler = sampler_inner ∘ sampler_outer # or `CompositionSampler(sampler_inner, sampler_outer, Val(true))`
AbstractMCMC.step(rng, model, composed_sampler) # one step of `sampler_inner`, and one step of `sampler_outer`
This sampler also has its own transition- and state-type
MCMCTempering.CompositionTransition
— TypeCompositionTransition
Wrapper around the inner and outer transitions obtained from a CompositionSampler
.
Fields
transition_outer
: The outer transitiontransition_inner
: The inner transition
MCMCTempering.CompositionState
— TypeCompositionState
Wrapper around the inner and outer states obtained from a CompositionSampler
.
Fields
state_outer
: The outer statestate_inner
: The inner state
Repeated sampler / composition with itself
Large compositions can have unfortunate effects on the compilation times in Julia.
To alleviate this issue we also have the MCMCTempering.RepeatedSampler
:
MCMCTempering.RepeatedSampler
— TypeRepeatedSampler <: AbstractMCMC.AbstractSampler
A RepeatedSampler
is a container for a sampler and a number of times to repeat it.
Fields
sampler
: The sampler to repeatnum_repeat
: The number of times to repeat the samplersaveall
: Whether to save all the transitions or just the last one
Examples
repeated_sampler = sampler^10 # or `RepeatedSampler(sampler, 10, Val(true))`
AbstractMCMC.step(rng, model, repeated_sampler) # take 10 steps of `sampler`
In the case where MCMCTempering.saveall
returns false
, step
for a MCMCTempering.RepeatedSampler
simply returns the last transition and state; if it returns true
, then the transition is of type MCMCTempering.SequentialTransitions
and the state is of type MCMCTempering.SequentialStates
.
MCMCTempering.SequentialTransitions
— TypeSequentialTransitions
A SequentialTransitions
object is a container for a sequence of transitions.
MCMCTempering.SequentialStates
— TypeSequentialStates
A SequentialStates
object is a container for a sequence of states.
This effectively allows you to specify whether or not the "intermediate" states should be kept or not.
You will rarely see MCMCTempering.SequentialTransitions
and MCMCTempering.SequentialStates
as a user because AbstractMCMC.bundle_samples
has been overloaded to these to return the flattened representation, i.e. we "un-roll" the transitions in every MCMCTempering.SequentialTransitions
.
Multiple or product of samplers
MCMCTempering.MultiSampler
— TypeMultiSampler <: AbstractMCMC.AbstractSampler
A MultiSampler
is a container for multiple samplers.
See also: MultiModel
.
Fields
samplers
: The samplers
Examples
# `sampler1` targets `model1`, `sampler2` targets `model2`, etc.
multi_model = model1 × model2 × model3 # or `MultiModel((model1, model2, model3))`
multi_sampler = sampler1 × sampler2 × sampler3 # or `MultiSampler((sampler1, sampler2, sampler3))`
# Target the joint model.
AbstractMCMC.step(rng, multi_model, multi_sampler)
where the tempered models are represented using a MCMCTempering.MultiModel
MCMCTempering.MultiModel
— TypeMultiModel <: AbstractMCMC.AbstractModel
A MultiModel
is a container for multiple models.
See also: MultiSampler
.
Fields
models
: The models
The step
for a MCMCTempering.MultiSampler
and a [MCMCTempering.MultiModel
] is a transition of type MCMCTempering.MultipleTransitions
and a state of type MCMCTempering.MultipleStates
MCMCTempering.MultipleTransitions
— TypeMultipleTransitions
A container for multiple transitions.
See also: MultipleStates
.
Fields
transitions
: The transitions
MCMCTempering.MultipleStates
— TypeMultipleStates
A container for multiple states.
See also: MultipleTransitions
.
Fields
states
: The states
- SYED19Syed, S., Bouchard-Côté, Alexandre, Deligiannidis, G., & Doucet, A., Non-reversible Parallel Tempering: A Scalable Highly Parallel MCMC Scheme, arXiv:1905.02939, (2019).
- SYED19Syed, S., Bouchard-Côté, Alexandre, Deligiannidis, G., & Doucet, A., Non-reversible Parallel Tempering: A Scalable Highly Parallel MCMC Scheme, arXiv:1905.02939, (2019).
- PTPH05Earl, D. J., & Deem, M. W., Parallel tempering: theory, applications, and new perspectives, Physical Chemistry Chemical Physics, 7(23), 3910–3916 (2005).
- 1Malcolm Sambridge, A Parallel Tempering algorithm for probabilistic sampling and multimodal optimization, Geophysical Journal International, Volume 196, Issue 1, January 2014, Pages 357–374, https://doi.org/10.1093/gji/ggt342