Example #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)), μ
Example #2
0
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 Π, μ