Convergence Diagnostics



# install.packages("geoR")
library(coda)  # Our main convergence diagnostic package
library(geoR)
'RandomFieldsUtils' will use OMP
'RandomFields' will use OMP
--------------------------------------------------------------
 Analysis of Geostatistical Data
 For an Introduction to geoR go to http://www.leg.ufpr.br/geoR
 geoR version 1.8-1 (built on 2020-02-08) is now loaded
--------------------------------------------------------------
library(MCMCpack)


Running Metropolis algorithm

library(mvtnorm)

N=10000
burn.in=N/2

# data
y=c(0,0)

# correlation
rho=0.8

# initial value
cov.var=matrix(c(1,rho,rho,1),2,2)        # cov for posterior density
cov.var.prop=matrix(c(1,rho,rho,1),2,2)   # cov for proposal density
theta=matrix(0,nrow=N,ncol=2)

# iterations
for (i in 1:(N-1)){
  theta.star=rmvnorm(1,mean=theta[i,],sigma=cov.var.prop)  # Candidate
  U=runif(1,0,1)  # Auxiliary variable
  
  # The ratio r
  ratio=dmvnorm(theta.star,mean=y,sigma=cov.var)/dmvnorm(theta[i,],mean=y,sigma=cov.var)
  
  # The probability of move
  alpha=min(ratio,1)
  
  if (U<=alpha){theta[i+1,]=theta.star}  # Accepting the candidate
  else theta[i+1,]=theta[i,]
}


Visual inspection: Traceplot

dev.new()
par(mfrow=c(2,1))
plot(1:N,theta[,1],type="l")
plot(1:N,theta[,2],type="l")

We can see that the chains don’t get stuck in certain areas. So these are kind of good I guess.


Visual inspection: Running mean plot

mean.th1=rep(0,N)  # To store the mean values
mean.th2=rep(0,N)  # To store the mean values

# Get the mean of the draws UP TO EACH ITERATION
for (i in 1:N){
  mean.th1[i]=mean(theta[1:i,1])
  mean.th2[i]=mean(theta[1:i,2])
}

dev.new()
par(mfrow=c(2,1))
plot(1:N,mean.th1,type="l")
plot(1:N,mean.th2,type="l")

Both thetas’ means seem to converge.



Convergence diagnostic using ‘coda’ package


Before we use the diagnostics, we must TURN OUR CHAINS INTO MCMC objects.

# mcmc() is from 'coda' package
theta=mcmc(theta)  # We must turn our chains into MCMC objects

summary(theta)  # Summary statistics for the distribution

Iterations = 1:10000
Thinning interval = 1 
Number of chains = 1 
Sample size per chain = 10000 

1. Empirical mean and standard deviation for each variable,
   plus standard error of the mean:

           Mean     SD Naive SE Time-series SE
[1,] -0.0002463 0.9831 0.009831        0.02998
[2,]  0.0052000 0.9770 0.009770        0.02962

2. Quantiles for each variable:

       2.5%     25%      50%    75% 97.5%
var1 -1.866 -0.6817 -0.02747 0.6463 1.987
var2 -1.944 -0.6377  0.01751 0.6711 1.907

Thinning interval here means the ‘keeping every kth samples only’ in the traceplot.


Visual inspection using ‘coda’ package

plot(theta)  # This gives us both dense plot and traceplot


# densplot(theta)
# traceplot(theta)

Note that these plots are plotted against the variance of theta instead of the values of theta directly.








Gelman and Rubin Diagnostic









Adaptive Simulation algorithm



Let’s monitor the acceptance rate of the Metropolis algo. using adaptive simulation algo.


library(mvtnorm)  # for mvnorm

N=10000  # Increase iterations for better performance
burn.in=N/2

## data
y=c(0,0)

## correlation
rho=0.8
c=2.4/sqrt(2)  # d=2 since it's a bivariate model

## initial value
cov.var=matrix(c(1,rho,rho,1),2,2)        #cov for posterior density
cov.var.prop=matrix(c(1,rho,rho,1),2,2)   #cov for proposal density
theta=matrix(0,nrow=N,ncol=2)

theta.1_out=rep(1,N)
c_out=NULL

## iterations
for (i in 1:(N-1)){
  
  # The adaptive simulation algo. part
  if (i>1 & ((i-1)%%100==0)){  # %% gets the remainder
                               # so this is saying every 100 iterations
    ar=sum(diff(theta.1_out[(i-100):(i-1)])!=0)/99
    # ar is the sum of the nonzeros of the sequence's differences?
    
    if (ar<0.44){c=c/sqrt(2)}  # we need smaller variance
    else if (ar>0.44){c=c*sqrt(2)}  # we need larger variance
  }
  
  
  # The Metropolis algo. part
  theta.star=rmvnorm(1,mean=theta[i,],sigma=c^2*cov.var.prop)
  # taking the candidate from the proposal dstn
  # c: scaling factor
  
  U=runif(1,0,1)  
  
  ratio=dmvnorm(theta.star,mean=y,sigma=cov.var)/dmvnorm(theta[i,],mean=y,sigma=cov.var)
  alpha=min(ratio,1)
  
  if (U<=alpha){theta[i+1,]=theta.star}
  else theta[i+1,]=theta[i,]
  
  theta.1_out[i]=theta[i,1]
  c_out[i]=c
}


Visualization


dev.new()
par(mfrow=c(2,1))
plot(1:N,theta[,1],type="l")
plot(1:N,theta[,2],type="l")


dev.new()
par(mfrow=c(1,3))
plot(theta[,1],theta[,2])
hist(theta[,1])
hist(theta[,2])


Estimated means of theta1 and theta2

mean(theta[(burn.in+1):N,1])
[1] 0.06777173
mean(theta[(burn.in+1):N,2])
[1] 0.06194615

Both are pretty close to 0.


The acceptance rates after iterations

library(coda)
library(MCMCpack)

theta=mcmc(theta)  # we need to turn it into an mcmc object first
1-rejectionRate(theta) # The acceptance rate
     var1      var2 
0.4463446 0.4463446 

Both are pretty close to 0.44 which is great I guess.








Adaptive Metropolis algorithm


Ignore the “Change the ~” from the image


Also, I guess you have to use conditional post. dstn in this case?


N=10000
burn.in=N/2

## data
y=c(0,0)

## correlation
rho=0.8

## scaling factor
c1=2.4/sqrt(1)
c2=2.4/sqrt(1)
eps=0.01  # This is to prevent the variance from shrinking to zero

## initial value
sig2=1-rho^2                   # variance for posterior density
var1.prop=1                    # variance for proposal density
var2.prop=1                    # variance for proposal density

theta.1=rep(10,N)
theta.2=rep(0,N)

c1_out=NULL
c2_out=NULL


#### iterations
for (i in 1:(N-1)){
  
  # Adaptive algorithm part
  
  ## update variance of proposal
  if (i>100){
    var1.prop=var(theta.1[1:(i-1)])  
    var2.prop=var(theta.2[1:(i-1)])  
  }
  
  ## control acceptance rate every 100 iterations
  if (i>1 & ((i-1)%%100==0)){  
    ar1=sum(diff(theta.1[(i-100):(i-1)])!=0)/99
    if (ar1<0.44){c1=c1/sqrt(2)}
    else if (ar1>0.44){c1=c1*sqrt(2)}
    
    ar2=sum(diff(theta.2[(i-100):(i-1)])!=0)/99
    if (ar2<0.44){c2=c2/sqrt(2)}
    else if (ar2>0.44){c2=c2*sqrt(2)}
  }
  
  
  # Metropolis part
  
  ## for theta.1
  theta.1.star=rnorm(1,theta.1[i],c1^2*var1.prop+c1^2*eps)
  U.1=runif(1,0,1)
  
  ratio.1=dnorm(theta.1.star,y[1]+rho*(theta.2[i]-y[2]),sqrt(sig2))/dnorm(theta.1[i],y[1]+rho*(theta.2[i]-y[2]),sqrt(sig2))
  alpha.1=min(ratio.1,1)
  
  if (U.1<=alpha.1){theta.1[i+1]=theta.1.star} else theta.1[i+1]=theta.1[i]
  
  ## for theta.2
  theta.2.star=rnorm(1,theta.2[i],c2^2*var2.prop+c2^2*eps)
  U.2=runif(1,0,1)
  
  ratio.2=dnorm(theta.2.star,y[2]+rho*(theta.1[i]-y[1]),sqrt(sig2))/dnorm(theta.2[i],y[2]+rho*(theta.1[i]-y[1]),sqrt(sig2))
  alpha.2=min(ratio.2,1)
  
  if (U.2<=alpha.2){theta.2[i+1]=theta.2.star} else theta.2[i+1]=theta.2[i]
  
  c1_out[i]=c1
  c2_out[i]=c2
}


Visualizations

dev.new()
par(mfrow=c(2,1))
plot(1:N,theta.1,type="l")
plot(1:N,theta.2,type="l")


par(mfrow=c(1,3))
plot(theta.1,theta.2)
hist(theta.1)
hist(theta.2)


Estimated means of theta1 and theta2

mean(theta.1[(burn.in+1):N])
[1] 0.05575984
mean(theta.2[(burn.in+1):N])
[1] 0.03889123

Both are pretty close to 0


Acceptance rate after iterations

library(coda)
library(MCMCpack)

theta.1=mcmc(theta.1)
theta.2=mcmc(theta.2)
1-rejectionRate(theta.1)
     var1 
0.4528453 
1-rejectionRate(theta.2)
     var1 
0.4461446 

Both have acceptance rates pretty close to 0.44








Slice Sampler



nsim=100000  # Increase iterations for better performance

u=rep(1,nsim)
x=rep(1,nsim)

for(i in 2:nsim){
  u[i]<-runif(1,0,0.5*exp(-sqrt(x[i-1])))
  x[i]<-runif(1,0,(log(2*u[i]))^2)
}


dev.new()
par(mfrow=c(1,1))

a=seq(0,50,0.01)
fa=0.5*exp(-sqrt(a))

hist(x,freq=F,xlim=c(0,50),breaks=200)
lines(a,fa,type="l",col="red")

The red line is the actual density, and the histogram is of samples from the slice sampler. It’s pretty close indeed.








Bayesian Linear Regression model


Example 1


Loading data

library(LearnBayes)  # for the 'birdextinct' data

Attaching package: ‘LearnBayes’

The following object is masked from ‘package:VGAM’:

    laplace

The following object is masked from ‘package:MCMCpack’:

    rdirichlet

The following object is masked from ‘package:TeachingDemos’:

    triplot
data("birdextinct")
attach(birdextinct)

birdextinct

time is the y variable, and nesting, size, and status are the x variables. Note that size and status are binary.


EDA

N <- dim(birdextinct)[1]  # Sample size

logtime=log(time)  # time is very skewed and log makes it less skewed

dev.new()
par(mfrow=c(1,2))
hist(time)
hist(logtime)

Since time is very skewed, we used log. We can see that it has lessened the skewness but not much to be honest.


Frequentist linear regression

lm.fit=lm(logtime~nesting+size+status,data=birdextinct,x=TRUE,y=TRUE)
summary(lm.fit)

Call:
lm(formula = logtime ~ nesting + size + status, data = birdextinct, 
    x = TRUE, y = TRUE)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.8410 -0.2932 -0.0709  0.2165  2.5167 

