def ergodic_distribution(model, dr, exo_grid: UnstructuredGrid, endo_grid: CartesianGrid, dp: MarkovChain, compute_μ=True): N_m = exo_grid.n_nodes() N_s = endo_grid.n_nodes() dims_s = tuple(endo_grid.n) # we have N_s = prod(dims_s) s = endo_grid.nodes() N = N_m * N_s Π = np.zeros((N_m, N_m, N_s) + dims_s) g = model.functions['transition'] p = model.calibration['parameters'] a = endo_grid.min b = endo_grid.max for i_m in range(N_m): m = exo_grid.node(i_m) x: np.array = dr(i_m, s) for i_M in range(dp.n_inodes(i_m)): w = dp.iweight(i_m, i_M) M = dp.inode(i_m, i_M) S = g(m, s, x, M, p) #renormalize S = (S - a[None, :]) / (b[None, :] - a[None, :]) # allocate weights dest = Π[i_m, i_M, ...] trembling_hand(dest, S, w) # these seem to be a bit expensive... Π = Π.reshape((N_m, N_m, N_s, N_s)) Π = Π.swapaxes(1, 2) Π = Π.reshape((N, N)) if not compute_μ: return Π.reshape((N_m, N_s, N_m, N_s)) else: B = np.zeros(N) B[-1] = 1.0 A = Π.T - np.eye(Π.shape[0]) A[-1, :] = 1.0 μ = np.linalg.solve(A, B) μ = μ.reshape((N_m, ) + dims_s) labels = [ np.linspace(endo_grid.min[i], endo_grid.max[i], endo_grid.n[i]) for i in range(len(endo_grid.max)) ] μ = xarray.DataArray( μ, [('i_m', np.arange(N_m))] + list({s: labels[i] for i, s in enumerate(model.symbols['states'])}.items())) return Π.reshape((N_m, N_s, N_m, N_s)), μ
def ergodic_distribution(model, dr, exo_grid: EmptyGrid, endo_grid: CartesianGrid, dp: DiscretizedIIDProcess, compute_μ=True): N_s = endo_grid.n_nodes() dims_s = tuple(endo_grid.n) # we have N_s = prod(dims_s) s = endo_grid.nodes() m = model.calibration['exogenous'] Π = np.zeros((N_s, ) + dims_s) g = model.functions['transition'] p = model.calibration['parameters'] a = endo_grid.min b = endo_grid.max x: np.array = dr(s) for i_M in range(dp.n_inodes(0)): w = dp.iweight(0, i_M) M = dp.inode(0, i_M) S = g(m, s, x, M, p) #renormalize S = (S - a[None, :]) / (b[None, :] - a[None, :]) # allocate weights trembling_hand(Π, S, w) Π = Π.reshape((N_s, N_s)) if not compute_μ: return Π else: B = np.zeros(N_s) B[-1] = 1.0 A = Π.T - np.eye(Π.shape[0]) A[-1, :] = 1.0 μ = np.linalg.solve(A, B) μ = μ.reshape(dims_s) labels = [ np.linspace(endo_grid.min[i], endo_grid.max[i], endo_grid.n[i]) for i in range(len(endo_grid.max)) ] μ = xarray.DataArray( μ, list({s: labels[i] for i, s in enumerate(model.symbols['states'])}.items())) return Π, μ