示例#1
0
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)), μ
示例#2
0
    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.")
示例#3
0
    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.")
示例#4
0
    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.")
示例#5
0
    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).")
示例#6
0
    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.")
示例#7
0
#     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))