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 test_grids(): from dolo.numeric.grids import CartesianGrid, UnstructuredGrid, NonUniformCartesianGrid, SmolyakGrid from dolo.numeric.grids import nodes, n_nodes, node print("Cartsian Grid") grid = CartesianGrid([0.1, 0.3], [9, 0.4], [50, 10]) print(grid.nodes()) print(nodes(grid)) print("UnstructuredGrid") ugrid = UnstructuredGrid([[0.1, 0.3], [9, 0.4], [50, 10]]) print(nodes(ugrid)) print(node(ugrid, 0)) print(n_nodes(ugrid)) print("Non Uniform CartesianGrid") ugrid = NonUniformCartesianGrid([[0.1, 0.3], [9, 0.4], [50, 10]]) print(nodes(ugrid)) print(node(ugrid, 0)) print(n_nodes(ugrid)) print("Smolyak Grid") sg = SmolyakGrid([0.1, 0.2], [1.0, 2.0], 2) print(nodes(sg)) print(node(sg, 1)) print(n_nodes(sg))
def test_grids(): from dolo.numeric.grids import CartesianGrid, UnstructuredGrid, NonUniformCartesianGrid, SmolyakGrid from dolo.numeric.grids import nodes, n_nodes, node print("Cartsian Grid") grid = CartesianGrid([0.1, 0.3], [9, 0.4], [50, 10]) print(grid.nodes()) print(nodes(grid)) print("UnstructuredGrid") ugrid = UnstructuredGrid([[0.1, 0.3], [9, 0.4], [50, 10]]) print(nodes(ugrid)) print(node(ugrid,0)) print(n_nodes(ugrid)) print("Non Uniform CartesianGrid") ugrid = NonUniformCartesianGrid([[0.1, 0.3], [9, 0.4], [50, 10]]) print(nodes(ugrid)) print(node(ugrid,0)) print(n_nodes(ugrid)) print("Smolyak Grid") sg = SmolyakGrid([0.1, 0.2], [1.0, 2.0], 2) print(nodes(sg)) print(node(sg, 1)) print(n_nodes(sg))
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 Π, μ
def get_grid(model, **dis_opts): import copy domain = model.get_domain() a = np.array([e[0] for e in domain.values()]) b = np.array([e[1] for e in domain.values()]) gg = model.symbolic.options.get('grid', {}) d = copy.deepcopy(gg) gtype = dis_opts.get('type') if gtype: from dolo.compiler.language import minilang try: cls = [ e for e in minilang if e.__name__.lower() == gtype.lower() ][0] except: raise Exception("Unknown grid type {}.".format(gtype)) d = cls(**d) # return cc d.update(**dis_opts) if 'a' not in d.keys(): d['min'] = a if 'b' not in d.keys(): d['max'] = b if 'type' in d: d.pop('type') grid = d.eval(d=model.calibration.flat) # temporary from dolo.numeric.grids import CartesianGrid, SmolyakGrid if 'Cartesian' in str(grid.__class__): return CartesianGrid(grid.a, grid.b, grid.orders) if 'Smolyak' in str(grid.__class__): return SmolyakGrid(grid.a, grid.b, grid.mu)
def eval_s(itp: object, exo_grid: EmptyGrid, endo_grid: CartesianGrid, interp_type: Cubic, s: object): from interpolation.splines import eval_cubic assert (s.ndim == 2) coeffs = itp.coefficients gg = endo_grid.__numba_repr__() return eval_cubic(gg, coeffs, s)
def get_coefficients(itp: object, exo_grid: UnstructuredGrid, endo_grid: CartesianGrid, interp_type: Cubic, x: object): from interpolation.splines.prefilter_cubic import prefilter_cubic gg = endo_grid.__numba_repr__() return [ prefilter_cubic(gg, x[i].reshape(tuple(endo_grid.n) + (-1, ))) for i in range(x.shape[0]) ]
def eval_is(itp: object, exo_grid: UnstructuredGrid, endo_grid: CartesianGrid, interp_type: Linear, i: object, s: object): from interpolation.splines import eval_linear assert(s.ndim==2) coeffs = itp.coefficients[i] gg = endo_grid.__numba_repr__() return eval_linear(gg, coeffs, s)
def eval_is( itp: object, exo_grid: CartesianGrid, endo_grid: CartesianGrid, interp_type: Cubic, i: object, s: object, ): m = exo_grid.node(i)[None, :] return eval_ms(itp, exo_grid, endo_grid, interp_type, m, s)
def get_coefficients( itp: object, exo_grid: EmptyGrid, endo_grid: CartesianGrid, interp_type: Cubic, x: object, ): from interpolation.splines.prefilter_cubic import prefilter_cubic grid = endo_grid # one single CartesianGrid gg = endo_grid.__numba_repr__() return prefilter_cubic(gg, x[0].reshape(tuple(grid.n) + (-1, )))
def eval_s( itp: object, exo_grid: EmptyGrid, endo_grid: CartesianGrid, interp_type: Linear, s: object, ): from interpolation.splines import eval_linear assert s.ndim == 2 coeffs = itp.coefficients gg = endo_grid.__numba_repr__() return eval_linear(gg, coeffs, s)
def discretize_gdp(self, N=3): Σ = self.Σ ρ = self.ρ n_nodes = N n_std = 2.5 n_integration_nodes = 5 try: assert Σ.shape[0] == 1 except: raise Exception("Not implemented.") try: assert ρ.shape[0] == ρ.shape[1] == 1 except: raise Exception("Not implemented.") ρ = ρ[0, 0] σ = np.sqrt(Σ[0, 0]) from dolo.numeric.discretization import gauss_hermite_nodes epsilons, weights = gauss_hermite_nodes([n_integration_nodes], Σ) min = -n_std * (σ / (np.sqrt(1 - ρ**2))) max = n_std * (σ / (np.sqrt(1 - ρ**2))) from .grids import CartesianGrid grid = CartesianGrid([min], [max], [n_nodes]) nodes = np.linspace(min, max, n_nodes)[:, None] iweights = weights[None, :].repeat(n_nodes, axis=0) integration_nodes = np.zeros((n_nodes, n_integration_nodes))[:, :, None] for i in range(n_nodes): for j in range(n_integration_nodes): integration_nodes[i, j, :] = ρ * nodes[i, :] + epsilons[j] return GDP(nodes, integration_nodes, iweights, grid=grid)
def get_grid(self): states = self.symbols['states'] # determine bounds: domain = self.get_domain() min = domain.min max = domain.max options = self.data.get("options", {}) # determine grid_type grid_type = get_type(options.get("grid")) if grid_type is None: grid_type = get_address(self.data, ["options:grid:type", "options:grid_type"]) if grid_type is None: raise Exception('Missing grid geometry ("options:grid:type")') args = {'min': min, 'max': max} if grid_type.lower() in ('cartesian', 'cartesiangrid'): # from dolo.numerid.grids import CartesianGrid from dolo.numeric.grids import CartesianGrid orders = get_address(self.data, ["options:grid:n", "options:grid:orders"]) if orders is None: orders = [20] * len(min) grid = CartesianGrid(min=min, max=max, n=orders) elif grid_type.lower() in ('smolyak', 'smolyakgrid'): from dolo.numeric.grids import SmolyakGrid mu = get_address(self.data, ["options:grid:mu"]) if mu is None: mu = 2 grid = SmolyakGrid(min=min, max=max, mu=mu) else: raise Exception("Unknown grid type.") return grid