Coefficients:
            Estimate Std. Error t value      Pr(>|t|)    
(Intercept)  0.43087    0.20706   2.081      0.041870 *  
nesting      0.26501    0.03679   7.203 0.00000000133 ***
size        -0.65220    0.16667  -3.913      0.000242 ***
status       0.50417    0.18263   2.761      0.007712 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.6524 on 58 degrees of freedom
Multiple R-squared:  0.5982,    Adjusted R-squared:  0.5775 
F-statistic: 28.79 on 3 and 58 DF,  p-value: 0.00000000001577


Residual plot

dev.new()
par(mfrow=c(1,1))
plot(lm.fit$fitted.values,lm.fit$residuals,ylim=c(-1.5,1.5),xlab="Fitted Values",ylab="Residuals")
abline(h=0)
abline(h=2*summary(lm.fit)$sigma,lty=2)   
abline(h=-2*summary(lm.fit)$sigma,lty=2)

# sigma is the residual standard error (or residual standard deviation) which is a measure used to assess how well a linear regression model fits the data, smaller meaning the model fits the data better.

There are no violations of equal variance of error terms, or the linearity of the model. Also there seem to be no extreme outliers although there is one that is outside of the 2 times the residual standard error.




Bayesian linear regression


Let’s use blinreg() to sample from the joint post. dstn of beta and sigma_squared

theta.sample=blinreg(lm.fit$y,lm.fit$x,1000)

dev.new()
par(mfrow=c(2,2))
hist(theta.sample$beta[,2],main="Nesting",xlab=expression(beta[1]))
hist(theta.sample$beta[,3],main="Size",xlab=expression(beta[2]))
hist(theta.sample$beta[,4],main="Status",xlab=expression(beta[3]))
hist(theta.sample$sigma,main="Error SD",xlab=expression(sigma))

These are the samples from marginal posterior distribution of each variable. Error SD is the error terms calculated from the samples(?). They look like normal distribution so mean and median are pretty much the same, so we can choose either.


Comparison of coefficients

apply(theta.sample$beta,2,quantile,c(0.025,0.5,0.975))  # 95% credible intervals
      X(Intercept)  Xnesting      Xsize   Xstatus
2.5%   0.002096505 0.1935873 -0.9666888 0.1415132
50%    0.430099242 0.2665441 -0.6566102 0.4938495
97.5%  0.816603110 0.3423739 -0.3243618 0.8661174
# We can think the median(50%) as the bayes estimates of the coefficients since they seem like they follow normal distribution
lm.fit$coefficients  # freq's estimators of coefficients
(Intercept)     nesting        size      status 
  0.4308716   0.2650140  -0.6521982   0.5041655 

We can see that both freq’s and bayes’ results are similar. This is due to bayes linear model using a noninformative prior. Bayes provides more information because we can clearly see the distribution of each variables.


Sigma comparison

quantile(theta.sample$sigma,c(0.025,0.5,0.975))  # 50% is the bayes estimate
     2.5%       50%     97.5% 
0.5566649 0.6597165 0.8047768 
summary(lm.fit)$sigma
[1] 0.6524084

We can see that sigma in both cases are similar too.




Sampling using marginal post. dstn of sigma_squared


EDA

##Determine explanatory variables
X <- as.matrix(birdextinct[,3:5])
cov.names <- names(birdextinct[,c(-1,-2)])

##Pairs plot
pairs(cbind(logtime,X))


##Add a column of 1s for the intercepts
X.int <- cbind(rep(1,N),X)

##Determine the number of explanatory variables
k <- dim(X.int)[2]


Functions to use to sample from cond. post. dstn of beta and marginal post. dstn of sigma_squared

library(MASS)  # for mvrnorm

##Function for sampling from p(beta|sigma2,X,y) : cond. post. dstn of beta
sample.beta <- function(sigma2,X,y){
  V.beta <- solve(t(X)%*%X)             
  beta.hat <- V.beta%*%t(X)%*%y
  return(mvrnorm(1,beta.hat,sigma2*V.beta))
}

#Function for sampling from p(sigma2|X,y) : marginal post. dstn of sigma_squared
sample.sigma2 <- function(X,y,N,k){
  V.beta <- solve(t(X)%*%X)            
  beta.hat <- V.beta%*%t(X)%*%y
  s2 <- t(y-X%*%beta.hat)%*%(y-X%*%beta.hat)/(N-k)
  return(1/rgamma(1,shape=(N-k)/2,rate=((N-k)/2)*s2))
}


Sampling

# Initialize variables for the posterior samples
nsim=1000
beta.post.samples = matrix(0,nsim,k)
sigma2.post.samples = rep(0,nsim)

# Iterations
for(i in 1:nsim){
  sigma2.post.samples[i] <- sample.sigma2(X.int,logtime,N,k-1)
  beta.post.samples[i,] <- sample.beta(sigma2.post.samples[i],X.int,logtime)
}


Visualization

#Examine posterior samples
dev.new()
par(mfrow=c(3,2))
hist(sigma2.post.samples)
boxplot(as.data.frame(beta.post.samples[,-1]),names=cov.names)
abline(h=0)

plot(1:nsim,sigma2.post.samples,type="l")
plot(1:nsim,beta.post.samples[,2],type="l")
plot(1:nsim,beta.post.samples[,3],type="l")
plot(1:nsim,beta.post.samples[,4],type="l")

The histogram is of sigma_squared, and the boxplot is of the betas. The traceplot is to show the convergence of the samples of sigma_squared and each beta.


The bayes estimates of sigma_squared

mean(sigma2.post.samples)
[1] 0.4288413

The bayes estimates of betas

colMeans(beta.post.samples)
[1]  0.4445125  0.2648737 -0.6600526  0.4931243

Comparison to the freq’s estimates

lm.fit$coefficients  # The betas
(Intercept)     nesting        size      status 
  0.4308716   0.2650140  -0.6521982   0.5041655 
(summary(lm.fit)$sigma)^2  # Sigma_squared
[1] 0.4256367

We can see that both bayes and freq’s results are similar. We can say that out bayes model is doing well I guess.


Correlation map of the betas

#Look at the correlation between the betas
pairs(beta.post.samples,labels=c("Intercept",cov.names))




Sampling using the conditional dstn of simga_squared (Gibbs sampler I guess)


Functions to sample sigma_squared from the cond. post. dstn of sigma_squared and beta from the cond. post. dstn of beta (same one as above)

##Function for sampling from p(beta|sigma2,X,y) : cond. post. dstn of beta
sample.beta <- function(sigma2,X,y){
  V.beta <- solve(t(X)%*%X)             
  beta.hat <- V.beta%*%t(X)%*%y
  return(mvrnorm(1,beta.hat,sigma2*V.beta))
}

#Function for sampling from p(sigma2|beta,X,y) : marginal post. dstn of sigma_squared
sample.sigma2.cond <- function(X,y,N,beta){
  par1=N/2
  par2=0.5*t(y-X%*%beta)%*%(y-X%*%beta)
  return(1/rgamma(1,shape=par1,rate=par2))
}


Sampling

#Initialize variables for the posterior samples
nsim=1000
beta.post.samples = matrix(0,nsim,k)
sigma2.cond.post.samples = rep(0,nsim)

for(i in 1:nsim){
  beta.post.samples[i,]=sample.beta(sigma2.post.samples[i],X.int,logtime)
  sigma2.cond.post.samples[i]=sample.sigma2.cond(X.int,logtime,N,beta.post.samples[i,])
}


Visualization

dev.new()
par(mfrow=c(2,1))
hist(sigma2.cond.post.samples)

plot(1:nsim,sigma2.cond.post.samples,type="l")

These are the results of the samples from the cond. post. dstn of sigma squared


Bayes estimate of sigma_squared

mean(sigma2.post.samples)
[1] 0.4288413


Bayes estimate of betas

colMeans(beta.post.samples)
[1]  0.4240287  0.2646643 -0.6447407  0.5092205


Comparison to the freq’s estimates

lm.fit$coefficients  # The betas
(Intercept)     nesting        size      status 
  0.4308716   0.2650140  -0.6521982   0.5041655 
(summary(lm.fit)$sigma)^2  # Sigma_squared
[1] 0.4256367

Again, we can see that both bayes and freq’s results are similar. Again, we can say that out bayes model is doing well I guess.



Conclusion

Samples from the blinreg() are almost the same as samples using the marginal post. dstn or the samples using the cond. post. dstn, which are all in turn very similar to the freq’s result (due to using noninformative prior).





Example 2


Loading data

baby=read.table("http://www.stat.berkeley.edu/~statlabs/data/babies.data",head=TRUE)
attach(baby)


Performing bayesian linear regression using MCMCregress()

library(MCMCpack)  # for MCMCregress
library(coda)  # for mcmc

options(scipen = 1)  # to remove scientific notation

reg<-MCMCregress(bwt~age+weight,b0=0,B0=0,burnin=1000,mcmc=10000)
summary(reg)

Iterations = 1001:11000
Thinning interval = 1 
Number of chains = 1 
Sample size per chain = 10000 

1. Empirical mean and standard deviation for each variable,
   plus standard error of the mean:

                  Mean        SD   Naive SE Time-series SE
(Intercept) 116.683971  2.283267 0.02283267     0.02279083
age           0.074110  0.080186 0.00080186     0.00080328
weight        0.005596  0.003552 0.00003552     0.00003552
sigma2      332.647666 13.449063 0.13449063     0.13449063

2. Quantiles for each variable:

                  2.5%        25%        50%        75%     97.5%
(Intercept) 112.280607 115.129890 116.674374 118.241310 121.16086
age          -0.082259   0.019546   0.074589   0.128984   0.22803
weight       -0.001408   0.003216   0.005631   0.007999   0.01249
sigma2      307.227120 323.355276 332.277383 341.446596 360.23436

We can use either the median(50%) or the mean as the bayes estimate


Visualization

dev.new()
plot(reg)

We can see that the density of the variables look like normal dstn so we can use either mean or median.


Comparison to freq.

freq=lm(bwt~age+weight,data=baby)
summary(freq)

Call:
lm(formula = bwt ~ age + weight, data = baby)

Residuals:
   Min     1Q Median     3Q    Max 
-65.06 -11.11   0.44  11.25  56.90 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) 116.693894   2.294315  50.862   <2e-16 ***
age           0.074025   0.080475   0.920    0.358    
weight        0.005564   0.003514   1.584    0.114    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 18.23 on 1233 degrees of freedom
Multiple R-squared:  0.002871,  Adjusted R-squared:  0.001254 
F-statistic: 1.775 on 2 and 1233 DF,  p-value: 0.1699
(summary(freq)$sigma)^2
[1] 332.1512

We can see that the results are very similar








Logistic regression for binary response



Loading data

library(MASS)
data(birthwt)
attach(birthwt)
The following objects are masked from baby:

    age, bwt, smoke
head(birthwt)

‘low’ is the binary response for low birth weight


Post. dstn of beta (with prior dstn for beta as default improper uniform prior)

library(coda)  # for mcmc
library(MCMCpack)  # for MCMClogit

