View the latest recording of this lecture

Linear regression models can be conveniently expressed using matrix notation.

In this lecture, we will see how results for linear models are much more easily derived and understood using matrix notation than without it.

Also note that the matrix approach is what is being done in the background by all good statistical software including R.

Matrix Formulation of the Linear Model

\[\boldsymbol{y} = X {\boldsymbol{\beta}} + {\boldsymbol{\varepsilon}} \label{eq:matrixLM}\]

where \(\boldsymbol{y}\) is the response vector, X is the model matrix, \({\boldsymbol{\beta}}\) is the vector of p+1 regression parameters, and \({\boldsymbol{\varepsilon}}\) is the vector of n error terms.

\(\boldsymbol{y} = \left [ \begin{array}{c} y_1\\ y_2\\ \vdots\\ y_n \end{array} \right ]\), \(X = \left [ \begin{array}{cccc} 1 & x_{11} & \ldots & x_{1p}\\ 1 & x_{21} & \ldots & x_{2p}\\ \vdots & \vdots & \ddots & \vdots\\ 1 & x_{n1} & \ldots & x_{np} \end{array} \right ]\), \(\boldsymbol{\beta} = \left [ \begin{array}{c} \beta_0\\ \beta_1\\ \vdots\\ \beta_p\\ \end{array} \right ]\), and \(\boldsymbol{\varepsilon} = \left [ \begin{array}{c} \varepsilon_1\\ \varepsilon_2\\ \vdots\\ \varepsilon_n\\ \end{array} \right ]\)

The mean (expected) value of the random vector \(\boldsymbol{y}\) is \[\begin{aligned} \boldsymbol{\mu} &=& E[\boldsymbol{y}]\\ &=& \left [ \begin{array}{c} E[y_1] \\ E[y_2] \\ \vdots \\ E[y_n] \end{array} \right ] \\ &=& E[X {\boldsymbol{\beta}} + {\boldsymbol{\varepsilon}}]\\ &=& X {\boldsymbol{\beta}}\end{aligned}\]

Least Squares Estimation by Matrices

For observed responses \(\boldsymbol{y}\) the sum of squared errors can be written as \[SS({\boldsymbol{\beta}}) = (\boldsymbol{y} - X {\boldsymbol{\beta}})^T (\boldsymbol{y} - X {\boldsymbol{\beta}}).\]

  • This can be minimised using multivariate (vector) calculus to give the least squares estimates as \[\hat{{\boldsymbol{\beta}}} = (X^T X)^{-1} X^T \boldsymbol{y}.\]

How did that matrix solution come about?

