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)

unlabelled

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.

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\]

unlabelled

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.

x = (1:10) * 10
x
 [1]  10  20  30  40  50  60  70  80  90 100

and take it out to the sixth power…

x^6
 [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