Banana log-target
density
The target density for \((x,y)\) is
given by \[
p(x,y) \propto \exp\{-0.5[x^2+(y-bx^2]^2)\}.
\]
# Banana log-density
logp = function(xx) {
b = 2
x = xx[1]
y = xx[2]
return(-0.5*(x^2+(y-b*x^2)^2))
}
N = 200
x = seq(-3,3,length=N)
y = seq(-3,10,length=N)
post = matrix(0,N,N)
for (i in 1:N)
for (j in 1:N)
post[i,j] = logp(c(x[i],y[j]))
par(mfrow=c(1,1))
contour(x,y,exp(post),drawlabels=FALSE,xlab="x",ylab="y",main="Target distribution")

Metropolis-Hastings
sampler
metropolis = function(logp,start=c(0,0),iter=niter,warmup=burnin,proposal_sd=0.4,seed=123){
samples = matrix(0,iter,2)
samples[1,] = start
logp_curr = logp(start)
for (i in 2:iter) {
proposal = rnorm(2,samples[i-1,],proposal_sd)
logp_prop = logp(proposal)
accept_prob = exp(logp_prop - logp_curr)
if (runif(1) < accept_prob) {
samples[i,] = proposal
logp_curr = logp_prop
} else {
samples[i,] = samples[i-1,]
}
}
samples[(warmup+1):iter,]
}
seed = 31416
set.seed(seed)
niter = 20000
burnin = 10000
M = niter - burnin
mh_samples = metropolis(logp)
Trace plots and ACF
plots
par(mfrow=c(2,2))
ts.plot(mh_samples[,1],xlab="Iterations",ylab="x",main="Metropolis-Hastings")
acf(mh_samples[,1],main="")
ts.plot(mh_samples[,2],xlab="Iterations",ylab="y")
acf(mh_samples[,2],main="")

Target draws
par(mfrow=c(1,1))
xrange = range(mh_samples[,1],x)
yrange = range(mh_samples[,2],y)
plot(mh_samples, pch=16, cex=0.3, main="Metropolis-Hastings",xlab="x",ylab="y",
xlim=xrange,ylim=yrange)
contour(x,y,exp(post),add=TRUE,col=2,lwd=2)

