Processing math: 73%

What does PCA do?

This methods tries to explain the correlation structure of a set of predictor variables using a smaller set o linear combinations of these variables called components, note that components are not variables, rather indicators of linear combinations between variables.
Given a dataset with m variables a set of k linear combinations can be used to represent it (meaning that k contains almost as much information as the m variables), also k<<m.

PCA Step by Step

1. Getting the dataset and things ready.

Before starting the process of dimensionality reduction one should make sure the data is standardized, this is done to avoid bised in the results by values to large or to small when compared to each other.

2. Centering the points

  • The standardization process is acomplished when the mean for each variable =0 and the standard deviation =1. The following formula can be followed to acomplish this process: Zi=(Xiμi)σii

Where: μi equals the mean of Xi and σii equals the standard deviation of Xi.

  • If the values are given as a set of points the process can be acomplished with the following formula:

xi,a=xi,aμa

This move will facilitate the calculations down the road.

3. Compute covariance (σX,Y) matrix

The covariance is a measure of the degree to which two variables vary together. Positive covariance indicates that when one variable increases, the other tends to increase. Negative covariance indicates that when one variable increases, the other tends to decrease. The covariance measure is not scaled.

In a 2x2 matrix: |2.00.80.80.6|

Since the mean (μ) is equal to thanks to centering the values in the previous step, the formula to calculate the covariance of the values in the matrix is: cov(x1,x2)=1nni=1xi,jxi,2 The way to interpret covariance is to understand it’s results as information about how one attribute changes as the other one changes.

It is important to remember that, if we multiply a vector by the covariance matrix or the resulting vector will turn towards the direction of the variance.

Changing the units of measure would change the results, this is an inconvenience and is addressed by calculating the correlation coefficient rij:

rij scales the covariance by each of the standard deviations: rij=σ2ijσiiσjj The rij gives us a value with reference to know how much of a correlation exists between two variables.

4. Eigenvectors + Eigenvalues

Define a new set of dimentions by:

  1. Taking the dataset and looking for the direction of the data, looking to draw a line in which, along it, there is the greatest amount of variance σ2 in the data, this line will be called the principal component 1 (PC1).

σ2=(Xμ)2N  or  σ2=X2Nμ2 In the previous formula σ2 is defined as the sum of the squared distances of each term in the distribution from the mean (μ2) divided by the number of terms in the distribution (N). In simple words: σ2 measures how far a set of random numbers are spread out from their mean.

  1. Once PC1 is determined, it will established the next dimension by drawing an orthogonal (perpendicular) line in relation to PC1, the exact area where the line will be drawn is determined by the same process of finding the gratest σ2 of the remaining data, once this is done PC2 is ready.

  2. This will be done iteratively until all the dimensions (d) of the dataset are covered and components (m) are generated for every single d.

  • The first m<<d components become m new dimensions.
    • Coordinates from every datapoint will be changed to these “new” dimensions.
  • Greatest variability is pursued to maintain the smoothness assumption of dimensions.


Eigenvectors and eigenvalues are mathematically expressed as:

Av=λv Where A represents transformation, v, a vector, also known as eigenvector, that comes out of the matrix being analysied and λ, a scalar value also known as eigenvalue.

Principal components = eigenvectors with largest eigenvalues.

Finding Eigenvalues and Eigenvectors

In order to exemplify the process of finding these values and vector steps are presented for a 2x2 matrix, but this can be done with any matrix of n x n dimensions following the rules of matrix algebra.

To begin with the example we will declare a matrix: A=[7331]

Now the steps:

  1. Multiply an n x n identity matrix by the scalar λ: IAλ
    [1001]λ=[λ00λ]

  2. Substract the identity matrix multiple from matrix A: AλI
    [7331][1001]=[7λ331λ]

  3. Find the determinant of the matrix obtained in previous step: det(AλI)
    det[7λ331λ]=(7λ)(1λ)(33) =77λ+λ+λ2=166λ+λ2 =λ26λ16

  4. Solve for the values of λ that satisfy the equation det(AλI)=0
    Solving for λ26λ16=0 will result in: (λ8)(λ+2)=0
    Therfore λ1=8 and λ2=2 these are the eigenvalues for matrix A.

  5. Solve for the corresponding vector to each λ

Solving for λ=8, in this process we will call the matrix with substituted values: B.

[7(8)331(8)]=[1339]

We will assume the following B¯X=0 

\left[ \begin{array}{cc} -1 & 3 \\ 3 & -9 \end{array} \right] \left[ \begin{array}{cc} x_1 \\ x_2 \end{array} \right] = \left[ \begin{array}{cc} 0 \\ 0 \end{array} \right]

