1 AR(1) plus noise model

In this exercise, we consider the AR(1) plus noise model, which is a special case of the more general normal dynamic linear model we’ve just studied. The follow assumes that

\[\begin{eqnarray*} y_t &=& x_t + \epsilon_t \qquad\qquad \epsilon_t \sim N(0,\sigma^2)\\ x_t &=& \alpha + \beta x_t + \omega_t \qquad \omega_t \sim N(0,\tau^2) \end{eqnarray*}\] for \(t=1,\ldots,n\) and \(x_0 \sim N(m_0,C_0)\).

2 Simulating some data

set.seed(3141593)
n     = 100
alpha = 0.0
beta  = 0.98
sig2  = 1.0
tau2  = 0.5
x0    = alpha/(1-beta)
e     = rnorm(n,0,sqrt(sig2))
w     = rnorm(n,0,sqrt(tau2))
y     = rep(0,n)
x     = rep(0,n)
x[1]  = rnorm(1,alpha+beta*x0,sqrt(tau2))
y[1]  = rnorm(1,x[1],sqrt(sig2))
for (t in 2:n){
  x[t] = rnorm(1,alpha+beta*x[t-1],sqrt(tau2))
  y[t] = rnorm(1,x[t],sqrt(sig2))
}
x.true     = x
sig2.true  = sig2
tau2.true  = tau2
x0.true    = x0
alpha.true = alpha
beta.true  = beta

par(mfrow=c(1,1))
plot(y,xlab="Time",ylab="",pch=16)
lines(x,col=2,type="b",pch=16)

3 Sampling the \(x_t\)s individually (Gibbs sampler)

Where we cycle through \(n+4\) univariate full conditional distributions for the components \(x_1,\ldots,x_n,\alpha,\beta,\sigma^2\) and \(\tau^2\).

The prior for the time-invariant parameters, \(\alpha,\beta,\sigma^2\) and \(\tau^2\), are as follows \[\begin{eqnarray*} p(\alpha,\beta) &\propto& 1 \qquad \mbox{(non-informative prior)}\\ \sigma^2 &\sim& IG(\nu_0/2,\nu_0\sigma_0^2/2)\\ \tau^2 &\sim& IG(\eta_0/2,\eta_0\tau_0^2/2). \end{eqnarray*}\]

Therefore, the joint posterior distribution is given by \[ p(x_0,x_1,\ldots,x_n,\alpha,\beta,\sigma^2,\tau^2) \propto p(\alpha,\beta)p(\sigma^2)p(\tau^2) p(x_0)\prod_{t=1}^n p(x_t|x_{t-1},\alpha,\beta,\tau^2) \prod_{t=1}^n p(y_t|x_t,\sigma^2). \] It easy to see that the full conditionals can be written as \[\begin{eqnarray*} p(x_0|\mbox{all}) &\propto& p(x_0)p(x_1|x_0,\alpha,\beta,\tau^2)\\ p(x_t|\mbox{all}) &\propto& p(x_t|x_{t-1},\alpha,\beta,\tau^2)p(x_{t+1}|x_t,\alpha,\beta,\tau^2)p(y_t|x_t,\sigma^2) \qquad t=1,\ldots,n\\ p(\alpha,\beta|\mbox{all}) &\propto& \prod_{t=1}^n p(x_t|x_{t-1},\alpha,\beta,\tau^2)\\ p(\tau^2|\mbox{all}) &\propto& p(\tau^2)\prod_{t=1}^n p(x_t|x_{t-1},\alpha,\beta,\tau^2)\\ p(\sigma^2|\mbox{all}) &\propto& p(\sigma^2)\prod_{t=1}^n p(y_t|x_t,\sigma^2), \end{eqnarray*}\] all of which are univariate, bivariate or inverse-gamma distributions.

# Set up of prior hyperparameters
m0        = 0
C0        = 100
nu0       = 10
sig20     = 1
eta0      = 10
tau20     = 1
nu0sig20  = nu0*sig20
eta0tau20 = eta0*tau20
nu0n      = (nu0+n)/2
eta0n     = (eta0+n)/2

# initial values
x     = x.true
x0    = x0.true
alpha = alpha.true
beta  = beta.true
# MCMC set up
thin   = 1
burnin = 1000
M      = 1000
niter  = burnin+thin*M
draws  = matrix(0,niter,n+5)
for (iter in 1:niter){
  # Learning sig2
  sig2 = 1/rgamma(1,nu0n,(nu0sig20+sum((y-x)^2))/2)
  # Learning tau2
  xx = c(x0,x[1:(n-1)])
  tau2 = 1/rgamma(1,eta0n,(eta0tau20+sum((x-alpha-beta*xx)^2))/2)
  # Learning (alpha,beta)
  X = cbind(1,xx)
  v = solve(t(X)%*%X)
  m = v%*%t(X)%*%x
  ab = m+t(chol(v))%*%rnorm(2,0,sqrt(tau2))
  alpha = ab[1]
  beta  = ab[2]
  # Learning x0
  var = 1/(1/C0+beta^2/tau2)
  mean = var*(m0/C0+(x[1]-alpha)*beta/tau2)
  x0 = rnorm(1,mean,sqrt(var))
  # Learning x(1)
  var = 1/((1+beta^2)/tau2+1/sig2) 
  mean = var*(beta*(x[2]+x0)/tau2+alpha*(1-beta)/tau2+y[1]/sig2)
  x[1] = rnorm(1,mean,sqrt(var))
  # Learning x(2)....x(n-1)
  var = 1/((1+beta^2)/tau2+1/sig2) 
  for (t in 2:(n-1)){
    mean = var*(beta*(x[t+1]+x[t-1])/tau2+alpha*(1-beta)/tau2+y[t]/sig2)
    x[t] = rnorm(1,mean,sqrt(var))
  }
  # Learning x(n)
  var = 1/(1/tau2+1/sig2) 
  mean = var*((alpha+beta*x[n-1])/tau2+y[n]/sig2)
  x[n] = rnorm(1,mean,sqrt(var))
  # Storing the draws
  draws[iter,] = c(x,sig2,tau2,alpha,beta,x0)
}
ind = seq(burnin+1,niter,by=thin)
draws = draws[ind,]


