Matemáticas para Machine Learning

Algebra Lineal cumple un importante rol en el ámbito del Aprendizaje Automático (Machine Learning). Esto por su estudio profundo de vectores, matrices, funciones lineales, entre otras ramas.

Al momento del uso de modelos de Machine Learning, estos manejan los datos representándolos como Matrices. Posterior se procede a su manipulación matemática, por esta razón es importante el conocimiento de Algebra Lineal para poder desempeñar de una manera optima los modelos de Machine Learning.

1.- Escalares, Vectores, Matrices y Tensores

“Broadly speaking, in Linear Algebra, data is represented in the form of linear equations. These linear equations are in turn represented in the form of matrices and vectors”

Vignesh Natarajan

1.1.- Escalares:

  • Un numero simple es un escalar (como por ejemplo: x = 23). A su vez es el ejemplo de un tensor de orden 0.

  • Es necesario describir el conjunto de valores al cual pertenece dicho escalar.

\[ a = 2 \] \[ b = 3.1416 \]


1.2.- Vectores:

  • Es una lista de números.

  • Hay dos maneras de interpretarlo. Primero, como un vector en un punto del espacio, donde los números que están en la lista son una manera para identificar al dicho punto en el espacio. Segundo, como una magnitud y dirección, como por ejemplo la velocidad.

  • Hay dos maneras de interpretar los vectores, una vendría siendo por el lado de la Física, y el otro por el lado de las Ciencias de la Computación.

\[ a = \{1,2,3,4\} \]


1.3.- Matrices:

  • Una matriz es parecida a un vector, en el sentido en que ambas son colecciones de números.

  • La diferencia entre una matriz y un vector, es que la primera es una tabla de números, y no así una lista.

\[ A= \begin{bmatrix} a_{11} & a_{12} & a_{13} & ... & a_{1n}\\ a_{21} & a_{22} & a_{23} & ... & a_{2n}\\ a_{31} & a_{32} & a_{33} & ... & a_{3n}\\ . & . & . & . & . \\ . & . & . & . & . \\ . & . & . & . & . \\ a_{m1} & a_{m2} & a_{m3} & ... & a_{mn}\\ \end{bmatrix} \]


1.4.- Tensores:

  • Un tensor es una generalización de vectores y matrices y se entiende fácilmente como una matriz multidimensional.


1.5.- En resumen:

Podemos interpretar de la siguiente manera gráfica:


- A continuación se presenta un vídeo obtenido de YouTube explicando conceptos y definiciones:

2.- Operaciones

2.1.- Operaciones con Vectores:

Adición de Vectores

\[ \vec{R} + \vec{S} = \vec{T} \] \[ R + S = S + R \] \[ (R_x,R_y) + (S_x,S_y) = (T_x,T_y) \]


Sustracción de Vectores

\[ \vec{R} - \vec{S} = \vec{U} \] \[ R - S = U \] \[ (R_x,R_y) - (S_x,S_y) = (U_x,U_y) \]


Multiplicación de Vectores:

  • Multiplicación de escalar con matriz

\[ 2\times r = \begin{bmatrix} 2\times3\\ 2\times2 \end{bmatrix} = \begin{bmatrix} 6\\ 4 \end{bmatrix} \]


2.2.- Operaciones con Matrices

Multiplicación de Escalar con Matriz:

  • Cuando un Escalar es multiplicado con una Matriz, esta se realiza con todos los números que yacen en la Matriz.

\[ 3\times \begin{pmatrix} 4 & 1 & 7\\ 5 & 9 & 12 \end{pmatrix} = \begin{pmatrix} 3\times4 & 3\times1 & 3\times7\\ 3\times5 & 3\times9 & 3\times12 \end{pmatrix} = \begin{pmatrix} 12 & 3 & 21\\ 15 & 27 & 36 \end{pmatrix} \]


Producto Dot:

  • Para multiplicar una matriz con otra matriz podemos realizarlo con el Dot Product.

