API

Temper samplers

MCMCTempering.temperedFunction
tempered(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 OR
    • num_temps, specifying the integer number of inverse temperatures to include in a generated inverse_temperatures

Keyword arguments

  • swap_strategy::AbstractSwapStrategy specifies the method for swapping inverse temperatures between chains
  • steps_per_swap::Integer steps are carried out between each attempt at a swap

See also

source
MCMCTempering.TemperedSamplerType
TemperedSampler <: 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 distributions

  • chain_to_beta: collection of inverse temperatures β; β[i] correponds i-th tempered model

  • swapstrategy: strategy to use for swapping

  • adapt: boolean flag specifying whether or not to adapt

  • adaptation_states: adaptation parameters

source

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.

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.TemperedLogDensityProblemType
TemperedLogDensityProblem

A tempered log density function implementing the LogDensityProblem.jl interface.

Fields

  • logdensity: underlying log density; assumed to implement LogDensityProblems.jl interface

  • beta

source

In addition, for computation of the tempered logdensities, we have

MCMCTempering.compute_logdensitiesFunction
compute_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.

source

Swapping

Swapping is implemented using the somewhat special MCMCTempering.SwapSampler

Warning

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.ReversibleSwapType
ReversibleSwap <: 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.

source
MCMCTempering.NonReversibleSwapType
NonReversibleSwap <: 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.

source
MCMCTempering.SingleSwapType
SingleSwap <: 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]

source
MCMCTempering.SingleRandomSwapType
SingleRandomSwap <: 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].

source
MCMCTempering.RandomSwapType
RandomSwap <: 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

source
MCMCTempering.NoSwapType
NoSwap <: AbstractSwapStrategy

Mainly useful for debugging or observing each chain independently, this overrides and disables all swapping functionality.

source
MCMCTempering.swap_stepFunction
swap_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.

source

Other samplers

Compositions of samplers

MCMCTempering.CompositionSamplerType
CompositionSampler <: AbstractMCMC.AbstractSampler

A CompositionSampler is a container for a sequence of samplers.

Fields

  • sampler_outer: The outer sampler

  • sampler_inner: The inner sampler

  • saveall: 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`
source

This sampler also has its own transition- and state-type

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.RepeatedSamplerType
RepeatedSampler <: AbstractMCMC.AbstractSampler

A RepeatedSampler is a container for a sampler and a number of times to repeat it.

Fields

  • sampler: The sampler to repeat

  • num_repeat: The number of times to repeat the sampler

  • saveall: 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`
source

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.

This effectively allows you to specify whether or not the "intermediate" states should be kept or not.

Note

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.MultiSamplerType
MultiSampler <: 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)
source

where the tempered models are represented using a MCMCTempering.MultiModel

The step for a MCMCTempering.MultiSampler and a [MCMCTempering.MultiModel] is a transition of type MCMCTempering.MultipleTransitions and a state of type MCMCTempering.MultipleStates

  • 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