par(mfrow=c(4,3))
ts.plot(draws[,n+1],xlab="iterations",ylab="",main=expression(sigma^2))
abline(h=sig2.true,col=2)
acf(draws[,n+1],main="")
hist(draws[,n+1],prob=TRUE,main="",xlab="")
abline(v=sig2.true,col=2)
ts.plot(draws[,n+2],xlab="iterations",ylab="",main=expression(tau^2))
abline(h=tau2.true,col=2)
acf(draws[,n+2],main="")
hist(draws[,n+2],prob=TRUE,main="",xlab="")
abline(v=tau2.true,col=2)
ts.plot(draws[,n+3],xlab="iterations",ylab="",main=expression(alpha))
abline(h=alpha.true,col=2)
acf(draws[,n+3],main="")
hist(draws[,n+3],prob=TRUE,main="",xlab="")
abline(v=alpha.true,col=2)
ts.plot(draws[,n+4],xlab="iterations",ylab="",main=expression(beta))
abline(h=beta.true,col=2)
acf(draws[,n+4],main="")
hist(draws[,n+4],prob=TRUE,main="",xlab="")
abline(v=beta.true,col=2)

3.1 Autocorrelation functions of the Markov chains

acf1 = acf(draws[,1],plot=FALSE)
plot(acf1$acf,type="l",xlab="Lag",ylab="ACF",col=grey(0.75),ylim=c(-0.2,1))
for (i in 2:n){
  acf1 = acf(draws[,i],plot=FALSE)
  lines(acf1$acf,col=grey(0.75))
}
title("ACF for each x(t)")
abline(h=0,lty=3)

3.2 Marginal quantiles from \(p(x_1,\ldots,x_n|y_1,\ldots,y_n)\)

qx = t(apply(draws[,1:n],2,quantile,c(0.025,0.5,0.975)))
ts.plot(qx,xlab="Time",col=c(3,2,3),lty=c(2,1,2))
lines(x.true,col=4)

4 Sampling \(x_t\)s jointly (FFBS)

The main difference between the current MCMC scheme (joint sampling the states) versus the previous MCMC scheme (individually sampling the states) is the fact that we can use the forward filtering and backward sampling scheme (FFBS) to sample from \[ p(x_1,\ldots,x_n|x_0,\alpha,\beta,\tau^2,\sigma^2,y_1,\ldots,y_n). \]

# initial values
x     = x.true
x0    = x0.true
alpha = alpha.true
beta  = beta.true
# MCMC set up
thin   = 1
burnin = 5000
M      = 5000
niter  = burnin+thin*M
draws1 = matrix(0,niter,n+5)
mts    = rep(0,n)
Cts    = rep(0,n)
for (iter in 1:niter){
  # Learning sig2
  sig2 = 1/rgamma(1,nu0n,(nu0sig20+sum((y-x)^2))/2)
  # Learning tau2
  xx = c(x0,x[1:(n-1)])
  tau2 = 1/rgamma(1,eta0n,(eta0tau20+sum((x-alpha-beta*xx)^2))/2)
  # Learning (alpha,beta)
  X = cbind(1,xx)
  v = solve(t(X)%*%X)
  m = v%*%t(X)%*%x
  ab = m+t(chol(v))%*%rnorm(2,0,sqrt(tau2))
  alpha = ab[1]
  beta  = ab[2]
  # Learning x0
  var  = 1/(1/C0+beta^2/tau2)
  mean = var*(m0/C0+(x[1]-alpha)*beta/tau2)
  x0   = rnorm(1,mean,sqrt(var))
  # Learning x1,...,xn
  mt = m0
  Ct = C0
  for (t in 1:n){
    at = alpha+beta*mt
    Rt = beta^2*Ct+tau2
    Qt = Rt+sig2
    At = Rt/Qt
    mt = (1-At)*at + At*y[t]
    Ct = Rt - At^2*Qt
    mts[t] = mt
    Cts[t] = Ct
  }  
  x[n] = rnorm(1,mts[n],sqrt(Cts[n]))
  for (t in (n-1):1){
      v = 1/(beta^2/tau2+1/Cts[t])
      m = v*(beta*(x[t+1]-alpha)/tau2+mts[t]/Cts[t])
    x[t] = rnorm(1,m,sqrt(v))
    }
  # Storing the draws
  draws1[iter,] = c(x,sig2,tau2,alpha,beta,x0)
}
ind = seq(burnin+1,niter,by=thin)
draws1 = draws1[ind,]