Applying row reduction 3R_1 + R_2 = R_2 to: \left[ \begin{array}{cc|r} -1 & 3 & 0\\ 3 & -9 & 0 \end{array} \right] = \left[ \begin{array}{cc|r} -1 & 3 & 0\\ 0 & 0 & 0 \end{array} \right] \space \therefore -x_1+3x_2 = 0

From the previous operation we obtain 3x_2 = x_1, at this point we can choose a value for any x, we will go for x_2 = 1 to keep it simple.

3x_2 = x_1 \space \therefore 3(1) = x_1 \space \therefore \space x_1 = 3

Now we know that the eigenvalue \lambda = 8 $ corresponds to the eigenvector \overline X = (3,1).

Solving for \lambda -2, generating matrix C.
C = \left[ \begin{array}{cc} 7-(-2) & 3 \\ 3 & -1-(-2) \end{array} \right] C\overline X = 0 \space \therefore

\left[ \begin{array}{cc} 9 & 3 \\ 3 & 1 \end{array} \right] \left[ \begin{array}{c} x_1 \\ x_2 \end{array} \right] = \left[ \begin{array}{c} 0 \\ 0 \end{array} \right]

Applying row reduction 3R_2 - R_1 = R_1:

\left[ \begin{array}{cc|r} 0 & 0 & 0\\ 3 & 1 & 0 \end{array} \right] \space \therefore 3x_1 + x_2 = 0

Assigning x_1 = 1: x_2 = -3x_1 \space \therefore x_2 = -3(1)

The eigenvalue \lambda = 8 corresponds to the eigenvector \overline X = (1,-3)

5. Pick m<d eigenvectors with highest eigenvalues.

In other words, usually the 2 eigenvectors with the highest scalars, or \lambda, will be selected to represent the whole dataset as Principal Component 1 and Principal Component 2.

6. Project datapoints to those eigenvectors.

One or the algoritm has to project the datapoints to these new set of dimensions so they can be analyized.

7. Perform analysis as needed according to study.

Pros and Cons of PCA

This algorithm, as all, is better suited for specific circumstances and performs poorly in others. The following list trys to summarize this idea:

Pros

  • Reduction in size of data.
  • Allows estimation of probabilites in high-dimensional data.
  • It renders a set of components that are uncorrelated.

Cons

  • It has a high computational cost, therefore it cannot be applied to very large datasets.
  • Not good when working with fine-grained classes.
