SMM con incertidumbre de simulación
puremacro.structural.fit_simulated_moments ajusta momentos simulados teniendo
en cuenta tanto el error muestral empírico como el error de Monte Carlo. Esta
primera interfaz admite momentos localmente suaves con un presupuesto fijo de
simulación. Extiende el puente empírico-estructural y
conserva los estimadores existentes de VFI, DMP y deuda soberana.
Un ajuste reproducible
La covarianza empírica es Cov(el estimador empírico), ya en su escala
muestral. El ejemplo utiliza una media observada sintética con varianza conocida
1/1000. Cada réplica simulada es una media de diez observaciones normales
independientes; 32 de esas medias forman el estimador simulado.
from dataclasses import replace
import numpy as np
from puremacro.structural import (
MomentReplication, MomentTargets, SimulationPlan,
fit_simulated_moments, simulate_moments, moment_error_covariance,
)
targets = MomentTargets([0.4], [[1/1000]], ("mean",), units="level")
plan = SimulationPlan(seed=20261108, replications=32, periods=10)
def simulator(theta, rng, budget):
values = theta[0] + rng.normal(size=budget.periods)
return MomentReplication([values.mean()], counts=[budget.periods])
fit = fit_simulated_moments(
simulator, targets, [0.0], plan=plan,
definition_id="iid-normal-mean-v1", parameter_names=("mu",),
jac=lambda theta: [[1.0]],
assume_independent=True, assume_smooth=True,
validation_plan=replace(plan, role="validation", replications=128),
)
assert fit.success and fit.inference_valid, fit.inference_reasons
print(fit.summary())
print(fit.moment_fit())
success describe al optimizador. inference_valid requiere además superar
las comprobaciones numéricas y de derivadas locales, sujeto a los supuestos
estadísticos siguientes. summary(), to_frame(), to_dataframe(),
to_markdown(), to_latex() y to_typst() presentan las mismas estimaciones
e intervalos. moment_fit(validation=True) ofrece una comparación descriptiva
separada.
Dos convenciones distintas de covarianza
Para vectores conjuntos independientes \(s_1,\ldots,s_R\), la media simulada es \(\bar s=R^{-1}\sum_r s_r\), con covarianza estimada
No se divide otra vez por el número de períodos: la variabilidad del
estadístico de cada trayectoria ya está incluida en su vector de réplica.
La dependencia temporal pertenece a cada trayectoria; las réplicas externas
deben ser independientes. En cambio, MomentTargets.from_draws estima la
covarianza de un estimador empírico con réplicas bootstrap/muestrales y no
divide por el número de réplicas.
batch = simulate_moments(
simulator, fit.theta, plan, labels=targets.labels, units=targets.units,
definition_id="iid-normal-mean-v1",
)
np.testing.assert_array_equal(batch.replicates, fit.simulation.replicates)
np.testing.assert_allclose(batch.covariance,
batch.replicate_covariance / plan.replications)
total = moment_error_covariance(targets, batch, assume_independent=True)
np.testing.assert_allclose(total, targets.covariance + batch.covariance)
Si los datos y la simulación comparten aleatoriedad, proporcione
cross_covariance=C, donde \(C=\operatorname{Cov}(\hat m,\bar s)\), en vez
de afirmar independencia. La covarianza del error de momentos es
\(V_e+V_s-C-C'\). La covarianza conjunta completa debe ser semidefinida
positiva; etiquetas y unidades deben coincidir exactamente. Usar semillas
distintas no establece independencia si el callback reutiliza datos observados.
La matriz constante C debe corresponder al parámetro relevante y al número
de réplicas del ajuste.
Pesos fijos y contribuciones separadas a la varianza
El objetivo es \((\bar s(\theta)-\hat m)'W(\bar s(\theta)-\hat m)\).
Por defecto se fija \(W=V_e^{-1}\). Se admite una matriz weight definida
positiva explícita. Alternativamente, pilot_plan estima los pesos en theta0
usando la covarianza de las réplicas piloto dividida por el número de réplicas
del ajuste. Los períodos y el burn-in del piloto y del ajuste deben
coincidir. Los pesos y el esfuerzo de simulación permanecen fijos durante
la optimización. No se aplica regularización ni truncamiento de autovalores.
pilot_fit = fit_simulated_moments(
simulator, targets, [0.0], plan=plan,
pilot_plan=replace(plan, role="pilot", replications=64),
definition_id="iid-normal-mean-v1", assume_independent=True,
assume_smooth=True, jac=lambda theta: [[1.0]],
)
assert pilot_fit.inference_valid
np.testing.assert_allclose(
pilot_fit.covariance,
pilot_fit.sampling_covariance + pilot_fit.simulation_covariance
+ pilot_fit.cross_covariance_adjustment,
)
Con \(G=\partial\bar s/\partial\theta'\) y
\(A=(G'WG)^{-1}G'W\), la covarianza local es
\(A(V_e+V_s-C-C')A'\). El resultado conserva por separado las contribuciones
muestral, de simulación y cruzada. moment_covariance usa unidades de momentos;
las tres contribuciones y covariance usan unidades de parámetros. La
covarianza final de simulación se evalúa en la estimación, incluso cuando los
pesos proceden de un piloto.
Aleatoriedad y contrato del callback
simulator(theta_copy, rng, plan)devuelve un vector conjunto o unMomentReplication. Utilice el generador suministrado para todas las decisiones aleatorias. Implemente explícitamenteperiodsobservaciones retenidas y elburn_indeclarado.- Cada réplica recibe un generador PCG64 nuevo. Su clave SeedSequence es
[replication, stream, role_code, seed], con códigos 0/1/2 para fit/pilot/validation. Un mismo plan reproduce las secuencias independientemente del orden de evaluación. Aumentar el número de réplicas conserva las secuencias existentes. Los roles separan secuencias, no definiciones de momentos: use el mismo estadístico en piloto, ajuste y validación. plan_idresume mediante hash la configuración, el esquema de secuencias, el generador y la versión de NumPy. No incluye el código del modelo, no garantiza identidad binaria entre entornos ni establece convenciones económicas de medición. Conserve también el código y el entorno.definition_ididentifica la convención de medición del usuario. Alinee condicionamiento, rezagos, transformaciones, ventanas muestrales, unidades y selección de ramas con los objetivos empíricos. Los identificadores y etiquetas no demuestran esa correspondencia.- La ausencia de observaciones condicionales debe producir conteos nulos o
momentos no finitos, nunca ceros fabricados. Valores no finitos, conteos
nulos o un estado distinto de
okinvalidan todo el lote conjunto. Todas las filas se conservan enreplicates,countsystatuses; los conteos ausentes significan desconocidos. No se filtran las réplicas supervivientes. Los errores de programación del callback se propagan sin modificación.
SimulationMomentError conserva .batch y, cuando está disponible, una
.reference para fallos de reproducción. El ajuste comprueba reproducción
exacta al inicio y en la estimación; también reproduce piloto y validación.
Una caché acotada puede reutilizar evaluaciones idénticas. n_evals cuenta
lotes realmente simulados, incluidas comprobaciones, piloto y validación;
n_replications_evaluated suma sus presupuestos de réplicas.
Alcance inferencial y validación
Los intervalos normales requieren assume_smooth=True explícito. Se omiten
ante fallo o falta de estacionariedad del optimizador, estimaciones en la
frontera, rango insuficiente, condicionamiento excesivo, covarianza singular
del error de momentos, covarianza no finita o comprobaciones de derivadas
inconsistentes. Un jac suministrado debe diferenciar la media simulada del
plan fijo. Dos radios de diferencias finitas y pendientes por izquierda y
derecha comprueban consistencia con números aleatorios comunes.
derivative_step controla el radio inicial escalado por parámetro;
derivative_tol, la tolerancia de discrepancia normalizada.
Superar estas comprobaciones no demuestra suavidad, identificación ni cobertura estadística. La inferencia también supone especificación correcta, identificación interior regular, estimaciones consistentes de covarianzas y jacobiano, y sesgos despreciables de inicialización, estadístico de horizonte finito y discretización. Un error de Monte Carlo grande puede deteriorar la aproximación local. Políticas discretas, cambios de rama, identificación débil y mala especificación requieren otros métodos. No se calcula automáticamente un valor p de J ni un conjunto de confianza robusto a identificación débil.
Las secuencias nuevas de validación son descriptivas y nunca se agregan al objetivo ajustado. Como la estimación depende de las secuencias del ajuste, su diferencia frente a validación no constituye automáticamente una prueba estándar de dos muestras independientes. Cambiar el presupuesto requiere un plan y ajuste explícitos nuevos. Esta interfaz genérica no audita la medición temporal ni los momentos condicionales del estimador soberano existente.
Ejecute python -m puremacro.examples.simulation_aware_smm --output /tmp/smm
para obtener CSV, Markdown, LaTeX, Typst y JSON. El ejemplo verifica momentos
brutos y varianza finita de la media de un AR(1) estacionario, además de momentos
de una cadena de Markov de dos estados con medición temporal coincidente.
Las pruebas comprueban independientemente la covarianza conjunta completa
del AR(1) mediante identidades gaussianas y el álgebra de GLS correlacionado.
Referencias: Duffie y Singleton (1993) sobre momentos simulados; documentación de secuencias aleatorias de NumPy para identificadores deterministas. Estas referencias no certifican callbacks arbitrarios ni la inferencia en muestras finitas.