Start with \[X \hat{{\boldsymbol{\beta}}} =\boldsymbol{y}\] and do a series of pre-multiplications: First by \(X^T\) (the transpose of the \(X\) model matrix. \[X^T X \hat{{\boldsymbol{\beta}}} = X^T \boldsymbol{y}\], then the inverse of \((X^T X)\) to give \[(X^T X)^{-1} (X^T X) \hat{{\boldsymbol{\beta}}} = (X^T X)^{-1} X^T \boldsymbol{y}\].

Anything multiplied by its inverse is equal to the identity matrix, and cancels itself out, rreducing the left hand side to be the parameter estimates $ $ we seek.

Simple Linear Regression in matrix form

For a simple linear regression model the model matrix is \[X = \left [ \begin{array}{cc} 1 & x_{1} \\ 1 & x_{2} \\ \vdots & \vdots \\ 1 & x_{n} \end{array} \right ]\] If we observe responses \(\boldsymbol{y}\), the least squares estimate of \({\boldsymbol{\beta}}\) is: \[\begin{aligned} \hat{\boldsymbol{\beta}} &=& (X^T X)^{-1} X^T \boldsymbol{y} = \left [ \begin{array}{cc} n & n \bar{x}\\ n\bar{x} & \sum_i x_i^2 \end{array} \right ]^{-1} \left [ \begin{array}{cccc} 1 & 1 & \ldots & 1 \\ x_1 & x_2 & \ldots & x_n \end{array} \right ] \left [ \begin{array}{c} y_1\\ y_2\\ \vdots\\ y_n \end{array} \right ] \\ &=& \frac{1}{n s_{xx}} \left [ \begin{array}{cc} \sum_i x_i^2 & - n \bar{x}\\ - n\bar{x} & n \end{array} \right ] \left [ \begin{array}{c} n \bar{y}\\ \sum_i x_i y_i \end{array} \right ] = \frac{1}{s_{xx}} \left [ \begin{array}{c} \bar{y} \sum_i x_i^2 - \bar{x} \sum_i{x_i y_i} \\ s_{xy} \end{array} \right ]\end{aligned}\]

Prediction and The Hat Matrix

The vector of fitted values is given by \(\hat{\boldsymbol{\mu}} = X \hat{\boldsymbol{\beta}} = X (X^TX)^{-1} X^T \boldsymbol{y}\) and the vector of residuals by \(\boldsymbol{e} = \boldsymbol{y} - \hat{\boldsymbol{\mu}}\).

The equation for the fitted values just given, can be re-written \(\hat{\boldsymbol{\mu}} = H \boldsymbol{y} = \hat{\boldsymbol{y}}\) where H = X (XTX)-1XT is often called the hat matrix because it “puts hats on things”!

We have the equality \(\hat{\boldsymbol{y}} = \hat{\boldsymbol{\mu}}\) because we use the same values for prediction and mean estimation.

Covariance Matrices

The Covariance Matrix for \(\hat{\boldsymbol{\beta}}\)

The covariance matrix of \(\hat{\boldsymbol{\beta}}\) is

\[\begin{aligned} \mbox{Var}(\hat{\boldsymbol{\beta}}) = \mbox{Var}[ (X^TX)^{-1} X^T \boldsymbol{y} ] &=& (X^TX)^{-1} X^T \mbox{Var}(\boldsymbol{y}) [(X^TX)^{-1} X^T]^T\\ &=& (X^TX)^{-1} X^T \sigma^2 I [(X^TX)^{-1} X^T]^T\\ &=& \sigma^2 (X^TX)^{-1} X^TX (X^T X)^{-1}\\ &=& \sigma^2 (X^TX)^{-1}\end{aligned}\]

We can use \(\mbox{Var}(\boldsymbol{y}) = \sigma^2 I\) since the responses are independent and hence uncorrelated.

The leading diagonal of this matrix is the basis for the standard errors of our parameter estimates seen in our regression output. is

LS0tDQp0aXRsZTogIkxlY3R1cmUgMTM6IE1hdHJpY2VzIGFuZCBMaW5lYXIgUmVncmVzc2lvbiBNb2RlbHMiDQpzdWJ0aXRsZTogMTYxLjI1MSBSZWdyZXNzaW9uIE1vZGVsbGluZw0KYXV0aG9yOiAiUHJlc2VudGVkIGJ5IEpvbmF0aGFuIEdvZGZyZXkgPGEuai5nb2RmcmV5QG1hc3NleS5hYy5uej4iICANCmRhdGU6ICJXZWVrIDUgb2YgU2VtZXN0ZXIgMiwgYHIgbHVicmlkYXRlOjp5ZWFyKGx1YnJpZGF0ZTo6bm93KCkpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIGh0bWxfbm90ZWJvb2s6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRoZW1lOiB5ZXRpDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KICBpb3NsaWRlc19wcmVzZW50YXRpb246DQogICAgd2lkZXNjcmVlbjogdHJ1ZQ0KICAgIHNtYWxsZXI6IHRydWUNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KICBzbGlkeV9wcmVzZW50YXRpb246IA0KICAgIHRoZW1lOiB5ZXRpDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQoNCg0KDQoNCltWaWV3IHRoZSBsYXRlc3QgcmVjb3JkaW5nIG9mIHRoaXMgbGVjdHVyZV0oaHR0cHM6Ly9SLVJlc291cmNlcy5tYXNzZXkuYWMubnovdmlkZW9zLzI1MUwxMy5tcDQpDQo8IS0tLSBEYXRhIGlzIG9uDQpodHRwczovL3ItcmVzb3VyY2VzLm1hc3NleS5hYy5uei9kYXRhLzE2MTI1MS8NCi0tLT4NCg0KYGBge3Igc2V0dXAsIHB1cmw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KGtuaXRyKQ0Kb3B0c19jaHVuayRzZXQoZGV2PWMoInBuZyIsICJwZGYiKSkNCm9wdHNfY2h1bmskc2V0KGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTcsIGZpZy5wYXRoPSJGaWd1cmVzLyIsIGZpZy5hbHQ9InVubGFiZWxsZWQiKQ0Kb3B0c19jaHVuayRzZXQoY29tbWVudD0iIiwgZmlnLmFsaWduPSJjZW50ZXIiLCB0aWR5PVRSVUUpDQpvcHRpb25zKGtuaXRyLmthYmxlLk5BID0gJycpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoYnJvb20pDQpgYGANCg0KDQo8IS0tLSBEbyBub3QgZWRpdCBhbnl0aGluZyBhYm92ZSB0aGlzIGxpbmUuIC0tLT4NCg0KTGluZWFyIHJlZ3Jlc3Npb24gbW9kZWxzIGNhbiBiZSBjb252ZW5pZW50bHkgZXhwcmVzc2VkIHVzaW5nIG1hdHJpeCAgbm90YXRpb24uDQoNCkluIHRoaXMgbGVjdHVyZSwgd2Ugd2lsbCBzZWUgaG93IHJlc3VsdHMgZm9yIGxpbmVhciBtb2RlbHMgYXJlIG11Y2ggbW9yZSBlYXNpbHkgZGVyaXZlZCBhbmQgdW5kZXJzdG9vZCB1c2luZyBtYXRyaXggbm90YXRpb24gdGhhbiB3aXRob3V0IGl0Lg0KDQpBbHNvIG5vdGUgdGhhdCB0aGUgbWF0cml4IGFwcHJvYWNoIGlzIHdoYXQgaXMgYmVpbmcgZG9uZSBpbiB0aGUgYmFja2dyb3VuZCBieSBhbGwgZ29vZCBzdGF0aXN0aWNhbCBzb2Z0d2FyZSBpbmNsdWRpbmcgUi4NCg0KIyMgTWF0cml4IEZvcm11bGF0aW9uIG9mIHRoZSBMaW5lYXIgTW9kZWwNCg0KJCRcYm9sZHN5bWJvbHt5fSA9IFgge1xib2xkc3ltYm9se1xiZXRhfX0gKyB7XGJvbGRzeW1ib2x7XHZhcmVwc2lsb259fQ0KXGxhYmVse2VxOm1hdHJpeExNfSQkDQoNCndoZXJlICRcYm9sZHN5bWJvbHt5fSQgaXMgdGhlIHJlc3BvbnNlIHZlY3RvciwgKlgqIGlzIHRoZSAqKm1vZGVsIG1hdHJpeCoqLCAke1xib2xkc3ltYm9se1xiZXRhfX0kIGlzIHRoZSB2ZWN0b3Igb2YgKnArMSogcmVncmVzc2lvbiBwYXJhbWV0ZXJzLCBhbmQgJHtcYm9sZHN5bWJvbHtcdmFyZXBzaWxvbn19JCBpcyB0aGUgdmVjdG9yIG9mICpuKiBlcnJvciB0ZXJtcy4NCg0KJFxib2xkc3ltYm9se3l9ID0gXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjfQ0KeV8xXFwNCnlfMlxcDQpcdmRvdHNcXA0KeV9uDQpcZW5ke2FycmF5fSBccmlnaHQgXSQsICRYID0gXGxlZnQgWyBcYmVnaW57YXJyYXl9e2NjY2N9DQoxICYgeF97MTF9ICYgXGxkb3RzICYgeF97MXB9XFwNCjEgJiB4X3syMX0gJiBcbGRvdHMgJiB4X3sycH1cXA0KXHZkb3RzICYgXHZkb3RzICYgXGRkb3RzICYgXHZkb3RzXFwNCjEgJiB4X3tuMX0gJiBcbGRvdHMgJiB4X3tucH0NClxlbmR7YXJyYXl9IFxyaWdodCBdJCwgJFxib2xkc3ltYm9se1xiZXRhfSA9IFxsZWZ0IFsNClxiZWdpbnthcnJheX17Y30NClxiZXRhXzBcXA0KXGJldGFfMVxcDQpcdmRvdHNcXA0KXGJldGFfcFxcDQpcZW5ke2FycmF5fSBccmlnaHQgXSQsIGFuZCAkXGJvbGRzeW1ib2x7XHZhcmVwc2lsb259ID0gXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjfQ0KXHZhcmVwc2lsb25fMVxcDQpcdmFyZXBzaWxvbl8yXFwNClx2ZG90c1xcDQpcdmFyZXBzaWxvbl9uXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXSQNCg0KDQpUaGUgbWVhbiAoZXhwZWN0ZWQpIHZhbHVlIG9mIHRoZSByYW5kb20gdmVjdG9yICRcYm9sZHN5bWJvbHt5fSQgaXMNCiAgICAkJFxiZWdpbnthbGlnbmVkfQ0KICAgIFxib2xkc3ltYm9se1xtdX0gJj0mIEVbXGJvbGRzeW1ib2x7eX1dXFwNCiAgICAgJj0mIFxsZWZ0IFsgXGJlZ2lue2FycmF5fXtjfSANCiAgICBFW3lfMV0gXFwgRVt5XzJdIFxcIFx2ZG90cyBcXCBFW3lfbl0gXGVuZHthcnJheX0gXHJpZ2h0IF0gXFwNCiAgICAgJj0mIEVbWCB7XGJvbGRzeW1ib2x7XGJldGF9fSArIHtcYm9sZHN5bWJvbHtcdmFyZXBzaWxvbn19XVxcICY9JiBYIHtcYm9sZHN5bWJvbHtcYmV0YX19XGVuZHthbGlnbmVkfSQkDQoNCiAgLSBIZXJlIHdlIGhhdmUgdXNlZCB0aGUgcmVzdWx0IHRoYXQgZm9yIGEgcmFuZG9tIHZlY3RvciAkXGJvbGRzeW1ib2x7en0kLCBhDQogICAgbWF0cml4ICpNKiBhbmQgYSAobm9ucmFuZG9tKSB2ZWN0b3IgJFxib2xkc3ltYm9se2F9JA0KICAgICQkRVtcYm9sZHN5bWJvbHthfSArIE1cYm9sZHN5bWJvbHt6fV0gPSBcYm9sZHN5bWJvbHthfSArIE0gRVtcYm9sZHN5bWJvbHt6fV0kJA0KDQojIyMgTGVhc3QgU3F1YXJlcyBFc3RpbWF0aW9uIGJ5IE1hdHJpY2VzDQoNCkZvciBvYnNlcnZlZCByZXNwb25zZXMgJFxib2xkc3ltYm9se3l9JCB0aGUgc3VtIG9mIHNxdWFyZWQgZXJyb3JzIGNhbiBiZQ0KICAgIHdyaXR0ZW4gYXMgJCRTUyh7XGJvbGRzeW1ib2x7XGJldGF9fSkgPSAoXGJvbGRzeW1ib2x7eX0gLSBYIHtcYm9sZHN5bWJvbHtcYmV0YX19KV5UIChcYm9sZHN5bWJvbHt5fSAtIFgge1xib2xkc3ltYm9se1xiZXRhfX0pLiQkDQoNCiAgLSBUaGlzIGNhbiBiZSBtaW5pbWlzZWQgdXNpbmcgbXVsdGl2YXJpYXRlICh2ZWN0b3IpIGNhbGN1bHVzIHRvIGdpdmUNCiAgICB0aGUgbGVhc3Qgc3F1YXJlcyBlc3RpbWF0ZXMgYXMNCiAgICAkJFxoYXR7e1xib2xkc3ltYm9se1xiZXRhfX19ID0gKFheVCBYKV57LTF9IFheVCBcYm9sZHN5bWJvbHt5fS4kJA0KDQojIyMgSG93IGRpZCB0aGF0IG1hdHJpeCBzb2x1dGlvbiBjb21lIGFib3V0Pw0KDQpTdGFydCB3aXRoICQkWCBcaGF0e3tcYm9sZHN5bWJvbHtcYmV0YX19fSA9XGJvbGRzeW1ib2x7eX0kJCBhbmQgZG8gYSBzZXJpZXMgb2YgcHJlLW11bHRpcGxpY2F0aW9uczogRmlyc3QgYnkgJFheVCQgKHRoZSB0cmFuc3Bvc2Ugb2YgdGhlICRYJCBtb2RlbCBtYXRyaXguDQokJFheVCBYIFxoYXR7e1xib2xkc3ltYm9se1xiZXRhfX19ID0gWF5UIFxib2xkc3ltYm9se3l9JCQsIHRoZW4gdGhlIGludmVyc2Ugb2YgJChYXlQgWCkkIHRvIGdpdmUNCiQkKFheVCBYKV57LTF9IChYXlQgWCkgXGhhdHt7XGJvbGRzeW1ib2x7XGJldGF9fX0gPSAoWF5UIFgpXnstMX0gWF5UIFxib2xkc3ltYm9se3l9JCQuDQoNCkFueXRoaW5nIG11bHRpcGxpZWQgYnkgaXRzIGludmVyc2UgaXMgZXF1YWwgdG8gdGhlIGlkZW50aXR5IG1hdHJpeCwgYW5kIGNhbmNlbHMgaXRzZWxmIG91dCwgcnJlZHVjaW5nIHRoZSBsZWZ0IGhhbmQgc2lkZSB0byBiZSB0aGUgcGFyYW1ldGVyIGVzdGltYXRlcyAkXGhhdHt7XGJvbGRzeW1ib2x7XGJldGF9fX0gJCB3ZSBzZWVrLg0KDQojIyMgU2ltcGxlIExpbmVhciBSZWdyZXNzaW9uIGluIG1hdHJpeCBmb3JtDQoNCkZvciBhIHNpbXBsZSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCB0aGUgbW9kZWwgbWF0cml4IGlzDQokJFggPSBcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjfQ0KMSAmIHhfezF9IFxcDQoxICYgeF97Mn0gXFwNClx2ZG90cyAmIFx2ZG90cyBcXA0KMSAmIHhfe259DQpcZW5ke2FycmF5fQ0KXHJpZ2h0IF0kJCBJZiB3ZSBvYnNlcnZlIHJlc3BvbnNlcyAkXGJvbGRzeW1ib2x7eX0kLCB0aGUgbGVhc3Qgc3F1YXJlcyBlc3RpbWF0ZQ0Kb2YgJHtcYm9sZHN5bWJvbHtcYmV0YX19JCBpczogJCRcYmVnaW57YWxpZ25lZH0NClxoYXR7XGJvbGRzeW1ib2x7XGJldGF9fSAmPSYgKFheVCBYKV57LTF9IFheVCBcYm9sZHN5bWJvbHt5fSA9IA0KXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjY30NCm4gJiBuIFxiYXJ7eH1cXA0KblxiYXJ7eH0gJiBcc3VtX2kgeF9pXjIgDQpcZW5ke2FycmF5fQ0KXHJpZ2h0IF1eey0xfSANClxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2NjY30NCjEgJiAxICYgXGxkb3RzICYgMSBcXA0KeF8xICYgeF8yICYgXGxkb3RzICYgeF9uIA0KXGVuZHthcnJheX0NClxyaWdodCBdDQpcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2N9DQp5XzFcXA0KeV8yXFwNClx2ZG90c1xcDQp5X24NClxlbmR7YXJyYXl9DQpccmlnaHQgXSBcXA0KICY9Jg0KXGZyYWN7MX17biBzX3t4eH19IFxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2N9DQpcc3VtX2kgeF9pXjIgJiAtIG4gXGJhcnt4fVxcDQotIG5cYmFye3h9ICYgbiANClxlbmR7YXJyYXl9DQpccmlnaHQgXSANClxsZWZ0IFsgDQpcYmVnaW57YXJyYXl9e2N9DQpuIFxiYXJ7eX1cXA0KXHN1bV9pIHhfaSB5X2kNClxlbmR7YXJyYXl9DQpccmlnaHQgXQ0KPSANClxmcmFjezF9e3Nfe3h4fX0gXGxlZnQgWyANClxiZWdpbnthcnJheX17Y30NClxiYXJ7eX0gXHN1bV9pIHhfaV4yIC0gXGJhcnt4fSBcc3VtX2l7eF9pIHlfaX0gXFwNCnNfe3h5fQ0KXGVuZHthcnJheX0NClxyaWdodCBdXGVuZHthbGlnbmVkfSQkDQoNCiMjIFByZWRpY3Rpb24gYW5kIFRoZSBIYXQgTWF0cml4DQoNClRoZSB2ZWN0b3Igb2YgZml0dGVkIHZhbHVlcyBpcyBnaXZlbiBieSAkXGhhdHtcYm9sZHN5bWJvbHtcbXV9fSA9IFggXGhhdHtcYm9sZHN5bWJvbHtcYmV0YX19ID0gWCAoWF5UWCleey0xfSBYXlQgXGJvbGRzeW1ib2x7eX0kIGFuZCB0aGUgdmVjdG9yIG9mIHJlc2lkdWFscyBieSAkXGJvbGRzeW1ib2x7ZX0gPSBcYm9sZHN5bWJvbHt5fSAtIFxoYXR7XGJvbGRzeW1ib2x7XG11fX0kLg0KDQoNClRoZSBlcXVhdGlvbiBmb3IgdGhlIGZpdHRlZCB2YWx1ZXMganVzdCBnaXZlbiwgY2FuIGJlIHJlLXdyaXR0ZW4gJFxoYXR7XGJvbGRzeW1ib2x7XG11fX0gPSBIIFxib2xkc3ltYm9se3l9ID0gXGhhdHtcYm9sZHN5bWJvbHt5fX0kICB3aGVyZSAqSCA9IFggKFheVF5YKV4tMV5YXlReKiBpcw0KICAgIG9mdGVuIGNhbGxlZCB0aGUgKipoYXQgbWF0cml4KiogYmVjYXVzZSBpdCAicHV0cyBoYXRzIG9uIHRoaW5ncyIhDQoNCldlIGhhdmUgdGhlIGVxdWFsaXR5ICRcaGF0e1xib2xkc3ltYm9se3l9fSA9IFxoYXR7XGJvbGRzeW1ib2x7XG11fX0kIGJlY2F1c2Ugd2UgdXNlIHRoZQ0KICAgIHNhbWUgdmFsdWVzIGZvciBwcmVkaWN0aW9uIGFuZCBtZWFuIGVzdGltYXRpb24uDQoNCiMjIENvdmFyaWFuY2UgTWF0cmljZXMNCg0KICAtIFRoZSB2YXJpYW5jZS1jb3ZhcmlhbmNlIChvciBzaW1wbGUgY292YXJpYW5jZSwgb3IgZGlzcGVyc2lvbiBtYXRyaXgpDQogICAgaGFzIHZhcmlhbmNlcyBkb3duIHRoZSBkaWFnb25hbCBhbmQgY292YXJpYW5jZXMgb2ZmIHRoZSBkaWFnb25hbC4NCg0KICAtIEl0IGNhbiBiZSBzaG93biB0aGF0IGZvciBhIG1hdHJpeCAqTSogYW5kIHJhbmRvbSB2ZWN0b3IgJFxib2xkc3ltYm9se3p9JA0KICAgIChvZiBhcHByb3ByaWF0ZSBkaW1lbnNpb25zKQ0KICAgICQkXG1ib3h7VmFyfSAoTVxib2xkc3ltYm9se3p9KSA9IE0gXG1ib3h7VmFyfSAoXGJvbGRzeW1ib2x7en0pIE1eVC4kJA0KDQojIyBUaGUgQ292YXJpYW5jZSBNYXRyaXggZm9yICRcaGF0e1xib2xkc3ltYm9se1xiZXRhfX0kDQoNClRoZSBjb3ZhcmlhbmNlIG1hdHJpeCBvZiAkXGhhdHtcYm9sZHN5bWJvbHtcYmV0YX19JCBpcyANCg0KJCRcYmVnaW57YWxpZ25lZH0NCiAgICBcbWJveHtWYXJ9KFxoYXR7XGJvbGRzeW1ib2x7XGJldGF9fSkgPSBcbWJveHtWYXJ9WyAoWF5UWCleey0xfSBYXlQgXGJvbGRzeW1ib2x7eX0gXSAmPSYgKFheVFgpXnstMX0gWF5UIFxtYm94e1Zhcn0oXGJvbGRzeW1ib2x7eX0pIFsoWF5UWCleey0xfSBYXlRdXlRcXA0KICAgICAgICAmPSYgKFheVFgpXnstMX0gWF5UIFxzaWdtYV4yIEkgWyhYXlRYKV57LTF9IFheVF1eVFxcDQogICAgICAgICY9JiBcc2lnbWFeMiAoWF5UWCleey0xfSBYXlRYIChYXlQgWCleey0xfVxcDQogICAgICAgICY9JiBcc2lnbWFeMiAoWF5UWCleey0xfVxlbmR7YWxpZ25lZH0kJA0KDQpXZSBjYW4gdXNlICRcbWJveHtWYXJ9KFxib2xkc3ltYm9se3l9KSA9IFxzaWdtYV4yIEkkIHNpbmNlIHRoZSByZXNwb25zZXMgYXJlDQogICAgaW5kZXBlbmRlbnQgYW5kIGhlbmNlIHVuY29ycmVsYXRlZC4NCg0KDQotIFRoZSB2YXJpYW5jZXMgZXhwcmVzcyB0aGUgdmFyaWFiaWxpdHkgb2YgdGhlIGVzdGltYXRvcnMgZnJvbSBzYW1wbGUNCiAgICB0byBzYW1wbGUuDQoNCi0gVGhlIGNvdmFyaWFuY2VzIGRlc2NyaWJlIHRoZSBpbnRlci1kZXBlbmRlbmNlIG9mIGVzdGltYXRvcnMuDQoNCg0KVGhlIGxlYWRpbmcgZGlhZ29uYWwgb2YgdGhpcyBtYXRyaXggaXMgdGhlIGJhc2lzIGZvciB0aGUgc3RhbmRhcmQgZXJyb3JzIG9mIG91ciBwYXJhbWV0ZXIgZXN0aW1hdGVzIHNlZW4gaW4gb3VyIHJlZ3Jlc3Npb24gb3V0cHV0Lg0KaXMg