par(mfrow=c(4,3))
ts.plot(draws1[,n+1],xlab="iterations",ylab="",main=expression(sigma^2))
abline(h=sig2.true,col=2)
acf(draws1[,n+1],main="")
hist(draws1[,n+1],prob=TRUE,main="",xlab="")
abline(v=sig2.true,col=2)
ts.plot(draws1[,n+2],xlab="iterations",ylab="",main=expression(tau^2))
abline(h=tau2.true,col=2)
acf(draws1[,n+2],main="")
hist(draws1[,n+2],prob=TRUE,main="",xlab="")
abline(v=tau2.true,col=2)
ts.plot(draws1[,n+3],xlab="iterations",ylab="",main=expression(alpha))
abline(h=alpha.true,col=2)
acf(draws1[,n+3],main="")
hist(draws1[,n+3],prob=TRUE,main="",xlab="")
abline(v=alpha.true,col=2)
ts.plot(draws1[,n+4],xlab="iterations",ylab="",main=expression(beta))
abline(h=beta.true,col=2)
acf(draws1[,n+4],main="")
hist(draws1[,n+4],prob=TRUE,main="",xlab="")
abline(v=beta.true,col=2)

4.1 Autocorrelation functions of the Markov chains

acf1 = acf(draws1[,1],plot=FALSE)
plot(acf1$acf,type="l",xlab="Lag",ylab="ACF",col=grey(0.75),ylim=c(-0.2,1))
for (i in 2:n){
  acf1 = acf(draws1[,i],plot=FALSE)
  lines(acf1$acf,col=grey(0.75))
}
title("ACF for each x(t)")
abline(h=0,lty=3)

4.2 Marginal quantiles from \(p(x_1,\ldots,x_n|y_1,\ldots,y_n)\)

qx = t(apply(draws1[,1:n],2,quantile,c(0.025,0.5,0.975)))
ts.plot(qx,xlab="Time",col=c(3,2,3),lty=c(2,1,2))
lines(x.true,col=4)

5 Comparing both MCMC schemes

par(mfrow=c(3,2))
acf1 = acf(draws[,1],plot=FALSE)
plot(acf1$acf,type="l",xlab="Lag",ylab="ACF",col=grey(0.75),ylim=c(-0.2,1))
for (i in 2:n){
  acf1 = acf(draws[,i],plot=FALSE)
  lines(acf1$acf)
}
for (i in 2:n){
  acf1 = acf(draws1[,i],plot=FALSE)
  lines(acf1$acf,col=grey(0.75))
}
abline(h=0,lty=3)
legend("topright",legend=c("Individual sampling","Joint sampling"),col=c(1,grey(0.75)),lty=1,lwd=2,bty="n")

qx1 = t(apply(draws[,1:n],2,quantile,c(0.025,0.5,0.975)))
qx2= t(apply(draws1[,1:n],2,quantile,c(0.025,0.5,0.975)))
ts.plot(qx1,xlab="Time")
for (i in 1:3)
  lines(qx2[,i],col=grey(0.75))

plot(density(draws[,n+1]),xlab="",main=expression(sigma^2))
lines(density(draws1[,n+1]),col=grey(0.75))
plot(density(draws[,n+2]),xlab="",main=expression(tau^2))
lines(density(draws1[,n+2]),col=grey(0.75))
plot(density(draws[,n+3]),xlab="",main=expression(alpha))
lines(density(draws1[,n+3]),col=grey(0.75))
plot(density(draws[,n+4]),xlab="",main=expression(beta))
lines(density(draws1[,n+4]),col=grey(0.75))

LS0tCnRpdGxlOiAiQVIoMSkgcGx1cyBub2lzZSBtb2RlbCIKYXV0aG9yOiAiSGVkaWJlcnQgRnJlaXRhcyBMb3BlcyIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiBwYXBlcgogICAgaGlnaGxpZ2h0OiBweWdtZW50cwogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKIyAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQotLS0KICAKCgojIEFSKDEpIHBsdXMgbm9pc2UgbW9kZWwKCkluIHRoaXMgZXhlcmNpc2UsIHdlIGNvbnNpZGVyIHRoZSBBUigxKSBwbHVzIG5vaXNlIG1vZGVsLCB3aGljaCBpcyBhIHNwZWNpYWwgY2FzZSBvZiB0aGUgbW9yZSBnZW5lcmFsIG5vcm1hbCBkeW5hbWljIGxpbmVhciBtb2RlbCB3ZSd2ZSBqdXN0IHN0dWRpZWQuICBUaGUgZm9sbG93IGFzc3VtZXMgdGhhdCAKClxiZWdpbntlcW5hcnJheSp9CnlfdCAmPSYgeF90ICsgXGVwc2lsb25fdCAgICAgICAgICAgICBccXF1YWRccXF1YWQgICAgXGVwc2lsb25fdCBcc2ltIE4oMCxcc2lnbWFeMilcXAp4X3QgJj0mIFxhbHBoYSArIFxiZXRhIHhfdCArIFxvbWVnYV90ICBccXF1YWQgIFxvbWVnYV90IFxzaW0gTigwLFx0YXVeMikKXGVuZHtlcW5hcnJheSp9CmZvciAkdD0xLFxsZG90cyxuJCBhbmQgJHhfMCBcc2ltIE4obV8wLENfMCkkLgoKCiMgU2ltdWxhdGluZyBzb21lIGRhdGEKCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NX0Kc2V0LnNlZWQoMzE0MTU5MykKbiAgICAgPSAxMDAKYWxwaGEgPSAwLjAKYmV0YSAgPSAwLjk4CnNpZzIgID0gMS4wCnRhdTIgID0gMC41CngwICAgID0gYWxwaGEvKDEtYmV0YSkKZSAgICAgPSBybm9ybShuLDAsc3FydChzaWcyKSkKdyAgICAgPSBybm9ybShuLDAsc3FydCh0YXUyKSkKeSAgICAgPSByZXAoMCxuKQp4ICAgICA9IHJlcCgwLG4pCnhbMV0gID0gcm5vcm0oMSxhbHBoYStiZXRhKngwLHNxcnQodGF1MikpCnlbMV0gID0gcm5vcm0oMSx4WzFdLHNxcnQoc2lnMikpCmZvciAodCBpbiAyOm4pewogIHhbdF0gPSBybm9ybSgxLGFscGhhK2JldGEqeFt0LTFdLHNxcnQodGF1MikpCiAgeVt0XSA9IHJub3JtKDEseFt0XSxzcXJ0KHNpZzIpKQp9CngudHJ1ZSAgICAgPSB4CnNpZzIudHJ1ZSAgPSBzaWcyCnRhdTIudHJ1ZSAgPSB0YXUyCngwLnRydWUgICAgPSB4MAphbHBoYS50cnVlID0gYWxwaGEKYmV0YS50cnVlICA9IGJldGEKCnBhcihtZnJvdz1jKDEsMSkpCnBsb3QoeSx4bGFiPSJUaW1lIix5bGFiPSIiLHBjaD0xNikKbGluZXMoeCxjb2w9Mix0eXBlPSJiIixwY2g9MTYpCmBgYAoKIyBTYW1wbGluZyB0aGUgJHhfdCRzIGluZGl2aWR1YWxseSAoR2liYnMgc2FtcGxlcikKV2hlcmUgd2UgY3ljbGUgdGhyb3VnaCAkbis0JCB1bml2YXJpYXRlIGZ1bGwgY29uZGl0aW9uYWwgZGlzdHJpYnV0aW9ucyBmb3IgdGhlIGNvbXBvbmVudHMgJHhfMSxcbGRvdHMseF9uLFxhbHBoYSxcYmV0YSxcc2lnbWFeMiQgYW5kICRcdGF1XjIkLgoKVGhlIHByaW9yIGZvciB0aGUgdGltZS1pbnZhcmlhbnQgcGFyYW1ldGVycywgJFxhbHBoYSxcYmV0YSxcc2lnbWFeMiQgYW5kICRcdGF1XjIkLCBhcmUgYXMgZm9sbG93cwpcYmVnaW57ZXFuYXJyYXkqfQpwKFxhbHBoYSxcYmV0YSkgJlxwcm9wdG8mIDEgXHFxdWFkIFxtYm94eyhub24taW5mb3JtYXRpdmUgcHJpb3IpfVxcClxzaWdtYV4yICZcc2ltJiBJRyhcbnVfMC8yLFxudV8wXHNpZ21hXzBeMi8yKVxcClx0YXVeMiAmXHNpbSYgSUcoXGV0YV8wLzIsXGV0YV8wXHRhdV8wXjIvMikuClxlbmR7ZXFuYXJyYXkqfQoKVGhlcmVmb3JlLCB0aGUgam9pbnQgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiBpcyBnaXZlbiBieQokJApwKHhfMCx4XzEsXGxkb3RzLHhfbixcYWxwaGEsXGJldGEsXHNpZ21hXjIsXHRhdV4yKSBccHJvcHRvIHAoXGFscGhhLFxiZXRhKXAoXHNpZ21hXjIpcChcdGF1XjIpCnAoeF8wKVxwcm9kX3t0PTF9Xm4gcCh4X3R8eF97dC0xfSxcYWxwaGEsXGJldGEsXHRhdV4yKSBccHJvZF97dD0xfV5uIHAoeV90fHhfdCxcc2lnbWFeMikuCiQkCkl0IGVhc3kgdG8gc2VlIHRoYXQgdGhlIGZ1bGwgY29uZGl0aW9uYWxzIGNhbiBiZSB3cml0dGVuIGFzClxiZWdpbntlcW5hcnJheSp9CnAoeF8wfFxtYm94e2FsbH0pICZccHJvcHRvJiBwKHhfMClwKHhfMXx4XzAsXGFscGhhLFxiZXRhLFx0YXVeMilcXApwKHhfdHxcbWJveHthbGx9KSAmXHByb3B0byYgcCh4X3R8eF97dC0xfSxcYWxwaGEsXGJldGEsXHRhdV4yKXAoeF97dCsxfXx4X3QsXGFscGhhLFxiZXRhLFx0YXVeMilwKHlfdHx4X3QsXHNpZ21hXjIpIFxxcXVhZCB0PTEsXGxkb3RzLG5cXApwKFxhbHBoYSxcYmV0YXxcbWJveHthbGx9KSAmXHByb3B0byYgXHByb2Rfe3Q9MX1ebiBwKHhfdHx4X3t0LTF9LFxhbHBoYSxcYmV0YSxcdGF1XjIpXFwKcChcdGF1XjJ8XG1ib3h7YWxsfSkgJlxwcm9wdG8mIHAoXHRhdV4yKVxwcm9kX3t0PTF9Xm4gcCh4X3R8eF97dC0xfSxcYWxwaGEsXGJldGEsXHRhdV4yKVxcCnAoXHNpZ21hXjJ8XG1ib3h7YWxsfSkgJlxwcm9wdG8mIHAoXHNpZ21hXjIpXHByb2Rfe3Q9MX1ebiBwKHlfdHx4X3QsXHNpZ21hXjIpLApcZW5ke2VxbmFycmF5Kn0KYWxsIG9mIHdoaWNoIGFyZSB1bml2YXJpYXRlLCBiaXZhcmlhdGUgb3IgaW52ZXJzZS1nYW1tYSBkaXN0cmlidXRpb25zLgoKYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0xMn0KIyBTZXQgdXAgb2YgcHJpb3IgaHlwZXJwYXJhbWV0ZXJzCm0wICAgICAgICA9IDAKQzAgICAgICAgID0gMTAwCm51MCAgICAgICA9IDEwCnNpZzIwICAgICA9IDEKZXRhMCAgICAgID0gMTAKdGF1MjAgICAgID0gMQpudTBzaWcyMCAgPSBudTAqc2lnMjAKZXRhMHRhdTIwID0gZXRhMCp0YXUyMApudTBuICAgICAgPSAobnUwK24pLzIKZXRhMG4gICAgID0gKGV0YTArbikvMgoKIyBpbml0aWFsIHZhbHVlcwp4ICAgICA9IHgudHJ1ZQp4MCAgICA9IHgwLnRydWUKYWxwaGEgPSBhbHBoYS50cnVlCmJldGEgID0gYmV0YS50cnVlCiMgTUNNQyBzZXQgdXAKdGhpbiAgID0gMQpidXJuaW4gPSAxMDAwCk0gICAgICA9IDEwMDAKbml0ZXIgID0gYnVybmluK3RoaW4qTQpkcmF3cyAgPSBtYXRyaXgoMCxuaXRlcixuKzUpCmZvciAoaXRlciBpbiAxOm5pdGVyKXsKICAjIExlYXJuaW5nIHNpZzIKICBzaWcyID0gMS9yZ2FtbWEoMSxudTBuLChudTBzaWcyMCtzdW0oKHkteCleMikpLzIpCiAgIyBMZWFybmluZyB0YXUyCiAgeHggPSBjKHgwLHhbMToobi0xKV0pCiAgdGF1MiA9IDEvcmdhbW1hKDEsZXRhMG4sKGV0YTB0YXUyMCtzdW0oKHgtYWxwaGEtYmV0YSp4eCleMikpLzIpCiAgIyBMZWFybmluZyAoYWxwaGEsYmV0YSkKICBYID0gY2JpbmQoMSx4eCkKICB2ID0gc29sdmUodChYKSUqJVgpCiAgbSA9IHYlKiV0KFgpJSoleAogIGFiID0gbSt0KGNob2wodikpJSolcm5vcm0oMiwwLHNxcnQodGF1MikpCiAgYWxwaGEgPSBhYlsxXQogIGJldGEgID0gYWJbMl0KICAjIExlYXJuaW5nIHgwCiAgdmFyID0gMS8oMS9DMCtiZXRhXjIvdGF1MikKICBtZWFuID0gdmFyKihtMC9DMCsoeFsxXS1hbHBoYSkqYmV0YS90YXUyKQogIHgwID0gcm5vcm0oMSxtZWFuLHNxcnQodmFyKSkKICAjIExlYXJuaW5nIHgoMSkKICB2YXIgPSAxLygoMStiZXRhXjIpL3RhdTIrMS9zaWcyKSAKICBtZWFuID0gdmFyKihiZXRhKih4WzJdK3gwKS90YXUyK2FscGhhKigxLWJldGEpL3RhdTIreVsxXS9zaWcyKQogIHhbMV0gPSBybm9ybSgxLG1lYW4sc3FydCh2YXIpKQogICMgTGVhcm5pbmcgeCgyKS4uLi54KG4tMSkKICB2YXIgPSAxLygoMStiZXRhXjIpL3RhdTIrMS9zaWcyKSAKICBmb3IgKHQgaW4gMjoobi0xKSl7CiAgICBtZWFuID0gdmFyKihiZXRhKih4W3QrMV0reFt0LTFdKS90YXUyK2FscGhhKigxLWJldGEpL3RhdTIreVt0XS9zaWcyKQogICAgeFt0XSA9IHJub3JtKDEsbWVhbixzcXJ0KHZhcikpCiAgfQogICMgTGVhcm5pbmcgeChuKQogIHZhciA9IDEvKDEvdGF1MisxL3NpZzIpIAogIG1lYW4gPSB2YXIqKChhbHBoYStiZXRhKnhbbi0xXSkvdGF1Mit5W25dL3NpZzIpCiAgeFtuXSA9IHJub3JtKDEsbWVhbixzcXJ0KHZhcikpCiAgIyBTdG9yaW5nIHRoZSBkcmF3cwogIGRyYXdzW2l0ZXIsXSA9IGMoeCxzaWcyLHRhdTIsYWxwaGEsYmV0YSx4MCkKfQppbmQgPSBzZXEoYnVybmluKzEsbml0ZXIsYnk9dGhpbikKZHJhd3MgPSBkcmF3c1tpbmQsXQoKCnBhcihtZnJvdz1jKDQsMykpCnRzLnBsb3QoZHJhd3NbLG4rMV0seGxhYj0iaXRlcmF0aW9ucyIseWxhYj0iIixtYWluPWV4cHJlc3Npb24oc2lnbWFeMikpCmFibGluZShoPXNpZzIudHJ1ZSxjb2w9MikKYWNmKGRyYXdzWyxuKzFdLG1haW49IiIpCmhpc3QoZHJhd3NbLG4rMV0scHJvYj1UUlVFLG1haW49IiIseGxhYj0iIikKYWJsaW5lKHY9c2lnMi50cnVlLGNvbD0yKQp0cy5wbG90KGRyYXdzWyxuKzJdLHhsYWI9Iml0ZXJhdGlvbnMiLHlsYWI9IiIsbWFpbj1leHByZXNzaW9uKHRhdV4yKSkKYWJsaW5lKGg9dGF1Mi50cnVlLGNvbD0yKQphY2YoZHJhd3NbLG4rMl0sbWFpbj0iIikKaGlzdChkcmF3c1ssbisyXSxwcm9iPVRSVUUsbWFpbj0iIix4bGFiPSIiKQphYmxpbmUodj10YXUyLnRydWUsY29sPTIpCnRzLnBsb3QoZHJhd3NbLG4rM10seGxhYj0iaXRlcmF0aW9ucyIseWxhYj0iIixtYWluPWV4cHJlc3Npb24oYWxwaGEpKQphYmxpbmUoaD1hbHBoYS50cnVlLGNvbD0yKQphY2YoZHJhd3NbLG4rM10sbWFpbj0iIikKaGlzdChkcmF3c1ssbiszXSxwcm9iPVRSVUUsbWFpbj0iIix4bGFiPSIiKQphYmxpbmUodj1hbHBoYS50cnVlLGNvbD0yKQp0cy5wbG90KGRyYXdzWyxuKzRdLHhsYWI9Iml0ZXJhdGlvbnMiLHlsYWI9IiIsbWFpbj1leHByZXNzaW9uKGJldGEpKQphYmxpbmUoaD1iZXRhLnRydWUsY29sPTIpCmFjZihkcmF3c1ssbis0XSxtYWluPSIiKQpoaXN0KGRyYXdzWyxuKzRdLHByb2I9VFJVRSxtYWluPSIiLHhsYWI9IiIpCmFibGluZSh2PWJldGEudHJ1ZSxjb2w9MikKYGBgCgojIyBBdXRvY29ycmVsYXRpb24gZnVuY3Rpb25zIG9mIHRoZSBNYXJrb3YgY2hhaW5zCgpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9CmFjZjEgPSBhY2YoZHJhd3NbLDFdLHBsb3Q9RkFMU0UpCnBsb3QoYWNmMSRhY2YsdHlwZT0ibCIseGxhYj0iTGFnIix5bGFiPSJBQ0YiLGNvbD1ncmV5KDAuNzUpLHlsaW09YygtMC4yLDEpKQpmb3IgKGkgaW4gMjpuKXsKICBhY2YxID0gYWNmKGRyYXdzWyxpXSxwbG90PUZBTFNFKQogIGxpbmVzKGFjZjEkYWNmLGNvbD1ncmV5KDAuNzUpKQp9CnRpdGxlKCJBQ0YgZm9yIGVhY2ggeCh0KSIpCmFibGluZShoPTAsbHR5PTMpCmBgYAoKCiMjIE1hcmdpbmFsIHF1YW50aWxlcyBmcm9tICRwKHhfMSxcbGRvdHMseF9ufHlfMSxcbGRvdHMseV9uKSQKCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0KcXggPSB0KGFwcGx5KGRyYXdzWywxOm5dLDIscXVhbnRpbGUsYygwLjAyNSwwLjUsMC45NzUpKSkKdHMucGxvdChxeCx4bGFiPSJUaW1lIixjb2w9YygzLDIsMyksbHR5PWMoMiwxLDIpKQpsaW5lcyh4LnRydWUsY29sPTQpCmBgYAoKIyBTYW1wbGluZyAkeF90JHMgam9pbnRseSAoRkZCUykKClRoZSBtYWluIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgY3VycmVudCBNQ01DIHNjaGVtZSAoam9pbnQgc2FtcGxpbmcgdGhlIHN0YXRlcykgdmVyc3VzIHRoZSBwcmV2aW91cyBNQ01DIHNjaGVtZSAoaW5kaXZpZHVhbGx5IHNhbXBsaW5nIHRoZSBzdGF0ZXMpIGlzIHRoZSBmYWN0IHRoYXQgd2UgY2FuIHVzZSB0aGUgZm9yd2FyZCBmaWx0ZXJpbmcgYW5kIGJhY2t3YXJkIHNhbXBsaW5nIHNjaGVtZSAoRkZCUykgdG8gc2FtcGxlIGZyb20KJCQKcCh4XzEsXGxkb3RzLHhfbnx4XzAsXGFscGhhLFxiZXRhLFx0YXVeMixcc2lnbWFeMix5XzEsXGxkb3RzLHlfbikuCiQkCgpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTEyfQojIGluaXRpYWwgdmFsdWVzCnggICAgID0geC50cnVlCngwICAgID0geDAudHJ1ZQphbHBoYSA9IGFscGhhLnRydWUKYmV0YSAgPSBiZXRhLnRydWUKIyBNQ01DIHNldCB1cAp0aGluICAgPSAxCmJ1cm5pbiA9IDUwMDAKTSAgICAgID0gNTAwMApuaXRlciAgPSBidXJuaW4rdGhpbipNCmRyYXdzMSA9IG1hdHJpeCgwLG5pdGVyLG4rNSkKbXRzICAgID0gcmVwKDAsbikKQ3RzICAgID0gcmVwKDAsbikKZm9yIChpdGVyIGluIDE6bml0ZXIpewogICMgTGVhcm5pbmcgc2lnMgogIHNpZzIgPSAxL3JnYW1tYSgxLG51MG4sKG51MHNpZzIwK3N1bSgoeS14KV4yKSkvMikKICAjIExlYXJuaW5nIHRhdTIKICB4eCA9IGMoeDAseFsxOihuLTEpXSkKICB0YXUyID0gMS9yZ2FtbWEoMSxldGEwbiwoZXRhMHRhdTIwK3N1bSgoeC1hbHBoYS1iZXRhKnh4KV4yKSkvMikKICAjIExlYXJuaW5nIChhbHBoYSxiZXRhKQogIFggPSBjYmluZCgxLHh4KQogIHYgPSBzb2x2ZSh0KFgpJSolWCkKICBtID0gdiUqJXQoWCklKiV4CiAgYWIgPSBtK3QoY2hvbCh2KSklKiVybm9ybSgyLDAsc3FydCh0YXUyKSkKICBhbHBoYSA9IGFiWzFdCiAgYmV0YSAgPSBhYlsyXQogICMgTGVhcm5pbmcgeDAKICB2YXIgID0gMS8oMS9DMCtiZXRhXjIvdGF1MikKICBtZWFuID0gdmFyKihtMC9DMCsoeFsxXS1hbHBoYSkqYmV0YS90YXUyKQogIHgwICAgPSBybm9ybSgxLG1lYW4sc3FydCh2YXIpKQogICMgTGVhcm5pbmcgeDEsLi4uLHhuCiAgbXQgPSBtMAogIEN0ID0gQzAKICBmb3IgKHQgaW4gMTpuKXsKICAgIGF0ID0gYWxwaGErYmV0YSptdAogICAgUnQgPSBiZXRhXjIqQ3QrdGF1MgogICAgUXQgPSBSdCtzaWcyCiAgICBBdCA9IFJ0L1F0CiAgICBtdCA9ICgxLUF0KSphdCArIEF0KnlbdF0KICAgIEN0ID0gUnQgLSBBdF4yKlF0CiAgICBtdHNbdF0gPSBtdAogICAgQ3RzW3RdID0gQ3QKICB9ICAKICB4W25dID0gcm5vcm0oMSxtdHNbbl0sc3FydChDdHNbbl0pKQogIGZvciAodCBpbiAobi0xKToxKXsKICAJICB2ID0gMS8oYmV0YV4yL3RhdTIrMS9DdHNbdF0pCiAgCSAgbSA9IHYqKGJldGEqKHhbdCsxXS1hbHBoYSkvdGF1MittdHNbdF0vQ3RzW3RdKQogICAgeFt0XSA9IHJub3JtKDEsbSxzcXJ0KHYpKQogIAl9CiAgIyBTdG9yaW5nIHRoZSBkcmF3cwogIGRyYXdzMVtpdGVyLF0gPSBjKHgsc2lnMix0YXUyLGFscGhhLGJldGEseDApCn0KaW5kID0gc2VxKGJ1cm5pbisxLG5pdGVyLGJ5PXRoaW4pCmRyYXdzMSA9IGRyYXdzMVtpbmQsXQoKCnBhcihtZnJvdz1jKDQsMykpCnRzLnBsb3QoZHJhd3MxWyxuKzFdLHhsYWI9Iml0ZXJhdGlvbnMiLHlsYWI9IiIsbWFpbj1leHByZXNzaW9uKHNpZ21hXjIpKQphYmxpbmUoaD1zaWcyLnRydWUsY29sPTIpCmFjZihkcmF3czFbLG4rMV0sbWFpbj0iIikKaGlzdChkcmF3czFbLG4rMV0scHJvYj1UUlVFLG1haW49IiIseGxhYj0iIikKYWJsaW5lKHY9c2lnMi50cnVlLGNvbD0yKQp0cy5wbG90KGRyYXdzMVssbisyXSx4bGFiPSJpdGVyYXRpb25zIix5bGFiPSIiLG1haW49ZXhwcmVzc2lvbih0YXVeMikpCmFibGluZShoPXRhdTIudHJ1ZSxjb2w9MikKYWNmKGRyYXdzMVssbisyXSxtYWluPSIiKQpoaXN0KGRyYXdzMVssbisyXSxwcm9iPVRSVUUsbWFpbj0iIix4bGFiPSIiKQphYmxpbmUodj10YXUyLnRydWUsY29sPTIpCnRzLnBsb3QoZHJhd3MxWyxuKzNdLHhsYWI9Iml0ZXJhdGlvbnMiLHlsYWI9IiIsbWFpbj1leHByZXNzaW9uKGFscGhhKSkKYWJsaW5lKGg9YWxwaGEudHJ1ZSxjb2w9MikKYWNmKGRyYXdzMVssbiszXSxtYWluPSIiKQpoaXN0KGRyYXdzMVssbiszXSxwcm9iPVRSVUUsbWFpbj0iIix4bGFiPSIiKQphYmxpbmUodj1hbHBoYS50cnVlLGNvbD0yKQp0cy5wbG90KGRyYXdzMVssbis0XSx4bGFiPSJpdGVyYXRpb25zIix5bGFiPSIiLG1haW49ZXhwcmVzc2lvbihiZXRhKSkKYWJsaW5lKGg9YmV0YS50cnVlLGNvbD0yKQphY2YoZHJhd3MxWyxuKzRdLG1haW49IiIpCmhpc3QoZHJhd3MxWyxuKzRdLHByb2I9VFJVRSxtYWluPSIiLHhsYWI9IiIpCmFibGluZSh2PWJldGEudHJ1ZSxjb2w9MikKYGBgCgojIyBBdXRvY29ycmVsYXRpb24gZnVuY3Rpb25zIG9mIHRoZSBNYXJrb3YgY2hhaW5zCgpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9CmFjZjEgPSBhY2YoZHJhd3MxWywxXSxwbG90PUZBTFNFKQpwbG90KGFjZjEkYWNmLHR5cGU9ImwiLHhsYWI9IkxhZyIseWxhYj0iQUNGIixjb2w9Z3JleSgwLjc1KSx5bGltPWMoLTAuMiwxKSkKZm9yIChpIGluIDI6bil7CiAgYWNmMSA9IGFjZihkcmF3czFbLGldLHBsb3Q9RkFMU0UpCiAgbGluZXMoYWNmMSRhY2YsY29sPWdyZXkoMC43NSkpCn0KdGl0bGUoIkFDRiBmb3IgZWFjaCB4KHQpIikKYWJsaW5lKGg9MCxsdHk9MykKYGBgCgojIyBNYXJnaW5hbCBxdWFudGlsZXMgZnJvbSAkcCh4XzEsXGxkb3RzLHhfbnx5XzEsXGxkb3RzLHlfbikkCgpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9CnF4ID0gdChhcHBseShkcmF3czFbLDE6bl0sMixxdWFudGlsZSxjKDAuMDI1LDAuNSwwLjk3NSkpKQp0cy5wbG90KHF4LHhsYWI9IlRpbWUiLGNvbD1jKDMsMiwzKSxsdHk9YygyLDEsMikpCmxpbmVzKHgudHJ1ZSxjb2w9NCkKYGBgCgoKIyBDb21wYXJpbmcgYm90aCBNQ01DIHNjaGVtZXMKCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTB9CnBhcihtZnJvdz1jKDMsMikpCmFjZjEgPSBhY2YoZHJhd3NbLDFdLHBsb3Q9RkFMU0UpCnBsb3QoYWNmMSRhY2YsdHlwZT0ibCIseGxhYj0iTGFnIix5bGFiPSJBQ0YiLGNvbD1ncmV5KDAuNzUpLHlsaW09YygtMC4yLDEpKQpmb3IgKGkgaW4gMjpuKXsKICBhY2YxID0gYWNmKGRyYXdzWyxpXSxwbG90PUZBTFNFKQogIGxpbmVzKGFjZjEkYWNmKQp9CmZvciAoaSBpbiAyOm4pewogIGFjZjEgPSBhY2YoZHJhd3MxWyxpXSxwbG90PUZBTFNFKQogIGxpbmVzKGFjZjEkYWNmLGNvbD1ncmV5KDAuNzUpKQp9CmFibGluZShoPTAsbHR5PTMpCmxlZ2VuZCgidG9wcmlnaHQiLGxlZ2VuZD1jKCJJbmRpdmlkdWFsIHNhbXBsaW5nIiwiSm9pbnQgc2FtcGxpbmciKSxjb2w9YygxLGdyZXkoMC43NSkpLGx0eT0xLGx3ZD0yLGJ0eT0ibiIpCgpxeDEgPSB0KGFwcGx5KGRyYXdzWywxOm5dLDIscXVhbnRpbGUsYygwLjAyNSwwLjUsMC45NzUpKSkKcXgyPSB0KGFwcGx5KGRyYXdzMVssMTpuXSwyLHF1YW50aWxlLGMoMC4wMjUsMC41LDAuOTc1KSkpCnRzLnBsb3QocXgxLHhsYWI9IlRpbWUiKQpmb3IgKGkgaW4gMTozKQogIGxpbmVzKHF4MlssaV0sY29sPWdyZXkoMC43NSkpCgpwbG90KGRlbnNpdHkoZHJhd3NbLG4rMV0pLHhsYWI9IiIsbWFpbj1leHByZXNzaW9uKHNpZ21hXjIpKQpsaW5lcyhkZW5zaXR5KGRyYXdzMVssbisxXSksY29sPWdyZXkoMC43NSkpCnBsb3QoZGVuc2l0eShkcmF3c1ssbisyXSkseGxhYj0iIixtYWluPWV4cHJlc3Npb24odGF1XjIpKQpsaW5lcyhkZW5zaXR5KGRyYXdzMVssbisyXSksY29sPWdyZXkoMC43NSkpCnBsb3QoZGVuc2l0eShkcmF3c1ssbiszXSkseGxhYj0iIixtYWluPWV4cHJlc3Npb24oYWxwaGEpKQpsaW5lcyhkZW5zaXR5KGRyYXdzMVssbiszXSksY29sPWdyZXkoMC43NSkpCnBsb3QoZGVuc2l0eShkcmF3c1ssbis0XSkseGxhYj0iIixtYWluPWV4cHJlc3Npb24oYmV0YSkpCmxpbmVzKGRlbnNpdHkoZHJhd3MxWyxuKzRdKSxjb2w9Z3JleSgwLjc1KSkKYGBgCgo=