knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
devtools::load_all()
A Restore Jump Process $X$ (see 'Regeneration-enriched Markov processes with application to Monte Carlo' - Wang, Pollock, Roberts, Steinsaltz - 2020) is defined by enriching a jump process $Y$ with regenerations from a distribution $\mu$ at rate $\kappa$. The process thus consists of local and global dynamics. The local dynamics determine how the jump process changes between regenerations. The global dynamics dictate how and when the process regenerates. Given a target denstiy $\pi$, a jump process $Y$ and regeneration distribution $\mu$, it is possible to choose the regeneration rate $\kappa$ such that the invariant distribution of $X$ is $\pi$. This allows the Restore Jump process to be used as a Monte Carlo method. In particular, when $Y$ is a jump process defined by a discrete time reversible Markov transition kernel $P$ on its jump chain, and constant holding rate $\lambda=1$, then $\pi$ is the invariant density of $X$ when $\kappa(x)=\mu(x)/\pi(x)$.
At regeneration times, the future of the process is independent of the past and identically distributed. This is useful because it allows the segments of $X$ between regeneration times, called tours, to be generated in parallel. Furthermore, when $\pi$ is a multi-modal distribution, regenerations can encourage the process to move between modes.
This example shows how a Restore Jump Process can be used to sample from a mixture of univariate Gaussians.
# Target density a mixture of Gaussians dtarg <- function(x) 0.5*dnorm(x, mean=-1,sd=1) + 0.5*dnorm(x, mean=1, sd=2) dtarg_log <- function(x) log(0.5*dnorm(x, mean=-1, sd=1) + 0.5*dnorm(x, mean=1, sd=2)) # Regeneration distribution an overdispersed Gaussian dmu <- function(x) dnorm(x, sd=4) dmu_log <- function(x) dnorm(x, sd=4, log=TRUE) rmu <- function(n) rnorm(n, sd=4) # Compare target (black) and regeneration (green) distributions curve(dtarg(x), from = -10, to = 10, ylab='density') curve(dmu(x), from = -10, to = 10, col='green', add=TRUE)
# Random walk Metropolis-Hastings kernel for the target density rwmh <- function(x){ x_prop <- rnorm(1, x, sd=1) log_alpha <- dtarg_log(x_prop) - dtarg_log(x) u <- runif(1) if (log(u) < log_alpha){ x_new <- x_prop } else { x_new <- x } x_new } # Check kernel: Metropolis-Hastings algorithm n <- 1000000 samples <- rep(0, n) samples[1] <- rmu(1) for (i in 1:(n-1)){ samples[i+1] <- rwmh(samples[i]) } plot(density(samples), col='blue', xlim=c(-10,10), main='Density estimate') curve(dtarg(x), from = -5, to = 5, add=TRUE) # Estimate of first and second moments (true values 0 and 3.5 respectively) mean(samples) mean(samples^2)
# Jump Process Restore Sampler ntours <- 100000 jp <- jprs(ntours, dtarg_log, dmu_log, rmu, rwmh) # Density plot plot(density(jp[,1], weights = jp[,2]/sum(jp[,2])), col='blue', xlim=c(-10,10), main='Density estimate') curve(dtarg(x), from = -5, to = 5, add=TRUE) # Estimate of first and second moment weighted.mean(jp[,1], jp[,2]) weighted.mean(jp[,1]^2, jp[,2])
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.