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:
\[
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:
VIDEO
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:
\[
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}
\]
\[
A (B + C) = AB + AC
\] \[
(B + C) A = BA + CA
\]
\[
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:
VIDEO
LS0tDQp0aXRsZTogIk1hdGVtw6F0aWNhcyBwYXJhIE1hY2hpbmUgTGVhcm5pbmcg4oCUIEFsZ2VicmEgTGluZWFsIg0KYXV0aG9yOiAiTmlsbyBKaG9uYXRhbiBCcmljZcOxbyBSb23DoW4iDQpkYXRlOiAiMjAyMi8wNC8zMCINCnN1YnRpdGxlOiAiSW50cm9kdWNjacOzbiBhIFJNYXJrZG93biINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQotLS0NCg0KIyAqKk1hdGVtw6F0aWNhcyBwYXJhIE1hY2hpbmUgTGVhcm5pbmcqKg0KDQo8IS0tIEHDsWFkaXIgY29tZW50YXJpb3MgYSBudWVzdHJvIGRvY3VtZW50byBNYXJrZG93biAtIEhUTUwgdGFncyAtLT4NCg0KIVtdKEFsZ2VicmEgTGluZWFsLnBuZykNCg0KQWxnZWJyYSBMaW5lYWwgY3VtcGxlIHVuIGltcG9ydGFudGUgcm9sIGVuIGVsIMOhbWJpdG8gZGVsIEFwcmVuZGl6YWplIEF1dG9tw6F0aWNvICoqKE1hY2hpbmUgTGVhcm5pbmcpKiouIEVzdG8gcG9yIHN1IGVzdHVkaW8gcHJvZnVuZG8gZGUgdmVjdG9yZXMsIG1hdHJpY2VzLCBmdW5jaW9uZXMgbGluZWFsZXMsIGVudHJlIG90cmFzIHJhbWFzLg0KDQpBbCBtb21lbnRvIGRlbCB1c28gZGUgbW9kZWxvcyBkZSBNYWNoaW5lIExlYXJuaW5nLCBlc3RvcyBtYW5lamFuIGxvcyBkYXRvcyByZXByZXNlbnTDoW5kb2xvcyBjb21vIE1hdHJpY2VzLiBQb3N0ZXJpb3Igc2UgcHJvY2VkZSBhIHN1IG1hbmlwdWxhY2nDs24gbWF0ZW3DoXRpY2EsIHBvciBlc3RhIHJhesOzbiBlcyBpbXBvcnRhbnRlIGVsIGNvbm9jaW1pZW50byBkZSBBbGdlYnJhIExpbmVhbCBwYXJhIHBvZGVyIGRlc2VtcGXDsWFyIGRlIHVuYSBtYW5lcmEgb3B0aW1hIGxvcyBtb2RlbG9zIGRlIE1hY2hpbmUgTGVhcm5pbmcuDQoNCiMjICoqMS4tIEVzY2FsYXJlcywgVmVjdG9yZXMsIE1hdHJpY2VzIHkgVGVuc29yZXMqKg0KDQo+4oCcQnJvYWRseSBzcGVha2luZywgaW4gTGluZWFyIEFsZ2VicmEsIGRhdGEgaXMgcmVwcmVzZW50ZWQgaW4gdGhlIGZvcm0gb2YgbGluZWFyIGVxdWF0aW9ucy4gVGhlc2UgbGluZWFyIGVxdWF0aW9ucyBhcmUgaW4gdHVybiByZXByZXNlbnRlZCBpbiB0aGUgZm9ybSBvZiBtYXRyaWNlcyBhbmQgdmVjdG9yc+KAnQ0KPg0KPioqVmlnbmVzaCBOYXRhcmFqYW4qKg0KDQoNCiMjIyAqKioxLjEuLSBFc2NhbGFyZXM6KioqDQoNCi0gVW4gbnVtZXJvIHNpbXBsZSBlcyB1biBlc2NhbGFyIChjb21vIHBvciBlamVtcGxvOiB4ID0gMjMpLiBBIHN1IHZleiBlcyBlbCBlamVtcGxvIGRlIHVuIHRlbnNvciBkZSBvcmRlbiAwLg0KDQotIEVzIG5lY2VzYXJpbyBkZXNjcmliaXIgZWwgY29uanVudG8gZGUgdmFsb3JlcyBhbCBjdWFsIHBlcnRlbmVjZSBkaWNobyBlc2NhbGFyLg0KDQokJA0KICAgIGEgPSAyDQokJA0KJCQNCiAgICBiID0gMy4xNDE2ICANCiQkDQoNCioqKg0KDQojIyMgKioqMS4yLi0gVmVjdG9yZXM6KioqDQoNCi0gRXMgdW5hIGxpc3RhIGRlIG7Dum1lcm9zLg0KDQotIEhheSBkb3MgbWFuZXJhcyBkZSBpbnRlcnByZXRhcmxvLiBQcmltZXJvLCBjb21vIHVuIHZlY3RvciBlbiB1biBwdW50byBkZWwgZXNwYWNpbywgZG9uZGUgbG9zIG7Dum1lcm9zIHF1ZSBlc3TDoW4gZW4gbGEgbGlzdGEgc29uIHVuYSBtYW5lcmEgcGFyYSBpZGVudGlmaWNhciBhbCBkaWNobyBwdW50byBlbiBlbCBlc3BhY2lvLiBTZWd1bmRvLCBjb21vIHVuYSBtYWduaXR1ZCB5IGRpcmVjY2nDs24sIGNvbW8gcG9yIGVqZW1wbG8gbGEgdmVsb2NpZGFkLg0KDQotIEhheSBkb3MgbWFuZXJhcyBkZSBpbnRlcnByZXRhciBsb3MgdmVjdG9yZXMsIHVuYSB2ZW5kcsOtYSBzaWVuZG8gcG9yIGVsIGxhZG8gZGUgbGEgRsOtc2ljYSwgeSBlbCBvdHJvIHBvciBlbCBsYWRvIGRlIGxhcyBDaWVuY2lhcyBkZSBsYSBDb21wdXRhY2nDs24uDQoNCiQkDQphID0gXHsxLDIsMyw0XH0NCiQkDQo8Y2VudGVyPg0KDQohW10oUG9pbnQgb2Ygdmlldy5wbmcpDQoNCioqKg0KDQojIyMgKioqMS4zLi0gTWF0cmljZXM6KioqDQoNCi0gVW5hIG1hdHJpeiBlcyBwYXJlY2lkYSBhIHVuIHZlY3RvciwgZW4gZWwgc2VudGlkbyBlbiBxdWUgYW1iYXMgc29uIGNvbGVjY2lvbmVzIGRlIG7Dum1lcm9zLg0KDQotIExhIGRpZmVyZW5jaWEgZW50cmUgdW5hIG1hdHJpeiB5IHVuIHZlY3RvciwgZXMgcXVlIGxhIHByaW1lcmEgZXMgdW5hIHRhYmxhIGRlIG7Dum1lcm9zLCB5IG5vIGFzw60gdW5hIGxpc3RhLg0KIA0KICQkDQogQT0gXGJlZ2lue2JtYXRyaXh9DQogYV97MTF9ICYgYV97MTJ9ICYgYV97MTN9ICYgLi4uICYgYV97MW59XFwNCiBhX3syMX0gJiBhX3syMn0gJiBhX3syM30gJiAuLi4gJiBhX3sybn1cXA0KIGFfezMxfSAmIGFfezMyfSAmIGFfezMzfSAmIC4uLiAmIGFfezNufVxcDQogICAgLiAgICYgICAgLiAgICYgICAgLiAgICYgLiAgICYgICAgLiAgXFwNCiAgICAuICAgJiAgICAuICAgJiAgICAuICAgJiAgLiAgJiAgICAuICBcXA0KICAgIC4gICAmICAgIC4gICAmICAgIC4gICAmICAgLiAmICAgIC4gIFxcDQogYV97bTF9ICYgYV97bTJ9ICYgYV97bTN9ICYgLi4uICYgYV97bW59XFwNCiBcZW5ke2JtYXRyaXh9DQogICQkDQogIA0KKioqDQogIA0KIyMjICoqKjEuNC4tIFRlbnNvcmVzOioqKg0KDQotIFVuIHRlbnNvciBlcyB1bmEgZ2VuZXJhbGl6YWNpw7NuIGRlIHZlY3RvcmVzIHkgbWF0cmljZXMgeSBzZSBlbnRpZW5kZSBmw6FjaWxtZW50ZSBjb21vIHVuYSBtYXRyaXogbXVsdGlkaW1lbnNpb25hbC4NCg0KIDxjZW50ZXI+DQoNCiFbXShUZW5zb3Jlcy5qcGVnKQ0KDQoqKioNCiANCiMjIyAqKioxLjUuLSBFbiByZXN1bWVuOioqKg0KDQpQb2RlbW9zIGludGVycHJldGFyIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmEgZ3LDoWZpY2E6IA0KIA0KICA8Y2VudGVyPg0KDQohW10oUmVzdW1lbi5wbmcpDQoNCioqKg0KIA0KIyMjIyAtIEEgY29udGludWFjacOzbiBzZSBwcmVzZW50YSB1biB2w61kZW8gb2J0ZW5pZG8gZGUgWW91VHViZSBleHBsaWNhbmRvIGNvbmNlcHRvcyB5IGRlZmluaWNpb25lczoNCiANCjxjZW50ZXI+DQoNCjxpZnJhbWUgd2lkdGg9IjU2MCIgaGVpZ2h0PSIzMTUiIHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vZW1iZWQvQk1CWkp3VFM3S3M/c3RhcnQ9MyIgIGZyYW1lYm9yZGVyPSIwIiBhbGxvd2Z1bGxzY3JlZW4gZGF0YS1leHRlcm5hbD0xPjwvaWZyYW1lPg0KDQo8L2NlbnRlcj4NCiANCiANCiMjICoqMi4tIE9wZXJhY2lvbmVzKioNCiANCiMjIyAqKioyLjEuLSBPcGVyYWNpb25lcyBjb24gVmVjdG9yZXM6KioqDQogDQojIyMjIEFkaWNpw7NuIGRlIFZlY3RvcmVzDQoNCiAkJA0KIFx2ZWN7Un0gKyBcdmVje1N9ID0gXHZlY3tUfQ0KICQkDQogJCQNCiBSICsgUyA9IFMgKyBSDQogJCQNCiAkJA0KIChSX3gsUl95KSArIChTX3gsU195KSA9IChUX3gsVF95KQ0KICQkDQogDQogPGNlbnRlcj4NCg0KIVtdKEFkaWNpw7NuIGRlIHZlY3RvcmVzLnBuZykNCg0KICoqKg0KIA0KIyMjIyBTdXN0cmFjY2nDs24gZGUgVmVjdG9yZXMNCiANCiAkJA0KIFx2ZWN7Un0gLSBcdmVje1N9ID0gXHZlY3tVfQ0KICQkDQogJCQNCiBSIC0gUyA9IFUNCiAkJA0KICQkDQogKFJfeCxSX3kpIC0gKFNfeCxTX3kpID0gKFVfeCxVX3kpDQogJCQNCiANCiA8Y2VudGVyPg0KDQohW10oU3VzdHJhY2Npw7NuIGRlIHZlY3RvcmVzLnBuZykNCg0KKioqDQoNCiMjIyMgTXVsdGlwbGljYWNpw7NuIGRlIFZlY3RvcmVzOg0KDQotIE11bHRpcGxpY2FjacOzbiBkZSBlc2NhbGFyIGNvbiBtYXRyaXoNCiANCiAkJA0KICAyXHRpbWVzIHIgPSBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAgICAgMlx0aW1lczNcXA0KICAgICAgICAgICAgICAyXHRpbWVzMg0KICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9ID0gXGJlZ2lue2JtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICAgICAgICA2XFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIDQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0NCiAkJA0KIA0KICA8Y2VudGVyPg0KDQohW10oTXVsdGlwbGljYWNpw7NuIGRlIHZlY3RvcmVzLnBuZykNCg0KICoqKg0KIA0KIyMjICoqKjIuMi4tIE9wZXJhY2lvbmVzIGNvbiBNYXRyaWNlcyoqKg0KDQojIyMjIE11bHRpcGxpY2FjacOzbiBkZSBFc2NhbGFyIGNvbiBNYXRyaXo6DQoNCi0gQ3VhbmRvIHVuIEVzY2FsYXIgZXMgbXVsdGlwbGljYWRvIGNvbiB1bmEgTWF0cml6LCBlc3RhIHNlIHJlYWxpemEgY29uIHRvZG9zIGxvcyBuw7ptZXJvcyBxdWUgeWFjZW4gZW4gbGEgTWF0cml6Lg0KDQokJA0KM1x0aW1lcyBcYmVnaW57cG1hdHJpeH0NCiAgICAgICAgICA0ICYgMSAmIDdcXA0KICAgICAgICAgIDUgJiA5ICYgMTINCiAgICAgICAgICBcZW5ke3BtYXRyaXh9ID0gXGJlZ2lue3BtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAzXHRpbWVzNCAmIDNcdGltZXMxICYgM1x0aW1lczdcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgM1x0aW1lczUgJiAzXHRpbWVzOSAmIDNcdGltZXMxMg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtwbWF0cml4fSA9IFxiZWdpbntwbWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMiAmIDMgICYgMjFcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxNSAmIDI3ICYgMzYNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtwbWF0cml4fQ0KJCQNCg0KKioqDQoNCiMjIyMgUHJvZHVjdG8gRG90Og0KDQotIFBhcmEgbXVsdGlwbGljYXIgdW5hIG1hdHJpeiBjb24gb3RyYSBtYXRyaXogcG9kZW1vcyByZWFsaXphcmxvIGNvbiBlbCBEb3QgUHJvZHVjdC4NCg0KJCQNClxiZWdpbntibWF0cml4fQ0KICAgICAgICAgIGEgJiBiDQogICAgICAgICAgXGVuZHtibWF0cml4fSDil48gXGJlZ2lue2JtYXRyaXh9DQogICAgICAgICAgICAgICAgICAgICAgICAgICB4XFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0gPSBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBheCArIGJ5DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fQ0KJCQNCiQkDQpcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICBhICYgYlxcDQogICAgICAgICAgYyAmIGQNCiAgICAgICAgICBcZW5ke2JtYXRyaXh9IOKXjyBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgeQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fSA9IFxiZWdpbntibWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4ICsgYnlcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN4ICsgZHkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9DQokJA0KJCQNClxiZWdpbntibWF0cml4fQ0KICAgICAgICAgIGEgJiBiXFwNCiAgICAgICAgICBjICYgZA0KICAgICAgICAgIFxlbmR7Ym1hdHJpeH0g4pePIFxiZWdpbntibWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHcgJiB4XFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ICYgeg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0gPSBcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3ICsgYnkgJiBheCArIGJ6XFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN3ICsgZHkgJiBjeCArIGR6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9DQokJA0KDQoqKioNCg0KIyMjIyBQcm9kdWN0byBIYWRhbWFyZDoNCg0KLSBPdHJhIG1hbmVyYSBkZSByZWFsaXphciBsYSBtdWx0aXBsaWNhY2nDs24gZGUgZG9zIG1hdHJpY2VzICh1bmEgdMOpY25pY2EgYmFzdGFudGUgc2ltaWxhciBhIGxhIHN1bWEgZGUgZG9zIG1hdHJpY2VzKSBwdWVkZSByZWFsaXphcnNlIG1lZGlhbnRlIGVsIFByb2R1Y3RvIEhhZGFtYXJkDQoNCiQkDQpcYmVnaW57Ym1hdHJpeH0NCiAgICAgICAgICAzICYgNSAmIDdcXA0KICAgICAgICAgIDQgJiA5ICYgOA0KICAgICAgICAgIFxlbmR7Ym1hdHJpeH0g4peLIFxiZWdpbntibWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgJiA2ICYgM1xcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAmIDIgJiA5DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fSA9IFxiZWdpbntibWF0cml4fQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgM1x0aW1lczEgJiA1XHRpbWVzNiAmIDdcdGltZXMzXFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDRcdGltZXMwICYgOVx0aW1lczIgJiA4XHRpbWVzOQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fQ0KJCQNCg0KKioqDQoNCiMjIyMgTWF0cml6IElkZW50aWRhZDoNCg0KLSBVbmEgbWF0cml6IGlkZW50aWRhZCwgcmVwcmVzZW50YWRvIHBvciBJLCB0aWVuZSB0b2RhIGxhIGRpYWdvbmFsIHByaW5jaXBhbCBkZWZpbmlkYSBwb3IgMSwgeSBsb3MgZGVtw6FzIHZhbG9yZXMgcmVsbGVuYWRhcyBjb24gMC4NCg0KLSBVbmEgbWF0cml6IGlkZW50aWRhZCBlcyBzaWVtcHJlIHVuYSBtYXRyaXogY3VhZHJhZGEuDQoNCiQkDQpcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KMSAmIDBcXCAgICAgICAgICAgICAgICAgICAgICANCjAgJiAxICAgICAgICAgICAgICAgICAgICAgICAgIA0KXGVuZHtibWF0cml4fV97MngyfSAgICAgICAgDQokJA0KDQokJA0KXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCjEgJiAwICYgMFxcICAgICAgICAgICAgICAgICAgICAgIA0KMCAmIDEgJiAwXFwgDQowICYgMCAmIDENClxlbmR7Ym1hdHJpeH1fezN4M30gICAgICAgIA0KJCQNCg0KKioqDQoNCiMjIyMgTWF0cml6IEludmVyc2E6DQoNCi0gTGEgaW52ZXJzYSBkZSB1bmEgbWF0cml6IGN1YWRyYWRhIEEsIGVzdMOhIGRlZmluaWRhIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQoNCiQkDQpBQV57LTF9ID0gQV57LTF9ID0gSQ0KJCQNCg0KLSBQYXJhIG9idGVuZXIgbGEgaW52ZXJzYSBkZSB1bmEgbWF0cml6IDJ4MiBzZSBwdWVkZSBvYnRlbmVyIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQoNCiQkDQpcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KYSAmIGJcXCAgICAgICAgICAgICAgICAgICAgICANCmMgJiBkICAgICAgICAgICAgICAgICAgICAgICAgIA0KXGVuZHtibWF0cml4fV57LTF9ICAgICAgICANCiQkDQoNCiQkDQo9IFxmcmFjezF9e2FkIC0gYmN9IFxiZWdpbntibWF0cml4fSAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIGQgJiAtYlxcICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAtYyAmIGQgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0NCiQkDQoNCioqKg0KDQojIyMjIFByb3BpZWRhZGVzIGRlIHByb2R1Y3RvIGRlIG1hdHJpY2VzOg0KDQotIEFzb2NpYXRpdmlkYWQ6DQoNCiQkDQpBID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCjEgJiAyXFwgICAgICAgICAgICAgICAgICAgICAgDQozICYgNFxcDQowICYgMQ0KXGVuZHtibWF0cml4fQ0KJCQNCiQkDQpCID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCjQgJiAzXFwgICAgICAgICAgICAgICAgICAgICAgDQoyICYgMQ0KXGVuZHtibWF0cml4fQ0KJCQNCiQkDQpBID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCjEgJiAwXFwgICAgICAgICAgICAgICAgICAgICAgDQoyICYgMw0KXGVuZHtibWF0cml4fSAgDQokJA0KDQpMdWVnbzoNCg0KJCQNCkEgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KMSAmIDJcXCAgICAgICAgICAgICAgICAgICAgICANCjMgJiA0XFwNCjAgJiAxDQpcZW5ke2JtYXRyaXh9IFxjZG90IEIgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgNCAmIDNcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgIDIgJiAxDQogICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9ID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA4ICYgNVxcICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIwICYgMTNcXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIgJiAxDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXGVuZHtibWF0cml4fQ0KJCQNCg0KeSANCg0KJCQNCkIgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KNCAmIDNcXCAgICAgICAgICAgICAgICAgICAgICANCjIgJiAxDQpcZW5ke2JtYXRyaXh9IFxjZG90IEMgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgMSAmIDBcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgIDIgJiAzDQogICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9ID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMCAmIDlcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0ICYgMw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxlbmR7Ym1hdHJpeH0NCiQkDQoNClBvciBsbyB0YW50bzoNCg0KJCQNCihBQilDID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCjggJiA1XFwgICAgICAgICAgICAgICAgICAgICAgDQoyMCAmIDEzXFwNCjIgJiAxDQpcZW5ke2JtYXRyaXh9IFxjZG90IEIgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgMSAmIDBcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgIDIgJiAzDQogICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9ID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxOCAmIDE1XFwgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDYgJiAzOVxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNCAmIDMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9DQokJA0KDQp5DQoNCiQkDQpBKEJDKSA9IFxiZWdpbntibWF0cml4fSAgICAgICAgICAgICAgICAgICAgICAgICAgDQoxICYgMlxcICAgICAgICAgICAgICAgICAgICAgIA0KMyAmIDRcXA0KMCAmIDENClxlbmR7Ym1hdHJpeH0gXGNkb3QgQiA9IFxiZWdpbntibWF0cml4fSAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAxMCAmIDlcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgIDQgJiAzDQogICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9ID0gXGJlZ2lue2JtYXRyaXh9ICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxOCAmIDE1XFwgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDYgJiAzOVxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNCAmIDMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcZW5ke2JtYXRyaXh9DQokJA0KDQoqKioNCg0KLSBEaXN0cmlidWlkYWQ6DQoNCiQkDQpBIChCICsgQykgPSBBQiArIEFDDQokJA0KJCQNCihCICsgQykgQSA9IEJBICsgQ0ENCiQkDQoNCioqKg0KDQotIENvbm11dGF0aXZpZGFkOiBBIGRpZmVyZW5jaWEgZGUgbGEgYWRpY2nDs24sIGVuIGxhIG11bHRpcGxpY2FjacOzbiBsYSBjb25tdXRhdGl2aWRhZCBkZSBtYXRyaWNlcyBubyBzYXRpc2ZhY2UgbGEgZXF1aXRpdmlkYWQuDQoNCiAgLSBBZGljacOzbiB5IE11bHRpcGxpY2FjacOzbg0KDQokJA0KQSArIEIgPSBCICsgQQ0KJCQNCg0KJCQNCkFCID0gIUJBDQokJA0KDQoqKioNCg0KLSBUcmFuc3B1ZXN0YToNClVuYSB0cmFuc3B1ZXN0YSBkZSB1bmEgbWF0cml6LCBlcyB1bmEgbnVldmEgbWF0cml6IGRvbmRlIHByw6FjdGljYW1lbnRlIGxhcyBmaWxhcyBzb24gbGFzIGNvbHVtbmFzIGRlIGxhIG1hdHJpeiBvcmlnaW5hbC4NCg0KJCQNCkEgPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KMyAmIDNcXCAgICAgICAgICAgICAgICAgICAgICANCjUgJiAtM1xcICAgICAgICAgICAgICAgICAgICAgIA0KMSAmIDNcXCAgICAgICAgICAgICAgICAgICAgICANCjAgJiAtMlxcICAgICAgICAgICAgICAgICAgICAgIA0KNSAmIC0yICAgIA0KXGVuZHtibWF0cml4fSANCiQkDQokJA0KQV57VH0gPSBcYmVnaW57Ym1hdHJpeH0gICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgMyAmIDUgJiAxICYgMCAmIDVcXCAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgIDMgJiAtMyAmIDMgJiAtMiAmIC0yXFwgICANClxlbmR7Ym1hdHJpeH0gICAgDQokJA0KDQoqKioNCg0KIyMjIyAtIEEgY29udGludWFjacOzbiBzZSBwcmVzZW50YSB1biB2w61kZW8gb2J0ZW5pZG8gZGUgWW91VHViZSwgcXVlIG11ZXN0cmEgY8OzbW8gTWF0bGFiIHJlc3VlbHZlIE9wZXJhY2lvbmVzIGNvbiBNYXRyaWNlcyB5IFZlY3RvcmVzOg0KDQo8Y2VudGVyPg0KDQo8aWZyYW1lIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkLzU0UzlIZHRkQWY4IiAgZnJhbWVib3JkZXI9IjAiICBhbGxvd2Z1bGxzY3JlZW4gZGF0YS1leHRlcm5hbD0xPjwvaWZyYW1lPg0KDQo8L2NlbnRlcj4NCg0KIyMgKipCaWJsaW9ncmFmw61hKioNCg0KU2lsdmEgRi4gKERlYyAzMCwgMjAxOSkuIFJlY3VwZXJhZG8gZGUgaHR0cHM6Ly9tZWRpdW0uY29tL2RhdGEtc2NpZW5jZS1ib2xpdmlhL21hdGVtJUMzJUExdGljYXMtcGFyYS1tYWNoaW5lLWxlYXJuaW5nLWFsZ2VicmEtbGluZWFsLWQzYjY3YjUyMWFlYQ0KDQo8ZGl2IGNsYXNzPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIGRhdGEtdW5pcXVlPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIHN0eWxlPSJoZWlnaHQ6IDA7Ij48L2Rpdj4NCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQo=