01 · Punto de partida
Misma matemática, distinto programa
Los Temas 39–42 te dieron el diagnóstico: grilla finita (39), ½ ulp por operación (40), sesgo al cortar (41) y suma que acumula (42). Ahora la cura: dos programas que en el pizarrón son idénticos pueden comportarse opuesto en la máquina. El ejemplo estrella: la varianza “de libro” Σx²/N − media² resta dos gigantes casi iguales y devuelve varianzas negativas; el incremental de Welford actualiza media y dispersión paso a paso y queda clavado en la verdad.
La lección general: el error de redondeo es inevitable, pero amplificarlo es opcional. Un algoritmo estable lo deja en 1–2 ulps; uno inestable lo multiplica por el número de condición hasta volverlo basura.
- ¿Qué distingue un problema mal condicionado de un algoritmo inestable?
- ¿Por qué restar casi-iguales (cancelación) es la放大器 del error?
- ¿Cómo se calcula varianza sin restar gigantes?
- ¿Qué recetas estables uso en simulación: Welford, dos pasadas, log?
02 · Definición
Condición del problema, estabilidad del algoritmo
Condición
Del problema, no tuya: si b ≈ a, a − b pierde dígitos significativos aunque operes perfecto. Dato sensible.
Cancelación
Restar casi-iguales borra los dígitos buenos y deja al descubierto el redondeo escondido: el error relativo explota.
Estabilidad
Del algoritmo: el estable evita esa resta (Welford, dos pasadas, fma); el inestable la pone en el centro (varianza de libro).
| Cálculo | Inestable | Estable |
|---|---|---|
| Varianza | Σx²/N − media² (cancela) | Welford o dos pasadas |
| Suma larga dispar | Naive sobre el gigante | Chicos-primero / Kahan / fsum |
1 − cos(x), x chico | Resta 1 − 0,999… | 2·sin²(x/2) |
03 · Anatomía
Las tres recetas estables
Casi toda inestabilidad es una resta de casi-iguales disfrazada. Tres formas de desarmarla:
- Centrar antes de operar (dos pasadas)
- Primero la media, después
Σ(x − media)²/N: los números chicos se restan entre sí, no dos gigantes. Dos recorridas, error mínimo. - Acumular incremental (Welford)
- Media y
M₂se actualizan dato a dato sin guardar el vector: una pasada, estable y online. El estándar para streams de simulación. - Reformular la expresión
- Cambiar la fórmula por una equivalente sin cancelación:
1 − cos(x) → 2·sin²(x/2),log(1+x)conlog1p, productos confma.
Bien planteado
Welford / dos pasadas
Error de 1–2 ulps aunque la media sea 1e8 y la varianza 2. Varianza siempre ≥ 0, promedio incremental gratis.
Mal planteado
Libro de una pasada
Con media grande, Σx²/N y media² coinciden en 15 dígitos: la resta deja solo redondeo, a veces negativo. Imposible físico.
04 · Ejemplos
Tres inestabilidades clásicas
- 1Varianza negativa.
Datos
1e8 ± 2: la de libro resta1,0000000000000004e16 − 1,0000000000000000e16y puede dar−4,0. Welford da2,0clavado. - 2
1 − cos(1e−8).Ingenuo:
1 − 0,9999999999999999 = 0,0(todo cancelado). Estable:2·sin²(5e−9) ≈ 5e−17correcto. - 3Promedio de 1 M de energías.
Sumar todo y dividir arrastra absorción (Tema 42); el promedio incremental (
μ += (x−μ)/n) nunca forma el gigante y es estable por construcción.
05 · Demostración en Python
La varianza que da negativa
El mismo vector, dos funciones: la de libro y Welford. Con media 1e8 la primera se rompe y la segunda ni se inmuta.
Python en tu navegador. Bajá la base a 0 y ambas coinciden; subila a 1e8 y solo una sobrevive.
def var_libro(xs):
n = len(xs)
return sum(x * x for x in xs) / n - (sum(xs) / n) ** 2
def var_welford(xs):
n = mu = m2 = 0
for x in xs:
n += 1
d = x - mu
mu += d / n
m2 += d * (x - mu)
return m2 / n
base, vals = 1e8, [1e8 + d for d in [-2, -1, 0, 1, 2]] * 400
print("libro: ", var_libro(vals))
print("welford:", var_welford(vals))
Libro ≈ negativa o disparatada; Welford ≈ 2,0: la resta de gigantes delata al inestable.
Promedio incremental (bonus estable)
mu = 0.0
for n, x in enumerate(vals, start=1):
mu += (x - mu) / n
print(mu)
06 · Exploración
Laboratorio: la varianza que explota con la media
Datos con varianza verdadera 2,0 (patrón −2…+2 repetido) montados sobre una media base M. La curva naranja es el error de la fórmula de libro y la verde el de Welford, en función de M (eje log). Elegí M y N y mirá dónde se rompe la ingenua.
Error |var − 2| frente a M
datos = M + {−2…+2} · var real = 2
Con M = 1e8 la de libro se rompe y Welford sigue en 2,0.
El eje x es la media base (log), el eje y el error absoluto en log. La ingenua sube en diagonal con M²; la estable queda abajo pegada al cero.
Preguntas para explorar
- Con M = 0: ¿ambas dan 2,0? ¿Por qué la cancelación no muerde ahí?
- Con M = 1e8: ¿la de libro da negativa, cero o gigante? ¿Qué dígitos se cancelaron?
- Subí N de 500 a 5000 con M = 1e8: ¿la ingenua mejora o empeora? ¿Y Welford?
Ver respuestas sugeridas
- Sí:
Σx²/Nymedia²son chicos y distintos; la resta conserva dígitos. Sin gigantes casi-iguales no hay cancelación. - Cualquiera de las tres según N: los 16 dígitos de
M²coinciden y solo queda redondeo (Tema 40) amplificado. Negativa = firma de inestabilidad. - La ingenua no mejora (más términos no devuelven dígitos perdidos); Welford converge a 2,0: el estable sí aprovecha más datos.
07 · Comprensión
Confusiones frecuentes
«Si la fórmula es correcta, el código es correcto»
En el pizarrón sí; en floats no: Σx²/N − μ² es matemáticamente perfecta y numéricamente inestable. La corrección incluye la estabilidad.
«Varianza negativa = bug mío en los datos»
Con datos sanos la de libro da negativa por cancelación: es el algoritmo, no tus datos. Cambiá a Welford antes de “arreglar” la entrada.
«Welford es más lento, uso la de libro»
Welford es O(N) en una pasada como la de libro, sin vector extra y con media gratis. Más estable al mismo costo: no hay trade-off.
«Con float64 alcanza para todo»
64 bits no salvan una resta que borró 15 dígitos: pasar a 128 bits retrasa la explosión, no la evita. La reformulación sí la evita.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: romper la de libro
Reproducí la varianza negativa con base 1e8 y confirmá que Welford da 2,0.
vals = [1e8 + d for d in [-2, -1, 0, 1, 2]] * 400
n = len(vals)
print(sum(x * x for x in vals) / n - (sum(vals) / n) ** 2)
Ver solución razonada
Da negativa o con error de decenas: Σx²/N ≈ μ² ≈ 1e16 y la resta deja solo redondeo amplificado (cancelación). La firma de inestabilidad es justamente un imposible físico.
Ejercicio 2: 1 − cos(x) que da cero
Mostrá que la forma ingenua colapsa con x chico y que 2·sin²(x/2) la salva.
import math
x = 1e-8
print(1 - math.cos(x))
print(2 * math.sin(x / 2) ** 2)
Ver solución
0,0 vs 5e−17: la ingenua resta 1 − 0,999… y cancela todo; la reformulada nunca forma el 1−casi-1. Mismo patrón que la varianza.
Ejercicio 3: Welford desde cero
Escribí welford que devuelva media y varianza en una pasada y probalo con base 1e6.
Ver una posible respuesta
def welford(xs):
n = mu = m2 = 0
for x in xs:
n += 1
d = x - mu
mu += d / n
m2 += d * (x - mu)
return mu, m2 / n
vals = [1e6 + d for d in [-2, -1, 0, 1, 2]] * 200
print(welford(vals))
(1000000,0, 2,0) estable: la media absorbe lo grande y m2 acumula solo desvíos chicos, sin restar gigantes.
09 · Síntesis
Ideas para recordar
- Condición = del problema; estabilidad = del algoritmo.
- La cancelación (restar casi-iguales) amplifica el ½ ulp hasta basura.
- Varianza: nunca la de libro; Welford o dos pasadas centradas.
- Recetas: centrar, acumular incremental, reformular sin la resta.
- Estable no es exacto: es no-amplificar. Medí contra la versión estable.
En el próximo tema volvemos al azar: cómo la calidad del generador sesga todos los resultados de la simulación.