Equilibrio HANK acoplado y optimizado
HANKEquilibriumWorkspace resuelve conjuntamente inflación, salarios,
producción, decisiones de los hogares y distribuciones en cada nodo de un
árbol finito de historias agregadas. Newton–GMRES usa productos analíticos
Jacobiano-vector a través del hogar y del transporte de la distribución,
sin construir un Jacobiano agregado denso. El precondicionador disperso y
los puntos iniciales explícitos permiten repetir experimentos.
Conserva la economía del modelo en árbol finito: un activo, deuda real fija, valoración empresarial neutral al riesgo en unidades nominales, riesgo idiosincrático independiente y valor marginal terminal del estado estacionario. No es todavía un equilibrio estocástico estacionario, una política sobre el espacio de distribuciones, un modelo de dos activos ni un modelo con límite inferior efectivo de la tasa de interés.
Uso
from puremacro.models import (
HANKEquilibriumWorkspace,
calibrate_one_asset_hank,
monetary_scenario_tree,
)
# Malla ilustrativa; la precisión de investigación requiere refinamientos.
ss = calibrate_one_asset_hank(n_a=240, n_e=7, a_max=150.)
tree = monetary_scenario_tree(
horizon=48, innovations=(-.005, .005), probabilities=(.3, .7),
)
workspace = HANKEquilibriumWorkspace(ss, tree)
base = workspace.solve()
cercano = workspace.solve(
monetary_shocks=1.02 * tree.monetary_shock,
initial=base,
)
print(cercano.converged, cercano.diagnostics["market_residual_max_abs"])
El espacio de trabajo copia los datos. Cambiar el objeto original no cambia el problema preparado. Nuevos choques deben conservar el orden de nodos; una Series debe tener exactamente el mismo índice. Cambios en parámetros, mallas, probabilidades condicionales o datos terminales requieren otro espacio de trabajo. La huella de esos datos comprueba la compatibilidad del resultado usado como punto inicial. No se reutiliza implícitamente la solución anterior.
solve_hank_equilibrium(ss, tree) permite una solución individual. Ambos
interfaces devuelven HANKScenarioTreeResult, con políticas, distribuciones
condicionales, trayectorias y expectativas no condicionales por fecha.
Algoritmo
La separación de bloques sigue la motivación del enfoque de espacio de secuencias de Auclert, Bardóczy, Rognlie y Straub (2021). Este backend diferencia el punto no lineal actual sobre el árbol:
- EGM resuelve hacia atrás utilizando valores marginales esperados de los sucesores. Se guardan intervalos, pendientes y restricciones activas.
- Las tangentes diferencian la malla endógena y las decisiones. En hogares restringidos se diferencian el presupuesto y la condición intratemporal.
- El transporte hacia delante diferencia tanto la masa como los pesos de las loterías de activos; los cambios de composición afectan la agregación.
- GMRES obtiene la corrección de precios mediante estos productos. Una búsqueda amortiguada evalúa de nuevo todas las ecuaciones no lineales.
El precondicionador aproxima respuestas contemporáneas del hogar y la
persistencia de activos agregados, junto con las ecuaciones de Phillips y de
política monetaria. Reutiliza una factorización LU dispersa. Las expectativas
y la composición de la distribución se aproximan solamente dentro del
precondicionador: sus efectos completos están presentes en los productos
Jacobiano-vector y en los residuos finales. preconditioner="none" permite
comparar. En puntos angulosos se selecciona la derivada de la rama actual;
las diferencias finitas que cruzan ramas pueden discrepar. Los datos de
derivación se renuevan después de cada paso aceptado.
Diagnósticos, memoria y evidencia
Las coordenadas concatenan log(1+inflación), log(salario/salario_ss) y
log(producción) por nodo. workspace.residual(x) devuelve residuos de
Phillips, activos y trabajo efectivo. jacobian_vector_product(x, direction)
expone el producto analítico para comprobaciones independientes.
converged exige también el equilibrio de bienes, conservación de masa,
distribuciones no negativas salvo redondeo, presupuestos y masa despreciable
fuera de la malla. Los errores Euler/KKT y la masa en el límite superior se
informan por separado. Convergencia numérica no equivale a precisión de malla,
de horizonte o de bienestar estocástico estacionario.
Los datos inválidos y un dominio inicial inviable producen una excepción.
Agotar iteraciones, fallar la solución lineal o la búsqueda de paso conserva
el último punto viable con converged=False. optimizer_message e history
registran la causa, el residuo lineal recalculado y el paso aceptado. Un
precondicionador singular indica que puede intentarse preconditioner="none".
El backend nuevo elimina el límite de 256 nodos del solver denso de referencia,
pero la memoria sigue creciendo con historias por celdas del hogar.
max_workspace_bytes limita una estimación de matrices de trabajo (un GiB
por defecto), no la memoria RSS; excluye objetos Python, BLAS y factores
dispersos. Reinicios Krylov mayores aumentan esa estimación.
Las pruebas contrastan derivadas con diferencias finitas, conservación de
masa y primer momento de activos; comparan con el solver denso y la transición
determinista publicada; resuelven 279 nodos y comprueban reutilización,
aislamiento de datos y fallos. El programa reproducible
tools/reference_validation/benchmark_hank_equilibrium.py registra fuentes,
entorno, calibración separada, tiempos repetidos con preparación incluida,
inicios cercanos, diferencias de políticas y trayectorias CSV. La equivalencia
usa las mismas mallas; los tiempos no son un criterio de CI.
El registro tests/fixtures/hank_optimized/record.json conserva estas medianas
de tres repeticiones en arm64, Python 3.11.17, NumPy 2.4.6 y SciPy
1.17.1. Ambas bibliotecas usan Apple Accelerate. El programa configura y
verifica su modo de un hilo mediante
BLASSetThreading / BLASGetThreading
en el hilo que ejecuta las llamadas, junto con límites de entorno para
OMP/OpenBLAS/MKL/vecLib. Todas las soluciones convergieron con tolerancia de
mercados 1e-8; la mayor diferencia de trayectorias frente a la referencia
densa fue 9.07e-09.
| Activos × ingresos | Periodos / nodos | Denso (s) | Optimizado inicial (s) | Razón | Inicio cercano (s) |
|---|---|---|---|---|---|
| 240 × 7 | 48 / 95 | 19.38 | 1.18 | 16.4× | 1.03 |
| 480 × 31 | 48 / 95 | 58.78 | 6.01 | 9.8× | 5.14 |
| 240 × 7 | 96 / 191 | 76.71 | 3.61 | 21.3× | 3.10 |
La calibración no está incluida en estos tiempos. Son observaciones de esta
máquina y estos casos, sin certificar precisión de malla. Los CSV permiten
recalcular diferencias agregadas; los grandes arreglos de hogares no se
archivan y sus diferencias requieren repetir el programa. El directorio
prior_uncontrolled/ conserva las observaciones iniciales y el programa
exacto, cuyos límites de entorno no fijaban explícitamente Accelerate;
esta ejecución con modo de un hilo verificado sustituye aquellos tiempos.
Continuación estocástica local y dos activos
Las interfaces HANK recursivas resuelven una política estocástica local de primer orden sobre estados distributivos comprimidos y la usan como frontera terminal endógena. También ofrecen un equilibrio con dos activos y bonos perpetuos, con cuentas fiscales y de bienes explícitas. Las auditorías externas conservan la distribución completa y muestran errores de compresión y aproximación local. La precisión global bajo riesgo agregado y el bienestar de orden superior requieren trabajo adicional; el backend finito de esta página mantiene su alcance original.