The Maximum Likelihood Estimation (MLE) method is a
statistical technique used for estimating the parameters of a
probability distribution or statistical model that best explain a given
set of data. The idea behind MLE is to find the parameter
values that maximize the likelihood function, which represents the
probability of observing the given data under certain parameter
values.
MLE is often used in statistical modeling and hypothesis testing to
estimate parameters such as the mean, variance, or coefficients in a
model. It’s commonly applied in various fields, including economics,
biology, machine learning, and more.
How MLE Works:
Given a set of observations and assuming that these observations come
from a certain distribution (e.g., normal distribution), MLE aims to
find the parameter values (such as mean and standard deviation in the
case of the normal distribution) that maximize the probability
(likelihood) of observing the data. The likelihood function is usually
expressed in terms of the parameters of the distribution.
For example: - For a normal distribution, MLE would estimate the mean
(μ) and standard deviation (σ). - For logistic regression, MLE estimates
the coefficients (betas) that best fit the model.
Advantages:
- Provides efficient and unbiased estimates when the model assumptions
are correct.
- Can handle large sample sizes effectively.
- Works for a wide range of statistical models.
Disadvantages:
- MLE can be sensitive to the choice of the initial values in some
models, and it may converge to a local maximum rather than a global
maximum.
- It requires assumptions about the distribution of the data.
- The likelihood function can be complex and difficult to optimize for
certain models.
Applications:
- Estimating parameters in probability distributions (e.g., normal,
Poisson).
- Used in logistic regression and other generalized linear
models.
- Widely used in machine learning for fitting models such as
classification and regression models.
Pros:
- Provides parameter estimates with desirable properties, such as
asymptotic consistency and efficiency.
- Works well for complex models.
- Can be extended to likelihood ratio tests, which help compare nested
models.
Cons:
- Requires accurate assumptions about the distribution of the
data.
- May not perform well in the presence of small sample sizes or
outliers.
- The likelihood function can be computationally expensive to
optimize.
Maximum Likelihood Estimation (MLE) Example in
R
In this example, we’ll use the
fitdistrplus
package in R to estimate the
parameters of a normal distribution using MLE. We will create a dataset
that follows a normal distribution and then use MLE to estimate the mean
and standard deviation.
Step 1: Install and Load Required Libraries
# Install the required package (if not already installed)
install.packages("fitdistrplus")
# Load the package
library(fitdistrplus)
Step 2: Create the Data
We will generate a dataset that follows a normal distribution with a
known mean (μ = 5) and standard deviation (σ = 2).
# Generate a dataset of 100 observations from a normal distribution
set.seed(123)
data <- rnorm(100, mean = 5, sd = 2)
# Display the first few values
head(data)
Step 3: Fit the Distribution Using MLE
We can use the fitdist()
function from the
fitdistrplus
package to estimate the
parameters of the normal distribution.
# Fit the normal distribution using MLE
fit <- fitdist(data, "norm")
# Display the results
summary(fit)
Output:
Fitting of the distribution ' norm ' by maximum likelihood
Parameters:
estimate Std. Error
mean 5.147177 0.1938262
sd 1.960458 0.1369752
Interpretation:
- Mean (estimate = 5.147): The estimated mean of the
normal distribution is approximately 5.15.
- Standard Deviation (estimate = 1.96): The estimated
standard deviation is approximately 1.96.
The standard errors for these estimates are also
provided, indicating the precision of the MLE estimates. The estimates
are very close to the true values of μ = 5 and
σ = 2, which were used to generate the data.
Logistic Regression Example Using MLE
MLE is also widely used in logistic regression, where the goal is to
model a binary outcome (e.g., success/failure) using one or more
predictor variables. Logistic regression estimates the coefficients
(betas) of the predictors by maximizing the likelihood of observing the
data.
In R, we can perform logistic regression using the glm()
function with the logit link.
Step 1: Create the Data
Let’s simulate some binary outcome data to illustrate logistic
regression.
# Simulate data: 100 observations, binary outcome (0 or 1)
set.seed(123)
n <- 100
x <- rnorm(n) # Predictor variable
p <- 1 / (1 + exp(-x)) # Probability (logistic function)
y <- rbinom(n, 1, p) # Binary outcome (0 or 1)
# Combine into a data frame
logit_data <- data.frame(x = x, y = y)
head(logit_data)
Step 2: Fit the Logistic Regression Model
Using MLE, we can estimate the coefficients for the logistic
regression model using the glm()
function.
# Fit logistic regression model
logit_model <- glm(y ~ x, data = logit_data, family = binomial(link = "logit"))
# Display the summary of the model
summary(logit_model)
Output (simplified):
Call:
glm(formula = y ~ x, family = binomial(link = "logit"), data = logit_data)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.0295 0.2178 -0.136 0.892
x 2.5521 0.6716 3.801 0.000144 ***
Interpretation:
- Intercept (Estimate = -0.03): The intercept term
represents the log-odds of the outcome when the predictor variable is
0.
- Coefficient for x (Estimate = 2.55): The estimated
coefficient for the predictor variable x is 2.55. This means that for
each one-unit increase in x, the log-odds of the outcome (y = 1)
increase by approximately 2.55.
The p-value (Pr(>|z|) = 0.000144) indicates that
the predictor variable x is statistically significant
in explaining the outcome.
Log-Likelihood:
Logistic regression uses MLE to estimate the parameters. The
log-likelihood of the model can be extracted as follows:
# Extract log-likelihood of the model
logLik(logit_model)
Likelihood Ratio Test
A common use of MLE is in likelihood ratio tests
(LRT). This test compares the fit of two nested models to
determine whether adding additional parameters significantly improves
the model.
Example:
We might compare a null model (with only the
intercept) to a full model (with the predictor
variable).
# Null model (intercept only)
null_model <- glm(y ~ 1, data = logit_data, family = binomial(link = "logit"))
# Likelihood ratio test
anova(null_model, logit_model, test = "LRT")
Output:
Analysis of Deviance Table
Model 1: y ~ 1
Model 2: y ~ x
Resid. Df Resid. Dev Df Deviance Pr(>Chi)
1 99 138.63
2 98 99.69 1 38.944 4.21e-10 ***
Interpretation:
- The p-value (4.21e-10) from the likelihood ratio
test suggests that adding the predictor variable x
significantly improves the model fit compared to the null model.
Summary:
The Maximum Likelihood Estimation (MLE) method is a
powerful tool for estimating parameters in statistical models. It is
widely used in fields like statistics, machine learning, and
econometrics. MLE can estimate the parameters of probability
distributions (like the normal distribution) or the coefficients of
regression models (like logistic regression). In R, the
fitdistrplus
package can be used for distribution fitting,
and glm()
applies MLE in generalized linear models.
LS0tDQp0aXRsZTogIk1heGltdW0gTGlrZWxpaG9vZCBUZXN0Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KVGhlICoqTWF4aW11bSBMaWtlbGlob29kIEVzdGltYXRpb24gKE1MRSkqKiBtZXRob2QgaXMgYSBzdGF0aXN0aWNhbCB0ZWNobmlxdWUgKip1c2VkIGZvciBlc3RpbWF0aW5nIHRoZSBwYXJhbWV0ZXJzIG9mIGEgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIG9yIHN0YXRpc3RpY2FsIG1vZGVsIHRoYXQgYmVzdCBleHBsYWluIGEgZ2l2ZW4gc2V0IG9mIGRhdGEqKi4gDQpUaGUgaWRlYSBiZWhpbmQgTUxFIGlzIHRvIGZpbmQgdGhlIHBhcmFtZXRlciB2YWx1ZXMgdGhhdCBtYXhpbWl6ZSB0aGUgbGlrZWxpaG9vZCBmdW5jdGlvbiwgd2hpY2ggcmVwcmVzZW50cyB0aGUgcHJvYmFiaWxpdHkgb2Ygb2JzZXJ2aW5nIHRoZSBnaXZlbiBkYXRhIHVuZGVyIGNlcnRhaW4gcGFyYW1ldGVyIHZhbHVlcy4NCg0KTUxFIGlzIG9mdGVuIHVzZWQgaW4gc3RhdGlzdGljYWwgbW9kZWxpbmcgYW5kIGh5cG90aGVzaXMgdGVzdGluZyB0byBlc3RpbWF0ZSBwYXJhbWV0ZXJzIHN1Y2ggYXMgdGhlIG1lYW4sIHZhcmlhbmNlLCBvciBjb2VmZmljaWVudHMgaW4gYSBtb2RlbC4gSXQncyBjb21tb25seSBhcHBsaWVkIGluIHZhcmlvdXMgZmllbGRzLCBpbmNsdWRpbmcgZWNvbm9taWNzLCBiaW9sb2d5LCBtYWNoaW5lIGxlYXJuaW5nLCBhbmQgbW9yZS4NCg0KIyMjIyAqKkhvdyBNTEUgV29ya3MqKjoNCkdpdmVuIGEgc2V0IG9mIG9ic2VydmF0aW9ucyBhbmQgYXNzdW1pbmcgdGhhdCB0aGVzZSBvYnNlcnZhdGlvbnMgY29tZSBmcm9tIGEgY2VydGFpbiBkaXN0cmlidXRpb24gKGUuZy4sIG5vcm1hbCBkaXN0cmlidXRpb24pLCBNTEUgYWltcyB0byBmaW5kIHRoZSBwYXJhbWV0ZXIgdmFsdWVzIChzdWNoIGFzIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBpbiB0aGUgY2FzZSBvZiB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbikgdGhhdCBtYXhpbWl6ZSB0aGUgcHJvYmFiaWxpdHkgKGxpa2VsaWhvb2QpIG9mIG9ic2VydmluZyB0aGUgZGF0YS4gVGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gaXMgdXN1YWxseSBleHByZXNzZWQgaW4gdGVybXMgb2YgdGhlIHBhcmFtZXRlcnMgb2YgdGhlIGRpc3RyaWJ1dGlvbi4NCg0KRm9yIGV4YW1wbGU6DQotIEZvciBhIG5vcm1hbCBkaXN0cmlidXRpb24sIE1MRSB3b3VsZCBlc3RpbWF0ZSB0aGUgbWVhbiAozrwpIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gKM+DKS4NCi0gRm9yIGxvZ2lzdGljIHJlZ3Jlc3Npb24sIE1MRSBlc3RpbWF0ZXMgdGhlIGNvZWZmaWNpZW50cyAoYmV0YXMpIHRoYXQgYmVzdCBmaXQgdGhlIG1vZGVsLg0KDQojIyMjICoqQWR2YW50YWdlcyoqOg0KLSBQcm92aWRlcyBlZmZpY2llbnQgYW5kIHVuYmlhc2VkIGVzdGltYXRlcyB3aGVuIHRoZSBtb2RlbCBhc3N1bXB0aW9ucyBhcmUgY29ycmVjdC4NCi0gQ2FuIGhhbmRsZSBsYXJnZSBzYW1wbGUgc2l6ZXMgZWZmZWN0aXZlbHkuDQotIFdvcmtzIGZvciBhIHdpZGUgcmFuZ2Ugb2Ygc3RhdGlzdGljYWwgbW9kZWxzLg0KDQojIyMjICoqRGlzYWR2YW50YWdlcyoqOg0KLSBNTEUgY2FuIGJlIHNlbnNpdGl2ZSB0byB0aGUgY2hvaWNlIG9mIHRoZSBpbml0aWFsIHZhbHVlcyBpbiBzb21lIG1vZGVscywgYW5kIGl0IG1heSBjb252ZXJnZSB0byBhIGxvY2FsIG1heGltdW0gcmF0aGVyIHRoYW4gYSBnbG9iYWwgbWF4aW11bS4NCi0gSXQgcmVxdWlyZXMgYXNzdW1wdGlvbnMgYWJvdXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGF0YS4NCi0gVGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gY2FuIGJlIGNvbXBsZXggYW5kIGRpZmZpY3VsdCB0byBvcHRpbWl6ZSBmb3IgY2VydGFpbiBtb2RlbHMuDQoNCiMjIyMgKipBcHBsaWNhdGlvbnMqKjoNCi0gRXN0aW1hdGluZyBwYXJhbWV0ZXJzIGluIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbnMgKGUuZy4sIG5vcm1hbCwgUG9pc3NvbikuDQotIFVzZWQgaW4gbG9naXN0aWMgcmVncmVzc2lvbiBhbmQgb3RoZXIgZ2VuZXJhbGl6ZWQgbGluZWFyIG1vZGVscy4NCi0gV2lkZWx5IHVzZWQgaW4gbWFjaGluZSBsZWFybmluZyBmb3IgZml0dGluZyBtb2RlbHMgc3VjaCBhcyBjbGFzc2lmaWNhdGlvbiBhbmQgcmVncmVzc2lvbiBtb2RlbHMuDQoNCiMjIyMgKipQcm9zKio6DQotIFByb3ZpZGVzIHBhcmFtZXRlciBlc3RpbWF0ZXMgd2l0aCBkZXNpcmFibGUgcHJvcGVydGllcywgc3VjaCBhcyBhc3ltcHRvdGljIGNvbnNpc3RlbmN5IGFuZCBlZmZpY2llbmN5Lg0KLSBXb3JrcyB3ZWxsIGZvciBjb21wbGV4IG1vZGVscy4NCi0gQ2FuIGJlIGV4dGVuZGVkIHRvIGxpa2VsaWhvb2QgcmF0aW8gdGVzdHMsIHdoaWNoIGhlbHAgY29tcGFyZSBuZXN0ZWQgbW9kZWxzLg0KDQojIyMjICoqQ29ucyoqOg0KLSBSZXF1aXJlcyBhY2N1cmF0ZSBhc3N1bXB0aW9ucyBhYm91dCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBkYXRhLg0KLSBNYXkgbm90IHBlcmZvcm0gd2VsbCBpbiB0aGUgcHJlc2VuY2Ugb2Ygc21hbGwgc2FtcGxlIHNpemVzIG9yIG91dGxpZXJzLg0KLSBUaGUgbGlrZWxpaG9vZCBmdW5jdGlvbiBjYW4gYmUgY29tcHV0YXRpb25hbGx5IGV4cGVuc2l2ZSB0byBvcHRpbWl6ZS4NCg0KLS0tDQoNCiMjIyAqKk1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0aW9uIChNTEUpIEV4YW1wbGUgaW4gUioqDQoNCkluIHRoaXMgZXhhbXBsZSwgd2XigJlsbCB1c2UgdGhlICoqYGZpdGRpc3RycGx1c2AqKiBwYWNrYWdlIGluIFIgdG8gZXN0aW1hdGUgdGhlIHBhcmFtZXRlcnMgb2YgYSBub3JtYWwgZGlzdHJpYnV0aW9uIHVzaW5nIE1MRS4gV2Ugd2lsbCBjcmVhdGUgYSBkYXRhc2V0IHRoYXQgZm9sbG93cyBhIG5vcm1hbCBkaXN0cmlidXRpb24gYW5kIHRoZW4gdXNlIE1MRSB0byBlc3RpbWF0ZSB0aGUgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uLg0KDQojIyMjICoqU3RlcCAxOiBJbnN0YWxsIGFuZCBMb2FkIFJlcXVpcmVkIExpYnJhcmllcyoqDQoNCmBgYFINCiMgSW5zdGFsbCB0aGUgcmVxdWlyZWQgcGFja2FnZSAoaWYgbm90IGFscmVhZHkgaW5zdGFsbGVkKQ0KaW5zdGFsbC5wYWNrYWdlcygiZml0ZGlzdHJwbHVzIikNCg0KIyBMb2FkIHRoZSBwYWNrYWdlDQpsaWJyYXJ5KGZpdGRpc3RycGx1cykNCmBgYA0KDQojIyMjICoqU3RlcCAyOiBDcmVhdGUgdGhlIERhdGEqKg0KDQpXZSB3aWxsIGdlbmVyYXRlIGEgZGF0YXNldCB0aGF0IGZvbGxvd3MgYSBub3JtYWwgZGlzdHJpYnV0aW9uIHdpdGggYSBrbm93biBtZWFuICjOvCA9IDUpIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gKM+DID0gMikuDQoNCmBgYFINCiMgR2VuZXJhdGUgYSBkYXRhc2V0IG9mIDEwMCBvYnNlcnZhdGlvbnMgZnJvbSBhIG5vcm1hbCBkaXN0cmlidXRpb24NCnNldC5zZWVkKDEyMykNCmRhdGEgPC0gcm5vcm0oMTAwLCBtZWFuID0gNSwgc2QgPSAyKQ0KDQojIERpc3BsYXkgdGhlIGZpcnN0IGZldyB2YWx1ZXMNCmhlYWQoZGF0YSkNCmBgYA0KDQojIyMjICoqU3RlcCAzOiBGaXQgdGhlIERpc3RyaWJ1dGlvbiBVc2luZyBNTEUqKg0KDQpXZSBjYW4gdXNlIHRoZSBgZml0ZGlzdCgpYCBmdW5jdGlvbiBmcm9tIHRoZSAqKmBmaXRkaXN0cnBsdXNgKiogcGFja2FnZSB0byBlc3RpbWF0ZSB0aGUgcGFyYW1ldGVycyBvZiB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KYGBgUg0KIyBGaXQgdGhlIG5vcm1hbCBkaXN0cmlidXRpb24gdXNpbmcgTUxFDQpmaXQgPC0gZml0ZGlzdChkYXRhLCAibm9ybSIpDQoNCiMgRGlzcGxheSB0aGUgcmVzdWx0cw0Kc3VtbWFyeShmaXQpDQpgYGANCg0KIyMjIyAqKk91dHB1dCoqOg0KYGBgDQpGaXR0aW5nIG9mIHRoZSBkaXN0cmlidXRpb24gJyBub3JtICcgYnkgbWF4aW11bSBsaWtlbGlob29kIA0KUGFyYW1ldGVyczoNCiAgICAgICAgIGVzdGltYXRlICBTdGQuIEVycm9yDQptZWFuICAgICA1LjE0NzE3NyAgMC4xOTM4MjYyDQpzZCAgICAgICAxLjk2MDQ1OCAgMC4xMzY5NzUyDQpgYGANCg0KIyMjIyAqKkludGVycHJldGF0aW9uKio6DQotICoqTWVhbiAoZXN0aW1hdGUgPSA1LjE0NykqKjogVGhlIGVzdGltYXRlZCBtZWFuIG9mIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIGlzIGFwcHJveGltYXRlbHkgNS4xNS4NCi0gKipTdGFuZGFyZCBEZXZpYXRpb24gKGVzdGltYXRlID0gMS45NikqKjogVGhlIGVzdGltYXRlZCBzdGFuZGFyZCBkZXZpYXRpb24gaXMgYXBwcm94aW1hdGVseSAxLjk2Lg0KDQpUaGUgKipzdGFuZGFyZCBlcnJvcnMqKiBmb3IgdGhlc2UgZXN0aW1hdGVzIGFyZSBhbHNvIHByb3ZpZGVkLCBpbmRpY2F0aW5nIHRoZSBwcmVjaXNpb24gb2YgdGhlIE1MRSBlc3RpbWF0ZXMuIFRoZSBlc3RpbWF0ZXMgYXJlIHZlcnkgY2xvc2UgdG8gdGhlIHRydWUgdmFsdWVzIG9mICoqzrwgPSA1KiogYW5kICoqz4MgPSAyKiosIHdoaWNoIHdlcmUgdXNlZCB0byBnZW5lcmF0ZSB0aGUgZGF0YS4NCg0KLS0tDQoNCiMjIyAqKkxvZ2lzdGljIFJlZ3Jlc3Npb24gRXhhbXBsZSBVc2luZyBNTEUqKg0KDQpNTEUgaXMgYWxzbyB3aWRlbHkgdXNlZCBpbiBsb2dpc3RpYyByZWdyZXNzaW9uLCB3aGVyZSB0aGUgZ29hbCBpcyB0byBtb2RlbCBhIGJpbmFyeSBvdXRjb21lIChlLmcuLCBzdWNjZXNzL2ZhaWx1cmUpIHVzaW5nIG9uZSBvciBtb3JlIHByZWRpY3RvciB2YXJpYWJsZXMuIExvZ2lzdGljIHJlZ3Jlc3Npb24gZXN0aW1hdGVzIHRoZSBjb2VmZmljaWVudHMgKGJldGFzKSBvZiB0aGUgcHJlZGljdG9ycyBieSBtYXhpbWl6aW5nIHRoZSBsaWtlbGlob29kIG9mIG9ic2VydmluZyB0aGUgZGF0YS4NCg0KSW4gUiwgd2UgY2FuIHBlcmZvcm0gbG9naXN0aWMgcmVncmVzc2lvbiB1c2luZyB0aGUgYGdsbSgpYCBmdW5jdGlvbiB3aXRoIHRoZSAqKmxvZ2l0IGxpbmsqKi4NCg0KIyMjIyAqKlN0ZXAgMTogQ3JlYXRlIHRoZSBEYXRhKioNCg0KTGV0J3Mgc2ltdWxhdGUgc29tZSBiaW5hcnkgb3V0Y29tZSBkYXRhIHRvIGlsbHVzdHJhdGUgbG9naXN0aWMgcmVncmVzc2lvbi4NCg0KYGBgUg0KIyBTaW11bGF0ZSBkYXRhOiAxMDAgb2JzZXJ2YXRpb25zLCBiaW5hcnkgb3V0Y29tZSAoMCBvciAxKQ0Kc2V0LnNlZWQoMTIzKQ0KbiA8LSAxMDANCnggPC0gcm5vcm0obikgICMgUHJlZGljdG9yIHZhcmlhYmxlDQpwIDwtIDEgLyAoMSArIGV4cCgteCkpICAjIFByb2JhYmlsaXR5IChsb2dpc3RpYyBmdW5jdGlvbikNCnkgPC0gcmJpbm9tKG4sIDEsIHApICAjIEJpbmFyeSBvdXRjb21lICgwIG9yIDEpDQoNCiMgQ29tYmluZSBpbnRvIGEgZGF0YSBmcmFtZQ0KbG9naXRfZGF0YSA8LSBkYXRhLmZyYW1lKHggPSB4LCB5ID0geSkNCmhlYWQobG9naXRfZGF0YSkNCmBgYA0KDQojIyMjICoqU3RlcCAyOiBGaXQgdGhlIExvZ2lzdGljIFJlZ3Jlc3Npb24gTW9kZWwqKg0KDQpVc2luZyBNTEUsIHdlIGNhbiBlc3RpbWF0ZSB0aGUgY29lZmZpY2llbnRzIGZvciB0aGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCB1c2luZyB0aGUgYGdsbSgpYCBmdW5jdGlvbi4NCg0KYGBgUg0KIyBGaXQgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbA0KbG9naXRfbW9kZWwgPC0gZ2xtKHkgfiB4LCBkYXRhID0gbG9naXRfZGF0YSwgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICJsb2dpdCIpKQ0KDQojIERpc3BsYXkgdGhlIHN1bW1hcnkgb2YgdGhlIG1vZGVsDQpzdW1tYXJ5KGxvZ2l0X21vZGVsKQ0KYGBgDQoNCiMjIyMgKipPdXRwdXQqKiAoc2ltcGxpZmllZCk6DQpgYGANCkNhbGw6DQpnbG0oZm9ybXVsYSA9IHkgfiB4LCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gImxvZ2l0IiksIGRhdGEgPSBsb2dpdF9kYXRhKQ0KDQpDb2VmZmljaWVudHM6DQogICAgICAgICAgICBFc3RpbWF0ZSBTdGQuIEVycm9yIHogdmFsdWUgUHIoPnx6fCkgICAgDQooSW50ZXJjZXB0KSAgLTAuMDI5NSAgICAgMC4yMTc4ICAtMC4xMzYgIDAuODkyICAgIA0KeCAgICAgICAgICAgICAyLjU1MjEgICAgIDAuNjcxNiAgIDMuODAxICAwLjAwMDE0NCAqKioNCmBgYA0KDQojIyMjICoqSW50ZXJwcmV0YXRpb24qKjoNCi0gKipJbnRlcmNlcHQgKEVzdGltYXRlID0gLTAuMDMpKio6IFRoZSBpbnRlcmNlcHQgdGVybSByZXByZXNlbnRzIHRoZSBsb2ctb2RkcyBvZiB0aGUgb3V0Y29tZSB3aGVuIHRoZSBwcmVkaWN0b3IgdmFyaWFibGUgaXMgMC4NCi0gKipDb2VmZmljaWVudCBmb3IgeCAoRXN0aW1hdGUgPSAyLjU1KSoqOiBUaGUgZXN0aW1hdGVkIGNvZWZmaWNpZW50IGZvciB0aGUgcHJlZGljdG9yIHZhcmlhYmxlIHggaXMgMi41NS4gVGhpcyBtZWFucyB0aGF0IGZvciBlYWNoIG9uZS11bml0IGluY3JlYXNlIGluIHgsIHRoZSBsb2ctb2RkcyBvZiB0aGUgb3V0Y29tZSAoeSA9IDEpIGluY3JlYXNlIGJ5IGFwcHJveGltYXRlbHkgMi41NS4NCg0KVGhlICoqcC12YWx1ZSAoUHIoPnx6fCkgPSAwLjAwMDE0NCkqKiBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJlZGljdG9yIHZhcmlhYmxlICoqeCoqIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgaW4gZXhwbGFpbmluZyB0aGUgb3V0Y29tZS4NCg0KIyMjIyAqKkxvZy1MaWtlbGlob29kKio6DQpMb2dpc3RpYyByZWdyZXNzaW9uIHVzZXMgTUxFIHRvIGVzdGltYXRlIHRoZSBwYXJhbWV0ZXJzLiBUaGUgbG9nLWxpa2VsaWhvb2Qgb2YgdGhlIG1vZGVsIGNhbiBiZSBleHRyYWN0ZWQgYXMgZm9sbG93czoNCg0KYGBgUg0KIyBFeHRyYWN0IGxvZy1saWtlbGlob29kIG9mIHRoZSBtb2RlbA0KbG9nTGlrKGxvZ2l0X21vZGVsKQ0KYGBgDQoNCi0tLQ0KDQojIyMgKipMaWtlbGlob29kIFJhdGlvIFRlc3QqKg0KDQpBIGNvbW1vbiB1c2Ugb2YgTUxFIGlzIGluICoqbGlrZWxpaG9vZCByYXRpbyB0ZXN0cyAoTFJUKSoqLiBUaGlzIHRlc3QgY29tcGFyZXMgdGhlIGZpdCBvZiB0d28gbmVzdGVkIG1vZGVscyB0byBkZXRlcm1pbmUgd2hldGhlciBhZGRpbmcgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIHNpZ25pZmljYW50bHkgaW1wcm92ZXMgdGhlIG1vZGVsLg0KDQojIyMjICoqRXhhbXBsZSoqOg0KV2UgbWlnaHQgY29tcGFyZSBhICoqbnVsbCBtb2RlbCoqICh3aXRoIG9ubHkgdGhlIGludGVyY2VwdCkgdG8gYSAqKmZ1bGwgbW9kZWwqKiAod2l0aCB0aGUgcHJlZGljdG9yIHZhcmlhYmxlKS4NCg0KYGBgUg0KIyBOdWxsIG1vZGVsIChpbnRlcmNlcHQgb25seSkNCm51bGxfbW9kZWwgPC0gZ2xtKHkgfiAxLCBkYXRhID0gbG9naXRfZGF0YSwgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICJsb2dpdCIpKQ0KDQojIExpa2VsaWhvb2QgcmF0aW8gdGVzdA0KYW5vdmEobnVsbF9tb2RlbCwgbG9naXRfbW9kZWwsIHRlc3QgPSAiTFJUIikNCmBgYA0KDQojIyMjICoqT3V0cHV0Kio6DQpgYGANCkFuYWx5c2lzIG9mIERldmlhbmNlIFRhYmxlDQoNCk1vZGVsIDE6IHkgfiAxDQpNb2RlbCAyOiB5IH4geA0KICBSZXNpZC4gRGYgUmVzaWQuIERldiBEZiBEZXZpYW5jZSAgUHIoPkNoaSkgICAgDQoxICAgICAgICA5OSAgICAgMTM4LjYzICAgICAgICAgICAgICAgICAgICAgICAgICANCjIgICAgICAgIDk4ICAgICAgOTkuNjkgIDEgICAzOC45NDQgIDQuMjFlLTEwICoqKg0KYGBgDQoNCiMjIyMgKipJbnRlcnByZXRhdGlvbioqOg0KLSBUaGUgKipwLXZhbHVlICg0LjIxZS0xMCkqKiBmcm9tIHRoZSBsaWtlbGlob29kIHJhdGlvIHRlc3Qgc3VnZ2VzdHMgdGhhdCBhZGRpbmcgdGhlIHByZWRpY3RvciB2YXJpYWJsZSAqKngqKiBzaWduaWZpY2FudGx5IGltcHJvdmVzIHRoZSBtb2RlbCBmaXQgY29tcGFyZWQgdG8gdGhlIG51bGwgbW9kZWwuDQoNCi0tLQ0KDQojIyMgKipTdW1tYXJ5Kio6DQpUaGUgKipNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdGlvbiAoTUxFKSoqIG1ldGhvZCBpcyBhIHBvd2VyZnVsIHRvb2wgZm9yIGVzdGltYXRpbmcgcGFyYW1ldGVycyBpbiBzdGF0aXN0aWNhbCBtb2RlbHMuIEl0IGlzIHdpZGVseSB1c2VkIGluIGZpZWxkcyBsaWtlIHN0YXRpc3RpY3MsIG1hY2hpbmUgbGVhcm5pbmcsIGFuZCBlY29ub21ldHJpY3MuIE1MRSBjYW4gZXN0aW1hdGUgdGhlIHBhcmFtZXRlcnMgb2YgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9ucyAobGlrZSB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbikgb3IgdGhlIGNvZWZmaWNpZW50cyBvZiByZWdyZXNzaW9uIG1vZGVscyAobGlrZSBsb2dpc3RpYyByZWdyZXNzaW9uKS4gSW4gUiwgdGhlIGBmaXRkaXN0cnBsdXNgIHBhY2thZ2UgY2FuIGJlIHVzZWQgZm9yIGRpc3RyaWJ1dGlvbiBmaXR0aW5nLCBhbmQgYGdsbSgpYCBhcHBsaWVzIE1MRSBpbiBnZW5lcmFsaXplZCBsaW5lYXIgbW9kZWxzLg==