# default improper uniform prior
logit.1 <- MCMClogit(low~age+as.factor(race)+smoke, data=birthwt, beta.start=rep(0.7,5))
# I think you have to make categorical variables into a factor first
# However, smoke is a binary variable, and you don't have to factor a binary variable

# beta.start is the starting values for the beta vector. There are total 5 betas including the intercept: intercept, age, race2, race3, smoke

# Here, b0 and B0 values were not given => this is an improper uniform prior

summary(logit.1)

Iterations = 1001:11000
Thinning interval = 1 
Number of chains = 1 
Sample size per chain = 10000 

1. Empirical mean and standard deviation for each variable,
   plus standard error of the mean:

                    Mean      SD  Naive SE Time-series SE
(Intercept)      -0.9883 0.89476 0.0089476       0.036991
age              -0.0382 0.03425 0.0003425       0.001416
as.factor(race)2  1.0488 0.51366 0.0051366       0.021548
as.factor(race)3  1.0972 0.42240 0.0042240       0.019524
smoke             1.1453 0.38656 0.0038656       0.015945

2. Quantiles for each variable:

                     2.5%     25%      50%      75%   97.5%
(Intercept)      -2.66847 -1.6161 -1.00037 -0.35902 0.82157
age              -0.10923 -0.0607 -0.03668 -0.01464 0.02724
as.factor(race)2  0.02845  0.6990  1.04471  1.40430 2.04175
as.factor(race)3  0.26664  0.7974  1.10880  1.38758 1.91430
smoke             0.37771  0.8948  1.13697  1.41022 1.91549

Visualization

dev.new()
plot(logit.1)


Convergence Diagnostic

logit.1<-MCMClogit(low~age+as.factor(race)+smoke, data=birthwt,beta.start=rep(-0.7,5))
logit.2<-MCMClogit(low~age+as.factor(race)+smoke, data=birthwt,beta.start=rep(-0.3,5))
logit.3<-MCMClogit(low~age+as.factor(race)+smoke, data=birthwt,beta.start=rep(0,5))
logit.4<-MCMClogit(low~age+as.factor(race)+smoke, data=birthwt,beta.start=rep(0.3,5))
logit.5<-MCMClogit(low~age+as.factor(race)+smoke, data=birthwt,beta.start=rep(0.7,5))

logit.list<-mcmc.list(list(logit.1,logit.2,logit.3,logit.4,logit.5))
gelman.diag(logit.list)
Potential scale reduction factors:

                 Point est. Upper C.I.
(Intercept)               1          1
age                       1          1
as.factor(race)2          1          1
as.factor(race)3          1          1
smoke                     1          1

Multivariate psrf

1

Since the potential scale reduction factors for each variable are all below 1.1, we can say that the MCMC convergence is good for each variable.

gelman.plot(logit.list)

The plots indicate good convergence as well.


Post. dstn of beta (with prior dstn for beta as MVN(0,1000I))

(large variance => noninformative prior)

## multivariate normal prior
logit.2 <- MCMClogit(low~age+as.factor(race)+smoke, b0=0, B0=0.001,data=birthwt)
# b0 is the prior mean of the MVN
# B0 is the prior precision(= 1/prior variance) of the MVN
# This means that the prior variance we used here is 1000
# Since the prior variance is very large, this is a noninformative prior

summary(logit.2)

Iterations = 1001:11000
Thinning interval = 1 
Number of chains = 1 
Sample size per chain = 10000 

1. Empirical mean and standard deviation for each variable,
   plus standard error of the mean:

                     Mean      SD  Naive SE Time-series SE
(Intercept)      -1.04275 0.91241 0.0091241       0.038374
age              -0.03591 0.03414 0.0003414       0.001384
as.factor(race)2  1.03163 0.49963 0.0049963       0.020275
as.factor(race)3  1.08843 0.41973 0.0041973       0.017280
smoke             1.13528 0.38761 0.0038761       0.015654

2. Quantiles for each variable:

                    2.5%      25%      50%      75%   97.5%
(Intercept)      -2.7988 -1.69138 -1.06366 -0.40923 0.79022
age              -0.1074 -0.05856 -0.03523 -0.01299 0.03033
as.factor(race)2  0.0360  0.69870  1.02284  1.37216 2.01679
as.factor(race)3  0.2908  0.80183  1.08516  1.36941 1.92019
smoke             0.3795  0.87363  1.13227  1.40031 1.92418

Visualization

plot(logit.2)








Poisson regression for count data


Loading data

data(epil)
attach(epil)
The following object is masked _by_ .GlobalEnv:

    y

The following object is masked from birthwt:

    age

The following object is masked from baby:

    age
head(epil)


Post. dstn of beta

## MCMCpack
pois=MCMCpoisson(y~lbase*trt+lage+V4,data = epil)
summary(pois)

Iterations = 1001:11000
Thinning interval = 1 
Number of chains = 1 
Sample size per chain = 10000 

1. Empirical mean and standard deviation for each variable,
   plus standard error of the mean:

                      Mean      SD  Naive SE Time-series SE
(Intercept)         1.8952 0.04213 0.0004213       0.001910
lbase               0.9481 0.04234 0.0004234       0.001898
trtprogabide       -0.3494 0.06029 0.0006029       0.002746
lage                0.8948 0.11668 0.0011668       0.005371
V4                 -0.1578 0.05384 0.0005384       0.002402
lbase:trtprogabide  0.5657 0.06225 0.0006225       0.002771

2. Quantiles for each variable:

                      2.5%     25%     50%     75%    97.5%
(Intercept)         1.8130  1.8680  1.8966  1.9221  1.97764
lbase               0.8648  0.9192  0.9490  0.9756  1.03506
trtprogabide       -0.4742 -0.3864 -0.3465 -0.3100 -0.23288
lage                0.6695  0.8168  0.8912  0.9689  1.14595
V4                 -0.2682 -0.1920 -0.1567 -0.1221 -0.05663
lbase:trtprogabide  0.4407  0.5227  0.5664  0.6059  0.68952

Visualization

dev.new()
plot(pois)


Comparison to the Freq. result

summary(glm(y ~ lbase*trt + lage + V4, family = poisson, data = epil), cor = TRUE)

Call:
glm(formula = y ~ lbase * trt + lage + V4, family = poisson, 
    data = epil)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-5.0915  -1.4126  -0.2739   0.7580  10.7711  

Coefficients:
                   Estimate Std. Error z value Pr(>|z|)    
(Intercept)         1.89791    0.04260  44.552  < 2e-16 ***
lbase               0.94862    0.04360  21.759  < 2e-16 ***
trtprogabide       -0.34588    0.06100  -5.670 1.42e-08 ***
lage                0.88760    0.11650   7.619 2.56e-14 ***
V4                 -0.15977    0.05458  -2.927  0.00342 ** 
lbase:trtprogabide  0.56154    0.06352   8.841  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 2517.83  on 235  degrees of freedom
Residual deviance:  869.07  on 230  degrees of freedom
AIC: 1647

Number of Fisher Scoring iterations: 5

Correlation of Coefficients:
                   (Intercept) lbase trtprogabide lage  V4   
lbase              -0.56                                     
trtprogabide       -0.63        0.39                         
lage               -0.18       -0.01  0.06                   
V4                 -0.28        0.00  0.00         0.00      
lbase:trtprogabide  0.33       -0.69 -0.60         0.32  0.00

We can see that the results are very similar.




