Data Generating Process Description

Model Specification

The data generating process for the variable \(y\) is defined by the following linear model:

\[ y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \epsilon \]

where:

  • \(\beta_0, \beta_1, \beta_2\) are the coefficients of the model.
  • \(x_1\) and \(x_2\) are the covariates.
  • \(\epsilon\) represents the error term.

Covariates

  • \(x_1\) and \(x_2\) are assumed to be independent random variables.
  • These covariates can be generated from any distribution deemed appropriate for the scenario (e.g., Normal, Uniform).
  • It is important to specify the distribution from which \(x_1\) and \(x_2\) are drawn if simulating data for practical applications.

Error Term

  • The error term \(\epsilon\) is typically assumed to be normally distributed with a mean of zero and a specified variance, \(\sigma^2\).
  • This assumption allows the model to account for random fluctuations in \(y\) that are not explained by the covariates \(x_1\) and \(x_2\).

Coefficients

  • The values of \(\beta_0\), \(\beta_1\), and \(\beta_2\) need to be specified.
  • These coefficients determine the impact of the respective covariates on the outcome variable \(y\).

Example

If one were to simulate data from this model: - Choose specific values for \(\beta_0\), \(\beta_1\), and \(\beta_2\) (e.g., 1, 0.5, and -0.3). - Generate random values for \(x_1\) and \(x_2\) from their respective distributions. - Calculate \(\epsilon\) as a random draw from a Normal distribution with mean 0 and a specific variance. - Compute \(y\) for each set of covariate values using the specified model.

# Set seed for reproducibility
set.seed(123)

# Set the number of observations
n <- 100

# Set the number of covariates
K <- 5

# Generate covariates
X <- matrix(rnorm(n * K), n, K)  # Generate a n x K matrix of random normal values

# Specify coefficients for each covariate
betas <- c(0.5, -0.3)  # Example values for beta_1 and beta_2

# Generate the error term
epsilon <- rnorm(n, mean = 0, sd = 1)

# Intercept (beta_0)
beta_0 <- 1.5

# Calculate the response variable y
y <- beta_0 + X[,1:2] %*% betas + epsilon

# Create a data frame
data <- data.frame(y = y, X)

# Rename columns appropriately
names(data) <- c("y", paste("x", 1:K, sep = ""))

# Print the first few rows of the data
head(data)
NA

Notes:

  • The markdown format is structured to provide clear documentation for users of the generate_linear_data function. It includes headings, parameter descriptions, and a detailed explanation of the output and model behavior.

  • Code blocks within markdown are delineated by triple backticks, which might not render correctly in some plain text environments but will work as intended in most markdown viewers and GitHub repositories.

  • Ensure to adjust any part of the documentation to better fit the actual functionality and parameters of your function as implemented in R.


generate_linear_data <- function(n = 100, K = 5, K_eff = 2, betas = c(5, -3), beta_0 = 1.5) {
  # Set seed for reproducibility
  set.seed(123)

  # Generate covariates
  X <- 10 * matrix(rnorm(n * K), n, K)  # Generate a n x K matrix of random normal values

  # Generate the error term
  epsilon <- rnorm(n, mean = 0, sd = 1)

  # Calculate the response variable y
  y <- beta_0 + X[, 1:K_eff] %*% betas + epsilon

  # Create a data frame
  data <- data.frame(y = y, X)

  # Rename columns appropriately
  names(data) <- c("y", paste("x", 1:K, sep = ""))

  return(data)
}

# Example of using the function
data_frame <- generate_linear_data(n = 100, K = 5, K_eff = 2)
head(data_frame)
NA

Post Lasso

To perform post-Lasso regression on a dataset in R, you generally follow a two-step process:

  1. Lasso Regression: Fit a Lasso model to select significant variables (covariates) from a potentially large set of predictors.
  2. Post-Lasso Regression: Use the selected variables to fit a traditional linear regression model.

This approach is beneficial when dealing with high-dimensional data, allowing for variable selection through the Lasso and then unbiased estimation using OLS on the selected variables.

Perform post-Lasso regression in R using the glmnet package for the Lasso step and the standard lm function for the OLS step. First, ensure you have the necessary package:

if (!require(glmnet)) {
    install.packages("glmnet")
    library(glmnet)
}

Step 0: Sample Data Preparation

Let’s assume you have a dataset data_frame from the previous example with one response variable y and multiple predictors x1, x2, ..., xK. Here’s a brief setup:


