1 Normal, Cauchy and Laplace priors

A parameter \(\beta\) is standard normal, Cauchy (standard Student’s \(t\) with one degree of freedom) or standard double-exponential (aka Laplace) if \[\begin{eqnarray*} p(\beta) &=& \frac{1}{\sqrt{2\pi}}\exp\{-0.5\beta^2\}, \ \ \mbox{or} \\ p(\beta) &=& \frac{1}{\pi(1+\beta^2)}, \ \ \mbox{or} \\ p(\beta) &=& \frac12 \exp\{-|\beta|\}, \end{eqnarray*}\] respectively, for \(\beta \in \Re\).

betas = seq(-5,5,length=1000)
plot(betas,dnorm(betas),type="l",ylim=c(0,0.5),xlab=expression(beta),ylab="Density",lwd=2)
lines(betas,dt(betas,1),col=2,lwd=2)
lines(betas,0.5*exp(-abs(betas)),col=3,lwd=2)
legend("topleft",legend=c("N(0,1)","t(1)","DE(1)"),col=1:3,lwd=2,lty=1,bty="n")

2 A simple linear regression example

set.seed(12345)
n    = 10
beta = 2
x    = rnorm(n)
y    = beta*x + rnorm(n)

plot(x,y)
abline(lm(y~x-1),col=2)
abline(h=0,lty=2)
abline(v=0,lty=2)

2.1 Maximum likelihood estimate

The maximum likelihood estimation of the simple Gaussian linear regression through the origin \[ y_i|x_i,\beta \sim N(\beta x_i,1), \] for \(i=1,\ldots,n\), is straightforward \[ {\widehat \beta}_{mle} = \frac{\sum_{i=1}^n y_ix_i}{\sum_{i=1}^n x_i^2}, \] such that \({\widehat \beta}_{mle}|\beta \sim N(\beta,v^2)\), where \(v^2=\frac{1}{\sum_{i=1}^n x_i^2}\).

beta.mle = sum(x*y)/sum(x^2)
se.beta  = 1/sqrt(sum(x^2))
c(beta.mle,se.beta)
## [1] 1.6650399 0.4037297

3 Bayesian inference via MCI

One of the main (computation) problems faced by applied Bayesian modelers/scientists is the computation of integrals, such as the normalizing constant \[ p(y|x) = \int_{-\infty}^\infty \left[\prod_{i=1}^n p_N(y_i|x_i\beta,1)\right]p(\beta)d\beta, \] or the posterior mean, \[ E(\beta|y,x) = \frac{\int_{-\infty}^\infty \beta \left[\prod_{i=1}^n p_N(y_i|x_i\beta,1)\right]p(\beta)d\beta}{p(y|x)}, \] or even \(Pr(\beta<0.75|y,x)\), \[ Pr(\beta<0.75|y,x) = \frac{\int_{-\infty}^\infty 1(\beta<0.75) \left[\prod_{i=1}^n p_N(y_i|x_i\beta,1)\right]p(\beta)d\beta}{p(y|x)}. \] Basically, Monte Carlo integration approximates the integral \[ I = \int h(\beta)g(\beta)d\beta = \int \left[\frac{h(\beta)g(\beta)}{q(\beta)}\right]q(\beta)d\beta, \] based on draws \(\{\beta^{(i)}\}_{i=1}^M\) from \(g(\beta)\) or based on draws \(\{{\tilde \beta}^{(i)}\}_{i=1}^M\) from \(q(\beta)\) (proposal/candidate/importance distribution), as \[\begin{eqnarray*} {\hat I}_1 &=& \frac{1}{M} \sum_{i=1}^M h(\beta^{(i)})\\ {\hat I}_2 &=& \frac{1}{M} \sum_{i=1}^M \frac{h({\tilde \beta}^{(i)})g({\tilde \beta}^{(i)})}{q({\tilde \beta}^{(i)})}. \end{eqnarray*}\] As \(M \longrightarrow \infty\), both \({\hat I}_1\) and \({\hat I}_2\) converge to \(I\).

Below we use a uniform distribution in the interval $(-5,5) as our proposal \(q(\beta)\).

M       = 10000
b.draws = runif(M,-5,5)
hist(b.draws,prob=TRUE,main="Draws from the proposal U(-5,5)",xlab=expression(beta))

3.1 Computing prior predictives

Here we compute \(p(y|x)\), the prior predictive density, based on each one of the three prior specifications of \(\beta\) (Gaussian, Student’s \(t\) and double-exponential).

like = rep(0,M)
for (i in 1:M)
  like[i] = prod(dnorm(y,x*b.draws[i],1))