LS0tCnRpdGxlOiAiQmF5ZXNpYW4gU3RhdGlzdGljcyAtIHB0LjIiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKLS0tCgpcClwKXApcCgojIENvbnZlcmdlbmNlIERpYWdub3N0aWNzCgpcCgohW10oL1VzZXJzL2phZXlvbmdsZWUvRG9jdW1lbnRzL0NvbGxlZ2UvQmFjaGVsb3IvNHlfMnMvYmF5ZXMvUi9pbWFnZXMvc3MyLnBuZykKCiFbXSgvVXNlcnMvamFleW9uZ2xlZS9Eb2N1bWVudHMvQ29sbGVnZS9CYWNoZWxvci80eV8ycy9iYXllcy9SL2ltYWdlcy9JTUdfMDE5NS5qcGVnKQoKXAoKYGBge3J9CiMgaW5zdGFsbC5wYWNrYWdlcygiZ2VvUiIpCmxpYnJhcnkoY29kYSkgICMgT3VyIG1haW4gY29udmVyZ2VuY2UgZGlhZ25vc3RpYyBwYWNrYWdlCmxpYnJhcnkoZ2VvUikKbGlicmFyeShNQ01DcGFjaykKYGBgCgpcCgojIyMgUnVubmluZyBNZXRyb3BvbGlzIGFsZ29yaXRobQoKYGBge3J9CmxpYnJhcnkobXZ0bm9ybSkKCk49MTAwMDAKYnVybi5pbj1OLzIKCiMgZGF0YQp5PWMoMCwwKQoKIyBjb3JyZWxhdGlvbgpyaG89MC44CgojIGluaXRpYWwgdmFsdWUKY292LnZhcj1tYXRyaXgoYygxLHJobyxyaG8sMSksMiwyKSAgICAgICAgIyBjb3YgZm9yIHBvc3RlcmlvciBkZW5zaXR5CmNvdi52YXIucHJvcD1tYXRyaXgoYygxLHJobyxyaG8sMSksMiwyKSAgICMgY292IGZvciBwcm9wb3NhbCBkZW5zaXR5CnRoZXRhPW1hdHJpeCgwLG5yb3c9TixuY29sPTIpCgojIGl0ZXJhdGlvbnMKZm9yIChpIGluIDE6KE4tMSkpewogIHRoZXRhLnN0YXI9cm12bm9ybSgxLG1lYW49dGhldGFbaSxdLHNpZ21hPWNvdi52YXIucHJvcCkgICMgQ2FuZGlkYXRlCiAgVT1ydW5pZigxLDAsMSkgICMgQXV4aWxpYXJ5IHZhcmlhYmxlCiAgCiAgIyBUaGUgcmF0aW8gcgogIHJhdGlvPWRtdm5vcm0odGhldGEuc3RhcixtZWFuPXksc2lnbWE9Y292LnZhcikvZG12bm9ybSh0aGV0YVtpLF0sbWVhbj15LHNpZ21hPWNvdi52YXIpCiAgCiAgIyBUaGUgcHJvYmFiaWxpdHkgb2YgbW92ZQogIGFscGhhPW1pbihyYXRpbywxKQogIAogIGlmIChVPD1hbHBoYSl7dGhldGFbaSsxLF09dGhldGEuc3Rhcn0gICMgQWNjZXB0aW5nIHRoZSBjYW5kaWRhdGUKICBlbHNlIHRoZXRhW2krMSxdPXRoZXRhW2ksXQp9CmBgYAoKXAoKIyMjIFZpc3VhbCBpbnNwZWN0aW9uOiBUcmFjZXBsb3QKCmBgYHtyfQpkZXYubmV3KCkKcGFyKG1mcm93PWMoMiwxKSkKcGxvdCgxOk4sdGhldGFbLDFdLHR5cGU9ImwiKQpwbG90KDE6Tix0aGV0YVssMl0sdHlwZT0ibCIpCmBgYAoKIyMjIyBXZSBjYW4gc2VlIHRoYXQgdGhlIGNoYWlucyBkb24ndCBnZXQgc3R1Y2sgaW4gY2VydGFpbiBhcmVhcy4gU28gdGhlc2UgYXJlIGtpbmQgb2YgZ29vZCBJIGd1ZXNzLgoKXAoKIyMjIFZpc3VhbCBpbnNwZWN0aW9uOiBSdW5uaW5nIG1lYW4gcGxvdAoKYGBge3J9Cm1lYW4udGgxPXJlcCgwLE4pICAjIFRvIHN0b3JlIHRoZSBtZWFuIHZhbHVlcwptZWFuLnRoMj1yZXAoMCxOKSAgIyBUbyBzdG9yZSB0aGUgbWVhbiB2YWx1ZXMKCiMgR2V0IHRoZSBtZWFuIG9mIHRoZSBkcmF3cyBVUCBUTyBFQUNIIElURVJBVElPTgpmb3IgKGkgaW4gMTpOKXsKICBtZWFuLnRoMVtpXT1tZWFuKHRoZXRhWzE6aSwxXSkKICBtZWFuLnRoMltpXT1tZWFuKHRoZXRhWzE6aSwyXSkKfQoKZGV2Lm5ldygpCnBhcihtZnJvdz1jKDIsMSkpCnBsb3QoMTpOLG1lYW4udGgxLHR5cGU9ImwiKQpwbG90KDE6TixtZWFuLnRoMix0eXBlPSJsIikKYGBgCgojIyMjIEJvdGggdGhldGFzJyBtZWFucyBzZWVtIHRvIGNvbnZlcmdlLgoKXApcCgojIyMgQ29udmVyZ2VuY2UgZGlhZ25vc3RpYyB1c2luZyAnY29kYScgcGFja2FnZQoKXAoKIyMjIyBCZWZvcmUgd2UgdXNlIHRoZSBkaWFnbm9zdGljcywgd2UgbXVzdCBUVVJOIE9VUiBDSEFJTlMgSU5UTyBNQ01DIG9iamVjdHMuCgpgYGB7cn0KIyBtY21jKCkgaXMgZnJvbSAnY29kYScgcGFja2FnZQp0aGV0YT1tY21jKHRoZXRhKSAgIyBXZSBtdXN0IHR1cm4gb3VyIGNoYWlucyBpbnRvIE1DTUMgb2JqZWN0cwoKc3VtbWFyeSh0aGV0YSkgICMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciB0aGUgZGlzdHJpYnV0aW9uCmBgYAoKIyMjIyBUaGlubmluZyBpbnRlcnZhbCBoZXJlIG1lYW5zIHRoZSAna2VlcGluZyBldmVyeSBrdGggc2FtcGxlcyBvbmx5JyBpbiB0aGUgdHJhY2VwbG90LgoKXAoKIyMjIFZpc3VhbCBpbnNwZWN0aW9uIHVzaW5nICdjb2RhJyBwYWNrYWdlCgpgYGB7cn0KcGxvdCh0aGV0YSkgICMgVGhpcyBnaXZlcyB1cyBib3RoIGRlbnNlIHBsb3QgYW5kIHRyYWNlcGxvdAoKIyBkZW5zcGxvdCh0aGV0YSkKIyB0cmFjZXBsb3QodGhldGEpCmBgYAoKIyMjIyBOb3RlIHRoYXQgdGhlc2UgcGxvdHMgYXJlIHBsb3R0ZWQgYWdhaW5zdCB0aGUgdmFyaWFuY2Ugb2YgdGhldGEgaW5zdGVhZCBvZiB0aGUgdmFsdWVzIG9mIHRoZXRhIGRpcmVjdGx5LgoKXApcClwKXApcClwKXAoKIyBHZWxtYW4gYW5kIFJ1YmluIERpYWdub3N0aWMKClwKCiFbXSgvVXNlcnMvamFleW9uZ2xlZS9Eb2N1bWVudHMvQ29sbGVnZS9CYWNoZWxvci80eV8ycy9iYXllcy9SL2ltYWdlcy9JTUdfMDI5Ni5qcGVnKQoKXApcClwKXApcClwKXAoKIyBBZGFwdGl2ZSBTaW11bGF0aW9uIGFsZ29yaXRobQoKXAoKIVtdKC9Vc2Vycy9qYWV5b25nbGVlL0RvY3VtZW50cy9Db2xsZWdlL0JhY2hlbG9yLzR5XzJzL2JheWVzL1IvaW1hZ2VzL0lNR18wMzAxLmpwZWcpCgpcCgojIyMjIExldCdzIG1vbml0b3IgdGhlIGFjY2VwdGFuY2UgcmF0ZSBvZiB0aGUgTWV0cm9wb2xpcyBhbGdvLiB1c2luZyBhZGFwdGl2ZSBzaW11bGF0aW9uIGFsZ28uCgpcCgpgYGB7cn0KbGlicmFyeShtdnRub3JtKSAgIyBmb3IgbXZub3JtCgpOPTEwMDAwICAjIEluY3JlYXNlIGl0ZXJhdGlvbnMgZm9yIGJldHRlciBwZXJmb3JtYW5jZQpidXJuLmluPU4vMgoKIyMgZGF0YQp5PWMoMCwwKQoKIyMgY29ycmVsYXRpb24KcmhvPTAuOApjPTIuNC9zcXJ0KDIpICAjIGQ9MiBzaW5jZSBpdCdzIGEgYml2YXJpYXRlIG1vZGVsCgojIyBpbml0aWFsIHZhbHVlCmNvdi52YXI9bWF0cml4KGMoMSxyaG8scmhvLDEpLDIsMikgICAgICAgICNjb3YgZm9yIHBvc3RlcmlvciBkZW5zaXR5CmNvdi52YXIucHJvcD1tYXRyaXgoYygxLHJobyxyaG8sMSksMiwyKSAgICNjb3YgZm9yIHByb3Bvc2FsIGRlbnNpdHkKdGhldGE9bWF0cml4KDAsbnJvdz1OLG5jb2w9MikKCnRoZXRhLjFfb3V0PXJlcCgxLE4pCmNfb3V0PU5VTEwKCiMjIGl0ZXJhdGlvbnMKZm9yIChpIGluIDE6KE4tMSkpewogIAogICMgVGhlIGFkYXB0aXZlIHNpbXVsYXRpb24gYWxnby4gcGFydAogIGlmIChpPjEgJiAoKGktMSklJTEwMD09MCkpeyAgIyAlJSBnZXRzIHRoZSByZW1haW5kZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc28gdGhpcyBpcyBzYXlpbmcgZXZlcnkgMTAwIGl0ZXJhdGlvbnMKICAgIGFyPXN1bShkaWZmKHRoZXRhLjFfb3V0WyhpLTEwMCk6KGktMSldKSE9MCkvOTkKICAgICMgYXIgaXMgdGhlIHN1bSBvZiB0aGUgbm9uemVyb3Mgb2YgdGhlIHNlcXVlbmNlJ3MgZGlmZmVyZW5jZXM/CiAgICAKICAgIGlmIChhcjwwLjQ0KXtjPWMvc3FydCgyKX0gICMgd2UgbmVlZCBzbWFsbGVyIHZhcmlhbmNlCiAgICBlbHNlIGlmIChhcj4wLjQ0KXtjPWMqc3FydCgyKX0gICMgd2UgbmVlZCBsYXJnZXIgdmFyaWFuY2UKICB9CiAgCiAgCiAgIyBUaGUgTWV0cm9wb2xpcyBhbGdvLiBwYXJ0CiAgdGhldGEuc3Rhcj1ybXZub3JtKDEsbWVhbj10aGV0YVtpLF0sc2lnbWE9Y14yKmNvdi52YXIucHJvcCkKICAjIHRha2luZyB0aGUgY2FuZGlkYXRlIGZyb20gdGhlIHByb3Bvc2FsIGRzdG4KICAjIGM6IHNjYWxpbmcgZmFjdG9yCiAgCiAgVT1ydW5pZigxLDAsMSkgIAogIAogIHJhdGlvPWRtdm5vcm0odGhldGEuc3RhcixtZWFuPXksc2lnbWE9Y292LnZhcikvZG12bm9ybSh0aGV0YVtpLF0sbWVhbj15LHNpZ21hPWNvdi52YXIpCiAgYWxwaGE9bWluKHJhdGlvLDEpCiAgCiAgaWYgKFU8PWFscGhhKXt0aGV0YVtpKzEsXT10aGV0YS5zdGFyfQogIGVsc2UgdGhldGFbaSsxLF09dGhldGFbaSxdCiAgCiAgdGhldGEuMV9vdXRbaV09dGhldGFbaSwxXQogIGNfb3V0W2ldPWMKfQpgYGAKClwKCiMjIyBWaXN1YWxpemF0aW9uCgpcCgpgYGB7cn0KZGV2Lm5ldygpCnBhcihtZnJvdz1jKDIsMSkpCnBsb3QoMTpOLHRoZXRhWywxXSx0eXBlPSJsIikKcGxvdCgxOk4sdGhldGFbLDJdLHR5cGU9ImwiKQpgYGAKClwKCmBgYHtyfQpkZXYubmV3KCkKcGFyKG1mcm93PWMoMSwzKSkKcGxvdCh0aGV0YVssMV0sdGhldGFbLDJdKQpoaXN0KHRoZXRhWywxXSkKaGlzdCh0aGV0YVssMl0pCmBgYAoKXAoKIyMjIEVzdGltYXRlZCBtZWFucyBvZiB0aGV0YTEgYW5kIHRoZXRhMgoKYGBge3J9Cm1lYW4odGhldGFbKGJ1cm4uaW4rMSk6TiwxXSkKbWVhbih0aGV0YVsoYnVybi5pbisxKTpOLDJdKQpgYGAKCiMjIyMgQm90aCBhcmUgcHJldHR5IGNsb3NlIHRvIDAuCgpcCgojIyMgVGhlIGFjY2VwdGFuY2UgcmF0ZXMgYWZ0ZXIgaXRlcmF0aW9ucwoKYGBge3J9CmxpYnJhcnkoY29kYSkKbGlicmFyeShNQ01DcGFjaykKCnRoZXRhPW1jbWModGhldGEpICAjIHdlIG5lZWQgdG8gdHVybiBpdCBpbnRvIGFuIG1jbWMgb2JqZWN0IGZpcnN0CjEtcmVqZWN0aW9uUmF0ZSh0aGV0YSkgIyBUaGUgYWNjZXB0YW5jZSByYXRlCmBgYAoKIyMjIyBCb3RoIGFyZSBwcmV0dHkgY2xvc2UgdG8gMC40NCB3aGljaCBpcyBncmVhdCBJIGd1ZXNzLgoKXApcClwKXApcClwKXAoKIyBBZGFwdGl2ZSBNZXRyb3BvbGlzIGFsZ29yaXRobQoKXAoKIVtdKC9Vc2Vycy9qYWV5b25nbGVlL0RvY3VtZW50cy9Db2xsZWdlL0JhY2hlbG9yLzR5XzJzL2JheWVzL1IvaW1hZ2VzL0lNR18wMjk5LmpwZWcpCgojIyMjIElnbm9yZSB0aGUgIkNoYW5nZSB0aGUgfiIgZnJvbSB0aGUgaW1hZ2UKClwKCiMjIyMgQWxzbywgSSBndWVzcyB5b3UgaGF2ZSB0byB1c2UgY29uZGl0aW9uYWwgcG9zdC4gZHN0biBpbiB0aGlzIGNhc2U/CgpcCgpgYGB7cn0KTj0xMDAwMApidXJuLmluPU4vMgoKIyMgZGF0YQp5PWMoMCwwKQoKIyMgY29ycmVsYXRpb24KcmhvPTAuOAoKIyMgc2NhbGluZyBmYWN0b3IKYzE9Mi40L3NxcnQoMSkKYzI9Mi40L3NxcnQoMSkKZXBzPTAuMDEgICMgVGhpcyBpcyB0byBwcmV2ZW50IHRoZSB2YXJpYW5jZSBmcm9tIHNocmlua2luZyB0byB6ZXJvCgojIyBpbml0aWFsIHZhbHVlCnNpZzI9MS1yaG9eMiAgICAgICAgICAgICAgICAgICAjIHZhcmlhbmNlIGZvciBwb3N0ZXJpb3IgZGVuc2l0eQp2YXIxLnByb3A9MSAgICAgICAgICAgICAgICAgICAgIyB2YXJpYW5jZSBmb3IgcHJvcG9zYWwgZGVuc2l0eQp2YXIyLnByb3A9MSAgICAgICAgICAgICAgICAgICAgIyB2YXJpYW5jZSBmb3IgcHJvcG9zYWwgZGVuc2l0eQoKdGhldGEuMT1yZXAoMTAsTikKdGhldGEuMj1yZXAoMCxOKQoKYzFfb3V0PU5VTEwKYzJfb3V0PU5VTEwKCgojIyMjIGl0ZXJhdGlvbnMKZm9yIChpIGluIDE6KE4tMSkpewogIAogICMgQWRhcHRpdmUgYWxnb3JpdGhtIHBhcnQKICAKICAjIyB1cGRhdGUgdmFyaWFuY2Ugb2YgcHJvcG9zYWwKICBpZiAoaT4xMDApewogICAgdmFyMS5wcm9wPXZhcih0aGV0YS4xWzE6KGktMSldKSAgCiAgICB2YXIyLnByb3A9dmFyKHRoZXRhLjJbMTooaS0xKV0pICAKICB9CiAgCiAgIyMgY29udHJvbCBhY2NlcHRhbmNlIHJhdGUgZXZlcnkgMTAwIGl0ZXJhdGlvbnMKICBpZiAoaT4xICYgKChpLTEpJSUxMDA9PTApKXsgIAogICAgYXIxPXN1bShkaWZmKHRoZXRhLjFbKGktMTAwKTooaS0xKV0pIT0wKS85OQogICAgaWYgKGFyMTwwLjQ0KXtjMT1jMS9zcXJ0KDIpfQogICAgZWxzZSBpZiAoYXIxPjAuNDQpe2MxPWMxKnNxcnQoMil9CiAgICAKICAgIGFyMj1zdW0oZGlmZih0aGV0YS4yWyhpLTEwMCk6KGktMSldKSE9MCkvOTkKICAgIGlmIChhcjI8MC40NCl7YzI9YzIvc3FydCgyKX0KICAgIGVsc2UgaWYgKGFyMj4wLjQ0KXtjMj1jMipzcXJ0KDIpfQogIH0KICAKICAKICAjIE1ldHJvcG9saXMgcGFydAogIAogICMjIGZvciB0aGV0YS4xCiAgdGhldGEuMS5zdGFyPXJub3JtKDEsdGhldGEuMVtpXSxjMV4yKnZhcjEucHJvcCtjMV4yKmVwcykKICBVLjE9cnVuaWYoMSwwLDEpCiAgCiAgcmF0aW8uMT1kbm9ybSh0aGV0YS4xLnN0YXIseVsxXStyaG8qKHRoZXRhLjJbaV0teVsyXSksc3FydChzaWcyKSkvZG5vcm0odGhldGEuMVtpXSx5WzFdK3JobyoodGhldGEuMltpXS15WzJdKSxzcXJ0KHNpZzIpKQogIGFscGhhLjE9bWluKHJhdGlvLjEsMSkKICAKICBpZiAoVS4xPD1hbHBoYS4xKXt0aGV0YS4xW2krMV09dGhldGEuMS5zdGFyfSBlbHNlIHRoZXRhLjFbaSsxXT10aGV0YS4xW2ldCiAgCiAgIyMgZm9yIHRoZXRhLjIKICB0aGV0YS4yLnN0YXI9cm5vcm0oMSx0aGV0YS4yW2ldLGMyXjIqdmFyMi5wcm9wK2MyXjIqZXBzKQogIFUuMj1ydW5pZigxLDAsMSkKICAKICByYXRpby4yPWRub3JtKHRoZXRhLjIuc3Rhcix5WzJdK3JobyoodGhldGEuMVtpXS15WzFdKSxzcXJ0KHNpZzIpKS9kbm9ybSh0aGV0YS4yW2ldLHlbMl0rcmhvKih0aGV0YS4xW2ldLXlbMV0pLHNxcnQoc2lnMikpCiAgYWxwaGEuMj1taW4ocmF0aW8uMiwxKQogIAogIGlmIChVLjI8PWFscGhhLjIpe3RoZXRhLjJbaSsxXT10aGV0YS4yLnN0YXJ9IGVsc2UgdGhldGEuMltpKzFdPXRoZXRhLjJbaV0KICAKICBjMV9vdXRbaV09YzEKICBjMl9vdXRbaV09YzIKfQpgYGAKClwKCiMjIyBWaXN1YWxpemF0aW9ucwoKYGBge3J9CmRldi5uZXcoKQpwYXIobWZyb3c9YygyLDEpKQpwbG90KDE6Tix0aGV0YS4xLHR5cGU9ImwiKQpwbG90KDE6Tix0aGV0YS4yLHR5cGU9ImwiKQpgYGAKClwKCmBgYHtyfQpwYXIobWZyb3c9YygxLDMpKQpwbG90KHRoZXRhLjEsdGhldGEuMikKaGlzdCh0aGV0YS4xKQpoaXN0KHRoZXRhLjIpCmBgYAoKXAoKIyMjIEVzdGltYXRlZCBtZWFucyBvZiB0aGV0YTEgYW5kIHRoZXRhMgoKYGBge3J9Cm1lYW4odGhldGEuMVsoYnVybi5pbisxKTpOXSkKbWVhbih0aGV0YS4yWyhidXJuLmluKzEpOk5dKQpgYGAKCiMjIyMgQm90aCBhcmUgcHJldHR5IGNsb3NlIHRvIDAKClwKCiMjIyBBY2NlcHRhbmNlIHJhdGUgYWZ0ZXIgaXRlcmF0aW9ucwoKYGBge3J9CmxpYnJhcnkoY29kYSkKbGlicmFyeShNQ01DcGFjaykKCnRoZXRhLjE9bWNtYyh0aGV0YS4xKQp0aGV0YS4yPW1jbWModGhldGEuMikKMS1yZWplY3Rpb25SYXRlKHRoZXRhLjEpCjEtcmVqZWN0aW9uUmF0ZSh0aGV0YS4yKQpgYGAKCiMjIyMgQm90aCBoYXZlIGFjY2VwdGFuY2UgcmF0ZXMgcHJldHR5IGNsb3NlIHRvIDAuNDQKClwKXApcClwKXApcClwKCiMgU2xpY2UgU2FtcGxlcgoKXAoKIVtdKC9Vc2Vycy9qYWV5b25nbGVlL0RvY3VtZW50cy9Db2xsZWdlL0JhY2hlbG9yLzR5XzJzL2JheWVzL1IvaW1hZ2VzL0lNR18wMzAwLmpwZWcpCgpcCgpgYGB7cn0KbnNpbT0xMDAwMDAgICMgSW5jcmVhc2UgaXRlcmF0aW9ucyBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlCgp1PXJlcCgxLG5zaW0pCng9cmVwKDEsbnNpbSkKCmZvcihpIGluIDI6bnNpbSl7CiAgdVtpXTwtcnVuaWYoMSwwLDAuNSpleHAoLXNxcnQoeFtpLTFdKSkpCiAgeFtpXTwtcnVuaWYoMSwwLChsb2coMip1W2ldKSleMikKfQpgYGAKClwKCmBgYHtyfQpkZXYubmV3KCkKcGFyKG1mcm93PWMoMSwxKSkKCmE9c2VxKDAsNTAsMC4wMSkKZmE9MC41KmV4cCgtc3FydChhKSkKCmhpc3QoeCxmcmVxPUYseGxpbT1jKDAsNTApLGJyZWFrcz0yMDApCmxpbmVzKGEsZmEsdHlwZT0ibCIsY29sPSJyZWQiKQpgYGAKCiMjIyMgVGhlIHJlZCBsaW5lIGlzIHRoZSBhY3R1YWwgZGVuc2l0eSwgYW5kIHRoZSBoaXN0b2dyYW0gaXMgb2Ygc2FtcGxlcyBmcm9tIHRoZSBzbGljZSBzYW1wbGVyLiBJdCdzIHByZXR0eSBjbG9zZSBpbmRlZWQuCgpcClwKXApcClwKXApcCgojIEJheWVzaWFuIExpbmVhciBSZWdyZXNzaW9uIG1vZGVsCgpcCgojIyBFeGFtcGxlIDEKCiFbXSgvVXNlcnMvamFleW9uZ2xlZS9Eb2N1bWVudHMvQ29sbGVnZS9CYWNoZWxvci80eV8ycy9iYXllcy9SL2ltYWdlcy9JTUdfMDM3Ny5qcGVnKQoKIVtdKC9Vc2Vycy9qYWV5b25nbGVlL0RvY3VtZW50cy9Db2xsZWdlL0JhY2hlbG9yLzR5XzJzL2JheWVzL1IvaW1hZ2VzL0lNR18wMzc4LmpwZWcpCgohW10oL1VzZXJzL2phZXlvbmdsZWUvRG9jdW1lbnRzL0NvbGxlZ2UvQmFjaGVsb3IvNHlfMnMvYmF5ZXMvUi9pbWFnZXMvSU1HXzAzNzkuanBlZykKClwKCiMjIyBMb2FkaW5nIGRhdGEKCmBgYHtyfQpsaWJyYXJ5KExlYXJuQmF5ZXMpICAjIGZvciB0aGUgJ2JpcmRleHRpbmN0JyBkYXRhCgpkYXRhKCJiaXJkZXh0aW5jdCIpCmF0dGFjaChiaXJkZXh0aW5jdCkKCmJpcmRleHRpbmN0CmBgYAoKIyMjIyB0aW1lIGlzIHRoZSB5IHZhcmlhYmxlLCBhbmQgbmVzdGluZywgc2l6ZSwgYW5kIHN0YXR1cyBhcmUgdGhlIHggdmFyaWFibGVzLiBOb3RlIHRoYXQgc2l6ZSBhbmQgc3RhdHVzIGFyZSBiaW5hcnkuCgpcCgojIyMgRURBCgpgYGB7cn0KTiA8LSBkaW0oYmlyZGV4dGluY3QpWzFdICAjIFNhbXBsZSBzaXplCgpsb2d0aW1lPWxvZyh0aW1lKSAgIyB0aW1lIGlzIHZlcnkgc2tld2VkIGFuZCBsb2cgbWFrZXMgaXQgbGVzcyBza2V3ZWQKCmRldi5uZXcoKQpwYXIobWZyb3c9YygxLDIpKQpoaXN0KHRpbWUpCmhpc3QobG9ndGltZSkKYGBgCgojIyMjIFNpbmNlIHRpbWUgaXMgdmVyeSBza2V3ZWQsIHdlIHVzZWQgbG9nLiBXZSBjYW4gc2VlIHRoYXQgaXQgaGFzIGxlc3NlbmVkIHRoZSBza2V3bmVzcyBidXQgbm90IG11Y2ggdG8gYmUgaG9uZXN0LgoKXAoKIyMjIEZyZXF1ZW50aXN0IGxpbmVhciByZWdyZXNzaW9uCgpgYGB7cn0KbG0uZml0PWxtKGxvZ3RpbWV+bmVzdGluZytzaXplK3N0YXR1cyxkYXRhPWJpcmRleHRpbmN0LHg9VFJVRSx5PVRSVUUpCnN1bW1hcnkobG0uZml0KQpgYGAKClwKCiMjIyBSZXNpZHVhbCBwbG90CgpgYGB7cn0KZGV2Lm5ldygpCnBhcihtZnJvdz1jKDEsMSkpCnBsb3QobG0uZml0JGZpdHRlZC52YWx1ZXMsbG0uZml0JHJlc2lkdWFscyx5bGltPWMoLTEuNSwxLjUpLHhsYWI9IkZpdHRlZCBWYWx1ZXMiLHlsYWI9IlJlc2lkdWFscyIpCmFibGluZShoPTApCmFibGluZShoPTIqc3VtbWFyeShsbS5maXQpJHNpZ21hLGx0eT0yKSAgIAphYmxpbmUoaD0tMipzdW1tYXJ5KGxtLmZpdCkkc2lnbWEsbHR5PTIpCiMgc2lnbWEgaXMgdGhlIHJlc2lkdWFsIHN0YW5kYXJkIGVycm9yIChvciByZXNpZHVhbCBzdGFuZGFyZCBkZXZpYXRpb24pIHdoaWNoIGlzIGEgbWVhc3VyZSB1c2VkIHRvIGFzc2VzcyBob3cgd2VsbCBhIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsIGZpdHMgdGhlIGRhdGEsIHNtYWxsZXIgbWVhbmluZyB0aGUgbW9kZWwgZml0cyB0aGUgZGF0YSBiZXR0ZXIuCmBgYAoKVGhlcmUgYXJlIG5vIHZpb2xhdGlvbnMgb2YgZXF1YWwgdmFyaWFuY2Ugb2YgZXJyb3IgdGVybXMsIG9yIHRoZSBsaW5lYXJpdHkgb2YgdGhlIG1vZGVsLiBBbHNvIHRoZXJlIHNlZW0gdG8gYmUgbm8gZXh0cmVtZSBvdXRsaWVycyBhbHRob3VnaCB0aGVyZSBpcyBvbmUgdGhhdCBpcyBvdXRzaWRlIG9mIHRoZSAyIHRpbWVzIHRoZSByZXNpZHVhbCBzdGFuZGFyZCBlcnJvci4KClwKXApcCgojIyMgQmF5ZXNpYW4gbGluZWFyIHJlZ3Jlc3Npb24KClwKCiMjIyMgTGV0J3MgdXNlIGJsaW5yZWcoKSB0byBzYW1wbGUgZnJvbSB0aGUgam9pbnQgcG9zdC4gZHN0biBvZiBiZXRhIGFuZCBzaWdtYV9zcXVhcmVkCgpgYGB7cn0KdGhldGEuc2FtcGxlPWJsaW5yZWcobG0uZml0JHksbG0uZml0JHgsMTAwMCkKCmRldi5uZXcoKQpwYXIobWZyb3c9YygyLDIpKQpoaXN0KHRoZXRhLnNhbXBsZSRiZXRhWywyXSxtYWluPSJOZXN0aW5nIix4bGFiPWV4cHJlc3Npb24oYmV0YVsxXSkpCmhpc3QodGhldGEuc2FtcGxlJGJldGFbLDNdLG1haW49IlNpemUiLHhsYWI9ZXhwcmVzc2lvbihiZXRhWzJdKSkKaGlzdCh0aGV0YS5zYW1wbGUkYmV0YVssNF0sbWFpbj0iU3RhdHVzIix4bGFiPWV4cHJlc3Npb24oYmV0YVszXSkpCmhpc3QodGhldGEuc2FtcGxlJHNpZ21hLG1haW49IkVycm9yIFNEIix4bGFiPWV4cHJlc3Npb24oc2lnbWEpKQpgYGAKCiMjIyMgVGhlc2UgYXJlIHRoZSBzYW1wbGVzIGZyb20gbWFyZ2luYWwgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiBvZiBlYWNoIHZhcmlhYmxlLiBFcnJvciBTRCBpcyB0aGUgZXJyb3IgdGVybXMgY2FsY3VsYXRlZCBmcm9tIHRoZSBzYW1wbGVzKD8pLiBUaGV5IGxvb2sgbGlrZSBub3JtYWwgZGlzdHJpYnV0aW9uIHNvIG1lYW4gYW5kIG1lZGlhbiBhcmUgcHJldHR5IG11Y2ggdGhlIHNhbWUsIHNvIHdlIGNhbiBjaG9vc2UgZWl0aGVyLgoKXAoKIyMjIENvbXBhcmlzb24gb2YgY29lZmZpY2llbnRzCgpgYGB7cn0KYXBwbHkodGhldGEuc2FtcGxlJGJldGEsMixxdWFudGlsZSxjKDAuMDI1LDAuNSwwLjk3NSkpICAjIDk1JSBjcmVkaWJsZSBpbnRlcnZhbHMKIyBXZSBjYW4gdGhpbmsgdGhlIG1lZGlhbig1MCUpIGFzIHRoZSBiYXllcyBlc3RpbWF0ZXMgb2YgdGhlIGNvZWZmaWNpZW50cyBzaW5jZSB0aGV5IHNlZW0gbGlrZSB0aGV5IGZvbGxvdyBub3JtYWwgZGlzdHJpYnV0aW9uCmBgYAoKYGBge3J9CmxtLmZpdCRjb2VmZmljaWVudHMgICMgZnJlcSdzIGVzdGltYXRvcnMgb2YgY29lZmZpY2llbnRzCmBgYAoKCiMjIyMgV2UgY2FuIHNlZSB0aGF0IGJvdGggZnJlcSdzIGFuZCBiYXllcycgcmVzdWx0cyBhcmUgc2ltaWxhci4gVGhpcyBpcyBkdWUgdG8gYmF5ZXMgbGluZWFyIG1vZGVsIHVzaW5nIGEgbm9uaW5mb3JtYXRpdmUgcHJpb3IuIEJheWVzIHByb3ZpZGVzIG1vcmUgaW5mb3JtYXRpb24gYmVjYXVzZSB3ZSBjYW4gY2xlYXJseSBzZWUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBlYWNoIHZhcmlhYmxlcy4KClwKCiMjIyBTaWdtYSBjb21wYXJpc29uCgpgYGB7cn0KcXVhbnRpbGUodGhldGEuc2FtcGxlJHNpZ21hLGMoMC4wMjUsMC41LDAuOTc1KSkgICMgNTAlIGlzIHRoZSBiYXllcyBlc3RpbWF0ZQpgYGAKCmBgYHtyfQpzdW1tYXJ5KGxtLmZpdCkkc2lnbWEKYGBgCgojIyMjIFdlIGNhbiBzZWUgdGhhdCBzaWdtYSBpbiBib3RoIGNhc2VzIGFyZSBzaW1pbGFyIHRvby4KClwKXApcCgojIyBTYW1wbGluZyB1c2luZyBtYXJnaW5hbCBwb3N0LiBkc3RuIG9mIHNpZ21hX3NxdWFyZWQKClwKCiMjIyBFREEKCmBgYHtyfQojI0RldGVybWluZSBleHBsYW5hdG9yeSB2YXJpYWJsZXMKWCA8LSBhcy5tYXRyaXgoYmlyZGV4dGluY3RbLDM6NV0pCmNvdi5uYW1lcyA8LSBuYW1lcyhiaXJkZXh0aW5jdFssYygtMSwtMildKQoKIyNQYWlycyBwbG90CnBhaXJzKGNiaW5kKGxvZ3RpbWUsWCkpCgojI0FkZCBhIGNvbHVtbiBvZiAxcyBmb3IgdGhlIGludGVyY2VwdHMKWC5pbnQgPC0gY2JpbmQocmVwKDEsTiksWCkKCiMjRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgZXhwbGFuYXRvcnkgdmFyaWFibGVzCmsgPC0gZGltKFguaW50KVsyXQpgYGAKClwKCiMjIyBGdW5jdGlvbnMgdG8gdXNlIHRvIHNhbXBsZSBmcm9tIGNvbmQuIHBvc3QuIGRzdG4gb2YgYmV0YSBhbmQgbWFyZ2luYWwgcG9zdC4gZHN0biBvZiBzaWdtYV9zcXVhcmVkCgpgYGB7cn0KbGlicmFyeShNQVNTKSAgIyBmb3IgbXZybm9ybQoKIyNGdW5jdGlvbiBmb3Igc2FtcGxpbmcgZnJvbSBwKGJldGF8c2lnbWEyLFgseSkgOiBjb25kLiBwb3N0LiBkc3RuIG9mIGJldGEKc2FtcGxlLmJldGEgPC0gZnVuY3Rpb24oc2lnbWEyLFgseSl7CiAgVi5iZXRhIDwtIHNvbHZlKHQoWCklKiVYKSAgICAgICAgICAgICAKICBiZXRhLmhhdCA8LSBWLmJldGElKiV0KFgpJSoleQogIHJldHVybihtdnJub3JtKDEsYmV0YS5oYXQsc2lnbWEyKlYuYmV0YSkpCn0KCiNGdW5jdGlvbiBmb3Igc2FtcGxpbmcgZnJvbSBwKHNpZ21hMnxYLHkpIDogbWFyZ2luYWwgcG9zdC4gZHN0biBvZiBzaWdtYV9zcXVhcmVkCnNhbXBsZS5zaWdtYTIgPC0gZnVuY3Rpb24oWCx5LE4sayl7CiAgVi5iZXRhIDwtIHNvbHZlKHQoWCklKiVYKSAgICAgICAgICAgIAogIGJldGEuaGF0IDwtIFYuYmV0YSUqJXQoWCklKiV5CiAgczIgPC0gdCh5LVglKiViZXRhLmhhdCklKiUoeS1YJSolYmV0YS5oYXQpLyhOLWspCiAgcmV0dXJuKDEvcmdhbW1hKDEsc2hhcGU9KE4taykvMixyYXRlPSgoTi1rKS8yKSpzMikpCn0KYGBgCgpcCgojIyMgU2FtcGxpbmcKCmBgYHtyfQojIEluaXRpYWxpemUgdmFyaWFibGVzIGZvciB0aGUgcG9zdGVyaW9yIHNhbXBsZXMKbnNpbT0xMDAwCmJldGEucG9zdC5zYW1wbGVzID0gbWF0cml4KDAsbnNpbSxrKQpzaWdtYTIucG9zdC5zYW1wbGVzID0gcmVwKDAsbnNpbSkKCiMgSXRlcmF0aW9ucwpmb3IoaSBpbiAxOm5zaW0pewogIHNpZ21hMi5wb3N0LnNhbXBsZXNbaV0gPC0gc2FtcGxlLnNpZ21hMihYLmludCxsb2d0aW1lLE4say0xKQogIGJldGEucG9zdC5zYW1wbGVzW2ksXSA8LSBzYW1wbGUuYmV0YShzaWdtYTIucG9zdC5zYW1wbGVzW2ldLFguaW50LGxvZ3RpbWUpCn0KYGBgCgpcCgojIyMgVmlzdWFsaXphdGlvbgoKYGBge3J9CiNFeGFtaW5lIHBvc3RlcmlvciBzYW1wbGVzCmRldi5uZXcoKQpwYXIobWZyb3c9YygzLDIpKQpoaXN0KHNpZ21hMi5wb3N0LnNhbXBsZXMpCmJveHBsb3QoYXMuZGF0YS5mcmFtZShiZXRhLnBvc3Quc2FtcGxlc1ssLTFdKSxuYW1lcz1jb3YubmFtZXMpCmFibGluZShoPTApCgpwbG90KDE6bnNpbSxzaWdtYTIucG9zdC5zYW1wbGVzLHR5cGU9ImwiKQpwbG90KDE6bnNpbSxiZXRhLnBvc3Quc2FtcGxlc1ssMl0sdHlwZT0ibCIpCnBsb3QoMTpuc2ltLGJldGEucG9zdC5zYW1wbGVzWywzXSx0eXBlPSJsIikKcGxvdCgxOm5zaW0sYmV0YS5wb3N0LnNhbXBsZXNbLDRdLHR5cGU9ImwiKQpgYGAKCiMjIyMgVGhlIGhpc3RvZ3JhbSBpcyBvZiBzaWdtYV9zcXVhcmVkLCBhbmQgdGhlIGJveHBsb3QgaXMgb2YgdGhlIGJldGFzLiBUaGUgdHJhY2VwbG90IGlzIHRvIHNob3cgdGhlIGNvbnZlcmdlbmNlIG9mIHRoZSBzYW1wbGVzIG9mIHNpZ21hX3NxdWFyZWQgYW5kIGVhY2ggYmV0YS4KClwKCiMjIyBUaGUgYmF5ZXMgZXN0aW1hdGVzIG9mIHNpZ21hX3NxdWFyZWQKCmBgYHtyfQptZWFuKHNpZ21hMi5wb3N0LnNhbXBsZXMpCmBgYAoKIyMjIFRoZSBiYXllcyBlc3RpbWF0ZXMgb2YgYmV0YXMKCmBgYHtyfQpjb2xNZWFucyhiZXRhLnBvc3Quc2FtcGxlcykKYGBgCgojIyMgQ29tcGFyaXNvbiB0byB0aGUgZnJlcSdzIGVzdGltYXRlcwoKYGBge3J9CmxtLmZpdCRjb2VmZmljaWVudHMgICMgVGhlIGJldGFzCmBgYAoKYGBge3J9CihzdW1tYXJ5KGxtLmZpdCkkc2lnbWEpXjIgICMgU2lnbWFfc3F1YXJlZApgYGAKCiMjIyMgV2UgY2FuIHNlZSB0aGF0IGJvdGggYmF5ZXMgYW5kIGZyZXEncyByZXN1bHRzIGFyZSBzaW1pbGFyLiBXZSBjYW4gc2F5IHRoYXQgb3V0IGJheWVzIG1vZGVsIGlzIGRvaW5nIHdlbGwgSSBndWVzcy4KCgpcCgojIyMgQ29ycmVsYXRpb24gbWFwIG9mIHRoZSBiZXRhcwoKYGBge3J9CiNMb29rIGF0IHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSBiZXRhcwpwYWlycyhiZXRhLnBvc3Quc2FtcGxlcyxsYWJlbHM9YygiSW50ZXJjZXB0Iixjb3YubmFtZXMpKQpgYGAKClwKXApcCgojIyBTYW1wbGluZyB1c2luZyB0aGUgY29uZGl0aW9uYWwgZHN0biBvZiBzaW1nYV9zcXVhcmVkICAoR2liYnMgc2FtcGxlciBJIGd1ZXNzKQoKXAoKIyMjIEZ1bmN0aW9ucyB0byBzYW1wbGUgc2lnbWFfc3F1YXJlZCBmcm9tIHRoZSBjb25kLiBwb3N0LiBkc3RuIG9mIHNpZ21hX3NxdWFyZWQgYW5kIGJldGEgZnJvbSB0aGUgY29uZC4gcG9zdC4gZHN0biBvZiBiZXRhIChzYW1lIG9uZSBhcyBhYm92ZSkKCmBgYHtyfQojI0Z1bmN0aW9uIGZvciBzYW1wbGluZyBmcm9tIHAoYmV0YXxzaWdtYTIsWCx5KSA6IGNvbmQuIHBvc3QuIGRzdG4gb2YgYmV0YQpzYW1wbGUuYmV0YSA8LSBmdW5jdGlvbihzaWdtYTIsWCx5KXsKICBWLmJldGEgPC0gc29sdmUodChYKSUqJVgpICAgICAgICAgICAgIAogIGJldGEuaGF0IDwtIFYuYmV0YSUqJXQoWCklKiV5CiAgcmV0dXJuKG12cm5vcm0oMSxiZXRhLmhhdCxzaWdtYTIqVi5iZXRhKSkKfQoKI0Z1bmN0aW9uIGZvciBzYW1wbGluZyBmcm9tIHAoc2lnbWEyfGJldGEsWCx5KSA6IG1hcmdpbmFsIHBvc3QuIGRzdG4gb2Ygc2lnbWFfc3F1YXJlZApzYW1wbGUuc2lnbWEyLmNvbmQgPC0gZnVuY3Rpb24oWCx5LE4sYmV0YSl7CiAgcGFyMT1OLzIKICBwYXIyPTAuNSp0KHktWCUqJWJldGEpJSolKHktWCUqJWJldGEpCiAgcmV0dXJuKDEvcmdhbW1hKDEsc2hhcGU9cGFyMSxyYXRlPXBhcjIpKQp9CmBgYAoKXAoKIyMjIFNhbXBsaW5nCgpgYGB7cn0KI0luaXRpYWxpemUgdmFyaWFibGVzIGZvciB0aGUgcG9zdGVyaW9yIHNhbXBsZXMKbnNpbT0xMDAwCmJldGEucG9zdC5zYW1wbGVzID0gbWF0cml4KDAsbnNpbSxrKQpzaWdtYTIuY29uZC5wb3N0LnNhbXBsZXMgPSByZXAoMCxuc2ltKQoKZm9yKGkgaW4gMTpuc2ltKXsKICBiZXRhLnBvc3Quc2FtcGxlc1tpLF09c2FtcGxlLmJldGEoc2lnbWEyLnBvc3Quc2FtcGxlc1tpXSxYLmludCxsb2d0aW1lKQogIHNpZ21hMi5jb25kLnBvc3Quc2FtcGxlc1tpXT1zYW1wbGUuc2lnbWEyLmNvbmQoWC5pbnQsbG9ndGltZSxOLGJldGEucG9zdC5zYW1wbGVzW2ksXSkKfQpgYGAKClwKCiMjIyBWaXN1YWxpemF0aW9uCgpgYGB7cn0KZGV2Lm5ldygpCnBhcihtZnJvdz1jKDIsMSkpCmhpc3Qoc2lnbWEyLmNvbmQucG9zdC5zYW1wbGVzKQoKcGxvdCgxOm5zaW0sc2lnbWEyLmNvbmQucG9zdC5zYW1wbGVzLHR5cGU9ImwiKQpgYGAKCiMjIyMgVGhlc2UgYXJlIHRoZSByZXN1bHRzIG9mIHRoZSBzYW1wbGVzIGZyb20gdGhlIGNvbmQuIHBvc3QuIGRzdG4gb2Ygc2lnbWEgc3F1YXJlZAoKXAoKIyMjIEJheWVzIGVzdGltYXRlIG9mIHNpZ21hX3NxdWFyZWQKCmBgYHtyfQptZWFuKHNpZ21hMi5wb3N0LnNhbXBsZXMpCmBgYAoKXAoKIyMjIEJheWVzIGVzdGltYXRlIG9mIGJldGFzCgpgYGB7cn0KY29sTWVhbnMoYmV0YS5wb3N0LnNhbXBsZXMpCmBgYAoKXAoKIyMjIENvbXBhcmlzb24gdG8gdGhlIGZyZXEncyBlc3RpbWF0ZXMKCmBgYHtyfQpsbS5maXQkY29lZmZpY2llbnRzICAjIFRoZSBiZXRhcwpgYGAKCmBgYHtyfQooc3VtbWFyeShsbS5maXQpJHNpZ21hKV4yICAjIFNpZ21hX3NxdWFyZWQKYGBgCgojIyMjIEFnYWluLCB3ZSBjYW4gc2VlIHRoYXQgYm90aCBiYXllcyBhbmQgZnJlcSdzIHJlc3VsdHMgYXJlIHNpbWlsYXIuIEFnYWluLCB3ZSBjYW4gc2F5IHRoYXQgb3V0IGJheWVzIG1vZGVsIGlzIGRvaW5nIHdlbGwgSSBndWVzcy4KClwKXAoKIyMjIENvbmNsdXNpb24KCiMjIyMgU2FtcGxlcyBmcm9tIHRoZSBibGlucmVnKCkgYXJlIGFsbW9zdCB0aGUgc2FtZSBhcyBzYW1wbGVzIHVzaW5nIHRoZSBtYXJnaW5hbCBwb3N0LiBkc3RuIG9yIHRoZSBzYW1wbGVzIHVzaW5nIHRoZSBjb25kLiBwb3N0LiBkc3RuLCB3aGljaCBhcmUgYWxsIGluIHR1cm4gdmVyeSBzaW1pbGFyIHRvIHRoZSBmcmVxJ3MgcmVzdWx0IChkdWUgdG8gdXNpbmcgbm9uaW5mb3JtYXRpdmUgcHJpb3IpLgoKClwKXApcClwKCiMjIEV4YW1wbGUgMgoKIVtdKC9Vc2Vycy9qYWV5b25nbGVlL0RvY3VtZW50cy9Db2xsZWdlL0JhY2hlbG9yLzR5XzJzL2JheWVzL1IvaW1hZ2VzL0lNR18wMzgwLmpwZWcpCgpcCgojIyMgTG9hZGluZyBkYXRhCgpgYGB7cn0KYmFieT1yZWFkLnRhYmxlKCJodHRwOi8vd3d3LnN0YXQuYmVya2VsZXkuZWR1L35zdGF0bGFicy9kYXRhL2JhYmllcy5kYXRhIixoZWFkPVRSVUUpCmF0dGFjaChiYWJ5KQpgYGAKClwKCiMjIyBQZXJmb3JtaW5nIGJheWVzaWFuIGxpbmVhciByZWdyZXNzaW9uIHVzaW5nIE1DTUNyZWdyZXNzKCkKCmBgYHtyfQpsaWJyYXJ5KE1DTUNwYWNrKSAgIyBmb3IgTUNNQ3JlZ3Jlc3MKbGlicmFyeShjb2RhKSAgIyBmb3IgbWNtYwoKb3B0aW9ucyhzY2lwZW4gPSAxKSAgIyB0byByZW1vdmUgc2NpZW50aWZpYyBub3RhdGlvbgoKcmVnPC1NQ01DcmVncmVzcyhid3R+YWdlK3dlaWdodCxiMD0wLEIwPTAsYnVybmluPTEwMDAsbWNtYz0xMDAwMCkKc3VtbWFyeShyZWcpCmBgYAoKIyMjIyBXZSBjYW4gdXNlIGVpdGhlciB0aGUgbWVkaWFuKDUwJSkgb3IgdGhlIG1lYW4gYXMgdGhlIGJheWVzIGVzdGltYXRlCgpcCgojIyMgVmlzdWFsaXphdGlvbgoKYGBge3J9CmRldi5uZXcoKQpwbG90KHJlZykKYGBgCgojIyMjIFdlIGNhbiBzZWUgdGhhdCB0aGUgZGVuc2l0eSBvZiB0aGUgdmFyaWFibGVzIGxvb2sgbGlrZSBub3JtYWwgZHN0biBzbyB3ZSBjYW4gdXNlIGVpdGhlciBtZWFuIG9yIG1lZGlhbi4KClwKCiMjIyBDb21wYXJpc29uIHRvIGZyZXEuCgpgYGB7cn0KZnJlcT1sbShid3R+YWdlK3dlaWdodCxkYXRhPWJhYnkpCnN1bW1hcnkoZnJlcSkKYGBgCgpgYGB7cn0KKHN1bW1hcnkoZnJlcSkkc2lnbWEpXjIKYGBgCgojIyMjIFdlIGNhbiBzZWUgdGhhdCB0aGUgcmVzdWx0cyBhcmUgdmVyeSBzaW1pbGFyCgpcClwKXApcClwKXApcCgojIExvZ2lzdGljIHJlZ3Jlc3Npb24gZm9yIGJpbmFyeSByZXNwb25zZQoKXAoKIVtdKC9Vc2Vycy9qYWV5b25nbGVlL0RvY3VtZW50cy9Db2xsZWdlL0JhY2hlbG9yLzR5XzJzL2JheWVzL1IvaW1hZ2VzL3NzMy5wbmcpCgpcCgojIyMgTG9hZGluZyBkYXRhCgpgYGB7cn0KbGlicmFyeShNQVNTKQpkYXRhKGJpcnRod3QpCmF0dGFjaChiaXJ0aHd0KQpoZWFkKGJpcnRod3QpCmBgYAoKIyMjIyAnbG93JyBpcyB0aGUgYmluYXJ5IHJlc3BvbnNlIGZvciBsb3cgYmlydGggd2VpZ2h0CgpcCgojIyMgUG9zdC4gZHN0biBvZiBiZXRhICh3aXRoIHByaW9yIGRzdG4gZm9yIGJldGEgYXMgZGVmYXVsdCBpbXByb3BlciB1bmlmb3JtIHByaW9yKQoKYGBge3J9CmxpYnJhcnkoY29kYSkgICMgZm9yIG1jbWMKbGlicmFyeShNQ01DcGFjaykgICMgZm9yIE1DTUNsb2dpdAoKIyBkZWZhdWx0IGltcHJvcGVyIHVuaWZvcm0gcHJpb3IKbG9naXQuMSA8LSBNQ01DbG9naXQobG93fmFnZSthcy5mYWN0b3IocmFjZSkrc21va2UsIGRhdGE9YmlydGh3dCwgYmV0YS5zdGFydD1yZXAoMC43LDUpKQojIEkgdGhpbmsgeW91IGhhdmUgdG8gbWFrZSBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgaW50byBhIGZhY3RvciBmaXJzdAojIEhvd2V2ZXIsIHNtb2tlIGlzIGEgYmluYXJ5IHZhcmlhYmxlLCBhbmQgeW91IGRvbid0IGhhdmUgdG8gZmFjdG9yIGEgYmluYXJ5IHZhcmlhYmxlCgojIGJldGEuc3RhcnQgaXMgdGhlIHN0YXJ0aW5nIHZhbHVlcyBmb3IgdGhlIGJldGEgdmVjdG9yLiBUaGVyZSBhcmUgdG90YWwgNSBiZXRhcyBpbmNsdWRpbmcgdGhlIGludGVyY2VwdDogaW50ZXJjZXB0LCBhZ2UsIHJhY2UyLCByYWNlMywgc21va2UKCiMgSGVyZSwgYjAgYW5kIEIwIHZhbHVlcyB3ZXJlIG5vdCBnaXZlbiA9PiB0aGlzIGlzIGFuIGltcHJvcGVyIHVuaWZvcm0gcHJpb3IKCnN1bW1hcnkobG9naXQuMSkKYGBgCgojIyMgVmlzdWFsaXphdGlvbgoKYGBge3J9CmRldi5uZXcoKQpwbG90KGxvZ2l0LjEpCmBgYAoKXAoKIyMjIENvbnZlcmdlbmNlIERpYWdub3N0aWMKCmBgYHtyfQpsb2dpdC4xPC1NQ01DbG9naXQobG93fmFnZSthcy5mYWN0b3IocmFjZSkrc21va2UsIGRhdGE9YmlydGh3dCxiZXRhLnN0YXJ0PXJlcCgtMC43LDUpKQpsb2dpdC4yPC1NQ01DbG9naXQobG93fmFnZSthcy5mYWN0b3IocmFjZSkrc21va2UsIGRhdGE9YmlydGh3dCxiZXRhLnN0YXJ0PXJlcCgtMC4zLDUpKQpsb2dpdC4zPC1NQ01DbG9naXQobG93fmFnZSthcy5mYWN0b3IocmFjZSkrc21va2UsIGRhdGE9YmlydGh3dCxiZXRhLnN0YXJ0PXJlcCgwLDUpKQpsb2dpdC40PC1NQ01DbG9naXQobG93fmFnZSthcy5mYWN0b3IocmFjZSkrc21va2UsIGRhdGE9YmlydGh3dCxiZXRhLnN0YXJ0PXJlcCgwLjMsNSkpCmxvZ2l0LjU8LU1DTUNsb2dpdChsb3d+YWdlK2FzLmZhY3RvcihyYWNlKStzbW9rZSwgZGF0YT1iaXJ0aHd0LGJldGEuc3RhcnQ9cmVwKDAuNyw1KSkKCmxvZ2l0Lmxpc3Q8LW1jbWMubGlzdChsaXN0KGxvZ2l0LjEsbG9naXQuMixsb2dpdC4zLGxvZ2l0LjQsbG9naXQuNSkpCmdlbG1hbi5kaWFnKGxvZ2l0Lmxpc3QpCmBgYAoKIyMjIyBTaW5jZSB0aGUgcG90ZW50aWFsIHNjYWxlIHJlZHVjdGlvbiBmYWN0b3JzIGZvciBlYWNoIHZhcmlhYmxlIGFyZSBhbGwgYmVsb3cgMS4xLCB3ZSBjYW4gc2F5IHRoYXQgdGhlIE1DTUMgY29udmVyZ2VuY2UgaXMgZ29vZCBmb3IgZWFjaCB2YXJpYWJsZS4KCmBgYHtyfQpnZWxtYW4ucGxvdChsb2dpdC5saXN0KQpgYGAKCiMjIyMgVGhlIHBsb3RzIGluZGljYXRlIGdvb2QgY29udmVyZ2VuY2UgYXMgd2VsbC4KClwKCiMjIyBQb3N0LiBkc3RuIG9mIGJldGEgKHdpdGggcHJpb3IgZHN0biBmb3IgYmV0YSBhcyBNVk4oMCwxMDAwSSkpIAoKIyMjIyAobGFyZ2UgdmFyaWFuY2UgPT4gbm9uaW5mb3JtYXRpdmUgcHJpb3IpCgpgYGB7cn0KIyMgbXVsdGl2YXJpYXRlIG5vcm1hbCBwcmlvcgpsb2dpdC4yIDwtIE1DTUNsb2dpdChsb3d+YWdlK2FzLmZhY3RvcihyYWNlKStzbW9rZSwgYjA9MCwgQjA9MC4wMDEsZGF0YT1iaXJ0aHd0KQojIGIwIGlzIHRoZSBwcmlvciBtZWFuIG9mIHRoZSBNVk4KIyBCMCBpcyB0aGUgcHJpb3IgcHJlY2lzaW9uKD0gMS9wcmlvciB2YXJpYW5jZSkgb2YgdGhlIE1WTgojIFRoaXMgbWVhbnMgdGhhdCB0aGUgcHJpb3IgdmFyaWFuY2Ugd2UgdXNlZCBoZXJlIGlzIDEwMDAKIyBTaW5jZSB0aGUgcHJpb3IgdmFyaWFuY2UgaXMgdmVyeSBsYXJnZSwgdGhpcyBpcyBhIG5vbmluZm9ybWF0aXZlIHByaW9yCgpzdW1tYXJ5KGxvZ2l0LjIpCmBgYAoKIyMjIFZpc3VhbGl6YXRpb24KCmBgYHtyfQpwbG90KGxvZ2l0LjIpCmBgYAoKXApcClwKXApcClwKXAoKIyBQb2lzc29uIHJlZ3Jlc3Npb24gZm9yIGNvdW50IGRhdGEKCiFbXSgvVXNlcnMvamFleW9uZ2xlZS9Eb2N1bWVudHMvQ29sbGVnZS9CYWNoZWxvci80eV8ycy9iYXllcy9SL2ltYWdlcy9zczQucG5nKQoKXAoKIyMjIExvYWRpbmcgZGF0YQoKYGBge3J9CmRhdGEoZXBpbCkKYXR0YWNoKGVwaWwpCmhlYWQoZXBpbCkKYGBgCgpcCgojIyMgUG9zdC4gZHN0biBvZiBiZXRhCgpgYGB7cn0KIyMgTUNNQ3BhY2sKcG9pcz1NQ01DcG9pc3Nvbih5fmxiYXNlKnRydCtsYWdlK1Y0LGRhdGEgPSBlcGlsKQpzdW1tYXJ5KHBvaXMpCmBgYAoKIyMjIFZpc3VhbGl6YXRpb24KCmBgYHtyfQpkZXYubmV3KCkKcGxvdChwb2lzKQpgYGAKClwKCiMjIyBDb21wYXJpc29uIHRvIHRoZSBGcmVxLiByZXN1bHQKCmBgYHtyfQpzdW1tYXJ5KGdsbSh5IH4gbGJhc2UqdHJ0ICsgbGFnZSArIFY0LCBmYW1pbHkgPSBwb2lzc29uLCBkYXRhID0gZXBpbCksIGNvciA9IFRSVUUpCmBgYAoKIyMjIyBXZSBjYW4gc2VlIHRoYXQgdGhlIHJlc3VsdHMgYXJlIHZlcnkgc2ltaWxhci4KClwKXApcCg==