Learn R Programming

mcmc (version 0.7-2)

temper: Simulated Tempering and Umbrella Sampling

Description

Markov chain Monte Carlo for continuous random vectors using parallel or serial simulated tempering, also called umbrella sampling. For serial tempering the state of the Markov chain is a pair $(i, x)$, where $i$ is an integer between 1 and $k$ and $x$ is a vector of length $p$. This pair is represented as a single real vector c(i, x). For parallel tempering the state of the Markov chain is vector of vectors $(x_1, \ldots, x_k)$, where each x is of length $p$. This vector of vectors is represented as a $k \times p$ matrix.

Usage

temper(obj, initial, neighbors, nbatch, blen = 1, nspac = 1, scale = 1,
    outfun, debug = FALSE, parallel = FALSE, ...)

Arguments

obj
either an Rfunction or an object of class "tempering" from a previous run. If a function, should evalutate the log unnormalized density $\log h(i, x)$ of the desired equilibrium distribution of the Markov chain for serial temperi
initial
for serial tempering, a real vector c(i, x) as described above. For parallel tempering, a real $k \times p$ matrix as described above. In either case, the initial state of the Markov chain.
neighbors
a logical symmetric matrix of dimension k by k. Elements that are TRUE indicate jumps or swaps attempted by the Markov chain.
nbatch
the number of batches.
blen
the length of batches.
nspac
the spacing of iterations that contribute to batches.
scale
controls the proposal step size for real elements of the state vector. For serial tempering, proposing a new value for the $x$ part of the state $(i, x)$. For parallel tempering, proposing a new value for the $x_i$ part of the state $(x_
outfun
controls the output. If a function, then the batch means of outfun(state, ...) are returned. The argument state is like the argument initial of this function. If missing, the batch means of the r
debug
if TRUE extra output useful for testing.
parallel
if TRUE does parallel tempering, if FALSE does serial tempering.
...
additional arguments for obj or outfun.

Value

  • an object of class "mcmc", subclass "tempering", which is a list containing at least the following components:
  • batchthe batch means of the continuous part of the state. If outfun is missing, an nbatch by k by p array. Otherwise, an nbatch by m matrix, where m is the length of the result of outfun.
  • ibatch(returned for serial tempering only) an nbatch by k matrix giving batch means for the multivariate Bernoulli random vector that is all zeros except for a 1 in the i-th place when the current state is $(i, x)$.
  • acceptxfraction of Metropolis within-component proposals accepted. A vector of length k giving the acceptance rate for each component.
  • acceptifraction of Metropolis jump/swap proposals accepted. A k by k matrix giving the acceptance rate for each allowed jump or swap component. NA for elements such that the corresponding elements of neighbors is FALSE.
  • initialvalue of argument initial.
  • finalfinal state of Markov chain.
  • initial.seedvalue of .Random.seed before the run.
  • final.seedvalue of .Random.seed after the run.
  • timerunning time of Markov chain from system.time().
  • ludthe function used to calculate log unnormalized density, either obj or obj$lud from a previous run.
  • nbatchthe argument nbatch or obj$nbatch.
  • blenthe argument blen or obj$blen.
  • nspacthe argument nspac or obj$nspac.
  • outfunthe argument outfun or obj$outfun.

Warning

If outfun is missing, then the log unnormalized density function can be defined without a ...argument and that works fine. One can define it starting ludfun <- function(state) and that works or ludfun <- function(state, foo, bar), where foo and bar are supplied as additional arguments to temper and that works too.

If outfun is a function, then both it and the log unnormalized density function can be defined without ...arguments if they have exactly the same arguments list and that works fine. Otherwise it doesn't work. Start the definitions ludfun <- function(state, foo) and outfun <- function(state, bar) and you get an error about unused arguments. Instead start the definitions ludfun <- function(state, foo, ...) and outfun <- function(state, bar, ...), supply foo and bar as additional arguments to temper, and that works fine.

In short, the log unnormalized density function and outfun need to have ...in their arguments list to be safe. Sometimes it works when ...is left out and sometimes it doesn't.

Of course, one can avoid this whole issue by always defining the log unnormalized density function and outfun to have only one argument state and use global variables (objects in the R global environment) to specify any other information these functions need to use. That too follows the R way. But some people consider that bad programming practice.

Details

Serial tempering simulates a mixture of distributions of a continuous random vector. The number of components of the mixture is k, and the dimension of the random vector is p. Denote the state $(i, x)$, where $i$ is a positive integer between 1 and $k$, and let $h(i, x)$ denote the unnormalized joint density of their equilibrium distribution. The logarithm of this function is what obj or obj$lud calculates. The mixture distribution is the marginal for $x$ derived from the equilibrium distribution $h(i, x)$, that is, $$h(x) = \sum_{i = 1}^k h(i, x)$$

Parallel tempering simulates a product of distributions of a continuous random vector. Denote the state $(x_1, \ldots, x_k)$, then the unnormalized joint density of the equilibrium distribution is $$h(x_1, \ldots, x_k) = \prod_{i = 1}^k h(i, x_i)$$

The update mechanism of the Markov chain combines two kinds of elementary updates: jump/swap updates (jump for serial tempering, swap for parallel tempering) and within-component updates. Each iteration of the Markov chain one of these elementary updates is done. With probability 1/2 a jump/swap update is done, and with probability 1/2 a with-component update is done.

Within-component updates are the same for both serial and parallel tempering. They are random-walk Metropolis updates with multivariate normal proposal, the proposal distribution being determined by the argument scale. In serial tempering, the $x$ part of the current state $(i, x)$ is updated preserving $h(i, x)$. In parallel tempering, an index $i$ is chosen at random and the part of the state $x_i$ representing that component is updated, again preserving $h(i, x)$.

Jump updates choose uniformly at random a neighbor of the current component: if $i$ indexes the current component, then it chooses uniformly at random a $j$ such that neighbors[i, j] == TRUE. It then does does a Metropolis-Hastings update for changing the current state from $(i, x)$ to $(j, x)$.

Swap updates choose a component uniformly at random and a neighbor of that component uniformly at random: first an index $i$ is chosen uniformly at random between 1 and $k$, then an index $j$ is chosen uniformly at random such that neighbors[i, j] == TRUE. It then does does a Metropolis-Hastings update for swapping the states of the two components: interchanging $x_i$ and $x_j$ while perserving $h(x_1, \ldots, x_k)$.

The initial state must satisfy lud(initial, ...) > - Inf for serial tempering or must satisfy lud(initial[i, ], ...) > - Inf for each i for parallel tempering, where lud is either obj or obj$lud. That is, the initial state must have positive probability.

Examples

Run this code
h <- function(x) if (all(x >= 0) && sum(x) <= 1) return(1) else return(-Inf)
out <- metrop(h, rep(0, 5), 1000)
out$accept
# acceptance rate too low
out <- metrop(out, scale = 0.1)
out$accept
# acceptance rate o. k. (about 25 percent)
plot(out$batch[ , 1])
# but run length too short (few excursions from end to end of range)
out <- metrop(out, nbatch = 1e4)
out$accept
plot(out$batch[ , 1])
hist(out$batch[ , 1])

Run the code above in your browser using DataLab