Generación de Variables Aleatorias · Tema 05

Método de la transformada inversa

La receta estrella X = F⁻¹(U): por qué funciona, el algoritmo en 3 pasos y cuándo es exacta, barata e imbatible.

01 · Punto de partida

El método que conviene intentar primero

Si conocés F y podés invertirla —con fórmula o numéricamente—, no necesitás nada más: un solo uniforme por muestra, sin rechazos, sin tablas, sin propuestas. Por eso la transformada inversa es el método por defecto y el patrón contra el que se comparan todos los demás.

Ya la usaste tres veces: Bernoulli por umbral, U(a,b) por escala, exponencial por logaritmo. Ahora la formalizamos como teorema y algoritmo general.

  • ¿Por qué P(F⁻¹(U) ≤ x) = F(x) exactamente?
  • ¿Cuáles son los 3 pasos del algoritmo, en discreto y continuo?
  • ¿Cuándo es O(1) y cuándo se vuelve costosa?
  • ¿Qué hacer si F no tiene inversa cerrada?

02 · Definición

Teorema y prueba en 4 líneas

Para F continua e invertible, Q = F⁻¹ clásica. La prueba usa solo monotonía:

La primera igualdad aplica F (creciente) a ambos lados; la segunda usa que P(U ≤ u) = u. Para F general (saltos, planos) vale lo mismo con la inversa generalizada Q(u) = mín{x : F(x) ≥ u}.

①

Generar U

Un U ~ U(0,1) por muestra. Nada más: sin propuestas, sin bucles de aceptación.

②

Evaluar Q

Fórmula cerrada (Temas 6), bisección numérica (Tema 7) o búsqueda en tabla (Tema 2). Ahí está todo el costo.

③

Devolver X

X = Q(U) ya es la muestra. Con 1−U en vez de U si evita un logaritmo o mejora bordes (misma distribución).

El mismo algoritmo, distintas Q.
X ~Q(u)Costo por muestra
U(a,b)a + (b−a)·uO(1), 1 multiplicación
Exp(λ)−ln(1−u)/λO(1), 1 logaritmo
Pareto(xm,α)xm·(1−u)^(−1/α)O(1), 1 potencia
Discreta finitabuscar k con Fk ≥ uO(log n) con bisect

03 · Anatomía

Cuándo brilla y cuándo no alcanza

Exacta
Si Q es exacta, la muestra respeta F sin error de método. El único error es Monte Carlo (finito N) y punto flotante en bordes.
Eficiente
Un U por X y O(1) o O(log n). Imbatible frente a rechazo cuando la tasa de aceptación es baja (Temas 8–10).
Monótona y acoplable
U grande ↔ X grande. Permite variables antitéticas, correlación por cuantiles comunes y reducción de varianza.
Limitada por Q
Normal, gamma con α no entero y muchas mezclas no tienen Q elemental. Ahí van numérica, Box-Muller, composición o rechazo.

Inversa directa

Determinista y predecible

Costo fijo por muestra, sin rechazos. Ideal para N millonario si Q es barata (un log, una potencia).

Rechazo / otros

Costo aleatorio

Necesarios cuando Q no existe o es carísima. Pagan con propuestas extra y muestras descartadas.

04 · Catálogo exprés

Las Q que conviene memorizar

F(x)→despejar Q(u)→X = Q(U)
  1. 1
    Uniforme y exponencial.

    Ya dominadas: escala y logaritmo. Base de tiempos y jitter. (Temas 21–22)

  2. 2
    Weibull y Pareto.

    Weibull(k,λ): λ·(−ln(1−u))^(1/k). Pareto: potencias de (1−u). Colas pesadas con una línea.

  3. 3
    Triangular y logística.

    Triangular por tramos con raíz cuadrada; logística con logit: μ − s·ln((1−u)/u).

  4. 4
    Sin cerrada.

    Normal, gamma general: numérica (Tema 7) o métodos dedicados (Temas 23–26). No fuerces una Q inexistente.

05 · Representación en Python

Una Q por distribución, un bucle común

El patrón es siempre el mismo: función Q + random.random(). Cambiar de distribución es cambiar una línea.

Python en tu navegador. Cambiá λ y N y compará media y cola contra la teoría.

import random
import math

random.seed(30)

def Q_exp(u, lam):
    return -math.log(1 - u) / lam

def Q_pareto(u, xm=1.0, alpha=2.0):
    return xm * (1 - u) ** (-1 / alpha)

def Q_weibull(u, lam=1.0, k=1.5):
    return lam * (-math.log(1 - u)) ** (1 / k)

lam, N = 1.5, 6000
m_exp = [Q_exp(random.random(), lam) for _ in range(N)]
print("exp media:", round(sum(m_exp) / N, 3), "teórica:", round(1 / lam, 3))
print("P(X>1):", round(sum(1 for x in m_exp if x > 1) / N, 3),
      "teórica:", round(math.exp(-lam), 3))
print("pareto:", [round(Q_pareto(random.random()), 2) for _ in range(5)])
print("weibull:", [round(Q_weibull(random.random()), 2) for _ in range(5)])

La media exponencial debe rondar 0,667 y P(X>1) ≈ 0,223. Si ves ValueError: math domain, entró u = 1 exacto: usá 1-u con resguardo.

06 · Exploración

Laboratorio: la exponencial por inversa

Movete λ y N. El histograma (densidad por área) debe pegarse a la curva naranja f(x) = λ·e^(−λx). Con N chico hay ruido; con N grande, calce.

EXPERIMENTO 05

Inversa exacta

X = −ln(1−U) / λ

Los resultados numéricos aparecen debajo.
Media muestral0,667
Media teórica 1/λ0,667
P(X>1) muestral0,223
P(X>1) teórica0,223

Con λ 1,5, media 0,667 y cola 0,223.

Histograma en densidad (área 1) hasta el percentil 99,5. La curva es la densidad teórica. Probá λ = 0,5 (cola larga) y λ = 3 (concentrada).

Preguntas para explorar

  1. Con λ = 1,5, ¿qué media y qué P(X>1) esperás? Leelas en el panel.
  2. Bajá N a 300. ¿El histograma se despega? ¿La media también?
  3. Subí λ a 3. ¿La masa se corre a la izquierda o a la derecha? ¿Por qué 1/λ lo explica?
Ver respuestas sugeridas
  1. Media 0,667 y cola e^(−1,5) ≈ 0,223.
  2. Sí: el ruido por barra crece como 1/√N. La media también fluctúa más.
  3. A la izquierda: media 1/3 ≈ 0,333. Mayor tasa ⇒ tiempos más cortos.

07 · Comprensión

Confusiones frecuentes

«Inversa = 1/f»

No: Q es la inversa funcional de F (despejar x de u = F(x)), no el recíproco 1/f(x). Para Exp, Q = −ln(1−u)/λ, no λ·e^(λx).

«Vale cualquier rama del logaritmo»

U ∈ [0,1) ⇒ 1−U ∈ (0,1] ⇒ ln ≤ 0 ⇒ −ln ≥ 0. Si usás log(U) es equivalente, pero log(1+U) o log(U)/λ sin menos da negativos o dominio inválido.

«Con N = 200 ya valida»

La cola P(X>1) ≈ 0,22 tiene error típico √[p(1−p)/N] ≈ 0,03 con N = 200. Para dos decimales necesitás miles.

«Si no hay fórmula, no hay inversa»

Sí la hay: numérica por bisección sobre F (Tema 7). Más lenta por muestra, pero igual de exacta a tolerancia dada.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: Pareto por inversa

Pareto xm=1, α=2: Q(u) = (1−u)^(−1/2). Con semilla 31 y N=6000, estimá la mediana y compará con xm·2^(1/α) = √2 ≈ 1,414.

import random

random.seed(31)
N = 6000
m = [(1 - random.random()) ** (-1 / 2) for _ in range(N)]
m_sorted = sorted(m)
print("mediana muestral:", round(m_sorted[N // 2], 3))
print("teórica:", round(2 ** 0.5, 3))
Ver solución razonada

Debe dar ≈ 1,41 (típicamente 1,38–1,45). Si da ≈ 0,5, invertiste el exponente (+1/2 en vez de −1/2).

Ejercicio 2: Weibull sin memorizar

Deducí Q para Weibull F(x) = 1 − exp(−(x/λ)^k) despejando u = F(x). Después verificá media con λ=1, k=1,5 (teórica λ·Γ(1+1/k) ≈ 0,903).

import random
import math

random.seed(32)
lam, k, N = 1.0, 1.5, 8000
m = [lam * (-math.log(1 - random.random())) ** (1 / k) for _ in range(N)]
print(round(sum(m) / N, 3), "vs 0.903")
Ver solución

Q(u) = λ·(−ln(1−u))^(1/k). La media muestral debe caer 0,89–0,92. El despeje: 1−u = exp(−(x/λ)^k) ⇒ x = λ·(−ln(1−u))^(1/k).

Ejercicio 3: el borde U = 0

Forzá u = 0 y u = 0,999999 en Q_exp con λ = 1. ¿Qué X salen? ¿Qué resguardo pondrías si tu generador puede dar 0 o 1 exactos?

Ver una posible respuesta
import math

def Q_exp(u, lam=1.0):
    u = min(max(u, 1e-12), 1 - 1e-12)  # resguardo
    return -math.log(1 - u) / lam

print(Q_exp(0.0), Q_exp(0.999999))
print(Q_exp(1.0))  # sin resguardo sería +inf

Sin resguardo: 0 y ≈ 13,8; u = 1 daría +∞. El clamp a [tiny, 1−tiny] evita +∞ y NaN sin sesgo medible.

09 · Síntesis

Ideas para recordar

  • X = Q(U) con Q(u) = mín{x : F(x) ≥ u} genera X ~ F exacta.
  • Cuesta un U por muestra más evaluar Q: ideal si Q es cerrada y barata.
  • Es monótona: habilita antitéticas y acoples por cuantiles.
  • Protegé bordes (u = 0/1) y documentá el par (F, Q).
  • Sin Q cerrada: numérica, Box-Muller o rechazo, no improvisación.

En el próximo tema veremos las Q cerradas más rentables: la inversión analítica.