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 discretize(self, to="iid"): if to == "iid": inddist = self.index.discretize(to=to) nodes = [] weights = [] for i in range(inddist.n_inodes(0)): wind = inddist.iweight(0, i) xind = inddist.inode(0, i) dist = self.distributions[str(i)].discretize(to=to) for j in range(dist.n_inodes(0)): w = dist.iweight(0, j) x = dist.inode(0, j) nodes.append(x) weights.append(wind * w) nodes = np.concatenate([e[None, :] for e in nodes], axis=0) weights = np.array(weights) return FiniteDistribution(nodes, weights) elif to == "mc": discr_iid = self.discretize(to="iid") nodes = discr_iid.points transitions = np.array([ discr_iid.weights, ] * N) return MarkovChain(transitions, nodes) else: raise Exception("Not implemented.")
def discretize(self, to="iid"): if to == "iid": return self elif to == "mc": from .processes import MarkovChain nodes = self.points N = len(nodes) transitions = np.array([ self.weights, ] * N) return MarkovChain(transitions, nodes) else: raise Exception("Not implemented.")
def discretize(self, to="iid"): if to == "iid": x = np.array([[0], [1]]) w = np.array([1 - self.π, self.π]) return FiniteDistribution(x, w) elif to == "mc": fin_distr = self.discretize(to="iid") nodes = fin_distr.points transitions = np.array([ fin_distr.weights, ] * 2) return MarkovChain(transitions, nodes) else: raise Exception("Not implemented.")
def discretize(self, to="iid", N=5, method="equiprobable", mass_point="median"): """ Returns a discretized version of this process. Parameters ---------- N : int Number of point masses in the discretized distribution. method : str 'equiprobable' or 'gauss-hermite' mass_point : str 'median', 'left', 'middle', or 'right' Returns: ------------ process : DiscreteDistribution A discrete distribution. """ if to == "iid": if method == "gauss-hermite": return self.__discretize_gh__(N=N) elif method == "equiprobable": return self.__discretize_ep__(N=N, mass_point=mass_point) else: raise Exception("Unknown discretization method.") elif to == "mc": discr_iid = self.discretize(to="iid") nodes = discr_iid.points transitions = np.array([ discr_iid.weights, ] * N) return MarkovChain(transitions, nodes) else: raise Exception("Not implemented (yet).")
def discretize(self, to="iid", N=None) -> FiniteDistribution: if to == "iid": if N is None: N = 5 if isinstance(N, int): N = [N] * self.d from dolo.numeric.discretization.quadrature import gauss_hermite_nodes # type: ignore [x, w] = gauss_hermite_nodes(N, self.Σ, mu=self.Μ) x = np.row_stack([(e + self.Μ) for e in x]) return FiniteDistribution(x, w, origin=self) elif to == "mc": discr_iid = self.discretize(to="iid") nodes = discr_iid.points transitions = np.array([ discr_iid.weights, ] * N) return MarkovChain(transitions, nodes) else: raise Exception("Not implemented.")
# name: python3 # --- # WARNING: this is not working yet from dolark import HModel from dolo import pcat hmodel = HModel("ks.yaml") # The yaml file allows for the agent's exogenous process to depend on the aggregate values. # !sed -n 40,51p ks.yaml | pygmentize -l yaml # Here is what is recovered from the yaml file exo = hmodel.model.exogenous exo.condition # the driving process coming from aggregate simulation μ = exo.condition.μ μ exo.arguments(μ) exo.arguments(μ + 0.1) from dolo.numeric.processes import MarkovChain # here is how one can contruct a markov chain mc = MarkovChain(**exo.arguments(μ + 0.1))