# Sample Data Generation (Repeating here for completeness)
set.seed(123)
n <- 1000
K <- 5
X <- matrix(rnorm(n * K), n, K)
data_frame <- generate_linear_data(n = n, K = K, K_eff = 2, betas <- c(0.5, -0.3))

# print the first few rows of the data_frame
print(head(data_frame))

# print the headers
print(colnames(data_frame))
[1] "y"  "x1" "x2" "x3" "x4" "x5"

Step 1: Lasso Regression

# Fitting Lasso model
x_matrix <- as.matrix(data_frame[, -1])  # Excluding the response variable 'y'
y_vector <- data_frame$y

# Using glmnet for Lasso
lasso_model <- glmnet(x_matrix, y_vector, alpha = 1, lambda = 0.1)  # alpha = 1 for Lasso; adjust lambda as needed

# Identify non-zero coefficients (selected variables)
coef_lasso <- lasso_model$beta
selected_vars <- which(coef_lasso != 0)

print(selected_vars)
[1] 1 2

Step 2: Use cross-validation to select alpha

cv.glmnet provides two lambda values: lambda.min and lambda.1se. lambda.min gives the minimum mean cross-validated error, and lambda.1se is the most regularized model such that error is within one standard error of the minimum.

set.seed(123)  # For reproducibility
cv_fit <- cv.glmnet(x_matrix, y_vector, alpha = 1, type.measure = "mse", nfolds = 10)

# View the plot of lambda vs. cross-validated MSE
plot(cv_fit)


# Optimal lambda that minimizes the cross-validation error
lambda_optimal <- cv_fit$lambda.min

# Lambda that is within one standard error of the minimum
lambda_1se <- cv_fit$lambda.1se

Step 3: Post-Lasso Regression

# Fit linear model using only the selected variables
if (length(selected_vars) > 0) {
    formula <- paste("y ~", paste(names(data_frame)[-1][selected_vars], collapse = " + "))
    post_lasso_model <- lm(formula, data = data_frame)
    summary(post_lasso_model)  # Display the summary of the model
} else {
    cat("No variables were selected by the Lasso.")
}

Call:
lm(formula = formula, data = data_frame)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.3356 -0.6680  0.0048  0.6747  3.6150 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)  1.536953   0.031345   49.03   <2e-16 ***
x1           0.498642   0.003171  157.24   <2e-16 ***
x2          -0.305311   0.003115  -98.02   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.9903 on 997 degrees of freedom
Multiple R-squared:  0.9697,    Adjusted R-squared:  0.9696 
F-statistic: 1.595e+04 on 2 and 997 DF,  p-value: < 2.2e-16

Explanation:

  • Lasso Model: The glmnet function is used to fit a Lasso model. The alpha parameter is set to 1 to enforce Lasso regression (as opposed to Ridge or Elastic Net), and lambda is the regularization parameter that needs to be chosen appropriately, often via cross-validation (cv.glmnet can be used for this purpose).
  • Post-Lasso OLS: After selecting the significant predictors, a traditional OLS model is fitted using only these predictors to estimate the parameters without the bias introduced by the Lasso’s shrinkage.

