# Random Walk Metropolis Algorithm
# Scott M. Lynch, Introduction to Applied Bayesian Statistics
# and Estimation for Social Scientists, 2007, p.16, p.21, p.115f
#
print(sprintf("-----------------------------------------------------------------------"))
## [1] "-----------------------------------------------------------------------"
print(sprintf("| R-code (modified and expanded by) PCM, 2016/02/18 |"))
## [1] "| R-code (modified and expanded by) PCM, 2016/02/18 |"
print(sprintf("-----------------------------------------------------------------------"))
## [1] "-----------------------------------------------------------------------"
linear_density_graph <- function(r=0, s=5, m=2, b=3) {
# "Linear Density", Lynch, 2007, ch2.2, p.16f
c <- 2/((s-r)*(m*(s+r)+2*b))
curve(c*(m*x+b), from=r, to=s, type="l", xlab="x", ylab="f(x)", lwd=3,
main="Linear Density f(x)=(1/40)*(2*x+3)", col="steelblue")
lines(c(r,r),c(0,c*(m*r+b)),type="l",col="steelblue",lwd=1)
lines(c(s,s),c(0,c*(m*s+b)),type="l",col="steelblue",lwd=1)
legend(x=2,y=0.15, legend="area under density f(x) is 1 ")
}
linear_density_graph()

library(lattice)
## Warning: package 'lattice' was built under R version 3.2.3
m_to_b <- function (m, s=5, r=0) {(2-m*(s-r)^2) / (2*(s-r))} # m -> b
likelihood_ratio <- function() {
log_likelihood_ratio <- sum(log(z[]*m[i]+b[i])) - sum(log(z[]*m[i-1]+b[i-1])) # log of ratio
return(exp(log_likelihood_ratio))}
pr_of_accept <- function() {min(1,likelihood_ratio())} # probability of acceptance
# like flip in Church = samples from Bernoulli distribution
flip <- function(theta)
{if (rbinom(n=1,size=1,prob=theta)) TRUE else FALSE}
T <- 100000 # number of samples
T_BIn <- T*0.10 # burn-in period is 10% of T
N <- 1337 # number of subjects
r <- 0 # minimal x limit
s <- 5 # maximal x limit
thin <- 25 # thin factor (only each thin_th sample will be retained)
# initials
m=matrix(0,T); b=matrix(.2,T); z=matrix(0,1377); acc=matrix(1,T); pr_of_acceptance=matrix(0.5,T)
# data
z[1:17]=0; z[18:32]=1; z[33:103]=2 # data table 2.1, p.21
z[104:425]=3; z[426:826]=4; z[827:N]=5 # data table 2.1, p.21
hist(z,breaks=seq(r-0.5, s+0.5, 1), main="Importance of Expressing Unpopular Views", col="steelblue",
xlab="less important ... most important")

