Documentation for ReversibleJumpMCMC.jl
ReversibleJumpMCMC.jl provides a lightweight framework for Reversible Jump Markov Chain Monte Carlo.
Overview
The framework is based around the following code block.
# select a jumptype
jt=rand(rjs.jumpprobability)
# propose a new state
mtest,vararg=rjs.proposalfuns[jt](mhs,rjc.states[nn])
# calculate acceptance probability
α=rjs.acceptfuns[jt](mhs,rjc.states[nn],mtest,vararg)
# accept or reject
rjc.α[nn+1]=α;
if α>rand()
rjc.accept[nn+1]=1;
rjc.states[nn+1]=mtest;
else
rjc.accept[nn+1]=0;
rjc.states[nn+1]=rjc.states[nn];
end
A jumptype jt::Int64
is selected from a Categorial distribution and used to select state proposal and acceptance functions.
rjs::RJMCMCStruct
holds a vector of functions for proposal generators and acceptance calculators.
States of the chain are accumlated in the vector rjc.states
where rjc::RJChain
is a struct holding the results of the RJMCMC run. mhs
is a user defined type, typically immutable, sent to all proposal and generator functions. vararg
can be customized for specific proposal/acceptance functions.
Basic Usage
1D Gaussian PDF
Explore a 1D Gaussian PDF using a basic MCMC chain
using ReversibleJumpMCMC
using Distributions
using CairoMakie
# setup a MH structure that gets passed around inside RJMMCMC
struct MHStruct
σ::Float64 # metropolis hasting jump size
end
mhs = MHStruct(1)
# setup a state type
mutable struct state1D
x::Float64
end
# setup proposal and acceptance functions
function mypropose(mhs::MHStruct, s::state1D)
teststate = state1D(s.x + mhs.σ * randn())
return teststate, 0
end
function myaccept(mhs::MHStruct, s::state1D, teststate::state1D, vararg)
σ = 5.0
d = Normal(0.0, σ)
α = pdf(d, teststate.x) / pdf(d, s.x)
return α
end
# setup the RJMCMCStruct
burnin = 100
iterations = 10000
njumptypes = 1
jumpprobability = Categorical([1.0])
proposalfuns = [mypropose]
acceptfuns = [myaccept]
rjs = ReversibleJumpMCMC.RJMCMCStruct(burnin, iterations, njumptypes, jumpprobability, proposalfuns, acceptfuns)
# initial state
state0 = state1D(0.0)
# run chain
rjc = ReversibleJumpMCMC.buildchain(rjs, mhs, state0)
# Extract parameters from states
xchain = zeros(Float32, iterations)
for ii = 1:iterations
xchain[ii] = rjc.states[ii].x
end
# Show parameter distribution
# true pdf
xvec = -20:0.1:20
σ = 5.0
d = Normal(0.0, σ)
fig = Figure()
ax = Axis(fig[1, 1], xlabel="θ", ylabel="pdf(θ)")
histplot = hist!(ax, xchain, normalization=:pdf)
pdfplot = lines!(ax, xvec, pdf.(d, xvec), color=:red)
legend = Legend(fig, [histplot, pdfplot], ["mcmc dist.", "true pdf"])
fig[1, 2] = legend
fig
njumps = 100