k.n = mean(like*dnorm(b.draws)/(1/10))
k.t = mean(like*dt(b.draws,df=1)/(1/10))
k.l = mean(like*0.5*exp(-abs(b.draws))/(1/10))
c(k.n,k.t,k.l)
## [1] 4.475916e-07 3.650963e-07 4.087623e-07

The only one we can obtain in closed-form is under the normal prior, \(\beta \sim N(0,1)\): \[ p(y|x,\mbox{normal prior}) = p_N(y|0,xx'+I_n) \]

#install.packages("mvtnorm")
library("mvtnorm")
XtX = x%*%t(x)+diag(1,n)
k.n.exact = dmvnorm(y,rep(0,n),XtX,log=FALSE)
c(k.n.exact,k.n)
## [1] 4.484789e-07 4.475916e-07

3.2 Computing posterior means

E.n = mean(b.draws*like*dnorm(b.draws)/(1/10))/k.n
E.t = mean(b.draws*like*dt(b.draws,df=1)/(1/10))/k.t
E.l = mean(b.draws*like*0.5*exp(-abs(b.draws))/(1/10))/k.l
c(E.n,E.t,E.l)
## [1] 1.429081 1.516261 1.499867

The only one we can obtain in closed-form is under the normal prior, i.e. \[ E(\beta|y,x,\mbox{normal prior}) = \frac{\sum_{i=1}^n y_ix_i}{\sum_{i=1}^n x_i^2}. \]

E.n.exact = sum(y*x)/(sum(x^2)+1)
c(E.n.exact,E.n)
## [1] 1.431680 1.429081

3.3 Computing posterior tails

P.n = mean((b.draws<0.75)*like*dnorm(b.draws)/(1/10))/k.n
P.t = mean((b.draws<0.75)*like*dt(b.draws,df=1)/(1/10))/k.t
P.l = mean((b.draws<0.75)*like*0.5*exp(-abs(b.draws))/(1/10))/k.l
c(P.n,P.t,P.l)
## [1] 0.03483404 0.03008621 0.03181092

The only one we can obtain in closed-form is under the normal prior

P.n.exact = pnorm(0.75,E.n.exact,sqrt(1/(sum(x^2)+1)))
c(P.n.exact,P.n)
## [1] 0.03431329 0.03483404

3.4 Priors, likelihood and posteriors

likelihood = rep(0,1000)
for (i in 1:1000)
  likelihood[i] = prod(dnorm(y,x*betas[i],1))
post.n = dnorm(betas)*likelihood/k.n
post.t = dt(betas,df=1)*likelihood/k.t
post.l = 0.5*exp(-abs(betas))*likelihood/k.l

plot(betas,post.n,type="l",col=2,lwd=2,xlab=expression(beta),ylab="Density")
lines(betas,post.t,col=3,lwd=2)
lines(betas,post.l,col=4,lwd=2)
lines(betas,dnorm(betas),lty=2,col=2,lwd=2)
lines(betas,dt(betas,1),col=3,lty=2,lwd=2)
lines(betas,0.5*exp(-abs(betas)),col=4,lty=2,lwd=2)
lines(betas,dnorm(betas,beta.mle,se.beta),lwd=2)
legend("topleft",legend=c("N(0,1) prior","t(1) prior","DE(1) prior","Likelihood"),
       col=c(2:4,1),lwd=2,lty=c(2,2,2,1),bty="n")
abline(v=0.75,lty=2)       

3.5 Quality of MC approximation

M       = 100000
b.draws = runif(M,-5,5)
like = rep(0,M)
for (i in 1:M)
  like[i] = prod(dnorm(y,x*b.draws[i],1))
M1 = c(seq(100,1000,by=100),seq(2000,10000,by=1000),seq(20000,M,by=10000))
P.n = NULL
for (m in M1){
  k.n = mean(like[1:m]*dnorm(b.draws[1:m])/(1/10))
  P.n = c(P.n,mean((b.draws[1:m]<0.75)*like[1:m]*dnorm(b.draws[1:m])/(1/10))/k.n)
}
plot(M1/100,P.n,xlab="Monte Carlo size (x100)",ylab="Integral",type="b")
abline(h=P.n.exact,col=2)

4 Monte Carlo simulation via SIR

Draws from a candidate distribution \(q(\beta)\) can be reweighted and resampled in order to approximate draws from a target distribution \(p(\beta)\). This is the SIR scheme, one of the most popular MC sampling method for situations where dim(\(\beta\)) is small, say less than 10. SIR comprises three simple steps:

  • Step 1: Draw \(\{{\tilde \beta}^{(i)}\}_{i=1}^M\) from the proposal/candidate/importance distribution \(q(\beta)\).
  • Step 2: For \(i=1,\ldots,M\), compute (unnormalized) weights \[ \omega^{(i)} = \frac{p({\tilde \beta}^{(i)})}{q({\tilde \beta}^{(i)})}. \]
  • Step 3: \(\{\beta^{(i)}\}_{i=1}^M\) from \(\{{\tilde \beta}^{(i)}\}_{i=1}^M\) with weights \(\{\omega^{(i)}\}_{i=1}^M\).

Notice that, one only need to be able to evaluate both \(p(\cdot)\) and \(q(\cdot)\) up to normalizing constants since when the weights are normalized these constants cancel out. Additionally, one needs to easily sample from \(q(\cdot)\).

4.1 SIR for linear regression

Usually, \(p(\beta)\) is proportional to the product of the prior \(\pi(\beta)\) and the likelihood \(L(\beta;\mbox{data})\), i.e. \[ p(\beta) = \kappa \pi(\beta)L(\beta;y,x), \] where \(k\) is the normalizing constant. If, in addition, one decides to use the prior as proposal (not a smart idea in most cases!), i.e. \(q(\beta) = \pi(\beta)\), it is easy to see that the SIR weights are \[ \omega^{(i)} = L({\tilde \beta}^{(i)};y,x). \] Let us now use SIR to sample from the posterior of \(\beta\) in our regression example when using the double exponential prior

4.1.1 Step 1 - Drawing from proposal

Here we will use the \(U(-5,5)\) as \(q(\beta)\).

M       = 20000
b.draws = runif(M,-5,5)

4.1.2 Step 2 - Computing weights

w = rep(0,M)
for (i in 1:M)
  w[i] = prod(dnorm(y,x*b.draws[i],1))*0.5*exp(-abs(b.draws[i]))/(1/10)

4.1.3 Step 3 - Resampling

beta.post = sample(b.draws,size=M,replace=TRUE,prob=w)
hist(beta.post,prob=TRUE,xlab=expression(beta),ylab="Density",main="")
lines(betas,post.l,col=2,lwd=2)

Now we can compare the MC integration with the MC simulation approximations to the three quantities of interest from the posterior \(p(\beta|y,x)\)

c(E.l,mean(beta.post))
## [1] 1.499867 1.501845
c(k.l,mean(w))
## [1] 4.087623e-07 4.133555e-07
c(P.l,mean(beta.post<0.75))
## [1] 0.03181092 0.03260000
LS0tCnRpdGxlOiAiTW9udGUgQ2FybG8gaW50ZWdyYXRpb24iCnN1YnRpdGxlOiAiU2ltcGxlIGxpbmVhciByZWdyZXNzaW9uIgphdXRob3I6ICJIZWRpYmVydCBGcmVpdGFzIExvcGVzIgpkYXRlOiAiNS8xMS8yMDIyIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICB0b2NfZGVwdGg6IDIKICAgIHRvY19mbG9hdDogCiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICAgIGNvZGVfZG93bmxvYWQ6IHllcwotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKCgojIE5vcm1hbCwgQ2F1Y2h5IGFuZCBMYXBsYWNlIHByaW9ycwoKQSBwYXJhbWV0ZXIgJFxiZXRhJCBpcyBzdGFuZGFyZCBub3JtYWwsIENhdWNoeSAoc3RhbmRhcmQgU3R1ZGVudCdzICR0JCB3aXRoIG9uZSBkZWdyZWUgb2YgZnJlZWRvbSkgb3Igc3RhbmRhcmQgZG91YmxlLWV4cG9uZW50aWFsIChha2EgTGFwbGFjZSkgaWYKXGJlZ2lue2VxbmFycmF5Kn0KcChcYmV0YSkgJj0mIFxmcmFjezF9e1xzcXJ0ezJccGl9fVxleHBcey0wLjVcYmV0YV4yXH0sIFwgXCBcbWJveHtvcn0gXFwKcChcYmV0YSkgJj0mIFxmcmFjezF9e1xwaSgxK1xiZXRhXjIpfSwgXCBcIFxtYm94e29yfSBcXApwKFxiZXRhKSAmPSYgXGZyYWMxMiBcZXhwXHstfFxiZXRhfFx9LApcZW5ke2VxbmFycmF5Kn0KcmVzcGVjdGl2ZWx5LCBmb3IgJFxiZXRhIFxpbiBcUmUkLgoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KYmV0YXMgPSBzZXEoLTUsNSxsZW5ndGg9MTAwMCkKcGxvdChiZXRhcyxkbm9ybShiZXRhcyksdHlwZT0ibCIseWxpbT1jKDAsMC41KSx4bGFiPWV4cHJlc3Npb24oYmV0YSkseWxhYj0iRGVuc2l0eSIsbHdkPTIpCmxpbmVzKGJldGFzLGR0KGJldGFzLDEpLGNvbD0yLGx3ZD0yKQpsaW5lcyhiZXRhcywwLjUqZXhwKC1hYnMoYmV0YXMpKSxjb2w9Myxsd2Q9MikKbGVnZW5kKCJ0b3BsZWZ0IixsZWdlbmQ9YygiTigwLDEpIiwidCgxKSIsIkRFKDEpIiksY29sPTE6Myxsd2Q9MixsdHk9MSxidHk9Im4iKQpgYGAKCiMgQSBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24gZXhhbXBsZQoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0Kc2V0LnNlZWQoMTIzNDUpCm4gICAgPSAxMApiZXRhID0gMgp4ICAgID0gcm5vcm0obikKeSAgICA9IGJldGEqeCArIHJub3JtKG4pCgpwbG90KHgseSkKYWJsaW5lKGxtKHl+eC0xKSxjb2w9MikKYWJsaW5lKGg9MCxsdHk9MikKYWJsaW5lKHY9MCxsdHk9MikKYGBgCgojIyBNYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGUKVGhlIG1heGltdW0gbGlrZWxpaG9vZCBlc3RpbWF0aW9uIG9mIHRoZSBzaW1wbGUgR2F1c3NpYW4gbGluZWFyIHJlZ3Jlc3Npb24gdGhyb3VnaCB0aGUgb3JpZ2luCiQkCnlfaXx4X2ksXGJldGEgXHNpbSBOKFxiZXRhIHhfaSwxKSwKJCQKZm9yICRpPTEsXGxkb3RzLG4kLCBpcyBzdHJhaWdodGZvcndhcmQKJCQKe1x3aWRlaGF0IFxiZXRhfV97bWxlfSA9IFxmcmFje1xzdW1fe2k9MX1ebiB5X2l4X2l9e1xzdW1fe2k9MX1ebiB4X2leMn0sCiQkCnN1Y2ggdGhhdCAke1x3aWRlaGF0IFxiZXRhfV97bWxlfXxcYmV0YSBcc2ltIE4oXGJldGEsdl4yKSQsIHdoZXJlICR2XjI9XGZyYWN7MX17XHN1bV97aT0xfV5uIHhfaV4yfSQuCgoKCmBgYHtyfQpiZXRhLm1sZSA9IHN1bSh4KnkpL3N1bSh4XjIpCnNlLmJldGEgID0gMS9zcXJ0KHN1bSh4XjIpKQpjKGJldGEubWxlLHNlLmJldGEpCmBgYAoKIyBCYXllc2lhbiBpbmZlcmVuY2UgdmlhIE1DSQpPbmUgb2YgdGhlIG1haW4gKGNvbXB1dGF0aW9uKSBwcm9ibGVtcyBmYWNlZCBieSBhcHBsaWVkIEJheWVzaWFuIG1vZGVsZXJzL3NjaWVudGlzdHMgaXMgdGhlIGNvbXB1dGF0aW9uIG9mIGludGVncmFscywgc3VjaCBhcyB0aGUgbm9ybWFsaXppbmcgY29uc3RhbnQKJCQKcCh5fHgpID0gXGludF97LVxpbmZ0eX1eXGluZnR5IFxsZWZ0W1xwcm9kX3tpPTF9Xm4gcF9OKHlfaXx4X2lcYmV0YSwxKVxyaWdodF1wKFxiZXRhKWRcYmV0YSwKJCQKb3IgdGhlIHBvc3RlcmlvciBtZWFuLAokJApFKFxiZXRhfHkseCkgPSBcZnJhY3tcaW50X3stXGluZnR5fV5caW5mdHkgXGJldGEgXGxlZnRbXHByb2Rfe2k9MX1ebiBwX04oeV9pfHhfaVxiZXRhLDEpXHJpZ2h0XXAoXGJldGEpZFxiZXRhfXtwKHl8eCl9LAokJApvciBldmVuICRQcihcYmV0YTwwLjc1fHkseCkkLAokJApQcihcYmV0YTwwLjc1fHkseCkgPSBcZnJhY3tcaW50X3stXGluZnR5fV5caW5mdHkgMShcYmV0YTwwLjc1KSBcbGVmdFtccHJvZF97aT0xfV5uIHBfTih5X2l8eF9pXGJldGEsMSlccmlnaHRdcChcYmV0YSlkXGJldGF9e3AoeXx4KX0uCiQkCkJhc2ljYWxseSwgTW9udGUgQ2FybG8gaW50ZWdyYXRpb24gYXBwcm94aW1hdGVzIHRoZSBpbnRlZ3JhbAokJApJID0gXGludCBoKFxiZXRhKWcoXGJldGEpZFxiZXRhID0gXGludCBcbGVmdFtcZnJhY3toKFxiZXRhKWcoXGJldGEpfXtxKFxiZXRhKX1ccmlnaHRdcShcYmV0YSlkXGJldGEsCiQkCmJhc2VkIG9uIGRyYXdzICRce1xiZXRhXnsoaSl9XH1fe2k9MX1eTSQgZnJvbSAkZyhcYmV0YSkkIG9yIGJhc2VkIG9uIGRyYXdzICRce3tcdGlsZGUgXGJldGF9XnsoaSl9XH1fe2k9MX1eTSQgZnJvbSAkcShcYmV0YSkkIChwcm9wb3NhbC9jYW5kaWRhdGUvaW1wb3J0YW5jZSBkaXN0cmlidXRpb24pLCBhcwpcYmVnaW57ZXFuYXJyYXkqfQp7XGhhdCBJfV8xICY9JiBcZnJhY3sxfXtNfSBcc3VtX3tpPTF9Xk0gaChcYmV0YV57KGkpfSlcXAp7XGhhdCBJfV8yICY9JiBcZnJhY3sxfXtNfSBcc3VtX3tpPTF9Xk0gXGZyYWN7aCh7XHRpbGRlIFxiZXRhfV57KGkpfSlnKHtcdGlsZGUgXGJldGF9XnsoaSl9KX17cSh7XHRpbGRlIFxiZXRhfV57KGkpfSl9LgpcZW5ke2VxbmFycmF5Kn0KQXMgJE0gXGxvbmdyaWdodGFycm93IFxpbmZ0eSQsIGJvdGggJHtcaGF0IEl9XzEkIGFuZCAke1xoYXQgSX1fMiQgY29udmVyZ2UgdG8gJEkkLgoKQmVsb3cgd2UgdXNlIGEgdW5pZm9ybSBkaXN0cmlidXRpb24gaW4gdGhlIGludGVydmFsICQoLTUsNSkgYXMgb3VyIHByb3Bvc2FsICRxKFxiZXRhKSQuCgoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KTSAgICAgICA9IDEwMDAwCmIuZHJhd3MgPSBydW5pZihNLC01LDUpCmhpc3QoYi5kcmF3cyxwcm9iPVRSVUUsbWFpbj0iRHJhd3MgZnJvbSB0aGUgcHJvcG9zYWwgVSgtNSw1KSIseGxhYj1leHByZXNzaW9uKGJldGEpKQpgYGAKCiMjIENvbXB1dGluZyBwcmlvciBwcmVkaWN0aXZlcwoKSGVyZSB3ZSBjb21wdXRlICRwKHl8eCkkLCB0aGUgcHJpb3IgcHJlZGljdGl2ZSBkZW5zaXR5LCBiYXNlZCBvbiBlYWNoIG9uZSBvZiB0aGUgdGhyZWUgcHJpb3Igc3BlY2lmaWNhdGlvbnMgb2YgJFxiZXRhJCAoR2F1c3NpYW4sIFN0dWRlbnQncyAkdCQgYW5kIGRvdWJsZS1leHBvbmVudGlhbCkuCgpgYGB7cn0KbGlrZSA9IHJlcCgwLE0pCmZvciAoaSBpbiAxOk0pCiAgbGlrZVtpXSA9IHByb2QoZG5vcm0oeSx4KmIuZHJhd3NbaV0sMSkpCmsubiA9IG1lYW4obGlrZSpkbm9ybShiLmRyYXdzKS8oMS8xMCkpCmsudCA9IG1lYW4obGlrZSpkdChiLmRyYXdzLGRmPTEpLygxLzEwKSkKay5sID0gbWVhbihsaWtlKjAuNSpleHAoLWFicyhiLmRyYXdzKSkvKDEvMTApKQpjKGsubixrLnQsay5sKQpgYGAKClRoZSBvbmx5IG9uZSB3ZSBjYW4gb2J0YWluIGluIGNsb3NlZC1mb3JtIGlzIHVuZGVyIHRoZSBub3JtYWwgcHJpb3IsICRcYmV0YSBcc2ltIE4oMCwxKSQ6CiQkCnAoeXx4LFxtYm94e25vcm1hbCBwcmlvcn0pID0gcF9OKHl8MCx4eCcrSV9uKQokJAoKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJtdnRub3JtIikKbGlicmFyeSgibXZ0bm9ybSIpClh0WCA9IHglKiV0KHgpK2RpYWcoMSxuKQprLm4uZXhhY3QgPSBkbXZub3JtKHkscmVwKDAsbiksWHRYLGxvZz1GQUxTRSkKYyhrLm4uZXhhY3Qsay5uKQpgYGAKCiMjIENvbXB1dGluZyBwb3N0ZXJpb3IgbWVhbnMKCmBgYHtyfQpFLm4gPSBtZWFuKGIuZHJhd3MqbGlrZSpkbm9ybShiLmRyYXdzKS8oMS8xMCkpL2subgpFLnQgPSBtZWFuKGIuZHJhd3MqbGlrZSpkdChiLmRyYXdzLGRmPTEpLygxLzEwKSkvay50CkUubCA9IG1lYW4oYi5kcmF3cypsaWtlKjAuNSpleHAoLWFicyhiLmRyYXdzKSkvKDEvMTApKS9rLmwKYyhFLm4sRS50LEUubCkKYGBgCgpUaGUgb25seSBvbmUgd2UgY2FuIG9idGFpbiBpbiBjbG9zZWQtZm9ybSBpcyB1bmRlciB0aGUgbm9ybWFsIHByaW9yLCBpLmUuCiQkCkUoXGJldGF8eSx4LFxtYm94e25vcm1hbCBwcmlvcn0pID0gXGZyYWN7XHN1bV97aT0xfV5uIHlfaXhfaX17XHN1bV97aT0xfV5uIHhfaV4yfS4KJCQKYGBge3J9CkUubi5leGFjdCA9IHN1bSh5KngpLyhzdW0oeF4yKSsxKQpjKEUubi5leGFjdCxFLm4pCmBgYAoKIyMgQ29tcHV0aW5nIHBvc3RlcmlvciB0YWlscwoKYGBge3J9ClAubiA9IG1lYW4oKGIuZHJhd3M8MC43NSkqbGlrZSpkbm9ybShiLmRyYXdzKS8oMS8xMCkpL2subgpQLnQgPSBtZWFuKChiLmRyYXdzPDAuNzUpKmxpa2UqZHQoYi5kcmF3cyxkZj0xKS8oMS8xMCkpL2sudApQLmwgPSBtZWFuKChiLmRyYXdzPDAuNzUpKmxpa2UqMC41KmV4cCgtYWJzKGIuZHJhd3MpKS8oMS8xMCkpL2subApjKFAubixQLnQsUC5sKQpgYGAKClRoZSBvbmx5IG9uZSB3ZSBjYW4gb2J0YWluIGluIGNsb3NlZC1mb3JtIGlzIHVuZGVyIHRoZSBub3JtYWwgcHJpb3IKCmBgYHtyfQpQLm4uZXhhY3QgPSBwbm9ybSgwLjc1LEUubi5leGFjdCxzcXJ0KDEvKHN1bSh4XjIpKzEpKSkKYyhQLm4uZXhhY3QsUC5uKQpgYGAKCiMjIFByaW9ycywgbGlrZWxpaG9vZCBhbmQgcG9zdGVyaW9ycwoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KbGlrZWxpaG9vZCA9IHJlcCgwLDEwMDApCmZvciAoaSBpbiAxOjEwMDApCiAgbGlrZWxpaG9vZFtpXSA9IHByb2QoZG5vcm0oeSx4KmJldGFzW2ldLDEpKQpwb3N0Lm4gPSBkbm9ybShiZXRhcykqbGlrZWxpaG9vZC9rLm4KcG9zdC50ID0gZHQoYmV0YXMsZGY9MSkqbGlrZWxpaG9vZC9rLnQKcG9zdC5sID0gMC41KmV4cCgtYWJzKGJldGFzKSkqbGlrZWxpaG9vZC9rLmwKCnBsb3QoYmV0YXMscG9zdC5uLHR5cGU9ImwiLGNvbD0yLGx3ZD0yLHhsYWI9ZXhwcmVzc2lvbihiZXRhKSx5bGFiPSJEZW5zaXR5IikKbGluZXMoYmV0YXMscG9zdC50LGNvbD0zLGx3ZD0yKQpsaW5lcyhiZXRhcyxwb3N0LmwsY29sPTQsbHdkPTIpCmxpbmVzKGJldGFzLGRub3JtKGJldGFzKSxsdHk9Mixjb2w9Mixsd2Q9MikKbGluZXMoYmV0YXMsZHQoYmV0YXMsMSksY29sPTMsbHR5PTIsbHdkPTIpCmxpbmVzKGJldGFzLDAuNSpleHAoLWFicyhiZXRhcykpLGNvbD00LGx0eT0yLGx3ZD0yKQpsaW5lcyhiZXRhcyxkbm9ybShiZXRhcyxiZXRhLm1sZSxzZS5iZXRhKSxsd2Q9MikKbGVnZW5kKCJ0b3BsZWZ0IixsZWdlbmQ9YygiTigwLDEpIHByaW9yIiwidCgxKSBwcmlvciIsIkRFKDEpIHByaW9yIiwiTGlrZWxpaG9vZCIpLAogICAgICAgY29sPWMoMjo0LDEpLGx3ZD0yLGx0eT1jKDIsMiwyLDEpLGJ0eT0ibiIpCmFibGluZSh2PTAuNzUsbHR5PTIpICAgICAgIApgYGAgICAgICAgCgoKIyMgUXVhbGl0eSBvZiBNQyBhcHByb3hpbWF0aW9uCgpgYGB7ciBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQpNICAgICAgID0gMTAwMDAwCmIuZHJhd3MgPSBydW5pZihNLC01LDUpCmxpa2UgPSByZXAoMCxNKQpmb3IgKGkgaW4gMTpNKQogIGxpa2VbaV0gPSBwcm9kKGRub3JtKHkseCpiLmRyYXdzW2ldLDEpKQpNMSA9IGMoc2VxKDEwMCwxMDAwLGJ5PTEwMCksc2VxKDIwMDAsMTAwMDAsYnk9MTAwMCksc2VxKDIwMDAwLE0sYnk9MTAwMDApKQpQLm4gPSBOVUxMCmZvciAobSBpbiBNMSl7CiAgay5uID0gbWVhbihsaWtlWzE6bV0qZG5vcm0oYi5kcmF3c1sxOm1dKS8oMS8xMCkpCiAgUC5uID0gYyhQLm4sbWVhbigoYi5kcmF3c1sxOm1dPDAuNzUpKmxpa2VbMTptXSpkbm9ybShiLmRyYXdzWzE6bV0pLygxLzEwKSkvay5uKQp9CnBsb3QoTTEvMTAwLFAubix4bGFiPSJNb250ZSBDYXJsbyBzaXplICh4MTAwKSIseWxhYj0iSW50ZWdyYWwiLHR5cGU9ImIiKQphYmxpbmUoaD1QLm4uZXhhY3QsY29sPTIpCmBgYAoKCiMgTW9udGUgQ2FybG8gc2ltdWxhdGlvbiB2aWEgU0lSCkRyYXdzIGZyb20gYSBjYW5kaWRhdGUgZGlzdHJpYnV0aW9uICRxKFxiZXRhKSQgY2FuIGJlIHJld2VpZ2h0ZWQgYW5kIHJlc2FtcGxlZCBpbiBvcmRlciB0byBhcHByb3hpbWF0ZSBkcmF3cyBmcm9tIGEgdGFyZ2V0IGRpc3RyaWJ1dGlvbiAkcChcYmV0YSkkLiAgVGhpcyBpcyB0aGUgU0lSIHNjaGVtZSwgb25lIG9mIHRoZSBtb3N0IHBvcHVsYXIgTUMgc2FtcGxpbmcgbWV0aG9kIGZvciBzaXR1YXRpb25zIHdoZXJlIGRpbSgkXGJldGEkKSBpcyBzbWFsbCwgc2F5IGxlc3MgdGhhbiAxMC4gIFNJUiBjb21wcmlzZXMgdGhyZWUgc2ltcGxlIHN0ZXBzOgoKKiBTdGVwIDE6IERyYXcgJFx7e1x0aWxkZSBcYmV0YX1eeyhpKX1cfV97aT0xfV5NJCBmcm9tIHRoZSBwcm9wb3NhbC9jYW5kaWRhdGUvaW1wb3J0YW5jZSBkaXN0cmlidXRpb24gJHEoXGJldGEpJC4KKiBTdGVwIDI6IEZvciAkaT0xLFxsZG90cyxNJCwgY29tcHV0ZSAodW5ub3JtYWxpemVkKSB3ZWlnaHRzIAokJApcb21lZ2FeeyhpKX0gPSBcZnJhY3twKHtcdGlsZGUgXGJldGF9XnsoaSl9KX17cSh7XHRpbGRlIFxiZXRhfV57KGkpfSl9LgokJAoqIFN0ZXAgMzogJFx7XGJldGFeeyhpKX1cfV97aT0xfV5NJCBmcm9tICRce3tcdGlsZGUgXGJldGF9XnsoaSl9XH1fe2k9MX1eTSQgd2l0aCB3ZWlnaHRzCiRce1xvbWVnYV57KGkpfVx9X3tpPTF9Xk0kLgoKTm90aWNlIHRoYXQsIG9uZSBvbmx5IG5lZWQgdG8gYmUgYWJsZSB0byBldmFsdWF0ZSBib3RoICRwKFxjZG90KSQgYW5kICRxKFxjZG90KSQgdXAgdG8gbm9ybWFsaXppbmcgY29uc3RhbnRzIHNpbmNlIHdoZW4gdGhlIHdlaWdodHMgYXJlIG5vcm1hbGl6ZWQgdGhlc2UgY29uc3RhbnRzIGNhbmNlbCBvdXQuICBBZGRpdGlvbmFsbHksIG9uZSBuZWVkcyB0byBlYXNpbHkgc2FtcGxlIGZyb20gJHEoXGNkb3QpJC4KCgojIyBTSVIgZm9yIGxpbmVhciByZWdyZXNzaW9uClVzdWFsbHksICRwKFxiZXRhKSQgaXMgcHJvcG9ydGlvbmFsIHRvIHRoZSBwcm9kdWN0IG9mIHRoZSBwcmlvciAkXHBpKFxiZXRhKSQgYW5kIHRoZSBsaWtlbGlob29kICRMKFxiZXRhO1xtYm94e2RhdGF9KSQsIGkuZS4KJCQKcChcYmV0YSkgPSBca2FwcGEgXHBpKFxiZXRhKUwoXGJldGE7eSx4KSwKJCQKd2hlcmUgJGskIGlzIHRoZSBub3JtYWxpemluZyBjb25zdGFudC4gIElmLCBpbiBhZGRpdGlvbiwgb25lIGRlY2lkZXMgdG8gdXNlIHRoZSBwcmlvciBhcyBwcm9wb3NhbCAobm90IGEgc21hcnQgaWRlYSBpbiBtb3N0IGNhc2VzISksIGkuZS4gJHEoXGJldGEpID0gXHBpKFxiZXRhKSQsIGl0IGlzIGVhc3kgdG8gc2VlIHRoYXQgdGhlIFNJUiB3ZWlnaHRzIGFyZQokJApcb21lZ2FeeyhpKX0gPSBMKHtcdGlsZGUgXGJldGF9XnsoaSl9O3kseCkuCiQkCkxldCB1cyBub3cgdXNlIFNJUiB0byBzYW1wbGUgZnJvbSB0aGUgcG9zdGVyaW9yIG9mICRcYmV0YSQgaW4gb3VyIHJlZ3Jlc3Npb24gZXhhbXBsZSB3aGVuIHVzaW5nIHRoZSBkb3VibGUgZXhwb25lbnRpYWwgcHJpb3IKCiMjIyBTdGVwIDEgLSBEcmF3aW5nIGZyb20gcHJvcG9zYWwKSGVyZSB3ZSB3aWxsIHVzZSB0aGUgJFUoLTUsNSkkIGFzICRxKFxiZXRhKSQuCmBgYHtyfQpNICAgICAgID0gMjAwMDAKYi5kcmF3cyA9IHJ1bmlmKE0sLTUsNSkKYGBgCgojIyMgU3RlcCAyIC0gQ29tcHV0aW5nIHdlaWdodHMKYGBge3J9CncgPSByZXAoMCxNKQpmb3IgKGkgaW4gMTpNKQogIHdbaV0gPSBwcm9kKGRub3JtKHkseCpiLmRyYXdzW2ldLDEpKSowLjUqZXhwKC1hYnMoYi5kcmF3c1tpXSkpLygxLzEwKQpgYGAKCiMjIyBTdGVwIDMgLSBSZXNhbXBsaW5nCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9CmJldGEucG9zdCA9IHNhbXBsZShiLmRyYXdzLHNpemU9TSxyZXBsYWNlPVRSVUUscHJvYj13KQpoaXN0KGJldGEucG9zdCxwcm9iPVRSVUUseGxhYj1leHByZXNzaW9uKGJldGEpLHlsYWI9IkRlbnNpdHkiLG1haW49IiIpCmxpbmVzKGJldGFzLHBvc3QubCxjb2w9Mixsd2Q9MikKYGBgCgpOb3cgd2UgY2FuIGNvbXBhcmUgdGhlIE1DIGludGVncmF0aW9uIHdpdGggdGhlIE1DIHNpbXVsYXRpb24gYXBwcm94aW1hdGlvbnMgdG8gdGhlIHRocmVlIHF1YW50aXRpZXMgb2YgaW50ZXJlc3QgZnJvbSB0aGUgcG9zdGVyaW9yICRwKFxiZXRhfHkseCkkCmBgYHtyfQpjKEUubCxtZWFuKGJldGEucG9zdCkpCmMoay5sLG1lYW4odykpCmMoUC5sLG1lYW4oYmV0YS5wb3N0PDAuNzUpKQoKYGBgCgo=