# MH-Algorithm
for(i in 2:T) { # Lynch's value is sd=0.002
m[i] <- rnorm(1,mean = m[i-1],sd = 0.001) # proposal q(x'|x) for m
b[i] <- m_to_b(m[i]) # dependent proposal for b
pr_of_acceptance[i] <- pr_of_accept()
if(! flip(pr_of_acceptance[i]) || b[i] < 0)
{ m[i] <- m[i - 1]; b[i] <- b[i - 1];
acc[i] <- 0; pr_of_acceptance[i] <- pr_of_acceptance[i-1] } # refuse proposal
# else
# { m[i] <- m[i]; b[i] <- b[i]; acc[i] <- 1; pr_of_acceptance[i] <- pr_of_acc() } # accept proposal
}
#
print(sprintf("Percentage(AcceptanceDecisions) = %f (Burn-In included)", mean(acc)*100.0))
## [1] "Percentage(AcceptanceDecisions) = 76.549000 (Burn-In included)"
print(sprintf("AcceptanceRate = %f (Burn-In included)", mean(pr_of_acceptance)))
## [1] "AcceptanceRate = 0.871779 (Burn-In included)"
plot(m, type="l", main="MH-Trace for m (Burn-In included)", col="steelblue")
lines(x=c(T_BIn,T_BIn),y=c(0,max(m)),lty=4,col="red",lwd=2) # vertical red line terminating burn-in period
legend(x=200,y=0.02, legend="Proposal Function q(x->x') = q(x'|x):
m' <- rnorm(1,mean = m[i-1],sd = 0.001)
")

acf(m, main="ACF(m) (Burn-In included)")

densityplot(m, main="Posterior Distribution for m (Burn-In included)", xlim=c(0, 0.1), col="steelblue")

# excluding samples from burn-in period
m <- m[-1: -T_BIn]
b <- b[-1: -T_BIn]
acc <- acc[-1: -T_BIn]
pr_of_acceptance <- pr_of_acceptance[-1: -T_BIn]
T <- length(m)
print(sprintf("Percentage(AcceptanceDecisions) = %f (Burn-In included)", mean(acc)*100.0))
## [1] "Percentage(AcceptanceDecisions) = 76.515556 (Burn-In included)"
print(sprintf("AcceptanceRate = %f (Burn-In included)", mean(pr_of_acceptance)))
## [1] "AcceptanceRate = 0.871724 (Burn-In included)"
plot(m, type="l", main="MH-Trace for m (Burn-In excluded)", col="steelblue")

acf(m, main="ACF(m) (Burn-In excluded)")

densityplot(m, main="Posterior Distribution for m (Burn-In excluded)", xlim=c(0, 0.1), col="steelblue")

m_est <- mean(m)
sdm_est <- sd(m)
print(sprintf("mean(m) = %f (Burn-In excluded)", m_est))
## [1] "mean(m) = 0.069693 (Burn-In excluded)"
print(sprintf("sd(m) = %f (Burn-In excluded)", sdm_est))
## [1] "sd(m) = 0.001307 (Burn-In excluded)"
plot(b, type="l", main="MH-Trace for b (Burn-In excluded)", col="steelblue")

acf(b, main="ACF(b) (Burn-In excluded)")

densityplot(b, main="Posterior Distribution for b (Burn-In excluded)", xlim=c(0, 0.1), col="steelblue")

b_est <- mean(b)
sdb_est <- sd(b)
print(sprintf("mean(b) = %f (Burn-In excluded)", b_est))
## [1] "mean(b) = 0.025767 (Burn-In excluded)"
print(sprintf("sd(b) = %f2 (Burn-In excluded)", sdb_est))
## [1] "sd(b) = 0.0032682 (Burn-In excluded)"
c_est <- 2/((s-r)*(m_est*(s+r)+2*b_est))
print(sprintf("const c = %f (Burn-In excluded)", c_est))
## [1] "const c = 1.000000 (Burn-In excluded)"
x <- c(0:5)
freq_est <- (m_est*x + b_est)*N
hist(z,breaks=seq(-0.5, 5.5, 1), main="MH-based Frequency Estimates (Burn-In excluded)", col="steelblue",
xlab="less important ... most important")
legend(x=-0.5,y=500,legend=sprintf("Percentage(AcceptanceDecisions) = %f", mean(acc)*100.0))
legend(x=-0.5,y=430,legend=sprintf("AcceptanceRate = %f",mean(pr_of_acceptance)))
mtext("Proposal Function q(x->x'): m' <- rnorm(1,mean = m[i-1],sd = 0.001)", side=3)
lines(x, freq_est,lwd=3, col="red")
lines(c(r,r),c(0,N*c_est*(m_est*r + b_est)),type="l",col="red",lwd=1)
lines(c(s,s),c(0,N*c_est*(m_est*s + b_est)),type="l",col="red",lwd=1)

# excluding samples by thinning
T <- length(m)
m <- m[seq(from=1,to=T,by=thin)]
b <- b[seq(from=1,to=T,by=thin)]
acc <- acc[seq(from=1,to=T,by=thin)]
pr_of_acceptance <- pr_of_acceptance[seq(from=1,to=T,by=thin)]
print(sprintf("Percentage(AcceptanceDecisions) = %f (Burn-In included)", mean(acc)*100.0))
## [1] "Percentage(AcceptanceDecisions) = 76.944444 (Burn-In included)"
print(sprintf("AcceptanceRate = %f (Burn-In included)", mean(pr_of_acceptance)))
## [1] "AcceptanceRate = 0.867402 (Burn-In included)"
plot(m, type="l", main="MH-Trace for m (Thinned)", col="steelblue")

acf(m, main="ACF(m) (Thinned)")

densityplot(m, main="Posterior Distribution for m (Thinned)", xlim=c(0, 0.1), col="steelblue")

m_est <- mean(m)
sdm_est <- sd(m)
print(sprintf("mean(m) = %f (Thinned)", m_est))
## [1] "mean(m) = 0.069686 (Thinned)"
print(sprintf("sd(m) = %f (Thinned)", sdm_est))
## [1] "sd(m) = 0.001310 (Thinned)"
plot(b, type="l", main="MH-Trace for b (Thinned)", col="steelblue")

acf(b, main="ACF(b) (Thinned)")

densityplot(b, main="Posterior Distribution for b (Thinned)", xlim=c(0, 0.1), col="steelblue")

b_est <- mean(b)
sdb_est <- sd(b)
print(sprintf("mean(b) = %f (Thinned)", b_est))
## [1] "mean(b) = 0.025785 (Thinned)"
print(sprintf("sd(b) = %f2 (Thinned)", sdb_est))
## [1] "sd(b) = 0.0032762 (Thinned)"
c_est <- 2/((s-r)*(m_est*(s+r)+2*b_est))
print(sprintf("const c = %f (Thinned)", c_est))
## [1] "const c = 1.000000 (Thinned)"
x <- c(0:5)
freq_est <- (m_est*x + b_est)*N
hist(z,breaks=seq(-0.5, 5.5, 1), main="MH-based Frequency Estimates (Thinned)", col="steelblue",
xlab="less important ... most important")
legend(x=-0.5,y=500,legend=sprintf("Percentage(AcceptanceDecisions) = %f",mean(acc)*100.0))
legend(x=-0.5,y=430,legend=sprintf("AcceptanceRate = %f",mean(pr_of_acceptance)))
mtext("Proposal Function q(x->x'): m' <- rnorm(1,mean = m[i-1],sd = 0.001)", side=3)
lines(x, freq_est,lwd=3, col="red")
lines(c(r,r),c(0,N*c_est*(m_est*r + b_est)),type="l",col="red",lwd=1)
lines(c(s,s),c(0,N*c_est*(m_est*s + b_est)),type="l",col="red",lwd=1)

#