Skip to content

🇬🇧 English · 🇪🇸 Español

Estado de validación de los solvers estructurales

Actualizado el 23 de septiembre de 2026 con una fila para el Newton-Krylov apilado y con las filas revisadas por las correcciones de la auditoría posterior a 4.3.0. La actualización del 20 de septiembre de 2026 siguió a los contraejemplos independientes de una evaluación crítica interna y de su seguimiento con Dynare en vivo. La disponibilidad de una función, la convergencia numérica y la replicación independiente son afirmaciones distintas. Superar una comprobación de residuos no valida un modelo económico.

Superficie Cálculo soportado y contrato de aceptación Evidencia y límites pendientes
DSGE de tercer orden Las pendientes de riesgo incluyen el calendario de los estados, términos en cadena del hessiano y contracciones de varianza de terceras derivadas. Los modelos parseados usan derivadas simbólicas; el respaldo para modelos definidos como funciones tiene precisión de diferencias finitas. Cinco modelos ejecutados en Dynare 7.0 en vivo en órdenes dos y tres, incluidos choques correlacionados, estados no lineales y un modelo RBC. Todos los tensores desplegados, correcciones de riesgo, covarianzas y simulaciones/momentos con innovaciones comunes coinciden (error máximo de tensor 1.15e-13; error de trayectoria 2.70e-13). El ensamblaje de derivadas mixtas conserva ahora cada permutación de índices. Es un benchmark acotado, no paridad general. MATLAB completó las exportaciones pero falló al cerrar; véase tools/reference_validation/README.md. Momentos exactos con poda (después de 4.3.0): la identidad del espacio de estados reproduce el simulador podado a 2e-15; medias y covarianzas coinciden con los momentos podados de Dynare 8 en seis modelos (2e-13) y con una forma cerrada (3e-15). Las autocorrelaciones de orden 3 de Dynare omiten un término de correlación; una forma cerrada y las propias simulaciones de Dynare de 4e6 períodos coinciden con puremacro (tests/test_dsge_order3_moments.py).
Panel de paridad con Dynare Los órdenes uno y dos comparan estados estacionarios y todos los tensores solicitados (ghx, ghu, ghxx, ghxu, ghuu, ghs2), alineados por etiquetas. Los oo_.mean/var/autocorr suministrados se comparan con los momentos del objeto resuelto en el orden comparado: en orden 2, la media corregida por riesgo y los segundos momentos de primer orden, que es la convención de stoch_simul(order=2) sin pruning. M_.Sigma_e se compara con la covarianza que declara el objeto. Las filas de autocorrelación de variables con varianza nula que son NaN en ambos lados cuentan como coincidentes y se listan en details["moments_excluded"]. Una entrada ausente, no finita (en un solo lado), mal formada o vacía, incluidos el oo_.dr = [] inicial de Dynare y la salida de loadmat como arreglo de registros, es no disponible. Los fixtures de Dynare 7 en vivo se exportaron con nomoments, así que la paridad de momentos de orden 2 se contrasta con las fórmulas de stoch_simul aplicadas a las propias reglas de decisión de Dynare (concordancia 3.6e-15 en la media, 7.0e-14 en la varianza, 1.8e-14 en la autocorrelación en rbc), no con momentos reportados por Dynare. Una referencia de stoch_simul(order=2, pruning) reporta segundos momentos podados: compárela con pruning=True, que usa los momentos podados exactos (las medias, covarianzas y autocorrelaciones podadas de Dynare 8 se reproducen a 7e-14 en los cinco modelos en vivo y en un modelo con forma cerrada). Los fixtures de serialización autogenerados son pruebas internas, no oráculos externos de Dynare. La CLI de paridad no puede consumir referencias y termina con un error explicativo; use la API de Python.
DSGE con cambio de régimen markoviano Los residuos de las ecuaciones acopladas se recalculan en las matrices devueltas. La convergencia es diff <= tol (absoluta), o cada entrada del residuo dentro de tol o dentro de rtol (64 eps) de las magnitudes de sus propios términos que se cancelan (error hacia atrás por componentes; el menor rtol que certifica se reporta como relative_residual). Las soluciones fallidas tienen impactos de choques, radios de estabilidad y momentos ergódicos no disponibles. Un fallo de raíz real no debe devolver una covarianza de equilibrio finita ni un certificado de estabilidad. Los momentos finitos requieren además estabilidad tras la convergencia. Casos contrastados: reescalado uniforme hasta 1e9; una ecuación reescalada por 1e6 y 1e9 en tres modelos (las ecuaciones O(1) siguen cumpliendo tol y T queda a menos de 1e-9 de la solución sin escalar); unidades de variables que abarcan 1e14; modelos O(1) (incluido un tol más estricto del usuario) idénticos bit a bit a la puerta absoluta.
Newton-Krylov apilado en el tiempo solve_stacked_newton_krylov acepta una senda solo cuando el residuo apilado cumple |F|_inf <= tol * s (s la escala del bloque estacionario) y el siguiente paso de Newton es menor que 1e-10 * max(1, |Y|_inf); step_tol=None omite la prueba del paso (con jacobian_scale=1.0 la prueba es entonces |F|_inf <= tol). El movimiento de Newton se acota en unidades de la senda (0.75 * max(1, |Y|_inf)) y se acepta mediante una búsqueda lineal de Armijo de 24 intentos. Una dirección devuelta en el tope de Krylov se registra (estado y residuo lineal verdadero recalculado) y se somete a la búsqueda lineal como cualquier otra; por sí sola no es un error. Las búsquedas lineales fallidas, los límites de iteraciones, los errores o valores no finitos dentro de una resolución lineal, un residuo en un suelo de ruido que cumple la tolerancia mientras la prueba del paso no puede cumplirse, y una matriz apilada estacionaria que no se puede factorizar lanzan StackedNewtonError con el último estado adjunto y la causa en converged_by. Los pivotes de block-Thomas con una estimación de condición de LAPACK inferior a n * eps, o una factorización cuyo error hacia atrás con un vector supera 1e-10, recurren a SuperLU (registrado en el nombre del precondicionador). Cuando ambas entradas son objetos StackedNewtonResult, compare_horizons exige entradas convergidas, fronteras idénticas y la misma senda exógena mantenida más allá del horizonte corto; los arreglos, DataFrames y entradas PerfectForesightResult se comparan tal como se dan. Oráculos de resolución densa hasta 1e-12 (bloques constantes y por fecha, con y sin bloques temporales), identidad de la inversa exacta en un ciclo de Krylov, paridad con solve_perfect_foresight en Ramsey y en una transición de crecimiento de 20 sectores hasta 1e-8 (observado 7e-11 y 3.5e-11), invarianza al escalado de ecuaciones (1e-9) y de variables (unidades de 1e-3 a 1e4, 1e-9 relativo, mismos recuentos de Newton), regresiones de pivotes a nivel de redondeo y mal condicionados (B = U V de rango deficiente, números de condición apilados 616 y 941; B = [[1, 1], [1, 1 + 1e-12]]), y el contrato de fallo, incluidos errores dentro de la resolución de Krylov y un suelo de ruido del residuo de 1e-12. La evidencia cubre solo fixtures analíticos de tamaño DSGE. La memoria es O(T n^2) (cerca de 3.2 GB con n_vars = 1000, T = 200); los sistemas con miles de incógnitas por fecha necesitan una eliminación estructurada, y no se incluye ninguna. La estructura por bloques por sí sola no establece la velocidad ni la memoria a escala, y las identidades lineales no garantizan por sí solas la precisión numérica ni la convergencia no lineal. Aquí no se resuelve ninguna transición a gran escala; MCP y el modo de sorpresa de solve_perfect_foresight no están disponibles. Véanse uso y evidencia.
Proyecciones VFI Las banderas de colocación de Euler, FEM, Smolyak y splines exigen residuos finales finitos dentro de la tolerancia solicitada. La terminación del optimizador por sí sola es insuficiente. Un residuo en los nodos de ajuste no establece precisión fuera de la malla, factibilidad, complementariedad ni optimalidad global. Los dominios adversos pueden devolver aproximaciones útiles con converged=False. Las variantes de Bellman tienen sus propios criterios de iteración.
Valores auxiliares de colocación La política y el valor usan una sola curvatura CRRA (sigma, alias gamma) y la productividad del modelo en los bloques de Euler, Coleman, Bellman y evaluación de la política. Los parámetros de return_fn/euler_residual_fn del usuario se transmiten sin interpretar. Casos contrastados: la forma cerrada del crecimiento logarítmico determinista con cada forma de escribir la curvatura; la identidad de Bellman con CRRA(2) y CRRA(3); concordancia de políticas Euler/Bellman (1.1e-6) con sigma = 2; la sensibilidad TFI respecto de gamma frente a la columna de sigma y una nueva resolución por diferencias finitas. El recorte en la frontera limita la interpretación fuera del dominio elegido. Desde 4.5.0 puremacro.vfi.splines y puremacro.vfi.smolyak siguen la misma regla (sigma y, si falta, gamma); solve_smolyak(method="bellman") solo cubre utilidad logarítmica con depreciación total y en otro caso lanza un error.
Deep Macro Iteración temporal de Euler con objetivo desacoplado. La caché hacia adelante del estado actual se restaura antes de actualizar los pesos. Un gradiente completo del paso de entrenamiento se comprueba por diferencias finitas. El éxito del entrenamiento depende de la calibración y de la semilla; incluso la trayectoria determinista por defecto de diez países puede no superar el criterio de Euler fuera de muestra. Una pérdida de entrenamiento pequeña por sí sola no es convergencia.
Sensibilidades VFI Soluciones lineales por el TFI usando jacobianos de residuos por diferencias centrales: derivadas semianalíticas. La precisión depende de los pasos de diferenciación y del condicionamiento. Las sensibilidades de distribución y de equilibrio general con agentes heterogéneos no están disponibles hasta que se implementen la KFE diferenciada y las ecuaciones de equilibrio acopladas.

La galería de validación de 110 casos (versión 4.5.0, todos superados) contiene 59 casos internos, 31 analíticos, 13 de paquetes, cinco de SciPy y dos de referencia publicada. Tiene varias clases de tolerancia. La galería no certifica cada función, cada backend ni cada despliegue.

Puremacro no distribuye ninguna extensión compilada propia. NumPy/SciPy y otros paquetes base incluyen componentes compilados; las dependencias obligatorias incluyen además pandas, Matplotlib y requests. La importabilidad en Pyodide, la ejecución realista en el navegador, la concordancia en GPU y la reproducibilidad bit a bit requieren pruebas distintas.