Make sure to adjust lambda and other function parameters based on the specific characteristics and scale of your data. This example assumes a simple case; in practice, you might need to customize the approach further based on your dataset’s needs.

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBEYXRhIEdlbmVyYXRpbmcgUHJvY2VzcyBEZXNjcmlwdGlvbgoKIyMgTW9kZWwgU3BlY2lmaWNhdGlvbgoKVGhlIGRhdGEgZ2VuZXJhdGluZyBwcm9jZXNzIGZvciB0aGUgdmFyaWFibGUgJHkkIGlzIGRlZmluZWQgYnkgdGhlIGZvbGxvd2luZyBsaW5lYXIgbW9kZWw6CgokJCB5ID0gXGJldGFfMCArIFxiZXRhXzEgeF8xICsgXGJldGFfMiB4XzIgKyBcZXBzaWxvbiAkJAoKd2hlcmU6CgotICAgJFxiZXRhXzAsIFxiZXRhXzEsIFxiZXRhXzIkIGFyZSB0aGUgY29lZmZpY2llbnRzIG9mIHRoZSBtb2RlbC4KLSAgICR4XzEkIGFuZCAkeF8yJCBhcmUgdGhlIGNvdmFyaWF0ZXMuCi0gICAkXGVwc2lsb24kIHJlcHJlc2VudHMgdGhlIGVycm9yIHRlcm0uCgojIyMgQ292YXJpYXRlcwoKLSAgICR4XzEkIGFuZCAkeF8yJCBhcmUgYXNzdW1lZCB0byBiZSBpbmRlcGVuZGVudCByYW5kb20gdmFyaWFibGVzLgotICAgVGhlc2UgY292YXJpYXRlcyBjYW4gYmUgZ2VuZXJhdGVkIGZyb20gYW55IGRpc3RyaWJ1dGlvbiBkZWVtZWQgYXBwcm9wcmlhdGUgZm9yIHRoZSBzY2VuYXJpbyAoZS5nLiwgTm9ybWFsLCBVbmlmb3JtKS4KLSAgIEl0IGlzIGltcG9ydGFudCB0byBzcGVjaWZ5IHRoZSBkaXN0cmlidXRpb24gZnJvbSB3aGljaCAkeF8xJCBhbmQgJHhfMiQgYXJlIGRyYXduIGlmIHNpbXVsYXRpbmcgZGF0YSBmb3IgcHJhY3RpY2FsIGFwcGxpY2F0aW9ucy4KCiMjIyBFcnJvciBUZXJtCgotICAgVGhlIGVycm9yIHRlcm0gJFxlcHNpbG9uJCBpcyB0eXBpY2FsbHkgYXNzdW1lZCB0byBiZSBub3JtYWxseSBkaXN0cmlidXRlZCB3aXRoIGEgbWVhbiBvZiB6ZXJvIGFuZCBhIHNwZWNpZmllZCB2YXJpYW5jZSwgJFxzaWdtYV4yJC4KLSAgIFRoaXMgYXNzdW1wdGlvbiBhbGxvd3MgdGhlIG1vZGVsIHRvIGFjY291bnQgZm9yIHJhbmRvbSBmbHVjdHVhdGlvbnMgaW4gJHkkIHRoYXQgYXJlIG5vdCBleHBsYWluZWQgYnkgdGhlIGNvdmFyaWF0ZXMgJHhfMSQgYW5kICR4XzIkLgoKIyMjIENvZWZmaWNpZW50cwoKLSAgIFRoZSB2YWx1ZXMgb2YgJFxiZXRhXzAkLCAkXGJldGFfMSQsIGFuZCAkXGJldGFfMiQgbmVlZCB0byBiZSBzcGVjaWZpZWQuCi0gICBUaGVzZSBjb2VmZmljaWVudHMgZGV0ZXJtaW5lIHRoZSBpbXBhY3Qgb2YgdGhlIHJlc3BlY3RpdmUgY292YXJpYXRlcyBvbiB0aGUgb3V0Y29tZSB2YXJpYWJsZSAkeSQuCgojIyBFeGFtcGxlCgpJZiBvbmUgd2VyZSB0byBzaW11bGF0ZSBkYXRhIGZyb20gdGhpcyBtb2RlbDogLSBDaG9vc2Ugc3BlY2lmaWMgdmFsdWVzIGZvciAkXGJldGFfMCQsICRcYmV0YV8xJCwgYW5kICRcYmV0YV8yJCAoZS5nLiwgMSwgMC41LCBhbmQgLTAuMykuIC0gR2VuZXJhdGUgcmFuZG9tIHZhbHVlcyBmb3IgJHhfMSQgYW5kICR4XzIkIGZyb20gdGhlaXIgcmVzcGVjdGl2ZSBkaXN0cmlidXRpb25zLiAtIENhbGN1bGF0ZSAkXGVwc2lsb24kIGFzIGEgcmFuZG9tIGRyYXcgZnJvbSBhIE5vcm1hbCBkaXN0cmlidXRpb24gd2l0aCBtZWFuIDAgYW5kIGEgc3BlY2lmaWMgdmFyaWFuY2UuIC0gQ29tcHV0ZSAkeSQgZm9yIGVhY2ggc2V0IG9mIGNvdmFyaWF0ZSB2YWx1ZXMgdXNpbmcgdGhlIHNwZWNpZmllZCBtb2RlbC4KCmBgYHtyfQojIFNldCBzZWVkIGZvciByZXByb2R1Y2liaWxpdHkKc2V0LnNlZWQoMTIzKQoKIyBTZXQgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMKbiA8LSAxMDAKCiMgU2V0IHRoZSBudW1iZXIgb2YgY292YXJpYXRlcwpLIDwtIDUKCiMgR2VuZXJhdGUgY292YXJpYXRlcwpYIDwtIG1hdHJpeChybm9ybShuICogSyksIG4sIEspICAjIEdlbmVyYXRlIGEgbiB4IEsgbWF0cml4IG9mIHJhbmRvbSBub3JtYWwgdmFsdWVzCgojIFNwZWNpZnkgY29lZmZpY2llbnRzIGZvciBlYWNoIGNvdmFyaWF0ZQpiZXRhcyA8LSBjKDAuNSwgLTAuMykgICMgRXhhbXBsZSB2YWx1ZXMgZm9yIGJldGFfMSBhbmQgYmV0YV8yCgojIEdlbmVyYXRlIHRoZSBlcnJvciB0ZXJtCmVwc2lsb24gPC0gcm5vcm0obiwgbWVhbiA9IDAsIHNkID0gMSkKCiMgSW50ZXJjZXB0IChiZXRhXzApCmJldGFfMCA8LSAxLjUKCiMgQ2FsY3VsYXRlIHRoZSByZXNwb25zZSB2YXJpYWJsZSB5CnkgPC0gYmV0YV8wICsgWFssMToyXSAlKiUgYmV0YXMgKyBlcHNpbG9uCgojIENyZWF0ZSBhIGRhdGEgZnJhbWUKZGF0YSA8LSBkYXRhLmZyYW1lKHkgPSB5LCBYKQoKIyBSZW5hbWUgY29sdW1ucyBhcHByb3ByaWF0ZWx5Cm5hbWVzKGRhdGEpIDwtIGMoInkiLCBwYXN0ZSgieCIsIDE6Sywgc2VwID0gIiIpKQoKIyBQcmludCB0aGUgZmlyc3QgZmV3IHJvd3Mgb2YgdGhlIGRhdGEKaGVhZChkYXRhKQoKYGBgCgojIyMgTm90ZXM6CgotICAgVGhlIG1hcmtkb3duIGZvcm1hdCBpcyBzdHJ1Y3R1cmVkIHRvIHByb3ZpZGUgY2xlYXIgZG9jdW1lbnRhdGlvbiBmb3IgdXNlcnMgb2YgdGhlIGBnZW5lcmF0ZV9saW5lYXJfZGF0YWAgZnVuY3Rpb24uIEl0IGluY2x1ZGVzIGhlYWRpbmdzLCBwYXJhbWV0ZXIgZGVzY3JpcHRpb25zLCBhbmQgYSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiB0aGUgb3V0cHV0IGFuZCBtb2RlbCBiZWhhdmlvci4KCi0gICBDb2RlIGJsb2NrcyB3aXRoaW4gbWFya2Rvd24gYXJlIGRlbGluZWF0ZWQgYnkgdHJpcGxlIGJhY2t0aWNrcywgd2hpY2ggbWlnaHQgbm90IHJlbmRlciBjb3JyZWN0bHkgaW4gc29tZSBwbGFpbiB0ZXh0IGVudmlyb25tZW50cyBidXQgd2lsbCB3b3JrIGFzIGludGVuZGVkIGluIG1vc3QgbWFya2Rvd24gdmlld2VycyBhbmQgR2l0SHViIHJlcG9zaXRvcmllcy4KCi0gICBFbnN1cmUgdG8gYWRqdXN0IGFueSBwYXJ0IG9mIHRoZSBkb2N1bWVudGF0aW9uIHRvIGJldHRlciBmaXQgdGhlIGFjdHVhbCBmdW5jdGlvbmFsaXR5IGFuZCBwYXJhbWV0ZXJzIG9mIHlvdXIgZnVuY3Rpb24gYXMgaW1wbGVtZW50ZWQgaW4gUi4KCmBgYHtyfQoKZ2VuZXJhdGVfbGluZWFyX2RhdGEgPC0gZnVuY3Rpb24obiA9IDEwMCwgSyA9IDUsIEtfZWZmID0gMiwgYmV0YXMgPSBjKDUsIC0zKSwgYmV0YV8wID0gMS41KSB7CiAgIyBTZXQgc2VlZCBmb3IgcmVwcm9kdWNpYmlsaXR5CiAgc2V0LnNlZWQoMTIzKQoKICAjIEdlbmVyYXRlIGNvdmFyaWF0ZXMKICBYIDwtIDEwICogbWF0cml4KHJub3JtKG4gKiBLKSwgbiwgSykgICMgR2VuZXJhdGUgYSBuIHggSyBtYXRyaXggb2YgcmFuZG9tIG5vcm1hbCB2YWx1ZXMKCiAgIyBHZW5lcmF0ZSB0aGUgZXJyb3IgdGVybQogIGVwc2lsb24gPC0gcm5vcm0obiwgbWVhbiA9IDAsIHNkID0gMSkKCiAgIyBDYWxjdWxhdGUgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIHkKICB5IDwtIGJldGFfMCArIFhbLCAxOktfZWZmXSAlKiUgYmV0YXMgKyBlcHNpbG9uCgogICMgQ3JlYXRlIGEgZGF0YSBmcmFtZQogIGRhdGEgPC0gZGF0YS5mcmFtZSh5ID0geSwgWCkKCiAgIyBSZW5hbWUgY29sdW1ucyBhcHByb3ByaWF0ZWx5CiAgbmFtZXMoZGF0YSkgPC0gYygieSIsIHBhc3RlKCJ4IiwgMTpLLCBzZXAgPSAiIikpCgogIHJldHVybihkYXRhKQp9CgojIEV4YW1wbGUgb2YgdXNpbmcgdGhlIGZ1bmN0aW9uCmRhdGFfZnJhbWUgPC0gZ2VuZXJhdGVfbGluZWFyX2RhdGEobiA9IDEwMCwgSyA9IDUsIEtfZWZmID0gMikKaGVhZChkYXRhX2ZyYW1lKQoKYGBgCgojIyBQb3N0IExhc3NvCgpUbyBwZXJmb3JtIHBvc3QtTGFzc28gcmVncmVzc2lvbiBvbiBhIGRhdGFzZXQgaW4gUiwgeW91IGdlbmVyYWxseSBmb2xsb3cgYSB0d28tc3RlcCBwcm9jZXNzOgoKMS4gICoqTGFzc28gUmVncmVzc2lvbioqOiBGaXQgYSBMYXNzbyBtb2RlbCB0byBzZWxlY3Qgc2lnbmlmaWNhbnQgdmFyaWFibGVzIChjb3ZhcmlhdGVzKSBmcm9tIGEgcG90ZW50aWFsbHkgbGFyZ2Ugc2V0IG9mIHByZWRpY3RvcnMuCjIuICAqKlBvc3QtTGFzc28gUmVncmVzc2lvbioqOiBVc2UgdGhlIHNlbGVjdGVkIHZhcmlhYmxlcyB0byBmaXQgYSB0cmFkaXRpb25hbCBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbC4KClRoaXMgYXBwcm9hY2ggaXMgYmVuZWZpY2lhbCB3aGVuIGRlYWxpbmcgd2l0aCBoaWdoLWRpbWVuc2lvbmFsIGRhdGEsIGFsbG93aW5nIGZvciB2YXJpYWJsZSBzZWxlY3Rpb24gdGhyb3VnaCB0aGUgTGFzc28gYW5kIHRoZW4gdW5iaWFzZWQgZXN0aW1hdGlvbiB1c2luZyBPTFMgb24gdGhlIHNlbGVjdGVkIHZhcmlhYmxlcy4KClBlcmZvcm0gcG9zdC1MYXNzbyByZWdyZXNzaW9uIGluIFIgdXNpbmcgdGhlIGBnbG1uZXRgIHBhY2thZ2UgZm9yIHRoZSBMYXNzbyBzdGVwIGFuZCB0aGUgc3RhbmRhcmQgYGxtYCBmdW5jdGlvbiBmb3IgdGhlIE9MUyBzdGVwLiBGaXJzdCwgZW5zdXJlIHlvdSBoYXZlIHRoZSBuZWNlc3NhcnkgcGFja2FnZToKCmBgYHtyfQppZiAoIXJlcXVpcmUoZ2xtbmV0KSkgewogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2xtbmV0IikKICAgIGxpYnJhcnkoZ2xtbmV0KQp9CmBgYAoKIyMjIFN0ZXAgMDogU2FtcGxlIERhdGEgUHJlcGFyYXRpb24KCkxldCdzIGFzc3VtZSB5b3UgaGF2ZSBhIGRhdGFzZXQgYGRhdGFfZnJhbWVgIGZyb20gdGhlIHByZXZpb3VzIGV4YW1wbGUgd2l0aCBvbmUgcmVzcG9uc2UgdmFyaWFibGUgYHlgIGFuZCBtdWx0aXBsZSBwcmVkaWN0b3JzIGB4MSwgeDIsIC4uLiwgeEtgLiBIZXJlJ3MgYSBicmllZiBzZXR1cDoKCmBgYHtyfQoKIyBTYW1wbGUgRGF0YSBHZW5lcmF0aW9uIChSZXBlYXRpbmcgaGVyZSBmb3IgY29tcGxldGVuZXNzKQpzZXQuc2VlZCgxMjMpCm4gPC0gMTAwMApLIDwtIDUKWCA8LSBtYXRyaXgocm5vcm0obiAqIEspLCBuLCBLKQpkYXRhX2ZyYW1lIDwtIGdlbmVyYXRlX2xpbmVhcl9kYXRhKG4gPSBuLCBLID0gSywgS19lZmYgPSAyLCBiZXRhcyA8LSBjKDAuNSwgLTAuMykpCgojIHByaW50IHRoZSBmaXJzdCBmZXcgcm93cyBvZiB0aGUgZGF0YV9mcmFtZQpwcmludChoZWFkKGRhdGFfZnJhbWUpKQoKIyBwcmludCB0aGUgaGVhZGVycwpwcmludChjb2xuYW1lcyhkYXRhX2ZyYW1lKSkKYGBgCgojIyMgU3RlcCAxOiBMYXNzbyBSZWdyZXNzaW9uCgpgYGB7cn0KIyBGaXR0aW5nIExhc3NvIG1vZGVsCnhfbWF0cml4IDwtIGFzLm1hdHJpeChkYXRhX2ZyYW1lWywgLTFdKSAgIyBFeGNsdWRpbmcgdGhlIHJlc3BvbnNlIHZhcmlhYmxlICd5Jwp5X3ZlY3RvciA8LSBkYXRhX2ZyYW1lJHkKCiMgVXNpbmcgZ2xtbmV0IGZvciBMYXNzbwpsYXNzb19tb2RlbCA8LSBnbG1uZXQoeF9tYXRyaXgsIHlfdmVjdG9yLCBhbHBoYSA9IDEsIGxhbWJkYSA9IDAuMSkgICMgYWxwaGEgPSAxIGZvciBMYXNzbzsgYWRqdXN0IGxhbWJkYSBhcyBuZWVkZWQKCiMgSWRlbnRpZnkgbm9uLXplcm8gY29lZmZpY2llbnRzIChzZWxlY3RlZCB2YXJpYWJsZXMpCmNvZWZfbGFzc28gPC0gbGFzc29fbW9kZWwkYmV0YQpzZWxlY3RlZF92YXJzIDwtIHdoaWNoKGNvZWZfbGFzc28gIT0gMCkKCnByaW50KHNlbGVjdGVkX3ZhcnMpCmBgYAoKIyMjIFN0ZXAgMjogVXNlIGNyb3NzLXZhbGlkYXRpb24gdG8gc2VsZWN0IGFscGhhCgpgY3YuZ2xtbmV0YCBwcm92aWRlcyB0d28gbGFtYmRhIHZhbHVlczogYGxhbWJkYS5taW5gIGFuZCBgbGFtYmRhLjFzZWAuIGBsYW1iZGEubWluYCBnaXZlcyB0aGUgbWluaW11bSBtZWFuIGNyb3NzLXZhbGlkYXRlZCBlcnJvciwgYW5kIGBsYW1iZGEuMXNlYCBpcyB0aGUgbW9zdCByZWd1bGFyaXplZCBtb2RlbCBzdWNoIHRoYXQgZXJyb3IgaXMgd2l0aGluIG9uZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgbWluaW11bS4KCmBgYHtyfQpzZXQuc2VlZCgxMjMpICAjIEZvciByZXByb2R1Y2liaWxpdHkKY3ZfZml0IDwtIGN2LmdsbW5ldCh4X21hdHJpeCwgeV92ZWN0b3IsIGFscGhhID0gMSwgdHlwZS5tZWFzdXJlID0gIm1zZSIsIG5mb2xkcyA9IDEwKQoKIyBWaWV3IHRoZSBwbG90IG9mIGxhbWJkYSB2cy4gY3Jvc3MtdmFsaWRhdGVkIE1TRQpwbG90KGN2X2ZpdCkKCiMgT3B0aW1hbCBsYW1iZGEgdGhhdCBtaW5pbWl6ZXMgdGhlIGNyb3NzLXZhbGlkYXRpb24gZXJyb3IKbGFtYmRhX29wdGltYWwgPC0gY3ZfZml0JGxhbWJkYS5taW4KCiMgTGFtYmRhIHRoYXQgaXMgd2l0aGluIG9uZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgbWluaW11bQpsYW1iZGFfMXNlIDwtIGN2X2ZpdCRsYW1iZGEuMXNlCmBgYAoKIyMjIFN0ZXAgMzogUG9zdC1MYXNzbyBSZWdyZXNzaW9uCgpgYGB7cn0KIyBGaXQgbGluZWFyIG1vZGVsIHVzaW5nIG9ubHkgdGhlIHNlbGVjdGVkIHZhcmlhYmxlcwppZiAobGVuZ3RoKHNlbGVjdGVkX3ZhcnMpID4gMCkgewogICAgZm9ybXVsYSA8LSBwYXN0ZSgieSB+IiwgcGFzdGUobmFtZXMoZGF0YV9mcmFtZSlbLTFdW3NlbGVjdGVkX3ZhcnNdLCBjb2xsYXBzZSA9ICIgKyAiKSkKICAgIHBvc3RfbGFzc29fbW9kZWwgPC0gbG0oZm9ybXVsYSwgZGF0YSA9IGRhdGFfZnJhbWUpCiAgICBzdW1tYXJ5KHBvc3RfbGFzc29fbW9kZWwpICAjIERpc3BsYXkgdGhlIHN1bW1hcnkgb2YgdGhlIG1vZGVsCn0gZWxzZSB7CiAgICBjYXQoIk5vIHZhcmlhYmxlcyB3ZXJlIHNlbGVjdGVkIGJ5IHRoZSBMYXNzby4iKQp9CmBgYAoKIyMjIEV4cGxhbmF0aW9uOgoKLSAgICoqTGFzc28gTW9kZWwqKjogVGhlIGBnbG1uZXRgIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZml0IGEgTGFzc28gbW9kZWwuIFRoZSBgYWxwaGFgIHBhcmFtZXRlciBpcyBzZXQgdG8gMSB0byBlbmZvcmNlIExhc3NvIHJlZ3Jlc3Npb24gKGFzIG9wcG9zZWQgdG8gUmlkZ2Ugb3IgRWxhc3RpYyBOZXQpLCBhbmQgYGxhbWJkYWAgaXMgdGhlIHJlZ3VsYXJpemF0aW9uIHBhcmFtZXRlciB0aGF0IG5lZWRzIHRvIGJlIGNob3NlbiBhcHByb3ByaWF0ZWx5LCBvZnRlbiB2aWEgY3Jvc3MtdmFsaWRhdGlvbiAoYGN2LmdsbW5ldGAgY2FuIGJlIHVzZWQgZm9yIHRoaXMgcHVycG9zZSkuCi0gICAqKlBvc3QtTGFzc28gT0xTKio6IEFmdGVyIHNlbGVjdGluZyB0aGUgc2lnbmlmaWNhbnQgcHJlZGljdG9ycywgYSB0cmFkaXRpb25hbCBPTFMgbW9kZWwgaXMgZml0dGVkIHVzaW5nIG9ubHkgdGhlc2UgcHJlZGljdG9ycyB0byBlc3RpbWF0ZSB0aGUgcGFyYW1ldGVycyB3aXRob3V0IHRoZSBiaWFzIGludHJvZHVjZWQgYnkgdGhlIExhc3NvJ3Mgc2hyaW5rYWdlLgoKTWFrZSBzdXJlIHRvIGFkanVzdCBgbGFtYmRhYCBhbmQgb3RoZXIgZnVuY3Rpb24gcGFyYW1ldGVycyBiYXNlZCBvbiB0aGUgc3BlY2lmaWMgY2hhcmFjdGVyaXN0aWNzIGFuZCBzY2FsZSBvZiB5b3VyIGRhdGEuIFRoaXMgZXhhbXBsZSBhc3N1bWVzIGEgc2ltcGxlIGNhc2U7IGluIHByYWN0aWNlLCB5b3UgbWlnaHQgbmVlZCB0byBjdXN0b21pemUgdGhlIGFwcHJvYWNoIGZ1cnRoZXIgYmFzZWQgb24geW91ciBkYXRhc2V0J3MgbmVlZHMuCg==