Effective sample
size
ESS.mh = c(M/sum(acf(mh_samples[,1],plot=FALSE)$acf^2),M/sum(acf(mh_samples[,2],plot=FALSE)$acf^2))
c(M,round(ESS.mh))
## [1] 10000 696 375
Hamiltonian Monte
Carlo
library(rstan)
## Loading required package: StanHeaders
##
## rstan version 2.32.7 (Stan version 2.32.2)
## For execution on a local, multicore CPU with excess RAM we recommend calling
## options(mc.cores = parallel::detectCores()).
## To avoid recompilation of unchanged Stan programs, we recommend calling
## rstan_options(auto_write = TRUE)
## For within-chain threading using `reduce_sum()` or `map_rect()` Stan functions,
## change `threads_per_chain` option:
## rstan_options(threads_per_chain = 1)
stan_code = "
data {
int<lower=0> N;
}
parameters {
real x;
real y;
}
model {
real b = 2;
x ~ normal(0, 1);
y ~ normal(b * x^2, 1);
}
"
Compiling and
sampling
sm = stan_model(model_code = stan_code)
fit = sampling(sm,data=list(N=1),iter=niter,warmup=burnin,chains=1,seed=seed)
##
## SAMPLING FOR MODEL 'anon_model' NOW (CHAIN 1).
## Chain 1:
## Chain 1: Gradient evaluation took 5e-06 seconds
## Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.05 seconds.
## Chain 1: Adjust your expectations accordingly!
## Chain 1:
## Chain 1:
## Chain 1: Iteration: 1 / 20000 [ 0%] (Warmup)
## Chain 1: Iteration: 2000 / 20000 [ 10%] (Warmup)
## Chain 1: Iteration: 4000 / 20000 [ 20%] (Warmup)
## Chain 1: Iteration: 6000 / 20000 [ 30%] (Warmup)
## Chain 1: Iteration: 8000 / 20000 [ 40%] (Warmup)
## Chain 1: Iteration: 10000 / 20000 [ 50%] (Warmup)
## Chain 1: Iteration: 10001 / 20000 [ 50%] (Sampling)
## Chain 1: Iteration: 12000 / 20000 [ 60%] (Sampling)
## Chain 1: Iteration: 14000 / 20000 [ 70%] (Sampling)
## Chain 1: Iteration: 16000 / 20000 [ 80%] (Sampling)
## Chain 1: Iteration: 18000 / 20000 [ 90%] (Sampling)
## Chain 1: Iteration: 20000 / 20000 [100%] (Sampling)
## Chain 1:
## Chain 1: Elapsed Time: 0.059 seconds (Warm-up)
## Chain 1: 0.071 seconds (Sampling)
## Chain 1: 0.13 seconds (Total)
## Chain 1:
## Warning: There were 15 divergent transitions after warmup. See
## https://mc-stan.org/misc/warnings.html#divergent-transitions-after-warmup
## to find out why this is a problem and how to eliminate them.
## Warning: Examine the pairs() plot to diagnose sampling problems
posterior = as.data.frame(fit)
Trace plots and ACF
plots
par(mfrow=c(2,2))
ts.plot(posterior$x,xlab="Iterations",ylab="x",main="Hamiltonian MC")
acf(posterior$x,main="")
ts.plot(posterior$y,xlab="Iterations",ylab="y")
acf(posterior$y,main="")

Target draws
par(mfrow=c(1,1))
plot(posterior$x, posterior$y, pch=16, cex=0.3,main="HMC (Stan)",xlab="x",ylab="y")
contour(x,y,exp(post),add=TRUE,col=2,lwd=2)

