Nothing
##########################################################################
## samples from a user-written posterior coded in R using a
## random walk Metropolis algorithm
##
## KQ 6/24/2004
##
## This software is distributed under the terms of the GNU GENERAL
## PUBLIC LICENSE Version 2, June 1991. See the package LICENSE
## file for more information.
##
## modified to work with non-invertible Hessian KQ 6/28/2005
##
## changed the method used to pass additional arguments to the user-defined
## function KQ 8/15/2005
##
## changed to allow more user control of optim KQ 6/18/2006
##
## Copyright (C) 2003-2007 Andrew D. Martin and Kevin M. Quinn
## Copyright (C) 2007-present Andrew D. Martin, Kevin M. Quinn,
## and Jong Hee Park
##########################################################################
#' Metropolis Sampling from User-Written R function
#'
#' This function allows a user to construct a sample from a user-defined
#' continuous distribution using a random walk Metropolis algorithm.
#'
#' MCMCmetrop1R produces a sample from a user-defined distribution using a
#' random walk Metropolis algorithm with multivariate normal proposal
#' distribution. See Gelman et al. (2003) and Robert & Casella (2004) for
#' details of the random walk Metropolis algorithm.
#'
#' The proposal distribution is centered at the current value of
#' \eqn{\theta} and has variance-covariance \eqn{V}. If \eqn{V} is
#' specified by the user to be \code{NULL} then \eqn{V} is calculated
#' as: \eqn{V = T (-1\cdot H)^{-1} T }, where \eqn{T} is a the
#' diagonal positive definite matrix formed from the \code{tune} and
#' \eqn{H} is the approximate Hessian of \code{fun} evaluated at its
#' mode. This last calculation is done via an initial call to
#' \code{optim}.
#'
#' @param fun The unnormalized (log)density of the distribution from which to
#' take a sample. This must be a function defined in R whose first argument is
#' a continuous (possibly vector) variable. This first argument is the point in
#' the state space at which the (log)density is to be evaluated. Additional
#' arguments can be passed to \code{fun()} by inserting them in the call to
#' \code{MCMCmetrop1R()}. See the Details section and the examples below for
#' more information.
#'
#' @param theta.init Starting values for the sampling. Must be of the
#' appropriate dimension. It must also be the case that \code{fun(theta.init,
#' ...)} is greater than \code{-Inf} if \code{fun()} is a logdensity or greater
#' than 0 if \code{fun()} is a density.
#'
#' @param burnin The number of burn-in iterations for the sampler.
#'
#' @param mcmc The number of MCMC iterations after burnin.
#'
#' @param thin The thinning interval used in the simulation. The number of
#' MCMC iterations must be divisible by this value.
#'
#' @param tune The tuning parameter for the Metropolis sampling. Can be either
#' a positive scalar or a \eqn{k}-vector, where \eqn{k} is the length of
#' \eqn{\theta}.
#'
#' @param verbose A switch which determines whether or not the progress of the
#' sampler is printed to the screen. If \code{verbose} is greater than 0 the
#' iteration number, the \eqn{\theta} vector, the function value, and
#' the Metropolis acceptance rate are sent to the screen every \code{verbose}th
#' iteration.
#'
#' @param seed The seed for the random number generator. If NA, the Mersenne
#' Twister generator is used with default seed 12345; if an integer is passed
#' it is used to seed the Mersenne twister. The user can also pass a list of
#' length two to use the L'Ecuyer random number generator, which is suitable
#' for parallel computation. The first element of the list is the L'Ecuyer
#' seed, which is a vector of length six or NA (if NA a default seed of
#' \code{rep(12345,6)} is used). The second element of list is a positive
#' substream number. See the MCMCpack specification for more details.
#'
#' @param logfun Logical indicating whether \code{fun} returns the natural log
#' of a density function (TRUE) or a density (FALSE).
#'
#' @param force.samp Logical indicating whether the sampling should proceed if
#' the Hessian calculated from the initial call to \code{optim} routine to
#' maximize the (log)density is not negative definite. If
#' \code{force.samp==TRUE} and the Hessian from \code{optim} is non-negative
#' definite, the Hessian is rescaled by subtracting small values from it's main
#' diagonal until it is negative definite. Sampling proceeds using this
#' rescaled Hessian in place of the original Hessian from \code{optim}. By
#' default, if \code{force.samp==FALSE} and the Hessian from \code{optim} is
#' non-negative definite, an error message is printed and the call to
#' \code{MCMCmetrop1R} is terminated.
#'
#' \emph{Please note that a non-negative Hessian at the mode is often an
#' indication that the function of interest is not a proper density. Thus,
#' \code{force.samp} should only be set equal to \code{TRUE} with great
#' caution.}
#'
#' @param V The variance-covariance matrix for the Gaussian proposal
#' distribution. Must be a square matrix or \code{NULL}. If a square matrix,
#' \code{V} must have dimension equal to the length of \code{theta.init}. If
#' \code{NULL}, \code{V} is calculated from \code{tune} and an initial call to
#' \code{optim}. See the Details section below for more information. Unless the
#' log-posterior is expensive to compute it will typically be best to use the
#' default \code{V = NULL}.
#'
#' @param optim.method The value of the \code{method} parameter sent to
#' \code{optim} during an initial maximization of \code{fun}. See \code{optim}
#' for more details.
#'
#' @param optim.lower The value of the \code{lower} parameter sent to
#' \code{optim} during an initial maximization of \code{fun}. See \code{optim}
#' for more details.
#'
#' @param optim.upper The value of the \code{upper} parameter sent to
#' \code{optim} during an initial maximization of \code{fun}. See \code{optim}
#' for more details.
#'
#' @param optim.control The value of the \code{control} parameter sent to
#' \code{optim} during an initial maximization of \code{fun}. See \code{optim}
#' for more details.
#'
#' @param \dots Additional arguments.
#'
#' @return An mcmc object that contains the posterior sample. This object can
#' be summarized by functions provided by the coda package.
#'
#' @export
#'
#' @seealso \code{\link[coda]{plot.mcmc}}, \code{\link[coda]{summary.mcmc}},
#' \code{\link[stats]{optim}}, \code{\link[mcmc]{metrop}}
#'
#' @references Siddhartha Chib; Edward Greenberg. 1995. ``Understanding the
#' Metropolis-Hastings Algorithm." \emph{The American Statistician}, 49,
#' 327-335.
#'
#' Andrew Gelman, John B. Carlin, Hal S. Stern, and Donald B. Rubin. 2003.
#' \emph{Bayesian Data Analysis}. 2nd Edition. Boca Raton: Chapman & Hall/CRC.
#'
#' Andrew D. Martin, Kevin M. Quinn, and Jong Hee Park. 2011. ``MCMCpack:
#' Markov Chain Monte Carlo in R.'', \emph{Journal of Statistical Software}.
#' 42(9): 1-21. \doi{10.18637/jss.v042.i09}.
#'
#' Daniel Pemstein, Kevin M. Quinn, and Andrew D. Martin. 2007. \emph{Scythe
#' Statistical Library 1.0.} \url{http://scythe.wustl.edu.s3-website-us-east-1.amazonaws.com/}.
#'
#' Martyn Plummer, Nicky Best, Kate Cowles, and Karen Vines. 2006. ``Output
#' Analysis and Diagnostics for MCMC (CODA)'', \emph{R News}. 6(1): 7-11.
#' \url{https://CRAN.R-project.org/doc/Rnews/Rnews_2006-1.pdf}.
#'
#' Christian P. Robert and George Casella. 2004. \emph{Monte Carlo Statistical
#' Methods}. 2nd Edition. New York: Springer.
#'
#' @keywords models
#'
#' @examples
#'
#' \dontrun{
#'
#' ## logistic regression with an improper uniform prior
#' ## X and y are passed as args to MCMCmetrop1R
#'
#' logitfun <- function(beta, y, X){
#' eta <- X %*% beta
#' p <- 1.0/(1.0+exp(-eta))
#' sum( y * log(p) + (1-y)*log(1-p) )
#' }
#'
#' x1 <- rnorm(1000)
#' x2 <- rnorm(1000)
#' Xdata <- cbind(1,x1,x2)
#' p <- exp(.5 - x1 + x2)/(1+exp(.5 - x1 + x2))
#' yvector <- rbinom(1000, 1, p)
#'
#' post.samp <- MCMCmetrop1R(logitfun, theta.init=c(0,0,0),
#' X=Xdata, y=yvector,
#' thin=1, mcmc=40000, burnin=500,
#' tune=c(1.5, 1.5, 1.5),
#' verbose=500, logfun=TRUE)
#'
#' raftery.diag(post.samp)
#' plot(post.samp)
#' summary(post.samp)
#' ## ##################################################
#'
#'
#' ## negative binomial regression with an improper unform prior
#' ## X and y are passed as args to MCMCmetrop1R
#' negbinfun <- function(theta, y, X){
#' k <- length(theta)
#' beta <- theta[1:(k-1)]
#' alpha <- exp(theta[k])
#' mu <- exp(X %*% beta)
#' log.like <- sum(
#' lgamma(y+alpha) - lfactorial(y) - lgamma(alpha) +
#' alpha * log(alpha/(alpha+mu)) +
#' y * log(mu/(alpha+mu))
#' )
#' }
#'
#' n <- 1000
#' x1 <- rnorm(n)
#' x2 <- rnorm(n)
#' XX <- cbind(1,x1,x2)
#' mu <- exp(1.5+x1+2*x2)*rgamma(n,1)
#' yy <- rpois(n, mu)
#'
#' post.samp <- MCMCmetrop1R(negbinfun, theta.init=c(0,0,0,0), y=yy, X=XX,
#' thin=1, mcmc=35000, burnin=1000,
#' tune=1.5, verbose=500, logfun=TRUE,
#' seed=list(NA,1))
#' raftery.diag(post.samp)
#' plot(post.samp)
#' summary(post.samp)
#' ## ##################################################
#'
#'
#' ## sample from a univariate normal distribution with
#' ## mean 5 and standard deviation 0.1
#' ##
#' ## (MCMC obviously not necessary here and this should
#' ## really be done with the logdensity for better
#' ## numerical accuracy-- this is just an illustration of how
#' ## MCMCmetrop1R works with a density rather than logdensity)
#'
#' post.samp <- MCMCmetrop1R(dnorm, theta.init=5.3, mean=5, sd=0.1,
#' thin=1, mcmc=50000, burnin=500,
#' tune=2.0, verbose=5000, logfun=FALSE)
#'
#' summary(post.samp)
#'
#' }
#'
"MCMCmetrop1R" <- function(fun, theta.init,
burnin=500, mcmc=20000, thin=1,
tune=1, verbose=0, seed=NA, logfun=TRUE,
force.samp=FALSE, V=NULL,
optim.method="BFGS",
optim.lower= -Inf,
optim.upper= Inf,
optim.control=list(fnscale=-1, trace=0,
REPORT=10, maxit=500),
...){
## following block creates an explicit copy of theta.init so that theta.init
## is not modified in place by the code below
theta.init.0 <- rep(NA, length(theta.init))
for (i in 1:length(theta.init)){
theta.init.0[i] <- theta.init[i]
}
## error checking here
check.offset(list(...))
check.mcmc.parameters(burnin, mcmc, thin)
## form the tuning vector
tune <- vector.tune(tune, length(theta.init.0))
## form seed
seeds <- form.seeds(seed)
lecuyer <- seeds[[1]]
seed.array <- seeds[[2]]
lecuyer.stream <- seeds[[3]]
## setup the environment so that fun can see the things passed as ...
userfun <- function(ttt) fun(ttt, ...)
my.env <- environment(fun = userfun)
## setup function for maximization based on value of logfun
if (logfun){
maxfun <- fun
}
else if (logfun==FALSE){
maxfun <- function(ttt, ...) log(fun(ttt, ...))
}
else{
cat("logfun not a logical value.\n")
stop("Respecifiy and call MCMCmetrop1R() again. \n",
call.=FALSE)
}
if (is.null(V)){
## find approx mode and Hessian using optim()
opt.out <- optim(theta.init.0, maxfun,
control=optim.control,
lower=optim.lower, upper=optim.upper,
method=optim.method, hessian=TRUE, ...)
if(opt.out$convergence!=0){
warning("Mode and Hessian were not found with call to optim().\nSampling proceeded anyway. \n")
}
CC <- NULL
try(CC <- chol(-1*opt.out$hessian), silent=TRUE)
hess.new <- opt.out$hessian
hess.flag <- 0
if (force.samp==TRUE){
if (max(diag(opt.out$hessian)==0)){
for (i in 1:nrow(hess.new)){
if (hess.new[i,i] == 0){
hess.new[i,i] <- -1e-6
}
}
}
while (is.null(CC)){
hess.flag <- 1
hess.new <- hess.new - diag(diag(0.01 * abs(opt.out$hessian)))
try(CC <- chol(-1*hess.new), silent=TRUE)
}
}
else{
if (is.null(CC)){
hess.flag <- 2
}
}
if (hess.flag==1){
warning("Hessian from call to optim() not negative definite.\nSampling proceeded after enforcing negative definiteness. \n")
}
if (hess.flag==2){
cat("Hessian from call to optim() not negative definite.\n")
cat("Sampling (as specified) cannot proceed.\n")
stop("Check data and fun() and call MCMCmetrop1R() again. \n",
call.=FALSE)
}
V <- tune %*% solve(-1*hess.new) %*% tune
}
else{ ## V is non NULL
if (nrow(V) != ncol(V) || nrow(V) != length(theta.init.0)){
cat("V not of appropriate dimension.\n")
stop("Check V and theta.init and call MCMCmetrop1R() again. \n",
call.=FALSE)
}
CC <- NULL
try(CC <- chol(V), silent=TRUE)
if (is.null(CC)){
cat("V not positive definite.\n")
stop("Check V and call MCMCmetrop1R() again. \n",
call.=FALSE)
}
V <- tune %*% V %*% tune
}
## Call the C++ function to do the MCMC sampling
sample <- .Call("MCMCmetrop1R_cc", userfun, as.double(theta.init.0),
my.env, as.integer(burnin), as.integer(mcmc),
as.integer(thin),
as.integer(verbose),
lecuyer=as.integer(lecuyer),
seedarray=as.integer(seed.array),
lecuyerstream=as.integer(lecuyer.stream),
as.logical(logfun),
as.matrix(V),
PACKAGE="MCMCpack")
## turn sample into an mcmc object
sample <- mcmc(data=sample, start=burnin+1, end=burnin+mcmc, thin=thin)
return(sample)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.