def ergodic_distribution( model: Model, dr: DecisionRule, 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 __discretize_ep__(self, N=5): #Equiprobable # this could be implemented once for all univariate processes which have a ppf xvec = np.linspace(0, 1, N+1) quantiles = 1/N/2 + xvec[:-1] x = self.ppf(quantiles) x = x[:,None] w = (1/(N))*np.ones(N) return DiscretizedIIDProcess(x, w)
def discretize(self, N=5): # do we want to include the boundaries here ? a, b = self.a, self.b xvec = np.linspace(a, b, N + 1) x = (b - a) / 2 / N + xvec[:-1] w = x * 0 + 1 / N x = x[:, None] return DiscretizedIIDProcess(x, w)
def discretize(self, to='iid'): if to !='iid': raise Exception("Not implemented") inddist = self.index.discretize() nodes = [] weights = [] for i in range(inddist.n_inodes(0)): wind = inddist.iweight(0,i) xind = inddist.inode(0,i) dist = self.distributions[int(xind)].discretize() for j in range(dist.n_inodes(0)): w = dist.iweight(0,j) x = dist.inode(0,j) nodes.append(float(x)) weights.append(wind*w) nodes = np.array(nodes) weights = np.array(weights) return DiscretizedIIDProcess(nodes[:,None], weights)
def discretize(self, to='iid'): if to !='iid': raise Exception("Not implemented") inddist = self.index.discretize() nodes = [] weights = [] for i in range(inddist.n_inodes(0)): wind = inddist.iweight(0,i) xind = inddist.inode(0,i) dist = self.distributions[int(xind)].discretize(to='iid') 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 DiscretizedIIDProcess(nodes, weights)
def __discretize_ep__(self, N=5, mass_point="median"): #Equiprobable if mass_point == "median": p = np.linspace(0.5/N,1-0.5/N,N) q = self.ppf(p) elif mass_point == "left": p = np.linspace(0,1-1/N,N) q = self.ppf(p) elif mass_point == "middle": p = np.linspace(0.,1,N+1) q = self.ppf(p) q = 0.5*(q[1:]+q[:-1]) elif mass_point == "right": p = np.linspace(1/N,1,N) q = self.ppf(p) else: raise Exception("Not implemented") w = (1/(N))*np.ones(N) return DiscretizedIIDProcess(q[:,None], w)
def discretize(self, to='iid'): if to !='iid': raise Exception("Not implemented") x = np.array([[0],[1]]) w = np.array([1-self.π, self.π]) return DiscretizedIIDProcess(x, w)
def __discretize_gh__(self, N=5): # Gauss-Hermite from dolo.numeric.discretization.quadrature import gauss_hermite_nodes [x, w] = gauss_hermite_nodes(N, np.array([[self.σ**2]]), mu=self.μ) x = np.row_stack( [(e + self.μ) for e in x] ) return DiscretizedIIDProcess(x, w)