Effective sample
size
ESS.hmc = c(M/sum(acf(posterior$x,plot=FALSE)$acf^2),M/sum(acf(posterior$y,plot=FALSE)$acf^2))
c(M,round(ESS.hmc))
## [1] 10000 2642 2500
LS0tCnRpdGxlOiAiQmFuYW5hLWxvZy10YXJnZXQgZGVuc2l0eSIKc3VidGl0bGU6ICJNZXRyb3BvbGlzLUhhc3RpbmdzIHZzIEhhbWlsdG9uaWFuIE1DIgphdXRob3I6ICJIZWRpYmVydCBGcmVpdGFzIExvcGVzIgpkYXRlOiAiMTEvMTEvMjAyNSIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6ICczJwotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKCiMgQmFuYW5hIGxvZy10YXJnZXQgZGVuc2l0eQpUaGUgdGFyZ2V0IGRlbnNpdHkgZm9yICQoeCx5KSQgaXMgZ2l2ZW4gYnkKJCQKcCh4LHkpIFxwcm9wdG8gXGV4cFx7LTAuNVt4XjIrKHktYnheMl1eMilcfS4KJCQKCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KIyBCYW5hbmEgbG9nLWRlbnNpdHkKbG9ncCA9IGZ1bmN0aW9uKHh4KSB7CiAgYiA9IDIKICB4ID0geHhbMV0KICB5ID0geHhbMl0KICByZXR1cm4oLTAuNSooeF4yKyh5LWIqeF4yKV4yKSkKfQoKTiAgICA9IDIwMAp4ICAgID0gc2VxKC0zLDMsbGVuZ3RoPU4pCnkgICAgPSBzZXEoLTMsMTAsbGVuZ3RoPU4pCnBvc3QgPSBtYXRyaXgoMCxOLE4pCmZvciAoaSBpbiAxOk4pCiAgZm9yIChqIGluIDE6TikKICAgIHBvc3RbaSxqXSA9IGxvZ3AoYyh4W2ldLHlbal0pKQoKcGFyKG1mcm93PWMoMSwxKSkKY29udG91cih4LHksZXhwKHBvc3QpLGRyYXdsYWJlbHM9RkFMU0UseGxhYj0ieCIseWxhYj0ieSIsbWFpbj0iVGFyZ2V0IGRpc3RyaWJ1dGlvbiIpCgpgYGAKCiMgTWV0cm9wb2xpcy1IYXN0aW5ncyBzYW1wbGVyCgpgYGB7cn0KbWV0cm9wb2xpcyA9IGZ1bmN0aW9uKGxvZ3Asc3RhcnQ9YygwLDApLGl0ZXI9bml0ZXIsd2FybXVwPWJ1cm5pbixwcm9wb3NhbF9zZD0wLjQsc2VlZD0xMjMpewogIHNhbXBsZXMgICAgID0gbWF0cml4KDAsaXRlciwyKQogIHNhbXBsZXNbMSxdID0gc3RhcnQKICBsb2dwX2N1cnIgICA9IGxvZ3Aoc3RhcnQpCiAgCiAgZm9yIChpIGluIDI6aXRlcikgewogICAgcHJvcG9zYWwgICAgPSAgcm5vcm0oMixzYW1wbGVzW2ktMSxdLHByb3Bvc2FsX3NkKQogICAgbG9ncF9wcm9wICAgPSBsb2dwKHByb3Bvc2FsKQogICAgYWNjZXB0X3Byb2IgPSBleHAobG9ncF9wcm9wIC0gbG9ncF9jdXJyKQogICAgCiAgICBpZiAocnVuaWYoMSkgPCBhY2NlcHRfcHJvYikgewogICAgICBzYW1wbGVzW2ksXSA9IHByb3Bvc2FsCiAgICAgIGxvZ3BfY3VyciAgID0gbG9ncF9wcm9wCiAgICB9IGVsc2UgewogICAgICBzYW1wbGVzW2ksXSA9IHNhbXBsZXNbaS0xLF0KICAgIH0KICB9CiAgc2FtcGxlc1sod2FybXVwKzEpOml0ZXIsXQp9CgpzZWVkID0gMzE0MTYKc2V0LnNlZWQoc2VlZCkKbml0ZXIgID0gMjAwMDAKYnVybmluID0gMTAwMDAKTSAgICAgID0gbml0ZXIgLSBidXJuaW4KCm1oX3NhbXBsZXMgPSBtZXRyb3BvbGlzKGxvZ3ApCmBgYAoKIyMgVHJhY2UgcGxvdHMgYW5kIEFDRiBwbG90cwoKYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9N30KcGFyKG1mcm93PWMoMiwyKSkKdHMucGxvdChtaF9zYW1wbGVzWywxXSx4bGFiPSJJdGVyYXRpb25zIix5bGFiPSJ4IixtYWluPSJNZXRyb3BvbGlzLUhhc3RpbmdzIikKYWNmKG1oX3NhbXBsZXNbLDFdLG1haW49IiIpCnRzLnBsb3QobWhfc2FtcGxlc1ssMl0seGxhYj0iSXRlcmF0aW9ucyIseWxhYj0ieSIpCmFjZihtaF9zYW1wbGVzWywyXSxtYWluPSIiKQpgYGAKCiMjIFRhcmdldCBkcmF3cwoKYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQpwYXIobWZyb3c9YygxLDEpKQp4cmFuZ2UgPSByYW5nZShtaF9zYW1wbGVzWywxXSx4KQp5cmFuZ2UgPSByYW5nZShtaF9zYW1wbGVzWywyXSx5KQpwbG90KG1oX3NhbXBsZXMsIHBjaD0xNiwgY2V4PTAuMywgbWFpbj0iTWV0cm9wb2xpcy1IYXN0aW5ncyIseGxhYj0ieCIseWxhYj0ieSIsCiAgICAgeGxpbT14cmFuZ2UseWxpbT15cmFuZ2UpCmNvbnRvdXIoeCx5LGV4cChwb3N0KSxhZGQ9VFJVRSxjb2w9Mixsd2Q9MikKYGBgCgojIyBFZmZlY3RpdmUgc2FtcGxlIHNpemUKYGBge3J9CkVTUy5taCA9IGMoTS9zdW0oYWNmKG1oX3NhbXBsZXNbLDFdLHBsb3Q9RkFMU0UpJGFjZl4yKSxNL3N1bShhY2YobWhfc2FtcGxlc1ssMl0scGxvdD1GQUxTRSkkYWNmXjIpKQpjKE0scm91bmQoRVNTLm1oKSkKYGBgCgoKIyBIYW1pbHRvbmlhbiBNb250ZSBDYXJsbwoKYGBge3J9CmxpYnJhcnkocnN0YW4pCnN0YW5fY29kZSA9ICIKZGF0YSB7CiAgaW50PGxvd2VyPTA+IE47Cn0KcGFyYW1ldGVycyB7CiAgcmVhbCB4OwogIHJlYWwgeTsKfQptb2RlbCB7CiAgcmVhbCBiID0gMjsKICB4IH4gbm9ybWFsKDAsIDEpOwogIHkgfiBub3JtYWwoYiAqIHheMiwgMSk7Cn0KIgpgYGAKCiMjIENvbXBpbGluZyBhbmQgc2FtcGxpbmcgCmBgYHtyfQpzbSA9IHN0YW5fbW9kZWwobW9kZWxfY29kZSA9IHN0YW5fY29kZSkKCmZpdCA9IHNhbXBsaW5nKHNtLGRhdGE9bGlzdChOPTEpLGl0ZXI9bml0ZXIsd2FybXVwPWJ1cm5pbixjaGFpbnM9MSxzZWVkPXNlZWQpCgpwb3N0ZXJpb3IgPSBhcy5kYXRhLmZyYW1lKGZpdCkKYGBgCgoKIyMgVHJhY2UgcGxvdHMgYW5kIEFDRiBwbG90cwoKYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9N30KcGFyKG1mcm93PWMoMiwyKSkKdHMucGxvdChwb3N0ZXJpb3IkeCx4bGFiPSJJdGVyYXRpb25zIix5bGFiPSJ4IixtYWluPSJIYW1pbHRvbmlhbiBNQyIpCmFjZihwb3N0ZXJpb3IkeCxtYWluPSIiKQp0cy5wbG90KHBvc3RlcmlvciR5LHhsYWI9Ikl0ZXJhdGlvbnMiLHlsYWI9InkiKQphY2YocG9zdGVyaW9yJHksbWFpbj0iIikKYGBgCgoKIyMgVGFyZ2V0IGRyYXdzCgpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9CnBhcihtZnJvdz1jKDEsMSkpCnBsb3QocG9zdGVyaW9yJHgsIHBvc3RlcmlvciR5LCBwY2g9MTYsIGNleD0wLjMsbWFpbj0iSE1DIChTdGFuKSIseGxhYj0ieCIseWxhYj0ieSIpCmNvbnRvdXIoeCx5LGV4cChwb3N0KSxhZGQ9VFJVRSxjb2w9Mixsd2Q9MikKYGBgCgojIyBFZmZlY3RpdmUgc2FtcGxlIHNpemUKYGBge3J9CkVTUy5obWMgPSBjKE0vc3VtKGFjZihwb3N0ZXJpb3IkeCxwbG90PUZBTFNFKSRhY2ZeMiksTS9zdW0oYWNmKHBvc3RlcmlvciR5LHBsb3Q9RkFMU0UpJGFjZl4yKSkKYyhNLHJvdW5kKEVTUy5obWMpKQpgYGAKCg==