LS0tDQp0aXRsZTogIlByaW5jaXBhbCBDb21wb25lbnRzIEFuYWx5c2lzIFBDQSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQo8c2NyaXB0IHNyYz0iRDpcRHJvcGJveFxNc0MgVUFCQ1wybyBTZW1lc3RyZVxDbGFzZXNcRGF0YSBNaW5pbmdcZGF0YW1pbmluZ1xOb3Rlcy9oaWRlT3V0cHV0LmpzIj48L3NjcmlwdD4NCjxzY3JpcHQgc3JjPSJEOlxEcm9wYm94XE1zQyBVQUJDXDJvIFNlbWVzdHJlXENsYXNlc1xEYXRhIE1pbmluZ1xkYXRhbWluaW5nXE5vdGVzL2J1dHRvblN0eWxlLmNzcyI+PC9zY3JpcHQ+DQoNCg0KIyMqKldoYXQqKiBkb2VzIFBDQSBkbz8NCg0KVGhpcyBtZXRob2RzIHRyaWVzIHRvIGV4cGxhaW4gdGhlIGNvcnJlbGF0aW9uIHN0cnVjdHVyZSBvZiBhIHNldCBvZiBwcmVkaWN0b3IgdmFyaWFibGVzIHVzaW5nIGEgc21hbGxlciBzZXQgbyBsaW5lYXIgY29tYmluYXRpb25zIG9mIHRoZXNlIHZhcmlhYmxlcyBjYWxsZWQgKioqY29tcG9uZW50cyoqKiwgbm90ZSB0aGF0ICpjb21wb25lbnRzKiBhcmUgbm90IHZhcmlhYmxlcywgcmF0aGVyIGluZGljYXRvcnMgb2YgbGluZWFyIGNvbWJpbmF0aW9ucyBiZXR3ZWVuIHZhcmlhYmxlcy48YnIgXD4NCkdpdmVuIGEgZGF0YXNldCB3aXRoICRtJCB2YXJpYWJsZXMgYSBzZXQgb2YgJGskIGxpbmVhciBjb21iaW5hdGlvbnMgY2FuIGJlIHVzZWQgdG8gcmVwcmVzZW50IGl0IChtZWFuaW5nIHRoYXQgJGskIGNvbnRhaW5zIGFsbW9zdCBhcyBtdWNoIGluZm9ybWF0aW9uIGFzIHRoZSAkbSQgdmFyaWFibGVzKSwgYWxzbyAkazw8bSQuDQoNCiMjKipQQ0EgU3RlcCBieSBTdGVwKioNCg0KIyMjMS4gR2V0dGluZyB0aGUgZGF0YXNldCBhbmQgdGhpbmdzIHJlYWR5Lg0KDQoNCkJlZm9yZSBzdGFydGluZyB0aGUgcHJvY2VzcyBvZiBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gb25lIHNob3VsZCBtYWtlIHN1cmUgdGhlIGRhdGEgaXMgc3RhbmRhcmRpemVkLCB0aGlzIGlzIGRvbmUgdG8gYXZvaWQgYmlzZWQgaW4gdGhlIHJlc3VsdHMgYnkgdmFsdWVzIHRvIGxhcmdlIG9yIHRvIHNtYWxsIHdoZW4gY29tcGFyZWQgdG8gZWFjaCBvdGhlci4gPGJyIFw+PGJyIFw+DQoNCiMjIyAyLiBDZW50ZXJpbmcgdGhlIHBvaW50cw0KDQogIC0gVGhlICoqc3RhbmRhcmRpemF0aW9uIHByb2Nlc3MqKiBpcyBhY29tcGxpc2hlZCB3aGVuIHRoZSBtZWFuIGZvciBlYWNoIHZhcmlhYmxlICQ9MCQgYW5kIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gJD0xJC4gVGhlIGZvbGxvd2luZyBmb3JtdWxhIGNhbiBiZSBmb2xsb3dlZCB0byBhY29tcGxpc2ggdGhpcyBwcm9jZXNzOg0KJCRaX2kgPSBcZnJhYyB7KFhfaS1cbXVfaSl9e1xzaWdtYV97aWl9fSQkDQoNCg0KV2hlcmU6ICRcbXVfaSQgZXF1YWxzIHRoZSBtZWFuIG9mICRYX2kkIGFuZCAkXHNpZ21hX3tpaX0kIGVxdWFscyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mICRYX2kkLiA8YnIgXD48YnIgXD4NCg0KICAtIElmIHRoZSB2YWx1ZXMgYXJlIGdpdmVuIGFzIGEgc2V0IG9mIHBvaW50cyB0aGUgcHJvY2VzcyBjYW4gYmUgYWNvbXBsaXNoZWQgd2l0aCB0aGUgZm9sbG93aW5nIGZvcm11bGE6DQoNCiQkeF97aSxhfSA9IHhfe2ksYX0gLSBcbXVfYSQkDQoNClRoaXMgbW92ZSB3aWxsIGZhY2lsaXRhdGUgdGhlIGNhbGN1bGF0aW9ucyBkb3duIHRoZSByb2FkLg0KDQoNCiMjIzMuIENvbXB1dGUgY292YXJpYW5jZSAoJFxzaWdtYV97WCxZfSQpIG1hdHJpeA0KDQpUaGUgKipjb3ZhcmlhbmNlKiogaXMgYSBtZWFzdXJlIG9mIHRoZSBkZWdyZWUgdG8gd2hpY2ggdHdvIHZhcmlhYmxlcyB2YXJ5IHRvZ2V0aGVyLiBQb3NpdGl2ZSBjb3ZhcmlhbmNlIGluZGljYXRlcyB0aGF0IHdoZW4gb25lIHZhcmlhYmxlIGluY3JlYXNlcywgdGhlIG90aGVyIHRlbmRzIHRvIGluY3JlYXNlLiBOZWdhdGl2ZSBjb3ZhcmlhbmNlIGluZGljYXRlcyB0aGF0IHdoZW4gb25lIHZhcmlhYmxlIGluY3JlYXNlcywgdGhlIG90aGVyIHRlbmRzIHRvIGRlY3JlYXNlLg0KVGhlIGNvdmFyaWFuY2UgbWVhc3VyZSAqKmlzIG5vdCBzY2FsZWQqKi4NCg0KSW4gYSAkMngyJCBtYXRyaXg6DQokJFxiZWdpbnt2bWF0cml4fQ0KMi4wICYgMC44IFxcDQowLjggJiAwLjYNClxlbmR7dm1hdHJpeH0kJA0KDQpTaW5jZSB0aGUgbWVhbiAoJFxtdSQpIGlzIGVxdWFsIHRvICRcZW1wdHlzZXQkIHRoYW5rcyB0byAqY2VudGVyaW5nKiB0aGUgdmFsdWVzIGluIHRoZSBwcmV2aW91cyBzdGVwLCB0aGUgZm9ybXVsYSB0byBjYWxjdWxhdGUgdGhlIGNvdmFyaWFuY2Ugb2YgdGhlIHZhbHVlcyBpbiB0aGUgbWF0cml4IGlzOg0KJCRjb3YoeF8xLHhfMikgPSBcZnJhY3sxfXtufVxzdW1fe2k9MX1ee259eF97aSxqfXhfe2ksMn0kJA0KKipUaGUgd2F5IHRvIGludGVycHJldCAqY292YXJpYW5jZSogaXMgdG8gdW5kZXJzdGFuZCBpdCdzIHJlc3VsdHMgYXMgaW5mb3JtYXRpb24gYWJvdXQgaG93IG9uZSBhdHRyaWJ1dGUgY2hhbmdlcyBhcyB0aGUgb3RoZXIgb25lIGNoYW5nZXMuKioNCg0KSXQgaXMgaW1wb3J0YW50IHRvIHJlbWVtYmVyIHRoYXQsIGlmIHdlIG11bHRpcGx5IGEgdmVjdG9yIGJ5IHRoZSBjb3ZhcmlhbmNlIG1hdHJpeCBvciAkXHN1bSQgdGhlIHJlc3VsdGluZyB2ZWN0b3Igd2lsbCB0dXJuIHRvd2FyZHMgdGhlIGRpcmVjdGlvbiBvZiB0aGUgdmFyaWFuY2UuDQoNCkNoYW5naW5nIHRoZSB1bml0cyBvZiBtZWFzdXJlIHdvdWxkIGNoYW5nZSB0aGUgcmVzdWx0cywgdGhpcyBpcyBhbiBpbmNvbnZlbmllbmNlIGFuZCBpcyBhZGRyZXNzZWQgYnkgY2FsY3VsYXRpbmcgdGhlICoqKmNvcnJlbGF0aW9uIGNvZWZmaWNpZW50ICRyX3tpan0kKioqOg0KDQokcl97aWp9JCBzY2FsZXMgdGhlIGNvdmFyaWFuY2UgYnkgZWFjaCBvZiB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uczoNCiQkcl97aWp9ID0gXGZyYWN7XHNpZ21hX3tpan1eMn17XHNpZ21hX3tpaX0gXHNpZ21hX3tqan19JCQNCioqVGhlICRyX3tpan0kIGdpdmVzIHVzIGEgdmFsdWUgd2l0aCByZWZlcmVuY2UgdG8ga25vdyBob3cgbXVjaCBvZiBhIGNvcnJlbGF0aW9uIGV4aXN0cyBiZXR3ZWVuIHR3byB2YXJpYWJsZXMuKioNCg0KDQojIyM0LiBFaWdlbnZlY3RvcnMgKyBFaWdlbnZhbHVlcw0KDQpEZWZpbmUgYSAqKm5ldyBzZXQgb2YgZGltZW50aW9ucyoqIGJ5Og0KDQogIDEuIFRha2luZyB0aGUgZGF0YXNldCBhbmQgbG9va2luZyBmb3IgdGhlIGRpcmVjdGlvbiBvZiB0aGUgZGF0YSwgbG9va2luZyB0byBkcmF3IGEgbGluZSBpbiB3aGljaCwgYWxvbmcgaXQsIHRoZXJlIGlzIHRoZSAqKmdyZWF0ZXN0IGFtb3VudCBvZiB2YXJpYW5jZSAkXHNpZ21hXjIkKiogaW4gdGhlIGRhdGEsIHRoaXMgbGluZSB3aWxsIGJlIGNhbGxlZCB0aGUgKipwcmluY2lwYWwgY29tcG9uZW50IDEgKFBDMSkqKi4NCiAgICANCiQkXHNpZ21hXjIgPSBcZnJhY3tcc3VtKFgtXG11KV4yfXtOfVxzcGFjZSBcc3BhY2UgIFx0ZXh0e29yfVxzcGFjZSBcc3BhY2UgXHNpZ21hXjIgPSBcZnJhY3tcc3VtIFheMn17Tn0gLSBcbXVeMiQkDQogKkluIHRoZSBwcmV2aW91cyBmb3JtdWxhICRcc2lnbWFeMiQgaXMgZGVmaW5lZCBhcyB0aGUgc3VtIG9mIHRoZSBzcXVhcmVkIGRpc3RhbmNlcyBvZiBlYWNoIHRlcm0gaW4gdGhlIGRpc3RyaWJ1dGlvbiBmcm9tIHRoZSBtZWFuICgkXG11XjIkKSBkaXZpZGVkIGJ5IHRoZSBudW1iZXIgb2YgdGVybXMgaW4gdGhlIGRpc3RyaWJ1dGlvbiAoJE4kKS4gSW4gc2ltcGxlIHdvcmRzOiAkXHNpZ21hXjIkIG1lYXN1cmVzICoqaG93IGZhciBhIHNldCBvZiByYW5kb20gbnVtYmVycyBhcmUgc3ByZWFkIG91dCBmcm9tIHRoZWlyIG1lYW4qKi4qDQoNCiAgMi4gT25jZSBQQzEgaXMgZGV0ZXJtaW5lZCwgaXQgd2lsbCBlc3RhYmxpc2hlZCB0aGUgbmV4dCBkaW1lbnNpb24gYnkgZHJhd2luZyBhbiAqKipvcnRob2dvbmFsKioqIChwZXJwZW5kaWN1bGFyKSBsaW5lIGluIHJlbGF0aW9uIHRvIFBDMSwgdGhlIGV4YWN0IGFyZWEgd2hlcmUgdGhlIGxpbmUgd2lsbCBiZSBkcmF3biBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBzYW1lIHByb2Nlc3Mgb2YgZmluZGluZyB0aGUgZ3JhdGVzdCAkXHNpZ21hXjIkIG9mIHRoZSByZW1haW5pbmcgZGF0YSwgb25jZSB0aGlzIGlzIGRvbmUgUEMyIGlzIHJlYWR5Lg0KDQogIDMuIFRoaXMgd2lsbCBiZSBkb25lIGl0ZXJhdGl2ZWx5IHVudGlsIGFsbCB0aGUgZGltZW5zaW9ucyAoJGQkKSBvZiB0aGUgZGF0YXNldCBhcmUgY292ZXJlZCBhbmQgY29tcG9uZW50cyAoJG0kKSBhcmUgZ2VuZXJhdGVkIGZvciBldmVyeSBzaW5nbGUgJGQkLg0KDQogIC0gVGhlIGZpcnN0ICRtPDxkJCBjb21wb25lbnRzIGJlY29tZSAkbSQgbmV3IGRpbWVuc2lvbnMuDQogICAgLSBDb29yZGluYXRlcyBmcm9tIGV2ZXJ5IGRhdGFwb2ludCB3aWxsIGJlIGNoYW5nZWQgdG8gdGhlc2UgIm5ldyIgZGltZW5zaW9ucy4NCiAgDQogIC0gKipHcmVhdGVzdCB2YXJpYWJpbGl0eSoqIGlzIHB1cnN1ZWQgdG8gbWFpbnRhaW4gdGhlIFsqc21vb3RobmVzcypdKGh0dHBzOi8vcnB1YnMuY29tL2dlbmVyYXZpbGVzLzI0ODY5MikgYXNzdW1wdGlvbiBvZiBkaW1lbnNpb25zLg0KDQo8YnIgXD4NCkVpZ2VudmVjdG9ycyBhbmQgZWlnZW52YWx1ZXMgYXJlIG1hdGhlbWF0aWNhbGx5IGV4cHJlc3NlZCBhczoNCg0KJCRBIFxvdmVycmlnaHRhcnJvd3t2fSA9IFxsYW1iZGEgXG92ZXJyaWdodGFycm93e3Z9JCQNCldoZXJlICRBJCByZXByZXNlbnRzICp0cmFuc2Zvcm1hdGlvbiosICRcb3ZlcnJpZ2h0YXJyb3d7dn0kLCBhIHZlY3RvciwgYWxzbyBrbm93biBhcyAqKmVpZ2VudmVjdG9yKiosIHRoYXQgY29tZXMgb3V0IG9mIHRoZSBtYXRyaXggYmVpbmcgYW5hbHlzaWVkIGFuZCAkXGxhbWJkYSQsIGEgc2NhbGFyIHZhbHVlIGFsc28ga25vd24gYXMgKiplaWdlbnZhbHVlKiouDQoNCioqUHJpbmNpcGFsIGNvbXBvbmVudHMgPSBlaWdlbnZlY3RvcnMgd2l0aCBsYXJnZXN0IGVpZ2VudmFsdWVzLioqPGJyIFw+PGJyIFw+DQoNCiMjIyNGaW5kaW5nIEVpZ2VudmFsdWVzIGFuZCBFaWdlbnZlY3RvcnMNCg0KSW4gb3JkZXIgdG8gZXhlbXBsaWZ5IHRoZSBwcm9jZXNzIG9mIGZpbmRpbmcgdGhlc2UgdmFsdWVzIGFuZCB2ZWN0b3Igc3RlcHMgYXJlIHByZXNlbnRlZCBmb3IgYSAkMngyJCBtYXRyaXgsIGJ1dCB0aGlzIGNhbiBiZSBkb25lIHdpdGggYW55IG1hdHJpeCBvZiAkblxzcGFjZSB4XHNwYWNlIG4kIGRpbWVuc2lvbnMgZm9sbG93aW5nIHRoZSBydWxlcyBvZiBtYXRyaXggYWxnZWJyYS4NCg0KVG8gYmVnaW4gd2l0aCB0aGUgZXhhbXBsZSB3ZSB3aWxsIGRlY2xhcmUgYSBtYXRyaXg6DQogICQkQSA9ICBcbGVmdFsgXGJlZ2lue2FycmF5fXtjY2N9DQo3ICYgMyBcXA0KMyAmIC0xICBcZW5ke2FycmF5fSBccmlnaHRdJCQNCg0KTm93IHRoZSBzdGVwczoNCg0KICAxLiAqKk11bHRpcGx5IGFuICRuXHNwYWNlIHhcc3BhY2UgbiQgaWRlbnRpdHkgbWF0cml4IGJ5IHRoZSBzY2FsYXIgJFxsYW1iZGEkOiAkSUFcbGFtYmRhJCoqPGJyIFw+DQogICQkXGxlZnRbIFxiZWdpbnthcnJheX17Y2N9DQoxICYgMCBcXA0KMCAmIDEgIFxlbmR7YXJyYXl9IFxyaWdodF0gKiBcbGFtYmRhID0gXGxlZnRbIFxiZWdpbnthcnJheX17Y2N9DQpcbGFtYmRhICYgMCBcXA0KMCAmIFxsYW1iZGEgIFxlbmR7YXJyYXl9IFxyaWdodF0kJA0KICANCiAgMS4gKipTdWJzdHJhY3QgdGhlIGlkZW50aXR5IG1hdHJpeCBtdWx0aXBsZSBmcm9tIG1hdHJpeCBBOiAkQS1cbGFtYmRhIEkkKio8YnIgXD4NCiAgJCRcbGVmdFsgXGJlZ2lue2FycmF5fXtjY30NCjcgJiAzIFxcDQozICYgLTEgIFxlbmR7YXJyYXl9IFxyaWdodF0gLSBcbGVmdFsgXGJlZ2lue2FycmF5fXtjY30NCjEgJiAwIFxcDQowICYgMSAgXGVuZHthcnJheX0gXHJpZ2h0XSA9IFxsZWZ0WyBcYmVnaW57YXJyYXl9e2NjfQ0KNy1cbGFtYmRhICYgMyBcXA0KMyAmIC0xLVxsYW1iZGEgIFxlbmR7YXJyYXl9IFxyaWdodF0kJA0KICANCiAgMS4gKipGaW5kIHRoZSBkZXRlcm1pbmFudCBvZiB0aGUgbWF0cml4IG9idGFpbmVkIGluIHByZXZpb3VzIHN0ZXA6ICRkZXQoQS1cbGFtYmRhIEkpJCoqPGJyIFw+DQogICQkIGRldFxsZWZ0WyBcYmVnaW57YXJyYXl9e2NjfQ0KNy1cbGFtYmRhICYgMyBcXA0KMyAmIC0xLVxsYW1iZGEgIFxlbmR7YXJyYXl9IFxyaWdodF0gPSAoNy1cbGFtYmRhKSgtMS1cbGFtYmRhKS0oMyozKSQkDQokJD0gLSA3IC0gNyBcbGFtYmRhICsgXGxhbWJkYSArIFxsYW1iZGFeMiA9IC0xNi02XGxhbWJkYSArIFxsYW1iZGFeMiQkDQokJD0gXGxhbWJkYV4yIC0gNlxsYW1iZGEgLTE2JCQNCiAgDQogIDEuICoqU29sdmUgZm9yIHRoZSB2YWx1ZXMgb2YgJFxsYW1iZGEkIHRoYXQgc2F0aXNmeSB0aGUgZXF1YXRpb24gJGRldChBLVxsYW1iZGEgSSk9MCQqKiA8YnIgXD4NCiAgU29sdmluZyBmb3IgJFxsYW1iZGFeMiAtIDZcbGFtYmRhIC0xNiA9IDAkIHdpbGwgcmVzdWx0IGluOiAkJChcbGFtYmRhLTgpKFxsYW1iZGErMik9MCQkDQo8YnIgXD4NClRoZXJmb3JlICRcbGFtYmRhXzEgPSA4JCBhbmQgJFxsYW1iZGFfMiA9IC0yJCAqKnRoZXNlIGFyZSB0aGUgZWlnZW52YWx1ZXMgZm9yIG1hdHJpeCAkQSQuKiogPGJyIFw+DQogIA0KICAxLiAqKlNvbHZlIGZvciB0aGUgY29ycmVzcG9uZGluZyB2ZWN0b3IgdG8gZWFjaCAkXGxhbWJkYSQqKg0KICANCiAgKipTb2x2aW5nIGZvciAqKiRcbGFtYmRhID0gOCQqKiwgaW4gdGhpcyBwcm9jZXNzIHdlIHdpbGwgY2FsbCB0aGUgbWF0cml4IHdpdGggc3Vic3RpdHV0ZWQgdmFsdWVzOiAkQiQuKio8YnIgXD4NCiAgDQogICQkIFxsZWZ0WyBcYmVnaW57YXJyYXl9e2NjfQ0KNy0oOCkgJiAzIFxcDQozICYgLTEtKDgpICBcZW5ke2FycmF5fSBccmlnaHRdID0gIFxsZWZ0WyBcYmVnaW57YXJyYXl9e2NjfQ0KLTEgJiAzIFxcDQozICYgLTkgIFxlbmR7YXJyYXl9IFxyaWdodF0kJA0KDQpXZSB3aWxsIGFzc3VtZSB0aGUgZm9sbG93aW5nICRCIFxvdmVybGluZSBYID0gMCBcc3BhY2UgXHRoZXJlZm9yZSQNCg0KJCRcbGVmdFsgXGJlZ2lue2FycmF5fXtjY30NCi0xICYgMyBcXA0KMyAmIC05ICBcZW5ke2FycmF5fSBccmlnaHRdIFxsZWZ0WyBcYmVnaW57YXJyYXl9e2NjfQ0KeF8xIFxcDQp4XzIgXGVuZHthcnJheX0gXHJpZ2h0XSA9IFxsZWZ0WyBcYmVnaW57YXJyYXl9e2NjfQ0KMCBcXA0KMCBcZW5ke2FycmF5fSBccmlnaHRdJCQNCg0KQXBwbHlpbmcgcm93IHJlZHVjdGlvbiAkM1JfMSArIFJfMiA9IFJfMiQgdG86DQokJFxsZWZ0WyBcYmVnaW57YXJyYXl9e2NjfHJ9DQotMSAmIDMgJiAwXFwNCjMgJiAtOSAmIDAgIFxlbmR7YXJyYXl9IFxyaWdodF0gPSBcbGVmdFsgXGJlZ2lue2FycmF5fXtjY3xyfQ0KLTEgJiAzICYgMFxcDQowICYgMCAmIDAgIFxlbmR7YXJyYXl9IFxyaWdodF0gXHNwYWNlIFx0aGVyZWZvcmUgLXhfMSszeF8yID0gMCQkDQoNCkZyb20gdGhlIHByZXZpb3VzIG9wZXJhdGlvbiB3ZSBvYnRhaW4gJDN4XzIgPSB4XzEkLCBhdCB0aGlzIHBvaW50IHdlIGNhbiBjaG9vc2UgYSB2YWx1ZSBmb3IgYW55ICR4JCwgd2Ugd2lsbCBnbyBmb3IgJHhfMiA9IDEkIHRvIGtlZXAgaXQgc2ltcGxlLg0KDQokJDN4XzIgPSB4XzEgXHNwYWNlIFx0aGVyZWZvcmUgMygxKSA9IHhfMSBcc3BhY2UgXHRoZXJlZm9yZSBcc3BhY2UgeF8xID0gMyQkDQoNCioqTm93IHdlIGtub3cgdGhhdCB0aGUgZWlnZW52YWx1ZSAkXGxhbWJkYSA9IDgkICQgY29ycmVzcG9uZHMgdG8gdGhlIGVpZ2VudmVjdG9yICRcb3ZlcmxpbmUgWCA9ICgzLDEpJC4qKjxiciBcPjxiciBcPg0KDQoqKlNvbHZpbmcgZm9yICRcbGFtYmRhIC0yJCwgZ2VuZXJhdGluZyBtYXRyaXggJEMkLioqPGJyIFw+DQokJEMgPSBcbGVmdFsgXGJlZ2lue2FycmF5fXtjY30NCjctKC0yKSAmIDMgXFwNCjMgJiAtMS0oLTIpICBcZW5ke2FycmF5fSBccmlnaHRdJCQNCiRDXG92ZXJsaW5lIFggPSAwIFxzcGFjZSBcdGhlcmVmb3JlJA0KDQokJFxsZWZ0WyBcYmVnaW57YXJyYXl9e2NjfQ0KOSAmIDMgXFwNCjMgJiAxICBcZW5ke2FycmF5fSBccmlnaHRdIFxsZWZ0WyBcYmVnaW57YXJyYXl9e2N9DQp4XzEgXFwNCnhfMiAgXGVuZHthcnJheX0gXHJpZ2h0XSA9IFxsZWZ0WyBcYmVnaW57YXJyYXl9e2N9DQowIFxcDQowICBcZW5ke2FycmF5fSBccmlnaHRdJCQNCg0KQXBwbHlpbmcgcm93IHJlZHVjdGlvbiAkM1JfMiAtIFJfMSA9IFJfMSQ6DQoNCiQkXGxlZnRbIFxiZWdpbnthcnJheX17Y2N8cn0NCjAgJiAwICYgMFxcDQozICYgMSAmIDAgXGVuZHthcnJheX0gXHJpZ2h0XSBcc3BhY2UgXHRoZXJlZm9yZSAzeF8xICsgeF8yID0gMCQkDQoNCkFzc2lnbmluZyAkeF8xID0gMSQ6DQokJHhfMiA9IC0zeF8xIFxzcGFjZSBcdGhlcmVmb3JlIHhfMiA9IC0zKDEpJCQNCg0KKipUaGUgZWlnZW52YWx1ZSAkXGxhbWJkYSA9IDgkIGNvcnJlc3BvbmRzIHRvIHRoZSBlaWdlbnZlY3RvciAkXG92ZXJsaW5lIFggPSAoMSwtMykkKio8YnIgXD48YnIgXD4NCg0KIyMjNS4gUGljayAkbTxkJCBlaWdlbnZlY3RvcnMgd2l0aCBoaWdoZXN0IGVpZ2VudmFsdWVzLg0KSW4gb3RoZXIgd29yZHMsIHVzdWFsbHkgdGhlICoqMioqIGVpZ2VudmVjdG9ycyB3aXRoIHRoZSBoaWdoZXN0IHNjYWxhcnMsIG9yICRcbGFtYmRhJCwgd2lsbCBiZSBzZWxlY3RlZCB0byByZXByZXNlbnQgdGhlIHdob2xlIGRhdGFzZXQgYXMgKlByaW5jaXBhbCBDb21wb25lbnQgMSogYW5kICpQcmluY2lwYWwgQ29tcG9uZW50IDIqLg0KDQojIyM2LiBQcm9qZWN0IGRhdGFwb2ludHMgdG8gdGhvc2UgZWlnZW52ZWN0b3JzLg0KDQpPbmUgb3IgdGhlIGFsZ29yaXRtIGhhcyB0byBwcm9qZWN0IHRoZSBkYXRhcG9pbnRzIHRvIHRoZXNlIG5ldyBzZXQgb2YgZGltZW5zaW9ucyBzbyB0aGV5IGNhbiBiZSBhbmFseWl6ZWQuDQoNCiMjIzcuIFBlcmZvcm0gYW5hbHlzaXMgYXMgbmVlZGVkIGFjY29yZGluZyB0byBzdHVkeS4NCg0KDQojIyBQcm9zIGFuZCBDb25zIG9mIFBDQQ0KDQpUaGlzIGFsZ29yaXRobSwgYXMgYWxsLCBpcyBiZXR0ZXIgc3VpdGVkIGZvciBzcGVjaWZpYyBjaXJjdW1zdGFuY2VzIGFuZCBwZXJmb3JtcyBwb29ybHkgaW4gb3RoZXJzLiBUaGUgZm9sbG93aW5nIGxpc3QgdHJ5cyB0byBzdW1tYXJpemUgdGhpcyBpZGVhOg0KDQojIyMjKipQcm9zKioNCiAgDQogIC0gUmVkdWN0aW9uIGluIHNpemUgb2YgZGF0YS4NCiAgLSBBbGxvd3MgZXN0aW1hdGlvbiBvZiBwcm9iYWJpbGl0ZXMgaW4gaGlnaC1kaW1lbnNpb25hbCBkYXRhLg0KICAtIEl0IHJlbmRlcnMgYSBzZXQgb2YgY29tcG9uZW50cyB0aGF0IGFyZSB1bmNvcnJlbGF0ZWQuDQogIA0KICANCiMjIyMqKkNvbnMqKg0KDQogIC0gSXQgaGFzIGEgaGlnaCBjb21wdXRhdGlvbmFsIGNvc3QsIHRoZXJlZm9yZSBpdCBjYW5ub3QgYmUgYXBwbGllZCB0byB2ZXJ5IGxhcmdlIGRhdGFzZXRzLg0KICAtIE5vdCBnb29kIHdoZW4gd29ya2luZyB3aXRoIGZpbmUtZ3JhaW5lZCBjbGFzc2VzLg0KICANCg==