View the
latest recording of this lecture
Simple and multiple regression models are types of linear
model.
Remember that the word linear refers to the fact
that the response is linearly related to the regression
parameters, not to the predictors.
In most regression models, the relationship between the response and
each of the explanatory variables is linear.
We can represent more general relationships using polynomial
functions of the explanatory variables.
The resulting models are often referred to as polynomial
regression models.
Child Lung Function Data
FEV (forced expiratory volume) is a measure of lung function. The
data include determinations of FEV on 318 female children who were seen
in a childhood respiratory disease study in Massachusetts in the U.S.
Child’s age (in years) also recorded. Of interest to model FEV
(response) as function of age.
Download fev.csv
Data source: Tager, I. B., Weiss, S. T., Rosner, B., and Speizer, F.
E. (1979). Effect of parental cigarette smoking on pulmonary function in
children. American Journal of Epidemiology,
110, 15-26.
Example : Scatter Plot
## Fev <- read.csv(file = "fev.csv", header = TRUE)
plot(FEV ~ Age, data = Fev)
The scatter plot of data indicates that relationship between FEV and
age is not linear. Will try to model FEV as a polynomial in age.
The Polynomial Regression Model
The polynomial linear regression model is \[Y_i = \beta_0 + \beta_1 x_{i} + \beta_2 x_i^2 +
\ldots + \beta_p x_{i}^p
+ \varepsilon_i ~~~~~~~~~ (i=1,\ldots,n)\]
where \(Y_i\) and \(x_i\) are the response and explanatory
variable observed on the \(i\)th individual.
\(\varepsilon_1, \ldots
\varepsilon_n\) are random errors satisfying the usual
assumptions A1 to
A4.
\(\beta_0, \beta_1, \ldots,
\beta_p\) are the regression parameters.
The polynomial regression equation and A1
imply that \[E[Y_i] = \mu_i = \beta_0 +
\beta_1 x_{i} + \beta_2 x_i^2 + \ldots + \beta_p x_{i}^p\]
The reasoning behind adding powers of the predictor (\(x_i^2, x_i^3\), etc) in the model is that
the resulting relationship between the predictor variable and the
response is no longer a line but rather a curve. Adding higher power
terms results in more complex shapes.
Notes on The Polynomial Regression Model
We have defined a pth order polynomial regression
model.
- Typically statisticians aim for low order polynomial models
- having p larger than 5 or 6 is unusual.
- If you use a polynomial model of order p, then you should
include all terms of lower order (unless the circumstances are
exceptional).
This last point is important. As an example, a cubic polynomial
should include linear and quadratic terms: \[E[Y_i] = \beta_0 + \beta_1 x_{i} + \beta_2 x_i^2
+ \beta_3 x_{i}^3\] is correct; we should not omit
(e.g.) the quadratic term: \[E[Y_i] = \beta_0
+ \beta_1 x_{i} + \beta_3 x_{i}^3\]
Example : Model Fitting in R
A sixth order polynomial model can be fitted with
lm(FEV~Age+I(Age^2)+I(Age^3)+I(Age^4)+I(Age^5)+I(Age^6),data=Fev)
Notice that the powers of Age
appear within the function
I()
. This function “protects” its contents, in the sense
that R reads the contents as a normal mathematical expression.
For example, I(Age^4)
is telling R to include the fourth
power of Age
in the model.
N.B. the expressions *
, /
and
^
have a different meaning in a model formula (explained in
later lectures)
Modern practice is to avoid all that typing though!
Example : Sixth Order Model
Let’s start by trying to fit a sixth order model on the FEV data:
Fev.lm.6 <- lm(FEV ~ poly(Age, 6, raw = TRUE), data = Fev)
summary(Fev.lm.6)
Call:
lm(formula = FEV ~ poly(Age, 6, raw = TRUE), data = Fev)
Residuals:
Min 1Q Median 3Q Max
-1.2047 -0.2791 0.0186 0.2509 0.9210
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1.520e+00 5.052e+00 -0.301 0.764
poly(Age, 6, raw = TRUE)1 2.079e+00 3.533e+00 0.588 0.557
poly(Age, 6, raw = TRUE)2 -6.468e-01 9.735e-01 -0.664 0.507
poly(Age, 6, raw = TRUE)3 1.033e-01 1.359e-01 0.761 0.447
poly(Age, 6, raw = TRUE)4 -8.145e-03 1.017e-02 -0.801 0.424
poly(Age, 6, raw = TRUE)5 3.056e-04 3.882e-04 0.787 0.432
poly(Age, 6, raw = TRUE)6 -4.360e-06 5.931e-06 -0.735 0.463
Residual standard error: 0.3902 on 311 degrees of freedom
Multiple R-squared: 0.6418, Adjusted R-squared: 0.6349
F-statistic: 92.87 on 6 and 311 DF, p-value: < 2.2e-16
The coefficient of poly(Age, 6)
is not significant, so
we can remove the 6th order term.
Example : Fifth Order Model
We now fit a fifth order polynomial model:
Fev.lm.5 <- lm(FEV ~ poly(Age, 5, raw = TRUE), data = Fev)
summary(Fev.lm.5)
Call:
lm(formula = FEV ~ poly(Age, 5, raw = TRUE), data = Fev)
Residuals:
Min 1Q Median 3Q Max
-1.19431 -0.27623 0.02088 0.24471 0.93266
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.750e+00 2.393e+00 0.731 0.465
poly(Age, 5, raw = TRUE)1 -3.209e-01 1.349e+00 -0.238 0.812
poly(Age, 5, raw = TRUE)2 3.714e-02 2.858e-01 0.130 0.897
poly(Age, 5, raw = TRUE)3 5.707e-03 2.860e-02 0.200 0.842
poly(Age, 5, raw = TRUE)4 -7.392e-04 1.359e-03 -0.544 0.587
poly(Age, 5, raw = TRUE)5 2.083e-05 2.467e-05 0.844 0.399
Residual standard error: 0.3899 on 312 degrees of freedom
Multiple R-squared: 0.6412, Adjusted R-squared: 0.6354
F-statistic: 111.5 on 5 and 312 DF, p-value: < 2.2e-16
As the coefficient of poly(Age, 5)
is not significant,
we can remove the 5th order term from the model.
Example : Fourth Order Model
We now try a fourth order polynomial model:
Fev.lm.4 <- lm(FEV ~ poly(Age, 4, raw = TRUE), data = Fev)
summary(Fev.lm.4)
Call:
lm(formula = FEV ~ poly(Age, 4, raw = TRUE), data = Fev)
Residuals:
Min 1Q Median 3Q Max
-1.20203 -0.27466 0.02218 0.24525 0.93709
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 3.5685906 1.0434415 3.420 0.000709 ***
poly(Age, 4, raw = TRUE)1 -1.3941151 0.4529027 -3.078 0.002267 **
poly(Age, 4, raw = TRUE)2 0.2712825 0.0692350 3.918 0.000110 ***
poly(Age, 4, raw = TRUE)3 -0.0181507 0.0044318 -4.096 5.37e-05 ***
poly(Age, 4, raw = TRUE)4 0.0004055 0.0001007 4.029 7.05e-05 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.3897 on 313 degrees of freedom
Multiple R-squared: 0.6404, Adjusted R-squared: 0.6358
F-statistic: 139.3 on 4 and 313 DF, p-value: < 2.2e-16
The fourth order term is statistically significant, so this is our
preferred model. Since the 4th order term is significant, we have to
keep all lower order terms.
Our fitted model equation is: \[E[\mbox{FEV}] = 3.57 - 1.39~\mbox{Age} +
0.27~\mbox{Age}^2 - 0.018~\mbox{Age}^3 +
0.00041~\mbox{Age}^4\]
Looking at the plot (above), the fitted model looks adequate for ages
in the range 5 to 15 years. At the extreme ends of the plot the fitted
curve exhibits spurious upward curvature. This feature of the plot is an
artifact of the form of the polynomial rather than a characteristic of
the data.
Example : Collinearity in the Fitted Model
Notice how in the 6th and 5th order models, none of the regression
coefficients are significant; however when dropping to a 4th order model
this leads to significant t-statistics. This is due to a
noticeable collinearity between the powers of Age
.
Collinearity in polynomial regression can lead to numerical
instability in statistical software packages.
Problems of collinearity can be addressed by using orthogonal
polynomials, coming up in a lecture quite soon.
Numeric instability (??)
Successive powers of our predictor variable frequently end up being
on very different orders of magnitude. Just for the sake of
illustration, let’s use a predictor taking on values from ten to
one-hundred in steps of ten.
[1] 10 20 30 40 50 60 70 80 90 100
and take it out to the sixth power…
[1] 1.00000e+06 6.40000e+07 7.29000e+08 4.09600e+09 1.56250e+10 4.66560e+10
[7] 1.17649e+11 2.62144e+11 5.31441e+11 1.00000e+12
When these two vectors end up in the same model matrix, the magnitude
of the largest value swamps the little numbers in the matrix when we are
finding the inverse matrix \((X^t
X)^{-1}\) when fitting the linear model.
We can avoid some of this problem by re-scaling the original
x variable, by centering (subtract the mean), seen next
lecture; we could then multiply by a scalar to bring the resulting
values into the range -1 to 1, before using the powers
(not shown in this course).
This re-scaling keeps the same information within the original
x variable as it hasn’t changed shape or been re-ordered in any
way. It’s like deciding to measure something in centimetres or
re-scaling to metres; the true measurements won’t change, just their
representation in numeric terms.
LS0tDQp0aXRsZTogIkxlY3R1cmUgMTY6IFBvbHlub21pYWwgUmVncmVzc2lvbiBNb2RlbHMiDQpzdWJ0aXRsZTogMTYxLjI1MSBSZWdyZXNzaW9uIE1vZGVsbGluZw0KYXV0aG9yOiAiUHJlc2VudGVkIGJ5IEpvbmF0aGFuIEdvZGZyZXkgPGEuai5nb2RmcmV5QG1hc3NleS5hYy5uej4iICANCmRhdGU6ICJXZWVrIDYgb2YgU2VtZXN0ZXIgMiwgYHIgbHVicmlkYXRlOjp5ZWFyKGx1YnJpZGF0ZTo6bm93KCkpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIGh0bWxfbm90ZWJvb2s6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRoZW1lOiB5ZXRpDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KICBpb3NsaWRlc19wcmVzZW50YXRpb246DQogICAgd2lkZXNjcmVlbjogdHJ1ZQ0KICAgIHNtYWxsZXI6IHRydWUNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KICBzbGlkeV9wcmVzZW50YXRpb246IA0KICAgIHRoZW1lOiB5ZXRpDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQoNCg0KDQoNCltWaWV3IHRoZSBsYXRlc3QgcmVjb3JkaW5nIG9mIHRoaXMgbGVjdHVyZV0oaHR0cHM6Ly9SLVJlc291cmNlcy5tYXNzZXkuYWMubnovdmlkZW9zLzI1MUwxNi5tcDQpDQo8IS0tLSBEYXRhIGlzIG9uDQpodHRwczovL3ItcmVzb3VyY2VzLm1hc3NleS5hYy5uei9kYXRhLzE2MTI1MS8NCi0tLT4NCg0KYGBge3Igc2V0dXAsIHB1cmw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KGtuaXRyKQ0Kb3B0c19jaHVuayRzZXQoZGV2PWMoInBuZyIsICJwZGYiKSkNCm9wdHNfY2h1bmskc2V0KGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTcsIGZpZy5wYXRoPSJGaWd1cmVzLyIsIGZpZy5hbHQ9InVubGFiZWxsZWQiKQ0Kb3B0c19jaHVuayRzZXQoY29tbWVudD0iIiwgZmlnLmFsaWduPSJjZW50ZXIiLCB0aWR5PVRSVUUpDQpvcHRpb25zKGtuaXRyLmthYmxlLk5BID0gJycpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoYnJvb20pDQpgYGANCg0KDQo8IS0tLSBEbyBub3QgZWRpdCBhbnl0aGluZyBhYm92ZSB0aGlzIGxpbmUuIC0tLT4NCg0KU2ltcGxlIGFuZCBtdWx0aXBsZSByZWdyZXNzaW9uIG1vZGVscyBhcmUgdHlwZXMgb2YgKipsaW5lYXIgbW9kZWwqKi4NCg0KUmVtZW1iZXIgdGhhdCB0aGUgd29yZCAqKmxpbmVhcioqIHJlZmVycyB0byB0aGUgZmFjdCB0aGF0IHRoZSByZXNwb25zZSBpcyBsaW5lYXJseSByZWxhdGVkIHRvIHRoZSByZWdyZXNzaW9uICoqcGFyYW1ldGVycyoqLCBub3QgdG8gdGhlIHByZWRpY3RvcnMuDQoNCkluIG1vc3QgcmVncmVzc2lvbiBtb2RlbHMsIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgcmVzcG9uc2UgYW5kIGVhY2ggb2YgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBpcyBsaW5lYXIuDQoNCldlIGNhbiByZXByZXNlbnQgbW9yZSBnZW5lcmFsIHJlbGF0aW9uc2hpcHMgdXNpbmcgcG9seW5vbWlhbCBmdW5jdGlvbnMgb2YgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcy4NCg0KVGhlIHJlc3VsdGluZyBtb2RlbHMgYXJlIG9mdGVuIHJlZmVycmVkIHRvIGFzICpwb2x5bm9taWFsIHJlZ3Jlc3Npb24gbW9kZWxzKi4NCg0KIyMgQ2hpbGQgTHVuZyBGdW5jdGlvbiBEYXRhDQoNCg0KDQpGRVYgKGZvcmNlZCBleHBpcmF0b3J5IHZvbHVtZSkgaXMgYSBtZWFzdXJlIG9mIGx1bmcgZnVuY3Rpb24uDQpUaGUgZGF0YSBpbmNsdWRlIGRldGVybWluYXRpb25zIG9mIEZFViBvbiAzMTggZmVtYWxlIGNoaWxkcmVuIHdobyB3ZXJlIHNlZW4gaW4gYSBjaGlsZGhvb2QgcmVzcGlyYXRvcnkgZGlzZWFzZSBzdHVkeSBpbiBNYXNzYWNodXNldHRzIGluIHRoZSBVLlMuDQpDaGlsZCdzIGFnZSAoaW4geWVhcnMpIGFsc28gcmVjb3JkZWQuDQpPZiBpbnRlcmVzdCB0byBtb2RlbCBGRVYgKHJlc3BvbnNlKSBhcyBmdW5jdGlvbiBvZiBhZ2UuDQoNCg0KYHIgeGZ1bjo6ZW1iZWRfZmlsZSgiLi4vLi4vZGF0YS9mZXYuY3N2IilgDQoNCg0KIERhdGEgc291cmNlOiBUYWdlciwgSS4gQi4sIFdlaXNzLCBTLiBULiwgUm9zbmVyLCBCLiwgYW5kIFNwZWl6ZXIsDQpGLiBFLiAoMTk3OSkuIEVmZmVjdCBvZiBwYXJlbnRhbCBjaWdhcmV0dGUgc21va2luZyBvbiBwdWxtb25hcnkgZnVuY3Rpb24gaW4gY2hpbGRyZW4uICpBbWVyaWNhbiBKb3VybmFsIG9mIEVwaWRlbWlvbG9neSosDQoqKjExMCoqLCAxNS0yNi4gDQoNCiMjIyBFeGFtcGxlIDogU2NhdHRlciBQbG90DQoNCmBgYHtyIGdldEZldkRhdGEsIGVjaG89LTEsIGV2YWw9LTJ9DQpGZXYgPC0gcmVhZC5jc3YoZmlsZT0iLi4vLi4vZGF0YS9mZXYuY3N2IiwgaGVhZGVyPVRSVUUpDQpGZXYgPC0gcmVhZC5jc3YoZmlsZT0iZmV2LmNzdiIsIGhlYWRlcj1UUlVFKQ0KcGxvdChGRVZ+QWdlLCBkYXRhPUZldikNCmBgYA0KDQoNClRoZSBzY2F0dGVyIHBsb3Qgb2YgZGF0YSBpbmRpY2F0ZXMgdGhhdCByZWxhdGlvbnNoaXAgYmV0d2VlbiBGRVYgYW5kIGFnZSBpcyBub3QgbGluZWFyLg0KV2lsbCB0cnkgdG8gbW9kZWwgRkVWIGFzIGEgcG9seW5vbWlhbCBpbiBhZ2UuDQoNCg0KDQoNCg0KIyMgVGhlIFBvbHlub21pYWwgUmVncmVzc2lvbiBNb2RlbA0KDQpUaGUgcG9seW5vbWlhbCBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCBpcw0KJCRZX2kgPSBcYmV0YV8wICsgXGJldGFfMSB4X3tpfSArIFxiZXRhXzIgeF9pXjIgKyBcbGRvdHMgKyBcYmV0YV9wIHhfe2l9XnANCisgXHZhcmVwc2lsb25faSB+fn5+fn5+fn4gKGk9MSxcbGRvdHMsbikkJCANCg0Kd2hlcmUgJFlfaSQgYW5kICR4X2kkIGFyZSB0aGUgcmVzcG9uc2UgYW5kIGV4cGxhbmF0b3J5IHZhcmlhYmxlDQogICAgb2JzZXJ2ZWQgb24gdGhlICRpJF50aF4gaW5kaXZpZHVhbC4NCg0KJFx2YXJlcHNpbG9uXzEsIFxsZG90cyBcdmFyZXBzaWxvbl9uJCBhcmUgcmFuZG9tIGVycm9ycyBzYXRpc2Z5aW5nDQogICAgdGhlIHVzdWFsIGFzc3VtcHRpb25zICoqKkExKioqIHRvICoqKkE0KioqLg0KDQokXGJldGFfMCwgXGJldGFfMSwgXGxkb3RzLCBcYmV0YV9wJCBhcmUgdGhlIHJlZ3Jlc3Npb24gcGFyYW1ldGVycy4NCg0KVGhlIHBvbHlub21pYWwgcmVncmVzc2lvbiBlcXVhdGlvbiBhbmQgKioqQTEqKiogaW1wbHkgdGhhdA0KJCRFW1lfaV0gPSBcbXVfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfe2l9ICsgXGJldGFfMiB4X2leMiArIFxsZG90cyArIFxiZXRhX3AgeF97aX1ecCQkDQoNClRoZSByZWFzb25pbmcgYmVoaW5kIGFkZGluZyBwb3dlcnMgb2YgdGhlIHByZWRpY3RvciAoJHhfaV4yLCB4X2leMyQsIGV0YykgaW4gdGhlIG1vZGVsIGlzIHRoYXQgdGhlIHJlc3VsdGluZyByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgcHJlZGljdG9yIHZhcmlhYmxlIGFuZCB0aGUgcmVzcG9uc2UgaXMgbm8gbG9uZ2VyIGEgbGluZSBidXQgcmF0aGVyIGEgY3VydmUuIEFkZGluZyBoaWdoZXIgcG93ZXIgdGVybXMgcmVzdWx0cyBpbiBtb3JlIGNvbXBsZXggc2hhcGVzLg0KDQojIyBOb3RlcyBvbiBUaGUgUG9seW5vbWlhbCBSZWdyZXNzaW9uIE1vZGVsDQoNCldlIGhhdmUgZGVmaW5lZCBhICpwKl50aF4gb3JkZXIgcG9seW5vbWlhbCByZWdyZXNzaW9uIG1vZGVsLg0KDQotIFR5cGljYWxseSBzdGF0aXN0aWNpYW5zIGFpbSBmb3IgbG93IG9yZGVyIHBvbHlub21pYWwgbW9kZWxzIA0KLSBoYXZpbmcgICAgICpwKiBsYXJnZXIgdGhhbiA1IG9yIDYgaXMgdW51c3VhbC4NCi0gSWYgeW91IHVzZSBhIHBvbHlub21pYWwgbW9kZWwgb2Ygb3JkZXIgKnAqLCB0aGVuIHlvdSBzaG91bGQNCiAgICBpbmNsdWRlIGFsbCB0ZXJtcyBvZiBsb3dlciBvcmRlciAodW5sZXNzIHRoZSBjaXJjdW1zdGFuY2VzIGFyZQ0KICAgIGV4Y2VwdGlvbmFsKS4gDQoNClRoaXMgbGFzdCBwb2ludCBpcyBpbXBvcnRhbnQuIEFzIGFuIGV4YW1wbGUsIGEgY3ViaWMgcG9seW5vbWlhbCBzaG91bGQgaW5jbHVkZSBsaW5lYXIgYW5kIHF1YWRyYXRpYyB0ZXJtczoNCiAgICAgICAgJCRFW1lfaV0gPSBcYmV0YV8wICsgXGJldGFfMSB4X3tpfSArIFxiZXRhXzIgeF9pXjIgKyBcYmV0YV8zIHhfe2l9XjMkJA0KICAgIGlzIGNvcnJlY3Q7IHdlIHNob3VsZCAqbm90KiBvbWl0IChlLmcuKSB0aGUgcXVhZHJhdGljIHRlcm06DQogICAgICAgICQkRVtZX2ldID0gXGJldGFfMCArIFxiZXRhXzEgeF97aX0gKyBcYmV0YV8zIHhfe2l9XjMkJA0KDQojIyBFeGFtcGxlIDogTW9kZWwgRml0dGluZyBpbiBSDQoNCkEgc2l4dGggb3JkZXIgcG9seW5vbWlhbCBtb2RlbCAqY2FuKiBiZSBmaXR0ZWQgd2l0aA0KDQpgYGByDQpsbShGRVZ+QWdlK0koQWdlXjIpK0koQWdlXjMpK0koQWdlXjQpK0koQWdlXjUpK0koQWdlXjYpLGRhdGE9RmV2KQ0KYGBgDQoNCk5vdGljZSB0aGF0IHRoZSBwb3dlcnMgb2YgYEFnZWAgYXBwZWFyIHdpdGhpbiB0aGUgZnVuY3Rpb24gYEkoKWAuIFRoaXMgZnVuY3Rpb24gInByb3RlY3RzIiBpdHMgY29udGVudHMsIGluIHRoZSBzZW5zZSB0aGF0IFIgcmVhZHMgdGhlDQogICAgY29udGVudHMgYXMgYSBub3JtYWwgbWF0aGVtYXRpY2FsIGV4cHJlc3Npb24uDQoNCkZvciBleGFtcGxlLCBgSShBZ2VeNClgIGlzIHRlbGxpbmcgUiB0byBpbmNsdWRlIHRoZSBmb3VydGggcG93ZXIgb2YgYEFnZWAgaW4gdGhlDQogICAgbW9kZWwuDQoNCk4uQi4gdGhlIGV4cHJlc3Npb25zIGAqYCwgYC9gIGFuZCBgXmAgaGF2ZSBhIGRpZmZlcmVudCBtZWFuaW5nIGluDQogICAgYSBtb2RlbCBmb3JtdWxhIChleHBsYWluZWQgaW4gbGF0ZXIgbGVjdHVyZXMpDQoNCk1vZGVybiBwcmFjdGljZSBpcyB0byBhdm9pZCBhbGwgdGhhdCB0eXBpbmcgdGhvdWdoIQ0KDQojIyMgRXhhbXBsZSA6IFNpeHRoIE9yZGVyIE1vZGVsDQoNCkxldCdzIHN0YXJ0IGJ5IHRyeWluZyB0byBmaXQgYSBzaXh0aCBvcmRlciBtb2RlbCBvbiB0aGUgRkVWIGRhdGE6DQoNCmBgYHtyIEZldi5sbS42fQ0KRmV2LmxtLjYgPC0gbG0oRkVWfnBvbHkoQWdlLDYsIHJhdz1UUlVFKSwgZGF0YT1GZXYpDQpzdW1tYXJ5KEZldi5sbS42KQ0KYGBgDQoNClRoZSBjb2VmZmljaWVudCBvZiBgcG9seShBZ2UsIDYpYCBpcyBub3Qgc2lnbmlmaWNhbnQsIHNvIHdlIGNhbiByZW1vdmUgdGhlIDZ0aCBvcmRlciB0ZXJtLg0KDQojIyMgRXhhbXBsZSA6IEZpZnRoIE9yZGVyIE1vZGVsDQoNCldlIG5vdyBmaXQgYSBmaWZ0aCBvcmRlciBwb2x5bm9taWFsIG1vZGVsOg0KDQpgYGB7ciBGZXYubG0uNX0NCkZldi5sbS41IDwtIGxtKEZFVn5wb2x5KEFnZSw1LCByYXc9VFJVRSksIGRhdGE9RmV2KQ0Kc3VtbWFyeShGZXYubG0uNSkNCmBgYA0KDQpBcyB0aGUgY29lZmZpY2llbnQgb2YgYHBvbHkoQWdlLCA1KWAgaXMgbm90IHNpZ25pZmljYW50LCB3ZSBjYW4gcmVtb3ZlIHRoZSA1dGggb3JkZXIgdGVybSBmcm9tIHRoZSBtb2RlbC4NCg0KIyMjIEV4YW1wbGUgOiBGb3VydGggT3JkZXIgTW9kZWwNCg0KV2Ugbm93IHRyeSBhIGZvdXJ0aCBvcmRlciBwb2x5bm9taWFsIG1vZGVsOg0KDQpgYGB7ciBGZXYubG0uNH0NCkZldi5sbS40IDwtIGxtKEZFVn5wb2x5KEFnZSw0LCByYXc9VFJVRSksIGRhdGE9RmV2KQ0Kc3VtbWFyeShGZXYubG0uNCkNCmBgYA0KDQpUaGUgZm91cnRoIG9yZGVyIHRlcm0gaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgc28gdGhpcyBpcyBvdXIgcHJlZmVycmVkIG1vZGVsLiBTaW5jZSB0aGUgNHRoIG9yZGVyIHRlcm0gaXMgc2lnbmlmaWNhbnQsIHdlIGhhdmUgdG8ga2VlcCBhbGwgbG93ZXIgb3JkZXIgdGVybXMuDQoNCk91ciBmaXR0ZWQgbW9kZWwgZXF1YXRpb24gaXM6DQogICAgJCRFW1xtYm94e0ZFVn1dID0gMy41NyAtIDEuMzl+XG1ib3h7QWdlfSArIDAuMjd+XG1ib3h7QWdlfV4yIC0gMC4wMTh+XG1ib3h7QWdlfV4zICsgMC4wMDA0MX5cbWJveHtBZ2V9XjQkJA0KDQoNCmBgYHtyIEZldi5sbS40LnBsb3QsIGVjaG8gPSBGQUxTRX0NCm5ld2RhdCA8LSBkYXRhLmZyYW1lKEFnZSA9IHNlcShtaW4oRmV2JEFnZSksIG1heChGZXYkQWdlKSwgbGVuZ3RoLm91dCA9IDEwMCkpDQpuZXdkYXQkcHJlZCA8LSBwcmVkaWN0KEZldi5sbS40LCBuZXdkYXRhID0gbmV3ZGF0KQ0KcGxvdChGRVZ+QWdlLCBkYXRhPUZldikNCndpdGgobmV3ZGF0LCBsaW5lcyh4ID0gQWdlLCB5ID0gcHJlZCwgY29sID0gInJlZCIsIGx3ZCA9IDIpKQ0KYGBgDQoNCkxvb2tpbmcgYXQgdGhlIHBsb3QgKGFib3ZlKSwgdGhlIGZpdHRlZCBtb2RlbCBsb29rcyBhZGVxdWF0ZSBmb3IgYWdlcyBpbiB0aGUgcmFuZ2UgNSB0byAxNSB5ZWFycy4NCkF0IHRoZSBleHRyZW1lIGVuZHMgb2YgdGhlIHBsb3QgdGhlIGZpdHRlZCBjdXJ2ZSBleGhpYml0cyBzcHVyaW91cyB1cHdhcmQgY3VydmF0dXJlLg0KVGhpcyBmZWF0dXJlIG9mIHRoZSBwbG90IGlzIGFuIGFydGlmYWN0IG9mIHRoZSBmb3JtIG9mIHRoZSBwb2x5bm9taWFsIHJhdGhlciB0aGFuIGEgY2hhcmFjdGVyaXN0aWMgb2YgdGhlIGRhdGEuDQoNCg0KDQoNCiMjIyBFeGFtcGxlIDogQ29sbGluZWFyaXR5IGluIHRoZSBGaXR0ZWQgTW9kZWwNCg0KTm90aWNlIGhvdyBpbiB0aGUgNnRoIGFuZCA1dGggb3JkZXIgbW9kZWxzLCBub25lIG9mIHRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50cyBhcmUgc2lnbmlmaWNhbnQ7IGhvd2V2ZXIgd2hlbiBkcm9wcGluZyB0byBhIDR0aCBvcmRlciBtb2RlbCB0aGlzIGxlYWRzIHRvIHNpZ25pZmljYW50ICp0Ki1zdGF0aXN0aWNzLiBUaGlzIGlzIGR1ZSB0byBhIG5vdGljZWFibGUgY29sbGluZWFyaXR5IGJldHdlZW4gdGhlIHBvd2VycyBvZiBgQWdlYC4NCg0KQ29sbGluZWFyaXR5IGluIHBvbHlub21pYWwgcmVncmVzc2lvbiBjYW4gbGVhZCB0byBudW1lcmljYWwNCiAgICBpbnN0YWJpbGl0eSBpbiBzdGF0aXN0aWNhbCBzb2Z0d2FyZSBwYWNrYWdlcy4NCg0KUHJvYmxlbXMgb2YgY29sbGluZWFyaXR5IGNhbiBiZSBhZGRyZXNzZWQgYnkgdXNpbmcgb3J0aG9nb25hbA0KICAgIHBvbHlub21pYWxzLCBjb21pbmcgdXAgaW4gYSBsZWN0dXJlIHF1aXRlIHNvb24uDQoNCg0KIyMgTnVtZXJpYyBpbnN0YWJpbGl0eSAoPz8pDQoNClN1Y2Nlc3NpdmUgcG93ZXJzIG9mIG91ciBwcmVkaWN0b3IgdmFyaWFibGUgZnJlcXVlbnRseSBlbmQgdXAgYmVpbmcgb24gdmVyeSBkaWZmZXJlbnQgb3JkZXJzIG9mIG1hZ25pdHVkZS4gSnVzdCBmb3IgdGhlIHNha2Ugb2YgaWxsdXN0cmF0aW9uLCBsZXQncyB1c2UgYSBwcmVkaWN0b3IgdGFraW5nIG9uIHZhbHVlcyBmcm9tIHRlbiB0byBvbmUtaHVuZHJlZCBpbiBzdGVwcyBvZiB0ZW4uDQoNCmBgYHtyIGdldE5ld1h9DQp4PSgxOjEwKSoxMDsgeA0KYGBgDQoNCmFuZCB0YWtlIGl0IG91dCB0byB0aGUgc2l4dGggcG93ZXIuLi4NCg0KYGBge3Igc2l4dGhQb3dlcn0NCnheNg0KYGBgDQoNCldoZW4gdGhlc2UgdHdvIHZlY3RvcnMgZW5kIHVwIGluIHRoZSBzYW1lIG1vZGVsIG1hdHJpeCwgdGhlIG1hZ25pdHVkZSBvZiB0aGUgbGFyZ2VzdCB2YWx1ZSBzd2FtcHMgdGhlIGxpdHRsZSBudW1iZXJzIGluIHRoZSBtYXRyaXggd2hlbiB3ZSBhcmUgZmluZGluZyB0aGUgaW52ZXJzZSBtYXRyaXggJChYXnQgWCleey0xfSQgd2hlbiBmaXR0aW5nIHRoZSAgbGluZWFyIG1vZGVsLiANCg0KV2UgY2FuIGF2b2lkIHNvbWUgb2YgdGhpcyBwcm9ibGVtIGJ5IHJlLXNjYWxpbmcgdGhlIG9yaWdpbmFsICp4KiB2YXJpYWJsZSwgYnkgY2VudGVyaW5nIChzdWJ0cmFjdCB0aGUgbWVhbiksIHNlZW4gbmV4dCBsZWN0dXJlOyB3ZSBjb3VsZCB0aGVuIG11bHRpcGx5IGJ5IGEgc2NhbGFyIHRvIGJyaW5nIHRoZSByZXN1bHRpbmcgdmFsdWVzIGludG8gdGhlIHJhbmdlICotMSogdG8gKjEqLCBiZWZvcmUgIHVzaW5nIHRoZSBwb3dlcnMgKG5vdCBzaG93biBpbiB0aGlzIGNvdXJzZSkuDQoNClRoaXMgcmUtc2NhbGluZyBrZWVwcyB0aGUgc2FtZSBpbmZvcm1hdGlvbiB3aXRoaW4gdGhlIG9yaWdpbmFsICp4KiB2YXJpYWJsZSBhcyBpdCBoYXNuJ3QgY2hhbmdlZCBzaGFwZSBvciBiZWVuIHJlLW9yZGVyZWQgaW4gYW55IHdheS4gSXQncyBsaWtlIGRlY2lkaW5nIHRvIG1lYXN1cmUgc29tZXRoaW5nIGluIGNlbnRpbWV0cmVzIG9yIHJlLXNjYWxpbmcgdG8gbWV0cmVzOyB0aGUgdHJ1ZSBtZWFzdXJlbWVudHMgd29uJ3QgY2hhbmdlLCBqdXN0IHRoZWlyIHJlcHJlc2VudGF0aW9uIGluIG51bWVyaWMgdGVybXMuDQoNCg0K