Números Pseudoaleatorios · Tema 30

Pruebas de series

Pares y ternas sucesivas: el cuadrado 10×10 que atrapa a RANDU y a todo LCG con planos.

01 · Punto de partida

En 1D pasa, en 2D cae

RANDU daba media 0,5, χ² digno y correlograma tímido (Temas 26–28). Pero graficá los pares (uₙ, uₙ₊₁): en vez de nube aparecen diagonales; con ternas, 15 planos. La prueba de series es ese gráfico convertido en cuenta: partir el cuadrado [0,1)² en k² celdas y contar pares como el Tema 29 contaba décimos.

Es la prueba que separa generadores “de juguete 1D” de generadores aptos para simulación real, donde casi todo usa pares (puntos, agentes, colas).

  • ¿Cómo se arma el χ² sobre k² celdas?
  • ¿Pares solapados o no solapados?
  • ¿Cuántos valores N exige un 10×10?
  • ¿Pares que pasan garantizan ternas?

02 · Definición

El cuadrado y el cubo

◈

Pares

(u₁,u₂), (u₃,u₄), … no solapados sobre 10×10: 100 celdas con E = P/100. χ² con 99 gl.

⇄

Ternas

(u₁,u₂,u₃), … sobre 10³ = 1000 celdas: exige P ≥ 5000 (E ≥ 5). Ahí murió RANDU: 15 planos.

▣

No solapados

Solapados (u₁,u₂), (u₂,u₃) rinden más pares pero correlacionan el conteo: el χ² clásico pide no solapados.

Diseño según dimensión.
DimensiónCeldas (k=10)N mínimo (E≥5)
Pares100P = 500 → N = 1000
Ternas1000P = 5000 → N = 15000
Cuaternas10000Solo baterías (BigCrush): N ≥ 50000

03 · Procedimiento correcto

Grilla, conteo y lectura

Con k = 4 (16 celdas, didáctico) y P = 800 pares, E = 50 por celda: un sano ronda 50 ± 14 y χ² ≈ 15 con 15 gl (crítico 25,0). Un LCG con diagonales deja celdas en 0 y otras en 120: χ² ≈ 300.

k chico primero
k = 4 didáctico (16 celdas visibles), k = 10 estándar. k = 20 en pares (400 celdas) exige P ≥ 2000: solo con N grande.
Scatter antes que χ²
El gráfico de pares es gratis y demoledor: diagonales, grillas gruesas o huecos se ven antes de contar (Tema 31).
Pares ≠ ternas
Pasar pares no absuelve ternas: RANDU pasaba 2D flojo y caía en 3D. La batería sube de dimensión.

Bien probado

k previo + scatter

Nube sin estructura, celdas ≈ E, χ² bajo crítico. Informe con k, P, χ² y gráfico.

Mal probado

Solapados sin ajuste

Duplicar pares solapando infla N ficticio: el χ² rechaza hasta sanos. No solapados o teoría de solapados, nunca mezcla.

04 · Ejemplos

Tres nubes típicas

Pares (x,y)→Grilla k×k→χ² con k²−1 gl
  1. 1
    Sano, P = 2000, k = 10.

    Nube pareja, celdas ≈ 20, χ² ≈ 99 < 123,2. Pasa.

  2. 2
    LCG a=5, c=3, m=16.

    Solo 16 puntos posibles en el cuadrado: celdas en 0 y picos. χ² astronómico con P grande.

  3. 3
    RANDU en ternas.

    Pares “aceptables”, ternas en 15 planos: el 2D perdona, el 3D condena. Por eso la batería sube.

05 · Implementación en Python

χ² sobre el cuadrado

Pares no solapados sobre grilla k×k con crítico Wilson-Hilferty al 5 %. Probalo con random (pasa) y con el juguete (no pasa).

Python en tu navegador. Subí k a 10 con P = 2000 y mirá E = 20: el test respira.

import random

def chi2_series(us, k=4):
    pares = [(us[i], us[i + 1]) for i in range(0, len(us) - 1, 2)]
    p = len(pares)
    e = p / (k * k)
    obs = [[0] * k for _ in range(k)]
    for x, y in pares:
        obs[min(k - 1, int(x * k))][min(k - 1, int(y * k))] += 1
    chi = sum((o - e) ** 2 / e for fila in obs for o in fila)
    return p, round(chi, 2)


rng = random.Random(30)
us = [rng.random() for _ in range(4000)]
print(chi2_series(us, k=4), "critico gl=15: 25.0")

P = 2000, χ² ≈ 10–20 bajo 25,0: nube sana en 4×4.

El juguete en el cuadrado

def chi2_series(us, k=4):
    pares = [(us[i], us[i + 1]) for i in range(0, len(us) - 1, 2)]
    e = len(pares) / (k * k)
    obs = [[0] * k for _ in range(k)]
    for x, y in pares:
        obs[min(k - 1, int(x * k))][min(k - 1, int(y * k))] += 1
    return round(sum((o - e) ** 2 / e for fila in obs for o in fila), 2)


x = 7
mal = []
for _ in range(4000):
    x = (5 * x + 3) % 16
    mal.append(x / 16)