\[ \begin{bmatrix} a & b \end{bmatrix} ● \begin{bmatrix} x\\ y \end{bmatrix} = \begin{bmatrix} ax + by \end{bmatrix} \] \[ \begin{bmatrix} a & b\\ c & d \end{bmatrix} ● \begin{bmatrix} x\\ y \end{bmatrix} = \begin{bmatrix} ax + by\\ cx + dy \end{bmatrix} \] \[ \begin{bmatrix} a & b\\ c & d \end{bmatrix} ● \begin{bmatrix} w & x\\ y & z \end{bmatrix} = \begin{bmatrix} aw + by & ax + bz\\ cw + dy & cx + dz \end{bmatrix} \]


Producto Hadamard:

  • Otra manera de realizar la multiplicación de dos matrices (una técnica bastante similar a la suma de dos matrices) puede realizarse mediante el Producto Hadamard

\[ \begin{bmatrix} 3 & 5 & 7\\ 4 & 9 & 8 \end{bmatrix} ○ \begin{bmatrix} 1 & 6 & 3\\ 0 & 2 & 9 \end{bmatrix} = \begin{bmatrix} 3\times1 & 5\times6 & 7\times3\\ 4\times0 & 9\times2 & 8\times9 \end{bmatrix} \]


Matriz Identidad:

  • Una matriz identidad, representado por I, tiene toda la diagonal principal definida por 1, y los demás valores rellenadas con 0.

  • Una matriz identidad es siempre una matriz cuadrada.

\[ \begin{bmatrix} 1 & 0\\ 0 & 1 \end{bmatrix}_{2x2} \]

\[ \begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1 \end{bmatrix}_{3x3} \]


Matriz Inversa:

  • La inversa de una matriz cuadrada A, está definida de la siguiente manera:

\[ AA^{-1} = A^{-1} = I \]

  • Para obtener la inversa de una matriz 2x2 se puede obtener de la siguiente manera:

\[ \begin{bmatrix} a & b\\ c & d \end{bmatrix}^{-1} \]

\[ = \frac{1}{ad - bc} \begin{bmatrix} d & -b\\ -c & d \end{bmatrix} \]


Propiedades de producto de matrices:

  • Asociatividad:

\[ A = \begin{bmatrix} 1 & 2\\ 3 & 4\\ 0 & 1 \end{bmatrix} \] \[ B = \begin{bmatrix} 4 & 3\\ 2 & 1 \end{bmatrix} \] \[ A = \begin{bmatrix} 1 & 0\\ 2 & 3 \end{bmatrix} \]

Luego:

\[ A = \begin{bmatrix} 1 & 2\\ 3 & 4\\ 0 & 1 \end{bmatrix} \cdot B = \begin{bmatrix} 4 & 3\\ 2 & 1 \end{bmatrix} = \begin{bmatrix} 8 & 5\\ 20 & 13\\ 2 & 1 \end{bmatrix} \]

y

\[ B = \begin{bmatrix} 4 & 3\\ 2 & 1 \end{bmatrix} \cdot C = \begin{bmatrix} 1 & 0\\ 2 & 3 \end{bmatrix} = \begin{bmatrix} 10 & 9\\ 4 & 3 \end{bmatrix} \]

Por lo tanto:

\[ (AB)C = \begin{bmatrix} 8 & 5\\ 20 & 13\\ 2 & 1 \end{bmatrix} \cdot B = \begin{bmatrix} 1 & 0\\ 2 & 3 \end{bmatrix} = \begin{bmatrix} 18 & 15\\ 46 & 39\\ 4 & 3 \end{bmatrix} \]

y

\[ A(BC) = \begin{bmatrix} 1 & 2\\ 3 & 4\\ 0 & 1 \end{bmatrix} \cdot B = \begin{bmatrix} 10 & 9\\ 4 & 3 \end{bmatrix} = \begin{bmatrix} 18 & 15\\ 46 & 39\\ 4 & 3 \end{bmatrix} \]


  • Distribuidad:

\[ A (B + C) = AB + AC \] \[ (B + C) A = BA + CA \]


  • Conmutatividad: A diferencia de la adición, en la multiplicación la conmutatividad de matrices no satisface la equitividad.

    • Adición y Multiplicación

\[ A + B = B + A \]

\[ AB = !BA \]


  • Transpuesta: Una transpuesta de una matriz, es una nueva matriz donde prácticamente las filas son las columnas de la matriz original.

