|
2 | 2 | :icons: font |
3 | 3 | :stem: mathjax |
4 | 4 |
|
5 | | -El álgebra lineal no es solo el estudio de tablas de números; es el marco mediante el cual entendemos cómo transformar y deformar espacios. Cuando añadimos el cálculo a esta mezcla, obtenemos las herramientas necesarias para optimizar funciones complejas en dimensiones masivas. |
| 5 | +Advertencia: El siguiente documento sacrifica rigurosidad matematica para hacer mas accesible su contenido. |
| 6 | + |
| 7 | +Un sistema de n ecuaciones lineales y m incognitas x_1, ...., x_m, se escribe de la forma |
| 8 | + |
| 9 | +a_11x_1 + a_12x_2 + ... + a_1mx_m = b_1 |
| 10 | +a_21x_1 + a_22x_2 + ... + a_2mx_m = b_2 |
| 11 | +...................................... |
| 12 | +a_n1x_1 + a_n2x_2 + ... + a_nmx_m = b_n |
| 13 | +donde los numeros a_ij y b_i son conocidos. |
| 14 | + |
| 15 | +Se denotara como "sistema n x m" para refernis a un sistema de n ecuaciones lineales con m incognitas. |
| 16 | + |
| 17 | +Dado un sistema de n ecuaciones lineales con m incognitas, se dice que (x_1,x_2,...,x_m) es una solucion del sistema, si satisface cada una de las n ecuaciones. Al conjunto de todas las soluciones posibles de un sistema se le va a denominar conjunto solucion del sistema. |
| 18 | + |
| 19 | +Por ejemplo, imagina que estamos tratando de predecir el precio de una suscripción basándonos en dos factores: el número de usuarios ($x_1$) y el almacenamiento extra ($x_2$). Podríamos tener un sistema como este: |
| 20 | + |
| 21 | +[stem] |
| 22 | +-- |
| 23 | +2x_1 + 1x_2 = 15 \\ |
| 24 | +1x_1 + 3x_2 = 20 |
| 25 | +-- |
| 26 | + |
| 27 | +En **Elixir**, usando la librería **Nx**, representaríamos los coeficientes y los resultados como tensores independientes: |
| 28 | + |
| 29 | +[source, elixir] |
| 30 | +---- |
| 31 | +# Los coeficientes de la izquierda |
| 32 | +a = Nx.tensor([[2, 1], [1, 3]]) |
| 33 | +
|
| 34 | +# Los resultados de la derecha |
| 35 | +b = Nx.tensor([15, 20]) |
| 36 | +---- |
| 37 | + |
| 38 | +Son permitidas tres tipos de operaciones para transformar un sistema a otro, sin modificar el conjunto solucion: |
| 39 | + |
| 40 | +i. Multiplicamos una ecuacion por un numero real. |
| 41 | +ii. Multiplicamos una ecuacion por un numero real Y lo sumamos a otra ecuacion. |
| 42 | +iii. Intercambiamos la posicion de dos ecuaciones. |
| 43 | + |
| 44 | +Dos sistemas de ecuaciones lineales con m incognitas son equivalentes si comparten un conjunto solucion. |
| 45 | + |
| 46 | +Para visualizar esto, piensa en el sistema anterior. Si multiplicamos la primera ecuación por 2, obtenemos $4x_1 + 2x_2 = 30$. Aunque los números "se vean" distintos, la recta que representan en el espacio es exactamente la misma. No hemos perdido ni ganado información, solo hemos cambiado la escala de nuestra observación. |
| 47 | + |
| 48 | +[source, elixir] |
| 49 | +---- |
| 50 | +# Multiplicar una fila por un escalar en Nx |
| 51 | +# Supongamos que 'a' es nuestro tensor de coeficientes |
| 52 | +fila_1 = a[0] |
| 53 | +fila_1_escalada = Nx.multiply(fila_1, 2) |
| 54 | +---- |
| 55 | + |
| 56 | +En un sistema nx m |
| 57 | + |
| 58 | +a_11x_1 + a_12x_2 + ... + a_1mx_m = b_1 |
| 59 | +a_21x_1 + a_22x_2 + ... + a_2mx_m = b_2 |
| 60 | +...................................... |
| 61 | +a_n1x_1 + a_n2x_2 + ... + a_nmx_m = b_n |
| 62 | + |
| 63 | + |
| 64 | +Esta estructura rectangular representa una entidad propia, mucho más allá de ser una simple convención de escritura. En matemáticas, la representamos así: |
| 65 | + |
| 66 | +[stem] |
| 67 | +-- |
| 68 | +A = \begin{pmatrix} |
| 69 | +a_{11} & a_{12} & \dots & a_{1m} \\ |
| 70 | +a_{21} & a_{22} & \dots & a_{2m} \\ |
| 71 | +\vdots & \vdots & \ddots & \vdots \\ |
| 72 | +a_{n1} & a_{n2} & \dots & a_{nm} |
| 73 | +\end{pmatrix} |
| 74 | +-- |
| 75 | + |
| 76 | +Y en el ecosistema de **Elixir**, la creación de este objeto es casi poética por su simplicidad: |
| 77 | + |
| 78 | +[source, elixir] |
| 79 | +---- |
| 80 | +alias Nx |
| 81 | +matrix = Nx.tensor([ |
| 82 | + [1, 2, 3], |
| 83 | + [4, 5, 6], |
| 84 | + [7, 8, 9] |
| 85 | +]) |
| 86 | +---- |
| 87 | + |
| 88 | +Una matriz A como esta se dice que es una matriz n x m. |
| 89 | + |
| 90 | +Para resolver un sistema como $Ax = b$, no necesitamos hacer cuentas a mano eternamente. Podemos usar la **Eliminación de Gauss** (llevar la matriz a su forma escalonada) o simplemente dejar que **Nx** haga el trabajo pesado: |
| 91 | + |
| 92 | +[source, elixir] |
| 93 | +---- |
| 94 | +# Resolver Ax = b |
| 95 | +# a es la matriz de coeficientes, b el vector de resultados |
| 96 | +solucion = Nx.LinAlg.solve(a, b) |
| 97 | +---- |
| 98 | + |
| 99 | + |
| 100 | +El rango de una matriz es el número de filas (o columnas) que son **linealmente independientes**. Es, de alguna forma, la medida de la "información real" que contiene la matriz. Si una fila se puede obtener sumando las otras, esa fila es redundante y no aumenta el rango. |
| 101 | + |
| 102 | +En computación, solemos estimar el rango observando los valores singulares (SVD). Si un valor es muy cercano a cero, esa dimensión es prácticamente despreciable. |
| 103 | + |
| 104 | +[source, elixir] |
| 105 | +---- |
| 106 | +# Una forma de ver la 'salud' del rango es vía SVD |
| 107 | +{u, s, vt} = Nx.LinAlg.svd(matrix) |
| 108 | +---- |
| 109 | + |
| 110 | + |
| 111 | +No todos los caminos tienen destino. A veces, las ecuaciones se contradicen (como decir que $x=1$ y $x=2$ al mismo tiempo). Geométricamente, esto sucede cuando las rectas o planos son paralelos y nunca se cruzan. En estos casos, el sistema es **inconsistente**. |
| 112 | + |
| 113 | +Es como girar la matriz sobre su diagonal principal. Las filas se convierten en columnas y viceversa. Es una operación fundamental para reorientar datos antes de un producto. |
| 114 | + |
| 115 | +[source, elixir] |
| 116 | +---- |
| 117 | +transpuesta = Nx.transpose(matrix) |
| 118 | +# O de forma abreviada |
| 119 | +transpuesta = Nx.t(matrix) |
| 120 | +---- |
| 121 | + |
| 122 | +Las matrices se pueden sumar (si tienen la misma forma) elemento a elemento. También se pueden multiplicar por un escalar, lo que "estira" o "encoge" toda la transformación. |
| 123 | + |
| 124 | +[source, elixir] |
| 125 | +---- |
| 126 | +suma = Nx.add(matrix_a, matrix_b) |
| 127 | +escalado = Nx.multiply(matrix, 0.5) |
| 128 | +---- |
| 129 | + |
| 130 | +Multiplicar dos matrices ($A \cdot B$) no es multiplicar elemento a producto. Es una **composición de transformaciones**. El elemento en la posición $(i, j)$ es el producto punto de la fila $i$ de $A$ por la columna $j$ de $B$. |
| 131 | + |
| 132 | +[IMPORTANT] |
| 133 | +==== |
| 134 | +El orden importa: $A \cdot B \neq B \cdot A$. En el mundo de las transformaciones, no es lo mismo girar y luego mover, que mover y luego girar. |
| 135 | +==== |
| 136 | + |
| 137 | +[source, elixir] |
| 138 | +---- |
| 139 | +producto = Nx.dot(matrix_a, matrix_b) |
| 140 | +---- |
| 141 | + |
| 142 | + |
| 143 | + |
| 144 | +En matemáticas, la linealidad es una propiedad que garantiza que un sistema sea predecible y fácil de analizar. Se apoya en dos pilares fundamentales: |
| 145 | + |
| 146 | +* *Aditividad:* El efecto combinado de dos entradas juntas es igual a la suma de sus efectos individuales. |
| 147 | +* *Homogeneidad (Escalamiento):* Si multiplicamos la magnitud de una entrada por un factor escalar constante, la salida se multiplicará exactamente por ese mismo factor. |
| 148 | +
|
| 149 | +En términos visuales, las transformaciones lineales mantienen las líneas rectas (no las curvan) y mantienen el origen fijo en su lugar. Esta simplicidad nos permite tomar problemas incomprensibles y descomponerlos en millones de operaciones básicas procesables en paralelo. |
| 150 | + |
| 151 | +== El Tejido del Espacio: Combinaciones y Bases |
| 152 | + |
| 153 | +Si la linealidad nos dice *cómo* cambian las cosas, necesitamos entender *con qué* estamos construyendo ese espacio. Aquí entran los conceptos que dan forma a cualquier sistema multidimensional: |
| 154 | + |
| 155 | + |
| 156 | + |
| 157 | +* *Combinación Lineal:* Es la operación constructiva por excelencia. Consiste en tomar un conjunto de vectores, "estirarlos" o "encogerlos" (multiplicarlos por un escalar) y sumarlos. Matemáticamente, un vector $\vec{w}$ es una combinación lineal de otros vectores si puede expresarse como: |
| 158 | ++ |
| 159 | +$$\vec{w} = c_1\vec{v}_1 + c_2\vec{v}_2 + \dots + c_n\vec{v}_n$$ |
| 160 | ++ |
| 161 | +(donde las $c$ representan números escalares). |
| 162 | + |
| 163 | +* *Espacio Generado (Span):* Imagina dos vectores que apuntan en direcciones distintas. Si calculas absolutamente *todas* sus combinaciones lineales posibles, obtendrás un plano infinito. Ese conjunto de todos los destinos posibles a los que puedes llegar combinando tus vectores se llama espacio generado. |
| 164 | + |
| 165 | +* *Independencia Lineal:* ¿Aportan todos los vectores información nueva? Si tienes un conjunto de vectores y *ninguno* puede construirse como una combinación lineal de los demás, son linealmente independientes; no hay redundancia. Si uno de ellos sí puede formarse combinando el resto, es información repetida (linealmente dependiente) y no expande tu espacio generado. |
| 166 | + |
| 167 | +* *Base y Dimensión:* Si encuentras un conjunto de vectores que son linealmente independientes (cero redundancia) y que generan todo tu espacio de interés, has encontrado una *base*. El número estricto de vectores en esa base es lo que define la *dimensión* del espacio. Es el equivalente a definir los ejes norte-sur, este-oeste y arriba-abajo para poder describir cualquier punto del universo. |
| 168 | + |
| 169 | +[NOTE] |
| 170 | +==== |
| 171 | +Pensar en términos de combinaciones y bases es crucial. Cuando entrenamos una red neuronal o comprimimos un archivo de audio, los algoritmos están, en el fondo, buscando la "base" más eficiente para representar esa información, descartando todo lo que sea "linealmente dependiente" o redundante. |
| 172 | +==== |
6 | 173 |
|
7 | 174 | == La Jerarquía de los Tensores |
8 | 175 |
|
9 | | -Un tensor es un objeto matemático multilineal definido por su **rango**. |
| 176 | +Ahora que entendemos cómo se estructuran y combinan los elementos dentro de un espacio, podemos organizar las "colecciones de información" que lo habitan. Un tensor es, en su forma más pura, un objeto matemático multilineal definido por su rango. |
10 | 177 |
|
11 | 178 | [cols="1,1,2", options="header"] |
12 | 179 | |=== |
13 | 180 | | Rango | Nombre | Significado Geométrico |
14 | | -| 0 | **Escalar** ($k$) | Magnitud pura en un punto. |
15 | | -| 1 | **Vector** ($\vec{v}$) | Dirección y magnitud en el espacio. |
16 | | -| 2 | **Matriz** ($A$) | Transformación lineal entre espacios. |
17 | | -| $n$ | **Tensor de orden $n$** | Generalización multidimensional. |
| 181 | +| 0 | Escalar ($k$) | Magnitud pura en un punto. |
| 182 | +| 1 | Vector ($\vec{v}$) | Dirección y magnitud en el espacio. |
| 183 | +| 2 | Matriz ($A$) | Transformación lineal entre espacios. |
| 184 | +| $n$ | Tensor de orden $n$ | Generalización multidimensional. |
18 | 185 | |=== |
19 | 186 |
|
20 | 187 | [IMPORTANT] |
21 | 188 | ==== |
22 | | -En computación, el rango de un tensor se suele llamar su **número de ejes** o **dimensiones** (`rank` o `ndim`). |
| 189 | +En computación y ciencia de datos, el rango de un tensor se suele llamar su número de ejes o dimensiones (conocido en librerías de código como `rank` o `ndim`). |
23 | 190 | ==== |
24 | 191 |
|
25 | 192 | == Espacios, Kernel e Imagen |
@@ -108,37 +275,39 @@ gradiente_f.(x) # [2.0, 4.0, 6.0] |
108 | 275 | Nx utiliza **modos de compilación** para calcular estos gradientes de forma extremadamente eficiente, permitiendo que el compilador optimice la cadena de derivadas (regla de la cadena) antes de la ejecución. |
109 | 276 | ==== |
110 | 277 |
|
111 | | -== Referencia: Funciones de Álgebra Lineal en Elixir |
| 278 | +== Compendio: Álgebra Lineal en el Ecosistema Elixir (Nx) |
112 | 279 |
|
113 | | -A continuación se presenta una tabla exhaustiva de las funciones disponibles en el ecosistema **Nx** para realizar operaciones de álgebra lineal y cálculo de tensores. |
| 280 | +Como hemos visto, **Nx** funciona como un lenguaje para describir transformaciones en el espacio, superando la función de una librería de cálculo convencional. Aquí tienes un resumen organizado de las herramientas fundamentales que hemos introducido: |
114 | 281 |
|
115 | | -[cols="2,2,3", options="header"] |
| 282 | +[cols="2,3,4", options="header"] |
116 | 283 | |=== |
117 | | -| Categoría | Concepto | Función (Nx / Nx.LinAlg) |
118 | | -.5+| **Operaciones Básicas** | Multiplicación Matricial / Dot | `Nx.dot/2` |
119 | | -| Producto Exterior | `Nx.outer/2` |
120 | | -| Transpuesta | `Nx.transpose/1` o `Nx.t/1` |
| 284 | +| Categoría | Operación | Función en Elixir (`Nx` / `Nx.LinAlg`) |
| 285 | +
|
| 286 | +.5+| **Manipulación de Tensores** |
| 287 | +| Creación de Matriz | `Nx.tensor([[...], [...]])` |
| 288 | +| Transpuesta (Espejo) | `Nx.transpose/1` o `Nx.t/1` |
121 | 289 | | Difusión (Broadcasting) | `Nx.broadcast/2` |
122 | | -| Suma / Resta / Escalar | `Nx.add/2`, `Nx.subtract/2`, `Nx.multiply/2` |
| 290 | +| Remodelar (Reshape) | `Nx.reshape/2` |
| 291 | +| Concatenación (Stack) | `Nx.stack/2` o `Nx.concatenate/2` |
| 292 | +
|
| 293 | +.5+| **Aritmética de Transformación** |
| 294 | +| Suma / Resta | `Nx.add/2`, `Nx.subtract/2` |
| 295 | +| Escalamiento | `Nx.multiply/2` (Matriz y Escalar) |
| 296 | +| Multiplicación Matricial | `Nx.dot/2` (Composición de transformaciones) |
| 297 | +| Producto Exterior | `Nx.outer/2` |
| 298 | +| Inversa de Matriz | `Nx.LinAlg.invert/1` |
123 | 299 |
|
124 | | -.4+| **Propiedades y Métricas** | Norma (Vector/Matriz) | `Nx.LinAlg.norm/2` |
| 300 | +.4+| **Análisis y Geometría** |
| 301 | +| Resolución de Sistemas ($Ax = b$) | `Nx.LinAlg.solve/2` |
| 302 | +| Norma (Magnitud) | `Nx.LinAlg.norm/2` |
125 | 303 | | Determinante | `Nx.LinAlg.determinant/1` |
126 | | -| Traza | `Nx.trace/1` |
127 | | -| Rango de Matriz (Aprox) | `Nx.LinAlg.svd/1` (vía valores singulares) |
| 304 | +| Rango e Información (SVD) | `Nx.LinAlg.svd/1` |
128 | 305 |
|
129 | | -.4+| **Soluciones y Sistemas** | Inversa de Matriz | `Nx.LinAlg.invert/1` |
130 | | -| Pseudoinversa (Moore-Penrose) | `Nx.LinAlg.pinv/1` |
131 | | -| Resolver Sistema $Ax = b$ | `Nx.LinAlg.solve/2` |
| 306 | +.4+| **Cálculo Avanzado** |
| 307 | +| Gradientes ($\nabla$) | `Nx.grad/1` |
| 308 | +| Diferenciación Automática | `Nx.ValueWithGrad` |
132 | 309 | | Potencia de Matriz | `Nx.LinAlg.matrix_power/2` |
133 | | -
|
134 | | -.5+| **Descomposiciones** | Valores y Vectores Propios | `Nx.LinAlg.eigh/1` (matrices simétricas) |
135 | | -| Val. Singulares (SVD) | `Nx.LinAlg.svd/1` |
136 | | -| QR | `Nx.LinAlg.qr/1` |
137 | | -| Cholesky | `Nx.LinAlg.cholesky/1` |
138 | | -| LU | `Nx.LinAlg.lu/1` |
139 | | -
|
140 | | -.2+| **Cálculo de Tensores** | Gradiente | `Nx.grad/1` |
141 | | -| Jacobiano (Vía gradientes) | `Nx.grad/1` (aplicado sobre funciones vectoriales) |
| 310 | +| Descomposición QR / Cholesky | `Nx.LinAlg.qr/1`, `Nx.LinAlg.cholesky/1` |
142 | 311 | |=== |
143 | 312 |
|
144 | 313 | [IMPORTANT] |
|
0 commit comments