print(chi2_series(mal, k=4), "critico gl=15: 25.0")

06 · Exploración

Laboratorio: la nube o las diagonales

Pares no solapados como puntos (x,y) sobre grilla 4×4. Fuentes: sano (nube), juguete m = 16 (16 puntos) y diagonal y ≈ (5x+c) mod 1 (LCG a ojo). El panel trae χ² con 15 gl.

EXPERIMENTO 30

Cuadrado 4×4

χ² con 15 gl · crít 25,0

Los resultados numéricos aparecen debajo.
χ² (crit 25,0)—
Celdas vacías—
E por celda—
Veredicto—

Sano con P = 400: nube sin estructura.

Puntos alineados en diagonales = dependencia lineal. Celdas vacías sistemáticas = resolución o planos.

Preguntas para explorar

  1. Con juguete y P = 1000: ¿cuántas celdas se llenan como máximo? ¿Qué χ² sale?
  2. Con diagonal: ¿el χ² pasa con P = 100? ¿Y con P = 1000?
  3. Si el scatter se ve bien, ¿puede igual fallar el χ²? ¿Y al revés?
Ver respuestas sugeridas
  1. 16 celdas como máximo (16 estados): χ² ≈ miles. El 2D revela lo que el 1D escondía.
  2. Con P chico la potencia no alcanza y “pasa”; con P grande el χ² explota. La potencia vive en P.
  3. Sí en ambos: el ojo subestima desvíos chicos sistemáticos y exagera huecos de azar. Gráfico + cuenta, siempre.

07 · Comprensión

Confusiones frecuentes

«Uso pares solapados, rinden el doble»

Rinden más pero correlacionan conteos: el χ² clásico se invalida. O no solapados, o teoría ajustada: nunca el χ² crudo sobre solapados.

«k = 20 en pares es más fino»

400 celdas exigen P ≥ 2000 (E ≥ 5): con P = 400 hay E = 1 y el test colapsa. k se elige por P.

«El scatter se ve bien, no cuento»

El ojo perdona desvíos del 20 % sistemáticos que el χ² condena, y condena huecos de azar que el χ² absuelve. Ver + contar.

«Pares bien = simulación a salvo»

Modelos con ternas (puntos 3D, física) exigen ternas: RANDU enseñó que el 2D perdona lo que el 3D condena.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: nube sana 4×4

Con 4000 valores de random (P = 2000) verificá χ² < 25,0 en grilla 4×4.

import random

rng = random.Random(17)
us = [rng.random() for _ in range(4000)]
pares = [(us[i], us[i + 1]) for i in range(0, len(us) - 1, 2)]
e = len(pares) / 16
obs = [[0] * 4 for _ in range(4)]
for x, y in pares:
    obs[min(3, int(x * 4))][min(3, int(y * 4))] += 1
chi = sum((o - e) ** 2 / e for fila in obs for o in fila)
print(len(pares), round(chi, 2), chi < 25.0)
Ver solución razonada

P = 2000, E = 125, χ² ≈ 8–22 con True: pasa. Celdas ≈ 125 ± 22.

Ejercicio 2: diagonal delatora

Construí pares y = (5x + 0,1) mod 1 y mostrá χ² ≫ 25 con P = 2000.

import random

rng = random.Random(17)
xs = [rng.random() for _ in range(2000)]
pares = [(x, (5 * x + 0.1) % 1.0) for x in xs]
e = len(pares) / 16
obs = [[0] * 4 for _ in range(4)]
for x, y in pares:
    obs[min(3, int(x * 4))][min(3, int(y * 4))] += 1
chi = sum((o - e) ** 2 / e for fila in obs for o in fila)
print(round(chi, 2))
Ver solución

χ² ≈ varios cientos: condena. El scatter mostraría 5 diagonales paralelas: dependencia lineal perfecta.

Ejercicio 3: P que esconde

Mostrá que la diagonal “pasa” con P = 40 (E = 2,5) por falta de potencia y cae con P = 2000.

Ver una posible respuesta
import random

def chi_diag(p):
    rng = random.Random(17)
    pares = [(x := rng.random(), (5 * x + 0.1) % 1.0) for _ in range(p)]
    e = p / 16
    obs = [[0] * 4 for _ in range(4)]
    for x, y in pares:
        obs[min(3, int(x * 4))][min(3, int(y * 4))] += 1
    return round(sum((o - e) ** 2 / e for fila in obs for o in fila), 2)


print("P=40:", chi_diag(40), "P=2000:", chi_diag(2000))

P = 40: χ² ≈ 10–20 (pasa sin validez, E < 5); P = 2000: χ² ≫ 25 (condena). Potencia = P.

09 · Síntesis

Ideas para recordar

  • Series: pares no solapados sobre k×k, E = P/k², χ² con k²−1 gl.
  • 10×10 estándar: 100 celdas, crítico ≈ 123,2; 4×4 didáctico: crítico 25,0.
  • Scatter primero, conteo después; solapados invalidan el χ² crudo.
  • Pares que pasan no absuelven ternas (RANDU).
  • Todo LCG tiene planos: importa a qué dimensión y con cuántos.

En el próximo tema miramos sin contar: pruebas gráficas, ver patrones a simple vista.