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-1} + \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      = 10000
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))

LS0tCnRpdGxlOiAiQVIoMSkgcGx1cyBub2lzZSBtb2RlbCIKYXV0aG9yOiAiSGVkaWJlcnQgRnJlaXRhcyBMb3BlcyIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiBwYXBlcgogICAgaGlnaGxpZ2h0OiBweWdtZW50cwogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKIyAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQotLS0KICAKCgojIEFSKDEpIHBsdXMgbm9pc2UgbW9kZWwKCkluIHRoaXMgZXhlcmNpc2UsIHdlIGNvbnNpZGVyIHRoZSBBUigxKSBwbHVzIG5vaXNlIG1vZGVsLCB3aGljaCBpcyBhIHNwZWNpYWwgY2FzZSBvZiB0aGUgbW9yZSBnZW5lcmFsIG5vcm1hbCBkeW5hbWljIGxpbmVhciBtb2RlbCB3ZSd2ZSBqdXN0IHN0dWRpZWQuICBUaGUgZm9sbG93IGFzc3VtZXMgdGhhdCAKClxiZWdpbntlcW5hcnJheSp9CnlfdCAmPSYgeF90ICsgXGVwc2lsb25fdCAgICAgICAgICAgICBccXF1YWRccXF1YWQgICAgXGVwc2lsb25fdCBcc2ltIE4oMCxcc2lnbWFeMilcXAp4X3QgJj0mIFxhbHBoYSArIFxiZXRhIHhfe3QtMX0gKyBcb21lZ2FfdCAgXHFxdWFkICBcb21lZ2FfdCBcc2ltIE4oMCxcdGF1XjIpClxlbmR7ZXFuYXJyYXkqfQpmb3IgJHQ9MSxcbGRvdHMsbiQgYW5kICR4XzAgXHNpbSBOKG1fMCxDXzApJC4KCgojIFNpbXVsYXRpbmcgc29tZSBkYXRhCgpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTV9CnNldC5zZWVkKDMxNDE1OTMpCm4gICAgID0gMTAwCmFscGhhID0gMC4wCmJldGEgID0gMC45OApzaWcyICA9IDEuMAp0YXUyICA9IDAuNQp4MCAgICA9IGFscGhhLygxLWJldGEpCmUgICAgID0gcm5vcm0obiwwLHNxcnQoc2lnMikpCncgICAgID0gcm5vcm0obiwwLHNxcnQodGF1MikpCnkgICAgID0gcmVwKDAsbikKeCAgICAgPSByZXAoMCxuKQp4WzFdICA9IHJub3JtKDEsYWxwaGErYmV0YSp4MCxzcXJ0KHRhdTIpKQp5WzFdICA9IHJub3JtKDEseFsxXSxzcXJ0KHNpZzIpKQpmb3IgKHQgaW4gMjpuKXsKICB4W3RdID0gcm5vcm0oMSxhbHBoYStiZXRhKnhbdC0xXSxzcXJ0KHRhdTIpKQogIHlbdF0gPSBybm9ybSgxLHhbdF0sc3FydChzaWcyKSkKfQp4LnRydWUgICAgID0geApzaWcyLnRydWUgID0gc2lnMgp0YXUyLnRydWUgID0gdGF1Mgp4MC50cnVlICAgID0geDAKYWxwaGEudHJ1ZSA9IGFscGhhCmJldGEudHJ1ZSAgPSBiZXRhCgpwYXIobWZyb3c9YygxLDEpKQpwbG90KHkseGxhYj0iVGltZSIseWxhYj0iIixwY2g9MTYpCmxpbmVzKHgsY29sPTIsdHlwZT0iYiIscGNoPTE2KQpgYGAKCiMgU2FtcGxpbmcgdGhlICR4X3QkcyBpbmRpdmlkdWFsbHkgKEdpYmJzIHNhbXBsZXIpCldoZXJlIHdlIGN5Y2xlIHRocm91Z2ggJG4rNCQgdW5pdmFyaWF0ZSBmdWxsIGNvbmRpdGlvbmFsIGRpc3RyaWJ1dGlvbnMgZm9yIHRoZSBjb21wb25lbnRzICR4XzEsXGxkb3RzLHhfbixcYWxwaGEsXGJldGEsXHNpZ21hXjIkIGFuZCAkXHRhdV4yJC4KClRoZSBwcmlvciBmb3IgdGhlIHRpbWUtaW52YXJpYW50IHBhcmFtZXRlcnMsICRcYWxwaGEsXGJldGEsXHNpZ21hXjIkIGFuZCAkXHRhdV4yJCwgYXJlIGFzIGZvbGxvd3MKXGJlZ2lue2VxbmFycmF5Kn0KcChcYWxwaGEsXGJldGEpICZccHJvcHRvJiAxIFxxcXVhZCBcbWJveHsobm9uLWluZm9ybWF0aXZlIHByaW9yKX1cXApcc2lnbWFeMiAmXHNpbSYgSUcoXG51XzAvMixcbnVfMFxzaWdtYV8wXjIvMilcXApcdGF1XjIgJlxzaW0mIElHKFxldGFfMC8yLFxldGFfMFx0YXVfMF4yLzIpLgpcZW5ke2VxbmFycmF5Kn0KClRoZXJlZm9yZSwgdGhlIGpvaW50IHBvc3RlcmlvciBkaXN0cmlidXRpb24gaXMgZ2l2ZW4gYnkKJCQKcCh4XzAseF8xLFxsZG90cyx4X24sXGFscGhhLFxiZXRhLFxzaWdtYV4yLFx0YXVeMikgXHByb3B0byBwKFxhbHBoYSxcYmV0YSlwKFxzaWdtYV4yKXAoXHRhdV4yKQpwKHhfMClccHJvZF97dD0xfV5uIHAoeF90fHhfe3QtMX0sXGFscGhhLFxiZXRhLFx0YXVeMikgXHByb2Rfe3Q9MX1ebiBwKHlfdHx4X3QsXHNpZ21hXjIpLgokJApJdCBlYXN5IHRvIHNlZSB0aGF0IHRoZSBmdWxsIGNvbmRpdGlvbmFscyBjYW4gYmUgd3JpdHRlbiBhcwpcYmVnaW57ZXFuYXJyYXkqfQpwKHhfMHxcbWJveHthbGx9KSAmXHByb3B0byYgcCh4XzApcCh4XzF8eF8wLFxhbHBoYSxcYmV0YSxcdGF1XjIpXFwKcCh4X3R8XG1ib3h7YWxsfSkgJlxwcm9wdG8mIHAoeF90fHhfe3QtMX0sXGFscGhhLFxiZXRhLFx0YXVeMilwKHhfe3QrMX18eF90LFxhbHBoYSxcYmV0YSxcdGF1XjIpcCh5X3R8eF90LFxzaWdtYV4yKSBccXF1YWQgdD0xLFxsZG90cyxuXFwKcChcYWxwaGEsXGJldGF8XG1ib3h7YWxsfSkgJlxwcm9wdG8mIFxwcm9kX3t0PTF9Xm4gcCh4X3R8eF97dC0xfSxcYWxwaGEsXGJldGEsXHRhdV4yKVxcCnAoXHRhdV4yfFxtYm94e2FsbH0pICZccHJvcHRvJiBwKFx0YXVeMilccHJvZF97dD0xfV5uIHAoeF90fHhfe3QtMX0sXGFscGhhLFxiZXRhLFx0YXVeMilcXApwKFxzaWdtYV4yfFxtYm94e2FsbH0pICZccHJvcHRvJiBwKFxzaWdtYV4yKVxwcm9kX3t0PTF9Xm4gcCh5X3R8eF90LFxzaWdtYV4yKSwKXGVuZHtlcW5hcnJheSp9CmFsbCBvZiB3aGljaCBhcmUgdW5pdmFyaWF0ZSwgYml2YXJpYXRlIG9yIGludmVyc2UtZ2FtbWEgZGlzdHJpYnV0aW9ucy4KCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTJ9CiMgU2V0IHVwIG9mIHByaW9yIGh5cGVycGFyYW1ldGVycwptMCAgICAgICAgPSAwCkMwICAgICAgICA9IDEwMApudTAgICAgICAgPSAxMApzaWcyMCAgICAgPSAxCmV0YTAgICAgICA9IDEwCnRhdTIwICAgICA9IDEKbnUwc2lnMjAgID0gbnUwKnNpZzIwCmV0YTB0YXUyMCA9IGV0YTAqdGF1MjAKbnUwbiAgICAgID0gKG51MCtuKS8yCmV0YTBuICAgICA9IChldGEwK24pLzIKCiMgaW5pdGlhbCB2YWx1ZXMKeCAgICAgPSB4LnRydWUKeDAgICAgPSB4MC50cnVlCmFscGhhID0gYWxwaGEudHJ1ZQpiZXRhICA9IGJldGEudHJ1ZQojIE1DTUMgc2V0IHVwCnRoaW4gICA9IDEKYnVybmluID0gMTAwMApNICAgICAgPSAxMDAwCm5pdGVyICA9IGJ1cm5pbit0aGluKk0KZHJhd3MgID0gbWF0cml4KDAsbml0ZXIsbis1KQpmb3IgKGl0ZXIgaW4gMTpuaXRlcil7CiAgIyBMZWFybmluZyBzaWcyCiAgc2lnMiA9IDEvcmdhbW1hKDEsbnUwbiwobnUwc2lnMjArc3VtKCh5LXgpXjIpKS8yKQogICMgTGVhcm5pbmcgdGF1MgogIHh4ID0gYyh4MCx4WzE6KG4tMSldKQogIHRhdTIgPSAxL3JnYW1tYSgxLGV0YTBuLChldGEwdGF1MjArc3VtKCh4LWFscGhhLWJldGEqeHgpXjIpKS8yKQogICMgTGVhcm5pbmcgKGFscGhhLGJldGEpCiAgWCA9IGNiaW5kKDEseHgpCiAgdiA9IHNvbHZlKHQoWCklKiVYKQogIG0gPSB2JSoldChYKSUqJXgKICBhYiA9IG0rdChjaG9sKHYpKSUqJXJub3JtKDIsMCxzcXJ0KHRhdTIpKQogIGFscGhhID0gYWJbMV0KICBiZXRhICA9IGFiWzJdCiAgIyBMZWFybmluZyB4MAogIHZhciA9IDEvKDEvQzArYmV0YV4yL3RhdTIpCiAgbWVhbiA9IHZhcioobTAvQzArKHhbMV0tYWxwaGEpKmJldGEvdGF1MikKICB4MCA9IHJub3JtKDEsbWVhbixzcXJ0KHZhcikpCiAgIyBMZWFybmluZyB4KDEpCiAgdmFyID0gMS8oKDErYmV0YV4yKS90YXUyKzEvc2lnMikgCiAgbWVhbiA9IHZhciooYmV0YSooeFsyXSt4MCkvdGF1MithbHBoYSooMS1iZXRhKS90YXUyK3lbMV0vc2lnMikKICB4WzFdID0gcm5vcm0oMSxtZWFuLHNxcnQodmFyKSkKICAjIExlYXJuaW5nIHgoMikuLi4ueChuLTEpCiAgdmFyID0gMS8oKDErYmV0YV4yKS90YXUyKzEvc2lnMikgCiAgZm9yICh0IGluIDI6KG4tMSkpewogICAgbWVhbiA9IHZhciooYmV0YSooeFt0KzFdK3hbdC0xXSkvdGF1MithbHBoYSooMS1iZXRhKS90YXUyK3lbdF0vc2lnMikKICAgIHhbdF0gPSBybm9ybSgxLG1lYW4sc3FydCh2YXIpKQogIH0KICAjIExlYXJuaW5nIHgobikKICB2YXIgPSAxLygxL3RhdTIrMS9zaWcyKSAKICBtZWFuID0gdmFyKigoYWxwaGErYmV0YSp4W24tMV0pL3RhdTIreVtuXS9zaWcyKQogIHhbbl0gPSBybm9ybSgxLG1lYW4sc3FydCh2YXIpKQogICMgU3RvcmluZyB0aGUgZHJhd3MKICBkcmF3c1tpdGVyLF0gPSBjKHgsc2lnMix0YXUyLGFscGhhLGJldGEseDApCn0KaW5kID0gc2VxKGJ1cm5pbisxLG5pdGVyLGJ5PXRoaW4pCmRyYXdzID0gZHJhd3NbaW5kLF0KCgpwYXIobWZyb3c9Yyg0LDMpKQp0cy5wbG90KGRyYXdzWyxuKzFdLHhsYWI9Iml0ZXJhdGlvbnMiLHlsYWI9IiIsbWFpbj1leHByZXNzaW9uKHNpZ21hXjIpKQphYmxpbmUoaD1zaWcyLnRydWUsY29sPTIpCmFjZihkcmF3c1ssbisxXSxtYWluPSIiKQpoaXN0KGRyYXdzWyxuKzFdLHByb2I9VFJVRSxtYWluPSIiLHhsYWI9IiIpCmFibGluZSh2PXNpZzIudHJ1ZSxjb2w9MikKdHMucGxvdChkcmF3c1ssbisyXSx4bGFiPSJpdGVyYXRpb25zIix5bGFiPSIiLG1haW49ZXhwcmVzc2lvbih0YXVeMikpCmFibGluZShoPXRhdTIudHJ1ZSxjb2w9MikKYWNmKGRyYXdzWyxuKzJdLG1haW49IiIpCmhpc3QoZHJhd3NbLG4rMl0scHJvYj1UUlVFLG1haW49IiIseGxhYj0iIikKYWJsaW5lKHY9dGF1Mi50cnVlLGNvbD0yKQp0cy5wbG90KGRyYXdzWyxuKzNdLHhsYWI9Iml0ZXJhdGlvbnMiLHlsYWI9IiIsbWFpbj1leHByZXNzaW9uKGFscGhhKSkKYWJsaW5lKGg9YWxwaGEudHJ1ZSxjb2w9MikKYWNmKGRyYXdzWyxuKzNdLG1haW49IiIpCmhpc3QoZHJhd3NbLG4rM10scHJvYj1UUlVFLG1haW49IiIseGxhYj0iIikKYWJsaW5lKHY9YWxwaGEudHJ1ZSxjb2w9MikKdHMucGxvdChkcmF3c1ssbis0XSx4bGFiPSJpdGVyYXRpb25zIix5bGFiPSIiLG1haW49ZXhwcmVzc2lvbihiZXRhKSkKYWJsaW5lKGg9YmV0YS50cnVlLGNvbD0yKQphY2YoZHJhd3NbLG4rNF0sbWFpbj0iIikKaGlzdChkcmF3c1ssbis0XSxwcm9iPVRSVUUsbWFpbj0iIix4bGFiPSIiKQphYmxpbmUodj1iZXRhLnRydWUsY29sPTIpCmBgYAoKIyMgQXV0b2NvcnJlbGF0aW9uIGZ1bmN0aW9ucyBvZiB0aGUgTWFya292IGNoYWlucwoKYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQphY2YxID0gYWNmKGRyYXdzWywxXSxwbG90PUZBTFNFKQpwbG90KGFjZjEkYWNmLHR5cGU9ImwiLHhsYWI9IkxhZyIseWxhYj0iQUNGIixjb2w9Z3JleSgwLjc1KSx5bGltPWMoLTAuMiwxKSkKZm9yIChpIGluIDI6bil7CiAgYWNmMSA9IGFjZihkcmF3c1ssaV0scGxvdD1GQUxTRSkKICBsaW5lcyhhY2YxJGFjZixjb2w9Z3JleSgwLjc1KSkKfQp0aXRsZSgiQUNGIGZvciBlYWNoIHgodCkiKQphYmxpbmUoaD0wLGx0eT0zKQpgYGAKCgojIyBNYXJnaW5hbCBxdWFudGlsZXMgZnJvbSAkcCh4XzEsXGxkb3RzLHhfbnx5XzEsXGxkb3RzLHlfbikkCgpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9CnF4ID0gdChhcHBseShkcmF3c1ssMTpuXSwyLHF1YW50aWxlLGMoMC4wMjUsMC41LDAuOTc1KSkpCnRzLnBsb3QocXgseGxhYj0iVGltZSIsY29sPWMoMywyLDMpLGx0eT1jKDIsMSwyKSkKbGluZXMoeC50cnVlLGNvbD00KQpgYGAKCiMgU2FtcGxpbmcgJHhfdCRzIGpvaW50bHkgKEZGQlMpCgpUaGUgbWFpbiBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGN1cnJlbnQgTUNNQyBzY2hlbWUgKGpvaW50IHNhbXBsaW5nIHRoZSBzdGF0ZXMpIHZlcnN1cyB0aGUgcHJldmlvdXMgTUNNQyBzY2hlbWUgKGluZGl2aWR1YWxseSBzYW1wbGluZyB0aGUgc3RhdGVzKSBpcyB0aGUgZmFjdCB0aGF0IHdlIGNhbiB1c2UgdGhlIGZvcndhcmQgZmlsdGVyaW5nIGFuZCBiYWNrd2FyZCBzYW1wbGluZyBzY2hlbWUgKEZGQlMpIHRvIHNhbXBsZSBmcm9tCiQkCnAoeF8xLFxsZG90cyx4X258eF8wLFxhbHBoYSxcYmV0YSxcdGF1XjIsXHNpZ21hXjIseV8xLFxsZG90cyx5X24pLgokJAoKYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0xMn0KIyBpbml0aWFsIHZhbHVlcwp4ICAgICA9IHgudHJ1ZQp4MCAgICA9IHgwLnRydWUKYWxwaGEgPSBhbHBoYS50cnVlCmJldGEgID0gYmV0YS50cnVlCiMgTUNNQyBzZXQgdXAKdGhpbiAgID0gMQpidXJuaW4gPSA1MDAwCk0gICAgICA9IDEwMDAwCm5pdGVyICA9IGJ1cm5pbit0aGluKk0KZHJhd3MxID0gbWF0cml4KDAsbml0ZXIsbis1KQptdHMgICAgPSByZXAoMCxuKQpDdHMgICAgPSByZXAoMCxuKQpmb3IgKGl0ZXIgaW4gMTpuaXRlcil7CiAgIyBMZWFybmluZyBzaWcyCiAgc2lnMiA9IDEvcmdhbW1hKDEsbnUwbiwobnUwc2lnMjArc3VtKCh5LXgpXjIpKS8yKQogICMgTGVhcm5pbmcgdGF1MgogIHh4ID0gYyh4MCx4WzE6KG4tMSldKQogIHRhdTIgPSAxL3JnYW1tYSgxLGV0YTBuLChldGEwdGF1MjArc3VtKCh4LWFscGhhLWJldGEqeHgpXjIpKS8yKQogICMgTGVhcm5pbmcgKGFscGhhLGJldGEpCiAgWCA9IGNiaW5kKDEseHgpCiAgdiA9IHNvbHZlKHQoWCklKiVYKQogIG0gPSB2JSoldChYKSUqJXgKICBhYiA9IG0rdChjaG9sKHYpKSUqJXJub3JtKDIsMCxzcXJ0KHRhdTIpKQogIGFscGhhID0gYWJbMV0KICBiZXRhICA9IGFiWzJdCiAgIyBMZWFybmluZyB4MAogIHZhciAgPSAxLygxL0MwK2JldGFeMi90YXUyKQogIG1lYW4gPSB2YXIqKG0wL0MwKyh4WzFdLWFscGhhKSpiZXRhL3RhdTIpCiAgeDAgICA9IHJub3JtKDEsbWVhbixzcXJ0KHZhcikpCiAgIyBMZWFybmluZyB4MSwuLi4seG4KICBtdCA9IG0wCiAgQ3QgPSBDMAogIGZvciAodCBpbiAxOm4pewogICAgYXQgPSBhbHBoYStiZXRhKm10CiAgICBSdCA9IGJldGFeMipDdCt0YXUyCiAgICBRdCA9IFJ0K3NpZzIKICAgIEF0ID0gUnQvUXQKICAgIG10ID0gKDEtQXQpKmF0ICsgQXQqeVt0XQogICAgQ3QgPSBSdCAtIEF0XjIqUXQKICAgIG10c1t0XSA9IG10CiAgICBDdHNbdF0gPSBDdAogIH0gIAogIHhbbl0gPSBybm9ybSgxLG10c1tuXSxzcXJ0KEN0c1tuXSkpCiAgZm9yICh0IGluIChuLTEpOjEpewogIAkgIHYgPSAxLyhiZXRhXjIvdGF1MisxL0N0c1t0XSkKICAJICBtID0gdiooYmV0YSooeFt0KzFdLWFscGhhKS90YXUyK210c1t0XS9DdHNbdF0pCiAgICB4W3RdID0gcm5vcm0oMSxtLHNxcnQodikpCiAgCX0KICAjIFN0b3JpbmcgdGhlIGRyYXdzCiAgZHJhd3MxW2l0ZXIsXSA9IGMoeCxzaWcyLHRhdTIsYWxwaGEsYmV0YSx4MCkKfQppbmQgPSBzZXEoYnVybmluKzEsbml0ZXIsYnk9dGhpbikKZHJhd3MxID0gZHJhd3MxW2luZCxdCgoKcGFyKG1mcm93PWMoNCwzKSkKdHMucGxvdChkcmF3czFbLG4rMV0seGxhYj0iaXRlcmF0aW9ucyIseWxhYj0iIixtYWluPWV4cHJlc3Npb24oc2lnbWFeMikpCmFibGluZShoPXNpZzIudHJ1ZSxjb2w9MikKYWNmKGRyYXdzMVssbisxXSxtYWluPSIiKQpoaXN0KGRyYXdzMVssbisxXSxwcm9iPVRSVUUsbWFpbj0iIix4bGFiPSIiKQphYmxpbmUodj1zaWcyLnRydWUsY29sPTIpCnRzLnBsb3QoZHJhd3MxWyxuKzJdLHhsYWI9Iml0ZXJhdGlvbnMiLHlsYWI9IiIsbWFpbj1leHByZXNzaW9uKHRhdV4yKSkKYWJsaW5lKGg9dGF1Mi50cnVlLGNvbD0yKQphY2YoZHJhd3MxWyxuKzJdLG1haW49IiIpCmhpc3QoZHJhd3MxWyxuKzJdLHByb2I9VFJVRSxtYWluPSIiLHhsYWI9IiIpCmFibGluZSh2PXRhdTIudHJ1ZSxjb2w9MikKdHMucGxvdChkcmF3czFbLG4rM10seGxhYj0iaXRlcmF0aW9ucyIseWxhYj0iIixtYWluPWV4cHJlc3Npb24oYWxwaGEpKQphYmxpbmUoaD1hbHBoYS50cnVlLGNvbD0yKQphY2YoZHJhd3MxWyxuKzNdLG1haW49IiIpCmhpc3QoZHJhd3MxWyxuKzNdLHByb2I9VFJVRSxtYWluPSIiLHhsYWI9IiIpCmFibGluZSh2PWFscGhhLnRydWUsY29sPTIpCnRzLnBsb3QoZHJhd3MxWyxuKzRdLHhsYWI9Iml0ZXJhdGlvbnMiLHlsYWI9IiIsbWFpbj1leHByZXNzaW9uKGJldGEpKQphYmxpbmUoaD1iZXRhLnRydWUsY29sPTIpCmFjZihkcmF3czFbLG4rNF0sbWFpbj0iIikKaGlzdChkcmF3czFbLG4rNF0scHJvYj1UUlVFLG1haW49IiIseGxhYj0iIikKYWJsaW5lKHY9YmV0YS50cnVlLGNvbD0yKQpgYGAKCiMjIEF1dG9jb3JyZWxhdGlvbiBmdW5jdGlvbnMgb2YgdGhlIE1hcmtvdiBjaGFpbnMKCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0KYWNmMSA9IGFjZihkcmF3czFbLDFdLHBsb3Q9RkFMU0UpCnBsb3QoYWNmMSRhY2YsdHlwZT0ibCIseGxhYj0iTGFnIix5bGFiPSJBQ0YiLGNvbD1ncmV5KDAuNzUpLHlsaW09YygtMC4yLDEpKQpmb3IgKGkgaW4gMjpuKXsKICBhY2YxID0gYWNmKGRyYXdzMVssaV0scGxvdD1GQUxTRSkKICBsaW5lcyhhY2YxJGFjZixjb2w9Z3JleSgwLjc1KSkKfQp0aXRsZSgiQUNGIGZvciBlYWNoIHgodCkiKQphYmxpbmUoaD0wLGx0eT0zKQpgYGAKCiMjIE1hcmdpbmFsIHF1YW50aWxlcyBmcm9tICRwKHhfMSxcbGRvdHMseF9ufHlfMSxcbGRvdHMseV9uKSQKCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0KcXggPSB0KGFwcGx5KGRyYXdzMVssMTpuXSwyLHF1YW50aWxlLGMoMC4wMjUsMC41LDAuOTc1KSkpCnRzLnBsb3QocXgseGxhYj0iVGltZSIsY29sPWMoMywyLDMpLGx0eT1jKDIsMSwyKSkKbGluZXMoeC50cnVlLGNvbD00KQpgYGAKCgojIENvbXBhcmluZyBib3RoIE1DTUMgc2NoZW1lcwoKYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0xMH0KcGFyKG1mcm93PWMoMywyKSkKYWNmMSA9IGFjZihkcmF3c1ssMV0scGxvdD1GQUxTRSkKcGxvdChhY2YxJGFjZix0eXBlPSJsIix4bGFiPSJMYWciLHlsYWI9IkFDRiIsY29sPWdyZXkoMC43NSkseWxpbT1jKC0wLjIsMSkpCmZvciAoaSBpbiAyOm4pewogIGFjZjEgPSBhY2YoZHJhd3NbLGldLHBsb3Q9RkFMU0UpCiAgbGluZXMoYWNmMSRhY2YpCn0KZm9yIChpIGluIDI6bil7CiAgYWNmMSA9IGFjZihkcmF3czFbLGldLHBsb3Q9RkFMU0UpCiAgbGluZXMoYWNmMSRhY2YsY29sPWdyZXkoMC43NSkpCn0KYWJsaW5lKGg9MCxsdHk9MykKbGVnZW5kKCJ0b3ByaWdodCIsbGVnZW5kPWMoIkluZGl2aWR1YWwgc2FtcGxpbmciLCJKb2ludCBzYW1wbGluZyIpLGNvbD1jKDEsZ3JleSgwLjc1KSksbHR5PTEsbHdkPTIsYnR5PSJuIikKCnF4MSA9IHQoYXBwbHkoZHJhd3NbLDE6bl0sMixxdWFudGlsZSxjKDAuMDI1LDAuNSwwLjk3NSkpKQpxeDI9IHQoYXBwbHkoZHJhd3MxWywxOm5dLDIscXVhbnRpbGUsYygwLjAyNSwwLjUsMC45NzUpKSkKdHMucGxvdChxeDEseGxhYj0iVGltZSIpCmZvciAoaSBpbiAxOjMpCiAgbGluZXMocXgyWyxpXSxjb2w9Z3JleSgwLjc1KSkKCnBsb3QoZGVuc2l0eShkcmF3c1ssbisxXSkseGxhYj0iIixtYWluPWV4cHJlc3Npb24oc2lnbWFeMikpCmxpbmVzKGRlbnNpdHkoZHJhd3MxWyxuKzFdKSxjb2w9Z3JleSgwLjc1KSkKcGxvdChkZW5zaXR5KGRyYXdzWyxuKzJdKSx4bGFiPSIiLG1haW49ZXhwcmVzc2lvbih0YXVeMikpCmxpbmVzKGRlbnNpdHkoZHJhd3MxWyxuKzJdKSxjb2w9Z3JleSgwLjc1KSkKcGxvdChkZW5zaXR5KGRyYXdzWyxuKzNdKSx4bGFiPSIiLG1haW49ZXhwcmVzc2lvbihhbHBoYSkpCmxpbmVzKGRlbnNpdHkoZHJhd3MxWyxuKzNdKSxjb2w9Z3JleSgwLjc1KSkKcGxvdChkZW5zaXR5KGRyYXdzWyxuKzRdKSx4bGFiPSIiLG1haW49ZXhwcmVzc2lvbihiZXRhKSkKbGluZXMoZGVuc2l0eShkcmF3czFbLG4rNF0pLGNvbD1ncmV5KDAuNzUpKQpgYGAKCg==