🧮 Computational Mathematics

Inicio · Parte 01 — Aritmética computacional y representación numérica

036 — Estabilidad de algoritmos

basico-computacional clase 16 de 20 4 horas demostración stability

Un algoritmo es estable si no amplifica el error más allá de lo que el condicionamiento del problema exige.

Fórmulas

raíz pequeña ingenua:  (−b + √(b²−4ac)) / 2a
raíz pequeña estable:  2c / (−b − √(b²−4ac))
invariante: r₁·r₂ = c/a

Desarrollo

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).

Ejemplo trabajado

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      ✓

Qué calcula el laboratorio

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

Salidas del laboratorio (7)

Muestra de la ejecución real

{
  "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
}

Errores comunes

Dónde se usa

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).

Idea rectora de la parte

Un float es un racional binario de precisión finita, no un número real.

Error a evitar

Comparar floats con `==` en lugar de una tolerancia razonada.

Conexión con IA

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.

Bibliografía de la clase

Archivos de la clase