Inicio · Parte 01 — Aritmética computacional y representación numérica
raíz pequeña ingenua: (−b + √(b²−4ac)) / 2a
raíz pequeña estable: 2c / (−b − √(b²−4ac))
invariante: r₁·r₂ = c/a
Estabilidad y condicionamiento son propiedades distintas que se confunden constantemente. El condicionamiento dice cuánta precisión permite el problema; la estabilidad dice cuánta precisión conserva el algoritmo. Un algoritmo estable aplicado a un problema mal condicionado dará un resultado impreciso, y eso no es culpa del algoritmo. Un algoritmo inestable aplicado a un problema bien condicionado dará un resultado impreciso, y eso sí lo es.
La fórmula cuadrática es el ejemplo canónico. Cuando b² ≫ 4ac, la raíz cuadrada del discriminante es casi igual a |b|, así que una de las dos raíces se obtiene restando dos números casi iguales: cancelación catastrófica. El problema —encontrar las raíces— está perfectamente bien condicionado; el algoritmo estándar es inestable para una de ellas.
La solución usa una identidad elemental: el producto de las raíces es c/a. Calculada la raíz grande de forma estable (la que no sufre cancelación), la pequeña se obtiene dividiendo. El invariante que se usa para calcularla sirve además como verificación: si r₁·r₂ no da c/a, hay un error.
Este patrón —usar un invariante conocido tanto para calcular como para verificar— es uno de los hábitos más transferibles del programa. Aparece en la ortogonalidad de QR (clase 130), en la conservación de la masa de un plan de transporte (clase 346) y en la suma de probabilidades de una softmax (clase 321).
Raíces de x² + 10⁸x + 1 = 0.
a = 1, b = 1e8, c = 1
√(b² − 4ac) = 99999999.99999999
Raíz grande (estable en ambos métodos):
r₂ = (−b − √Δ)/2a = −1e8
Raíz pequeña:
ingenua: (−b + √Δ)/2a = −7.45e−09 ← cancelación
estable: 2c/(−b − √Δ) = −1.0e−08 ← correcta
Verificación con el invariante r₁·r₂ = c/a = 1:
ingenua: −7.45e−09 × −1e8 = 0.745 ✗
estable: −1.0e−08 × −1e8 = 1.0 ✓
Misma raíz cuadrática por dos algoritmos: uno estable, otro no.
python classes/part-01-aritmetica-computacional-y-representacion-numerica/036-estabilidad-de-algoritmos/lab.py
compmath run 036
coeficientesraiz_pequena_ingenuaraiz_pequena_estableraiz_grandeproducto_raices_ingenuaproducto_raices_estableproducto_teorico_c/a{
"coeficientes": [
1.0,
100000000.0,
1.0
],
"raiz_pequena_ingenua": -7.450580596923828e-09,
"raiz_pequena_estable": -1e-08,
"raiz_grande": -100000000.0,
"producto_raices_ingenua": 0.7450580596923828,
"producto_raices_estable": 1.0
}
Selección de algoritmos numéricos, implementación de fórmulas cerradas y verificación de resultados. Es la razón por la que se prefiere QR frente a las ecuaciones normales en mínimos cuadrados (clase 234).
float32, bfloat16 y la cuantización a int8 son decisiones de representación. Los NaN en un entrenamiento casi siempre nacen aquí, no en la arquitectura.
9780898718027, pendiente de resolver.