\[ A = \begin{bmatrix} 3 & 3\\ 5 & -3\\ 1 & 3\\ 0 & -2\\ 5 & -2 \end{bmatrix} \] \[ A^{T} = \begin{bmatrix} 3 & 5 & 1 & 0 & 5\\ 3 & -3 & 3 & -2 & -2\\ \end{bmatrix} \]


- A continuación se presenta un vídeo obtenido de YouTube, que muestra cómo Matlab resuelve Operaciones con Matrices y Vectores:

LS0tDQp0aXRsZTogIk1hdGVtw6F0aWNhcyBwYXJhIE1hY2hpbmUgTGVhcm5pbmcg4oCUIEFsZ2VicmEgTGluZWFsIg0KYXV0aG9yOiAiTmlsbyBKaG9uYXRhbiBCcmljZcOxbyBSb23DoW4iDQpkYXRlOiAiMjAyMi8wNC8zMCINCnN1YnRpdGxlOiAiSW50cm9kdWNjacOzbiBhIFJNYXJrZG93biINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQotLS0NCg0KIyAqKk1hdGVtw6F0aWNhcyBwYXJhIE1hY2hpbmUgTGVhcm5pbmcqKg0KDQo8IS0tIEHDsWFkaXIgY29tZW50YXJpb3MgYSBudWVzdHJvIGRvY3VtZW50byBNYXJrZG93biAtIEhUTUwgdGFncyAtLT4NCg0KIVtdKEFsZ2VicmEgTGluZWFsLnBuZykNCg0KQWxnZWJyYSBMaW5lYWwgY3VtcGxlIHVuIGltcG9ydGFudGUgcm9sIGVuIGVsIMOhbWJpdG8gZGVsIEFwcmVuZGl6YWplIEF1dG9tw6F0aWNvICoqKE1hY2hpbmUgTGVhcm5pbmcpKiouIEVzdG8gcG9yIHN1IGVzdHVkaW8gcHJvZnVuZG8gZGUgdmVjdG9yZXMsIG1hdHJpY2VzLCBmdW5jaW9uZXMgbGluZWFsZXMsIGVudHJlIG90cmFzIHJhbWFzLg0KDQpBbCBtb21lbnRvIGRlbCB1c28gZGUgbW9kZWxvcyBkZSBNYWNoaW5lIExlYXJuaW5nLCBlc3RvcyBtYW5lamFuIGxvcyBkYXRvcyByZXByZXNlbnTDoW5kb2xvcyBjb21vIE1hdHJpY2VzLiBQb3N0ZXJpb3Igc2UgcHJvY2VkZSBhIHN1IG1hbmlwdWxhY2nDs24gbWF0ZW3DoXRpY2EsIHBvciBlc3RhIHJhesOzbiBlcyBpbXBvcnRhbnRlIGVsIGNvbm9jaW1pZW50byBkZSBBbGdlYnJhIExpbmVhbCBwYXJhIHBvZGVyIGRlc2VtcGXDsWFyIGRlIHVuYSBtYW5lcmEgb3B0aW1hIGxvcyBtb2RlbG9zIGRlIE1hY2hpbmUgTGVhcm5pbmcuDQoNCiMjICoqMS4tIEVzY2FsYXJlcywgVmVjdG9yZXMsIE1hdHJpY2VzIHkgVGVuc29yZXMqKg0KDQo+4oCcQnJvYWRseSBzcGVha2luZywgaW4gTGluZWFyIEFsZ2VicmEsIGRhdGEgaXMgcmVwcmVzZW50ZWQgaW4gdGhlIGZvcm0gb2YgbGluZWFyIGVxdWF0aW9ucy4gVGhlc2UgbGluZWFyIGVxdWF0aW9ucyBhcmUgaW4gdHVybiByZXByZXNlbnRlZCBpbiB0aGUgZm9ybSBvZiBtYXRyaWNlcyBhbmQgdmVjdG9yc+KAnQ0KPg0KPioqVmlnbmVzaCBOYXRhcmFqYW4qKg0KDQoNCiMjIyAqKioxLjEuLSBFc2NhbGFyZXM6KioqDQoNCi0gVW4gbnVtZXJvIHNpbXBsZSBlcyB1biBlc2NhbGFyIChjb21vIHBvciBlamVtcGxvOiB4ID0gMjMpLiBBIHN1IHZleiBlcyBlbCBlamVtcGxvIGRlIHVuIHRlbnNvciBkZSBvcmRlbiAwLg0KDQotIEVzIG5lY2VzYXJpbyBkZXNjcmliaXIgZWwgY29uanVudG8gZGUgdmFsb3JlcyBhbCBjdWFsIHBlcnRlbmVjZSBkaWNobyBlc2NhbGFyLg0KDQokJA0KICAgIGEgPSAyDQokJA0KJCQNCiAgICBiID0gMy4xNDE2ICANCiQkDQoNCioqKg0KDQojIyMgKioqMS4yLi0gVmVjdG9yZXM6KioqDQoNCi0gRXMgdW5hIGxpc3RhIGRlIG7Dum1lcm9zLg0KDQotIEhheSBkb3MgbWFuZXJhcyBkZSBpbnRlcnByZXRhcmxvLiBQcmltZXJvLCBjb21vIHVuIHZlY3RvciBlbiB1biBwdW50byBkZWwgZXNwYWNpbywgZG9uZGUgbG9zIG7Dum1lcm9zIHF1ZSBlc3TDoW4gZW4gbGEgbGlzdGEgc29uIHVuYSBtYW5lcmEgcGFyYSBpZGVudGlmaWNhciBhbCBkaWNobyBwdW50byBlbiBlbCBlc3BhY2lvLiBTZWd1bmRvLCBjb21vIHVuYSBtYWduaXR1ZCB5IGRpcmVjY2nDs24sIGNvbW8gcG9yIGVqZW1wbG8gbGEgdmVsb2NpZGFkLg0KDQotIEhheSBkb3MgbWFuZXJhcyBkZSBpbnRlcnByZXRhciBsb3MgdmVjdG9yZXMsIHVuYSB2ZW5kcsOtYSBzaWVuZG8gcG9yIGVsIGxhZG8gZGUgbGEgRsOtc2ljYSwgeSBlbCBvdHJvIHBvciBlbCBsYWRvIGRlIGxhcyBDaWVuY2lhcyBkZSBsYSBDb21wdXRhY2nDs24uDQoNCiQkDQphID0gXHsxLDIsMyw0XH0NCiQkDQo8Y2VudGVyPg0KDQohW10oUG9pbnQgb2Ygdmlldy5wbmcpDQoNCioqKg0KDQojIyMgKioqMS4zLi0gTWF0cmljZXM6KioqDQoNCi0gVW5hIG1hdHJpeiBlcyBwYXJlY2lkYSBhIHVuIHZlY3RvciwgZW4gZWwgc2VudGlkbyBlbiBxdWUgYW1iYXMgc29uIGNvbGVjY2lvbmVzIGRlIG7Dum1lcm9zLg0KDQotIExhIGRpZmVyZW5jaWEgZW50cmUgdW5hIG1hdHJpeiB5IHVuIHZlY3RvciwgZXMgcXVlIGxhIHByaW1lcmEgZXMgdW5hIHRhYmxhIGRlIG7Dum1lcm9zLCB5IG5vIGFzw60gdW5hIGxpc3RhLg0KIA0KICQkDQogQT0gXGJlZ2lue2JtYXRyaXh9DQogYV97MTF9ICYgYV97MTJ9ICYgYV97MTN9ICYgLi4uICYgYV97MW59XFwNCiBhX3syMX0gJiBhX3syMn0gJiBhX3syM30gJiAuLi4gJiBhX3sybn1cXA0KIGFfezMxfSAmIGFfezMyfSAmIGFfezMzfSAmIC4uLiAmIGFfezNufVxcDQogICAgLiAgICYgICAgLiAgICYgICAgLiAgICYgLiAgICYgICAgLiAgXFwNCiAgICAuICAgJiAgICAuICAgJiAgICAuICAgJiAgLiAgJiAgICAuICBcXA0KICAgIC4gICAmICAgIC4gICAmICAgIC4gICAmICAgLiAmICAgIC4gIFxcDQogYV97bTF9ICYgYV97bTJ9ICYgYV97bTN9ICYgLi4uICYgYV97bW59XFwNCiBcZW5ke2JtYXRyaXh9DQogICQkDQogIA0KKioqDQogIA0KIyMjICoqKjEuNC4tIFRlbnNvcmVzOioqKg0KDQotIFVuIHRlbnNvciBlcyB1bmEgZ2VuZXJhbGl6YWNpw7NuIGRlIHZlY3RvcmVzIHkgbWF0cmljZXMgeSBzZSBlbnRpZW5kZSBmw6FjaWxtZW50ZSBjb21vIHVuYSBtYXRyaXogbXVsdGlkaW1lbnNpb25hbC4NCg0KIDxjZW50ZXI+DQoNCiFbXShUZW5zb3Jlcy5qcGVnKQ0KDQoqKioNCiANCiMjIyAqKioxLjUuLSBFbiByZXN1bWVuOioqKg0KDQpQb2RlbW9zIGludGVycHJldGFyIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmEgZ3LDoWZpY2E6IA0KIA0KICA8Y2VudGVyPg0KDQohW10oUmVzdW1lbi5wbmcpDQoNCioqKg0KIA0KIyMjIyAtIEEgY29udGludWFjacOzbiBzZSBwcmVzZW50YSB1biB2w61kZW8gb2J0ZW5pZG8gZGUgWW91VHViZSBleHBsaWNhbmRvIGNvbmNlcHRvcyB5IGRlZmluaWNpb25lczoNCiANCjxjZW50ZXI+DQoNCjxpZnJhbWUgd2lkdGg9IjU2MCIgaGVpZ2h0PSIzMTUiIHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vZW1iZWQvQk1CWkp3VFM3S3M/c3RhcnQ9MyIgIGZyYW1lYm9yZGVyPSIwIiBhbGxvd2Z1bGxzY3JlZW4gZGF0YS1leHRlcm5hbD0xPjwvaWZyYW1lPg0KDQo8L2NlbnRlcj4NCiANCiANCiMjICoqMi4tIE9wZXJhY2lvbmVzKioNCiANCiMjIyAqKioyLjEuLSBPcGVyYWNpb25lcyBjb24gVmVjdG9yZXM6KioqDQogDQojIyMjIEFkaWNpw7NuIGRlIFZlY3RvcmVzDQoNCiAkJA0KIFx2ZWN7Un0gKyBcdmVje1N9ID0gXHZlY3tUfQ0KICQkDQogJCQNCiBSICsgUyA9IFMgKyBSDQogJCQNCiAkJA0KIChSX3gsUl95KSArIChTX3gsU195KSA9IChUX3gsVF95KQ0KICQkDQogDQogPGNlbnRlcj4NCg0KIVtdKEFkaWNpw7NuIGRlIHZlY3RvcmVzLnBuZykNCg0KICoqKg0KIA0KIyMjIyBTdXN0cmFjY2nDs24gZGUgVmVjdG9yZXMNCiANCiAkJA0KIFx2ZWN7Un0gLSBcdmVje1N9ID0gXHZlY3tVfQ0KICQkDQogJCQNCiBSIC0gUyA9IFUNCiAkJA0KICQkDQogKFJfeCxSX3kpIC0gKFNfeCxTX3kpID0gKFVfeCxVX3kpDQogJCQNCiANCiA8Y2VudGVyPg0KDQohW10oU3VzdHJhY2Npw7NuIGRlIHZlY3RvcmVzLnBuZykNCg0KKioqDQoNCiMjIyMgTXVsdGlwbGljYWNpw7NuIGRlIFZlY3RvcmVzOg0KDQotIE11bHRpcGxpY2FjacOzbiBkZSBlc2NhbGFyIGNvbiBtYXRyaXoNCiANCiAkJA0KICAyXHRpbWVzIHIgPSBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAgICAgMlx0aW1lczNcXA0KICAgICAgICAgICAgICAyXHRpbWVzMg0KICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9ID0gXGJlZ2lue2JtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICAgICAgICA2XFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIDQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0NCiAkJA0KIA0KICA8Y2VudGVyPg0KDQohW10oTXVsdGlwbGljYWNpw7NuIGRlIHZlY3RvcmVzLnBuZykNCg0KICoqKg0KIA0KIyMjICoqKjIuMi4tIE9wZXJhY2lvbmVzIGNvbiBNYXRyaWNlcyoqKg0KDQojIyMjIE11bHRpcGxpY2FjacOzbiBkZSBFc2NhbGFyIGNvbiBNYXRyaXo6DQoNCi0gQ3VhbmRvIHVuIEVzY2FsYXIgZXMgbXVsdGlwbGljYWRvIGNvbiB1bmEgTWF0cml6LCBlc3RhIHNlIHJlYWxpemEgY29uIHRvZG9zIGxvcyBuw7ptZXJvcyBxdWUgeWFjZW4gZW4gbGEgTWF0cml6Lg0KDQokJA0KM1x0aW1lcyBcYmVnaW57cG1hdHJpeH0NCiAgICAgICAgICA0ICYgMSAmIDdcXA0KICAgICAgICAgIDUgJiA5ICYgMTINCiAgICAgICAgICBcZW5ke3BtYXRyaXh9ID0gXGJlZ2lue3BtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAzXHRpbWVzNCAmIDNcdGltZXMxICYgM1x0aW1lczdcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgM1x0aW1lczUgJiAzXHRpbWVzOSAmIDNcdGltZXMxMg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtwbWF0cml4fSA9IFxiZWdpbntwbWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMiAmIDMgICYgMjFcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxNSAmIDI3ICYgMzYNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtwbWF0cml4fQ0KJCQNCg0KKioqDQoNCiMjIyMgUHJvZHVjdG8gRG90Og0KDQotIFBhcmEgbXVsdGlwbGljYXIgdW5hIG1hdHJpeiBjb24gb3RyYSBtYXRyaXogcG9kZW1vcyByZWFsaXphcmxvIGNvbiBlbCBEb3QgUHJvZHVjdC4NCg0KJCQNClxiZWdpbntibWF0cml4fQ0KICAgICAgICAgIGEgJiBiDQogICAgICAgICAgXGVuZHtibWF0cml4fSDil48gXGJlZ2lue2JtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICAgICAgICB4XFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0gPSBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBheCArIGJ5DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fQ0KJCQNCiQkDQpcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICBhICYgYlxcDQogICAgICAgICAgYyAmIGQNCiAgICAgICAgICBcZW5ke2JtYXRyaXh9IOKXjyBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgeQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fSA9IFxiZWdpbntibWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4ICsgYnlcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN4ICsgZHkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9DQokJA0KJCQNClxiZWdpbntibWF0cml4fQ0KICAgICAgICAgIGEgJiBiXFwNCiAgICAgICAgICBjICYgZA0KICAgICAgICAgIFxlbmR7Ym1hdHJpeH0g4pePIFxiZWdpbntibWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHcgJiB4XFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ICYgeg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0gPSBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3ICsgYnkgJiBheCArIGJ6XFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN3ICsgZHkgJiBjeCArIGR6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9DQokJA0KDQoqKioNCg0KIyMjIyBQcm9kdWN0byBIYWRhbWFyZDoNCg0KLSBPdHJhIG1hbmVyYSBkZSByZWFsaXphciBsYSBtdWx0aXBsaWNhY2nDs24gZGUgZG9zIG1hdHJpY2VzICh1bmEgdMOpY25pY2EgYmFzdGFudGUgc2ltaWxhciBhIGxhIHN1bWEgZGUgZG9zIG1hdHJpY2VzKSBwdWVkZSByZWFsaXphcnNlIG1lZGlhbnRlIGVsIFByb2R1Y3RvIEhhZGFtYXJkDQoNCiQkDQpcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAzICYgNSAmIDdcXA0KICAgICAgICAgIDQgJiA5ICYgOA0KICAgICAgICAgIFxlbmR7Ym1hdHJpeH0g4peLIFxiZWdpbntibWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgJiA2ICYgM1xcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAmIDIgJiA5DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fSA9IFxiZWdpbntibWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgM1x0aW1lczEgJiA1XHRpbWVzNiAmIDdcdGltZXMzXFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDRcdGltZXMwICYgOVx0aW1lczIgJiA4XHRpbWVzOQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fQ0KJCQNCg0KKioqDQoNCiMjIyMgTWF0cml6IElkZW50aWRhZDoNCg0KLSBVbmEgbWF0cml6IGlkZW50aWRhZCwgcmVwcmVzZW50YWRvIHBvciBJLCB0aWVuZSB0b2RhIGxhIGRpYWdvbmFsIHByaW5jaXBhbCBkZWZpbmlkYSBwb3IgMSwgeSBsb3MgZGVtw6FzIHZhbG9yZXMgcmVsbGVuYWRhcyBjb24gMC4NCg0KLSBVbmEgbWF0cml6IGlkZW50aWRhZCBlcyBzaWVtcHJlIHVuYSBtYXRyaXogY3VhZHJhZGEuDQoNCiQkDQpcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KMSAmIDBcXCAgICAgICAgICAgICAgICAgICAgICANCjAgJiAxICAgICAgICAgICAgICAgICAgICAgICAgIA0KXGVuZHtibWF0cml4fV97MngyfSAgICAgICAgDQokJA0KDQokJA0KXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCjEgJiAwICYgMFxcICAgICAgICAgICAgICAgICAgICAgIA0KMCAmIDEgJiAwXFwgDQowICYgMCAmIDENClxlbmR7Ym1hdHJpeH1fezN4M30gICAgICAgIA0KJCQNCg0KKioqDQoNCiMjIyMgTWF0cml6IEludmVyc2E6DQoNCi0gTGEgaW52ZXJzYSBkZSB1bmEgbWF0cml6IGN1YWRyYWRhIEEsIGVzdMOhIGRlZmluaWRhIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQoNCiQkDQpBQV57LTF9ID0gQV57LTF9ID0gSQ0KJCQNCg0KLSBQYXJhIG9idGVuZXIgbGEgaW52ZXJzYSBkZSB1bmEgbWF0cml6IDJ4MiBzZSBwdWVkZSBvYnRlbmVyIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQoNCiQkDQpcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KYSAmIGJcXCAgICAgICAgICAgICAgICAgICAgICANCmMgJiBkICAgICAgICAgICAgICAgICAgICAgICAgIA0KXGVuZHtibWF0cml4fV57LTF9ICAgICAgICANCiQkDQoNCiQkDQo9IFxmcmFjezF9e2FkIC0gYmN9IFxiZWdpbntibWF0cml4fSAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIGQgJiAtYlxcICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAtYyAmIGQgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0NCiQkDQoNCioqKg0KDQojIyMjIFByb3BpZWRhZGVzIGRlIHByb2R1Y3RvIGRlIG1hdHJpY2VzOg0KDQotIEFzb2NpYXRpdmlkYWQ6DQoNCiQkDQpBID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCjEgJiAyXFwgICAgICAgICAgICAgICAgICAgICAgDQozICYgNFxcDQowICYgMQ0KXGVuZHtibWF0cml4fQ0KJCQNCiQkDQpCID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCjQgJiAzXFwgICAgICAgICAgICAgICAgICAgICAgDQoyICYgMQ0KXGVuZHtibWF0cml4fQ0KJCQNCiQkDQpBID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCjEgJiAwXFwgICAgICAgICAgICAgICAgICAgICAgDQoyICYgMw0KXGVuZHtibWF0cml4fSAgDQokJA0KDQpMdWVnbzoNCg0KJCQNCkEgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KMSAmIDJcXCAgICAgICAgICAgICAgICAgICAgICANCjMgJiA0XFwNCjAgJiAxDQpcZW5ke2JtYXRyaXh9IFxjZG90IEIgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgNCAmIDNcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgIDIgJiAxDQogICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9ID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA4ICYgNVxcICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIwICYgMTNcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIgJiAxDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fQ0KJCQNCg0KeSANCg0KJCQNCkIgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KNCAmIDNcXCAgICAgICAgICAgICAgICAgICAgICANCjIgJiAxDQpcZW5ke2JtYXRyaXh9IFxjZG90IEMgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgMSAmIDBcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgIDIgJiAzDQogICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9ID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMCAmIDlcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0ICYgMw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0NCiQkDQoNClBvciBsbyB0YW50bzoNCg0KJCQNCihBQilDID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCjggJiA1XFwgICAgICAgICAgICAgICAgICAgICAgDQoyMCAmIDEzXFwNCjIgJiAxDQpcZW5ke2JtYXRyaXh9IFxjZG90IEIgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgMSAmIDBcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgIDIgJiAzDQogICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9ID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxOCAmIDE1XFwgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDYgJiAzOVxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNCAmIDMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9DQokJA0KDQp5DQoNCiQkDQpBKEJDKSA9IFxiZWdpbntibWF0cml4fSAgICAgICAgICAgICAgICAgICAgICAgICAgDQoxICYgMlxcICAgICAgICAgICAgICAgICAgICAgIA0KMyAmIDRcXA0KMCAmIDENClxlbmR7Ym1hdHJpeH0gXGNkb3QgQiA9IFxiZWdpbntibWF0cml4fSAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAxMCAmIDlcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgIDQgJiAzDQogICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9ID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxOCAmIDE1XFwgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDYgJiAzOVxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNCAmIDMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9DQokJA0KDQoqKioNCg0KLSBEaXN0cmlidWlkYWQ6DQoNCiQkDQpBIChCICsgQykgPSBBQiArIEFDDQokJA0KJCQNCihCICsgQykgQSA9IEJBICsgQ0ENCiQkDQoNCioqKg0KDQotIENvbm11dGF0aXZpZGFkOiBBIGRpZmVyZW5jaWEgZGUgbGEgYWRpY2nDs24sIGVuIGxhIG11bHRpcGxpY2FjacOzbiBsYSBjb25tdXRhdGl2aWRhZCBkZSBtYXRyaWNlcyBubyBzYXRpc2ZhY2UgbGEgZXF1aXRpdmlkYWQuDQoNCiAgLSBBZGljacOzbiB5IE11bHRpcGxpY2FjacOzbg0KDQokJA0KQSArIEIgPSBCICsgQQ0KJCQNCg0KJCQNCkFCID0gIUJBDQokJA0KDQoqKioNCg0KLSBUcmFuc3B1ZXN0YToNClVuYSB0cmFuc3B1ZXN0YSBkZSB1bmEgbWF0cml6LCBlcyB1bmEgbnVldmEgbWF0cml6IGRvbmRlIHByw6FjdGljYW1lbnRlIGxhcyBmaWxhcyBzb24gbGFzIGNvbHVtbmFzIGRlIGxhIG1hdHJpeiBvcmlnaW5hbC4NCg0KJCQNCkEgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KMyAmIDNcXCAgICAgICAgICAgICAgICAgICAgICANCjUgJiAtM1xcICAgICAgICAgICAgICAgICAgICAgIA0KMSAmIDNcXCAgICAgICAgICAgICAgICAgICAgICANCjAgJiAtMlxcICAgICAgICAgICAgICAgICAgICAgIA0KNSAmIC0yICAgIA0KXGVuZHtibWF0cml4fSANCiQkDQokJA0KQV57VH0gPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgMyAmIDUgJiAxICYgMCAmIDVcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgIDMgJiAtMyAmIDMgJiAtMiAmIC0yXFwgICANClxlbmR7Ym1hdHJpeH0gICAgDQokJA0KDQoqKioNCg0KIyMjIyAtIEEgY29udGludWFjacOzbiBzZSBwcmVzZW50YSB1biB2w61kZW8gb2J0ZW5pZG8gZGUgWW91VHViZSwgcXVlIG11ZXN0cmEgY8OzbW8gTWF0bGFiIHJlc3VlbHZlIE9wZXJhY2lvbmVzIGNvbiBNYXRyaWNlcyB5IFZlY3RvcmVzOg0KDQo8Y2VudGVyPg0KDQo8aWZyYW1lIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkLzU0UzlIZHRkQWY4IiAgZnJhbWVib3JkZXI9IjAiICBhbGxvd2Z1bGxzY3JlZW4gZGF0YS1leHRlcm5hbD0xPjwvaWZyYW1lPg0KDQo8L2NlbnRlcj4NCg0KIyMgKipCaWJsaW9ncmFmw61hKioNCg0KU2lsdmEgRi4gKERlYyAzMCwgMjAxOSkuIFJlY3VwZXJhZG8gZGUgaHR0cHM6Ly9tZWRpdW0uY29tL2RhdGEtc2NpZW5jZS1ib2xpdmlhL21hdGVtJUMzJUExdGljYXMtcGFyYS1tYWNoaW5lLWxlYXJuaW5nLWFsZ2VicmEtbGluZWFsLWQzYjY3YjUyMWFlYQ0KDQo8ZGl2IGNsYXNzPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIGRhdGEtdW5pcXVlPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIHN0eWxlPSJoZWlnaHQ6IDA7Ij48L2Rpdj4NCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQo=