Esempio n. 1
0
def get_SS(c1_guess, r_old, params):
    beta, sigma, p, ltilde, b, upsilon, chi_n_vec, A, alpha, delta, ss_max_iter, ss_tol, xi_ss = params
    abs_ss = 1
    ss_iter = 0
    while abs_ss > ss_tol and ss_iter < ss_max_iter:
        ss_iter += 1
        r_old = r_old * np.ones(p)
        w_old = firms.get_w(r_old, (A, alpha, delta)) * np.ones(p)
        # Calculate household decisions that make last-period savings zero
        c1_args = (r_old, w_old, beta, sigma, ltilde, b, upsilon, chi_n_vec, p, 0.0)
        result_c1 = opt.root(hh.get_b_last, c1_guess, args = (c1_args))
        if result_c1.success:
            c1 = result_c1.x
        else:
            raise ValueError("failed to find an appropriate initial consumption")
        # Calculate aggregate supplies for capital and labor
        cvec = hh.get_c(c1, r_old, beta, sigma, p)
        nvec = hh.get_n(cvec, sigma, ltilde, b, upsilon, chi_n_vec, w_old, p)
        bvec = hh.get_b(cvec, nvec, r_old, w_old, p)
        K = aggr.get_K(bvec)[0]
        L = aggr.get_L(nvec)[0]
        C = aggr.get_C(cvec)
        Y = aggr.get_Y(K, L, (A, alpha))
        b_err = abs(hh.get_b_errors(cvec, r_old[0], beta, sigma)).max()
        n_err = abs(hh.get_n_errors(nvec, cvec, sigma, ltilde, b, upsilon, chi_n_vec, w_old[0])).max()
        b_last = hh.get_b_last(cvec[0], r_old, w_old, beta, sigma, ltilde, b, upsilon, chi_n_vec, p, 0.0)
        r_new = firms.get_r(K, L, (A, alpha, delta))
        # Check market clearing
        abs_ss = ((r_new - r_old) ** 2).max()
        # Update guess
        r_old = xi_ss * r_new + (1 - xi_ss) * r_old
        print('iteration:', ss_iter, ' squared distance: ', abs_ss)
    return r_old[0], w_old[0], cvec, nvec, bvec, K, L, C, Y, b_err, n_err, b_last
Esempio n. 2
0
def solve_ss(r_init, params):
    '''
    Solves for the steady-state equlibrium of the OG model
    '''
    beta, sigma, n, alpha, A, delta, xi = params
    ss_dist = 7.0
    ss_tol = 1e-8
    ss_iter = 0
    ss_max_iter = 300
    r = r_init
    while (ss_dist > ss_tol) & (ss_iter < ss_max_iter):
        # get w
        w = firm.get_w(r, alpha, A, delta)
        # solve HH problem
        foc_args = (beta, sigma, r, w, n, 0.0)
        b_sp1_guess = [0.05, 0.05]
        result = opt.root(hh.FOCs, b_sp1_guess, args=foc_args)
        b_sp1 = result.x
        euler_errors = result.fun
        b_s = np.append(0.0, b_sp1)
        # use market clearing
        L = agg.get_L(n)
        K = agg.get_K(b_s)
        # find implied r
        r_prime = firm.get_r(L, K, alpha, A, delta)
        # check distance
        ss_dist = np.absolute(r - r_prime)
        print('Iteration = ', ss_iter, ', Distance = ', ss_dist, ', r = ', r)
        # update r
        r = xi * r_prime + (1 - xi) * r
        # update iteration counter
        ss_iter += 1

    return r, b_sp1, euler_errors
Esempio n. 3
0
def SS_EulErrs(bvec, *args):
    '''
    --------------------------------------------------------------------
    --------------------------------------------------------------------
    INPUTS:
    bvec = (S-1,) vector, lifetime savings
    args = length 7 tuple, (nvec, beta, sigma, A, alpha, delta, EulDiff)

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        aggr.get_K()
        aggr.get_L()
        firms.get_r()
        firms.get_w()
        hh.get_cons()
        hh.get_b_errors()

    OBJECTS CREATED WITHIN FUNCTION:
    nvec     = (S,) vector, exogenous lifetime labor supply n_s
    beta     = scalar in (0,1), discount factor for each model per
    sigma    = scalar > 0, coefficient of relative risk aversion
    A        = scalar > 0, total factor productivity parameter in
               firms' production function
    alpha    = scalar in (0,1), capital share of income
    delta    = scalar in [0,1], model-period depreciation rate of
               capital
    EulDiff  = boolean, =True if want difference version of Euler errors
               beta*(1+r)*u'(c2) - u'(c1), =False if want ratio version
               version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1
    K        = scalar > 0, aggregate capital stock
    K_cstr   = boolean, =True if K < epsilon
    L        = scalar > 0, exogenous aggregate labor
    r_params = length 3 tuple, (A, alpha, delta)
    r        = scalar > 0, interest rate
    w_params = length 2 tuple, (A, alpha)
    w        = scalar > 0, wage
    c_args   = length 3 tuple, (nvec, r, w)
    cvec     = (S,) vector, household consumption c_s
    b_args   = length 4 tuple, (beta, sigma, r, EulDiff)
    errors   = (S-1,) vector, savings Euler errors given bvec

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: errors
    --------------------------------------------------------------------
    '''
    nvec, beta, sigma, A, alpha, delta, EulDiff = args
    K, K_cstr = aggr.get_K(bvec)
    L = aggr.get_L(nvec)
    r_params = (A, alpha, delta)
    r = firms.get_r(K, L, r_params)
    w_params = (A, alpha)
    w = firms.get_w(K, L, w_params)
    c_args = (nvec, r, w)
    cvec = hh.get_cons(bvec, 0.0, c_args)
    b_args = (beta, sigma, r, EulDiff)
    errors = hh.get_b_errors(cvec, b_args)

    return errors
Esempio n. 4
0
def solve_tp(r_path_init, params):
    '''
    Solves for the time path equlibrium using TPI
    '''
    (beta, sigma, n, alpha, A, delta, T, xi, b_sp1_pre, r_ss,
     b_sp1_ss) = params
    tpi_dist = 7.0
    tpi_tol = 1e-8
    tpi_iter = 0
    tpi_max_iter = 300
    r_path = np.append(r_path_init, np.ones(2) * r_ss)
    while (tpi_dist > tpi_tol) & (tpi_iter < tpi_max_iter):
        w_path = firm.get_w(r_path, alpha, A, delta)
        # Solve HH problem
        b_sp1_mat = np.zeros((T + 2, 2))
        euler_errors_mat = np.zeros((T + 2, 2))
        # solve upper right corner
        foc_args = (beta, sigma, r_path[:2], w_path[:2], n[-2:], b_sp1_pre[0])
        b_sp1_guess = b_sp1_ss[-1]
        result = opt.root(hh.FOCs, b_sp1_guess, args=foc_args)
        b_sp1_mat[0, -1] = result.x
        euler_errors_mat[0, -1] = result.fun
        # solve all full lifetimes
        DiagMaskb = np.eye(2, dtype=bool)
        for t in range(T):
            foc_args = (beta, sigma, r_path[t:t + 3], w_path[t:t + 3], n, 0.0)
            b_sp1_guess = b_sp1_ss
            result = opt.root(hh.FOCs, b_sp1_guess, args=foc_args)
            b_sp1_mat[t:t + 2, :] = (DiagMaskb * result.x +
                                     b_sp1_mat[t:t + 2, :])
            euler_errors_mat[t:t + 2, :] = (DiagMaskb * result.fun +
                                            euler_errors_mat[t:t + 2, :])
        # create a b_s_mat
        b_s_mat = np.zeros((T, 3))
        b_s_mat[0, 1:] = b_sp1_pre
        b_s_mat[1:, 1:] = b_sp1_mat[:T - 1, :]
        # use market clearing
        L_path = np.ones(T) * agg.get_L(n)
        K_path = agg.get_K(b_s_mat)
        # find implied r
        r_path_prime = firm.get_r(L_path, K_path, alpha, A, delta)
        # check distance
        tpi_dist = np.absolute(r_path[:T] - r_path_prime[:T]).max()
        print('Iteration = ', tpi_iter, ', Distance = ', tpi_dist)
        # update r
        r_path[:T] = xi * r_path_prime[:T] + (1 - xi) * r_path[:T]
        # update iteration counter
        tpi_iter += 1

    if tpi_iter < tpi_max_iter:
        print('The time path solved')
    else:
        print('The time path did not solve')

    return r_path[:T], euler_errors_mat[:T, :]
Esempio n. 5
0
def solve_ss(r_init, params):
    '''
    Solves for the steady-state equlibrium of the OG model
    '''
    beta, sigma, alpha, A, delta, xi, omega_SS, imm_rates_SS, S = params
    ss_dist = 7.0
    ss_tol = 1e-8
    ss_iter = 0
    ss_max_iter = 300
    r = r_init
    # w = w_init
    # Why do we need w as well? Are we not going to get it by providing r_init to firm.get_w()?
    # I think Jason said this too and I'm going to stick to what we did in class.
    while (ss_dist > ss_tol) & (ss_iter < ss_max_iter):

        # get w
        w = firm.get_w(r, alpha, A, delta)
        # solve HH problem
        foc_args = (beta, sigma, r, w, 0.0)
        n_s_guess = np.ones(S)
        b_sp1_guess = np.ones(S - 1) * 0.5
        HH_guess = np.append(b_sp1_guess, n_s_guess)
        result = opt.root(hh.FOCs, HH_guess, args=foc_args)
        b_sp1 = result.x[0:S - 1]
        n_s = result.x[S - 1:]
        euler_errors = result.fun
        b_s = np.append(0.0, b_sp1)
        # use market clearing
        L = agg.get_L(n_s, omega_SS)
        K = agg.get_K(b_s, omega_SS, imm_rates_SS)
        # find implied r
        r_prime = firm.get_r(L, K, alpha, A, delta)
        # find implied w
        w_prime = firm.get_w(r, alpha, A, delta)
        # check distance
        ss_dist_r = np.absolute(r - r_prime)
        ss_dist_w = np.absolute(w - w_prime)
        print('Iteration = ', ss_iter, ', Distance r = ', ss_dist_r, ', r = ',
              r, ', w = ', w)
        # update r
        r = xi * r_prime + (1 - xi) * r
        # update iteration counter
        ss_iter += 1

    return r, w, b_sp1, euler_errors
Esempio n. 6
0
def solve_ss(r_init, w_init, params):
    '''
    Solves for the steady-state equlibrium of the OG model
    '''
    beta, sigma, n, alpha, A, delta, xi = params
    ss_dist = 7.0
    ss_tol = 1e-8
    ss_iter = 0
    ss_max_iter = 300
    r = r_init
    w = w_init
    while (ss_dist > ss_tol) & (ss_iter < ss_max_iter):
        # solve HH problem
        foc_args = (beta, sigma, r, w, 0.0)
        n_s_guess = np.ones(S)
        b_sp1_guess = np.ones(S-1) * 0.5
        HH_guess = np.append(b_sp1_guess, n_s_guess)
        result = opt.root(hh.FOCs, HH_guess, args=foc_args)
        b_sp1 = result.x[0: S-1]
        n_s = result.x[S-1:]
        euler_errors = result.fun
        b_s = np.append(0.0, b_sp1)
        # use market clearing
        L = agg.get_L(n)
        K = agg.get_K(b_s)
        # find implied r
        r_prime = firm.get_r(L, K, alpha, A, delta)
        # find implied w
        w_prime = firm.get_w(L, K, G, alpha, A)
        # check distance
        ss_dist_r = np.absolute(r - r_prime)
        ss_dist_w = np.absolute(w - w_prime)
        print('Iteration = ', ss_iter, ', Distance r = ', ss_dist_r,
              ', Disrance w = ' ss_dist_w,
              ', r = ', r, ', w = ', w)
        # update r
        r = xi * r_prime + (1 - xi) * r
        # update w
        w = xi * w_prime + (1 - xi) * w
        # update iteration counter
        ss_iter += 1

    return r, w, b_sp1, euler_errors
Esempio n. 7
0
def solve_ss(r_init, params):
    '''
    Solves for the steady-state equlibrium of the OG model
    '''
    beta, sigma, alpha, A, delta, xi, l_tilde, chi, theta, omega_SS, imm_rates_SS, rho_s, S = params
    ss_dist = 7.0
    ss_tol = 1e-8
    ss_iter = 0
    ss_max_iter = 300
    r = r_init
    while (ss_dist > ss_tol) & (ss_iter < ss_max_iter):

        # get w
        w = firm.get_w(r, alpha, A, delta)
        # solve HH problem
        foc_args = (beta, sigma, r, w, 0.0, l_tilde, chi, theta, omega_SS, rho_s)
        n_s_guess = np.ones(S)
        b_sp1_guess = np.ones(S-1) * 0.5
        HH_guess = np.append(b_sp1_guess, n_s_guess)
        result = opt.root(hh.FOCs, HH_guess, args=foc_args)
        b_sp1 = result.x[0: S-1]
        n_s = result.x[S-1:]
        euler_errors = result.fun
        b_s = np.append(0.0, b_sp1)
        # use market clearing
        L = agg.get_L(n_s, omega_SS)
        K = agg.get_K(b_s, omega_SS, imm_rates_SS)
        # find implied r
        r_prime = firm.get_r(L, K, alpha, A, delta)
        # check distance
        ss_dist_r = np.absolute(r - r_prime)
        print('Iteration = ', ss_iter, ', Distance r = ', ss_dist_r,
              ', r = ', r)
        # update r
        r = xi * r_prime + (1 - xi) * r
        # update iteration counter
        ss_iter += 1

    return ss_iter, r, w, b_sp1, euler_errors
Esempio n. 8
0
def get_SS(args, graph=False):
    (init_vals, beta, sigma, chi_n_vec, l_tilde, b_ellip, upsilon, S, alpha, A,
     delta, etrparam_vec, mtrxparam_vec, mtryparam_vec, avg_inc_data) = args
    dist = 10
    mindist = 1e-08
    maxiter = 500
    ss_iter = 0
    xi = 0.2

    r_params = (alpha, A, delta)
    w_params = (alpha, A)
    Y_params = (alpha, A)

    while dist > mindist and ss_iter < maxiter:
        ss_iter += 1
        K, L, X = init_vals
        Y = aggr.get_Y(K, L, Y_params)
        factor = (S * avg_inc_data) / (Y - delta * K)
        r = firms.get_r(K, L, r_params)
        w = firms.get_w(K, L, w_params)
        c1_guess = 0.1
        c1_args = (r, w, X, factor, beta, sigma, chi_n_vec, l_tilde, b_ellip,
                   upsilon, S, etrparam_vec, mtrxparam_vec, mtryparam_vec)
        results_c1 = opt.root(hh.get_bSp1, c1_guess, args=(c1_args))
        c1 = results_c1.x
        cvec, nvec, bvec = hh.get_cnbvecs(c1, c1_args)
        # print('cvec: ', cvec)
        # print('nvec: ', nvec)
        # print('bvec: ', bvec)
        bs_vec = np.append(0, bvec[:-1])
        K_new = max(aggr.get_K(bvec[:-1]), 0.001)
        L_new = max(aggr.get_L(nvec), 0.001)
        lab_inc = w * nvec
        cap_inc = r * bs_vec
        tot_tax_liab_all = tax.get_tot_tax_liab(lab_inc, cap_inc, factor,
                                                etrparam_vec)
        X_new = (1 / S) * (tot_tax_liab_all.sum())
        # factor_new = avg_inc_data / ((1 / S) *
        #                              (r * bs_vec + w * nvec).sum())
        new_vals = np.array([K_new, L_new, X_new])
        dist = ((((new_vals - init_vals) / init_vals) * 100)**2).sum()
        init_vals = xi * new_vals + (1 - xi) * init_vals
        print('iter:', ss_iter, ' dist: ', dist)
        print(init_vals)

    c_ss = cvec
    n_ss = nvec
    b_ss = bs_vec
    K_ss = K_new
    L_ss = L_new
    r_ss = r
    w_ss = w
    Y_params = (alpha, A)
    Y_ss = aggr.get_Y(K_ss, L_ss, Y_params)
    C_ss = aggr.get_C(c_ss)
    X_ss = X_new
    factor_ss = factor
    tot_tax_liab_all_ss = tot_tax_liab_all
    tot_tax_liab_ss = X_ss * S

    ss_output = {
        'c_ss': c_ss,
        'n_ss': n_ss,
        'b_ss': b_ss,
        'K_ss': K_ss,
        'L_ss': L_ss,
        'r_ss': r_ss,
        'w_ss': w_ss,
        'Y_ss': Y_ss,
        'C_ss': C_ss,
        'X_ss': X_ss,
        'factor_ss': factor_ss,
        'tot_tax_liab_all_ss': tot_tax_liab_all_ss,
        'tot_tax_liab_ss': tot_tax_liab_ss
    }

    if graph:
        # Create directory if images directory does not already exist
        cur_path = os.path.split(os.path.abspath(__file__))[0]
        output_fldr = 'images'
        output_dir = os.path.join(cur_path, output_fldr)
        if not os.access(output_dir, os.F_OK):
            os.makedirs(output_dir)

        # Plot c_ss, n_ss, b_ss
        # Plot steady-state consumption and savings distributions
        age_pers = np.arange(1, S + 1)
        fig, ax = plt.subplots()
        plt.plot(age_pers, c_ss, marker='D', label='Consumption')
        plt.plot(age_pers,
                 np.append(0, b_ss[:-1]),
                 marker='D',
                 label='Savings')
        # for the minor ticks, use no labels; default NullFormatter
        minorLocator = MultipleLocator(1)
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        # plt.title('Steady-state consumption and savings', fontsize=20)
        plt.xlabel(r'Age $s$')
        plt.ylabel(r'Units of consumption')
        plt.xlim((0, S + 1))
        # plt.ylim((-1.0, 1.15 * (b_ss.max())))
        plt.legend(loc='upper left')
        output_path = os.path.join(output_dir, 'SS_bc')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot steady-state labor supply distributions
        fig, ax = plt.subplots()
        plt.plot(age_pers, n_ss, marker='D', label='Labor supply')
        # for the minor ticks, use no labels; default NullFormatter
        minorLocator = MultipleLocator(1)
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        # plt.title('Steady-state labor supply', fontsize=20)
        plt.xlabel(r'Age $s$')
        plt.ylabel(r'Labor supply')
        plt.xlim((0, S + 1))
        # plt.ylim((-0.1, 1.15 * (n_ss.max())))
        plt.legend(loc='upper right')
        output_path = os.path.join(output_dir, 'SS_n')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

    return ss_output
Esempio n. 9
0
def solve_tp(g_n_path, omega_S_preTP, rho_s, imm_rates_path, omega_SS, omega_path_S, params):
    '''
    Solves for the time path equilibrium using TPI
    '''
    # Missing some elements of params
    b_ss, r_ss, n_s, r_11, alpha, A, delta, beta, sigma, T, S = params
    dist = 8.0
    mindist = 1e-08
    maxiter = 300
    tpi_iter = 0
    xi = 0.2
    while dist > mindist and tpi_iter < maxiter:

        # Define paths
        b_11 = 1.1 * b_ss
        BQ_params = (g_n_path[0], omega_S_preTP, rho_s)
        K_params = (g_n_path[0], omega_S_preTP, imm_rates_path[0, :])
        BQ_11 = agg.get_BQ(b_11, r_11, BQ_params, method = "TPI")
        BQ_ss = agg.get_BQ(b_ss, r_ss, BQ_params, method = "SS")
        K_11 = agg.get_K(b_11, K_params)
        BQpath_init = np.zeros(T + S - 1)
        BQpath_init[:T] = np.linspace(BQ_11, BQ_ss, T)
        BQpath_init[T:] = BQ_ss
        L_ss = agg.get_L(n_s, omega_SS)
        r_11 = firm.get_r(L_ss, K_11, alpha, A, delta)
        # I can't figure out how r_11 and r_path differ
        ''' Is r_11 an initial guess? Depending on how you're defining
        r_11, the arguments passed to the function call above and below
        will vary
        ''' 
        r_path = firm.get_r(L_ss, K_11, alpha, A, delta)
        w_path = firm.get_w(r_path, alpha, A, delta)
        bmat = np.zeros((S - 1, T + S - 1))
        # What is b_1 supposed to be?
        bmat[:, 0] = b_1

        # Solve for households
        for p in range(2, S):
            b_guess = np.diagonal(bmat[S - p:, :p - 1])
            b_init = bmat[S - p - 1, 0]
            b_params = (b_init, n_s[-p:], r_path[:p], w_path[:p],
                        BQpath_init[:p], rho_s[-p:], beta, sigma)
            results_bp = opt.root(hh.FOCs, b_guess, args=(b_params))
            b_solve_p = results_bp.x
            DiagMaskbp = np.eye(p - 1, dtype=bool)
            bmat[S - p:, 1:p] = DiagMaskbp * b_solve_p + bmat[S - p:, 1:p]

        for t in range(1, T + 1):
            b_guess = np.diagonal(bmat[:, t - 1:t + S - 2])
            b_init = 0.0
            b_params = (b_init, n_s, r_path[t - 1:t + S - 1],
                        w_path[t - 1:t + S - 1], BQpath_init[t - 1:t + S - 1],
                        rho_s, beta, sigma)
            results_bt = opt.root(hh.FOCs, b_guess, args=(b_params))
            b_solve_t = results_bt.x
            DiagMaskbt = np.eye(S - 1, dtype=bool)
            bmat[:, t:t + S - 1] = (DiagMaskbt * b_solve_t +
                                    bmat[:, t:t + S - 1])

        new_Kpath = np.zeros(T)
        new_Kpath[0] = K_11
        new_Kpath[1:] = \
            (1 / (omega_path_S[:T - 1, :-1]) *
                bmat[:, 1:T].T +
                imm_rates_path[:T - 1, 1:] *
                omega_path_S[:T - 1, 1:] * bmat[:, 1:T].T).sum(axis=1)
        new_BQpath = np.zeros(T)
        new_BQpath[0] = BQ_11
        new_BQpath[1:] = \
            ((1 + r_path[1:T]) / (rho_s[:-1]) *
                omega_path_S[:T - 1, :-1] * bmat[:, 1:T].T).sum(axis=1)

        dist = ((BQ_init - new_BQ) ** 2).sum()
        BQpath_init[:T] = xi * new_BQpath[:T] + (1 - xi) * BQpath_init[:T]
        # update iteration counter
        tpi_iter += 1

    if tpi_iter < maxiter:
        print('The time path solved! ->', ' iter:', tpi_iter, ', dist: ', dist)
    else:
        print('The time path did not solve.')

    return [new_Kpath, new_BQpath]
Esempio n. 10
0
def inner_loop(r, w, args):
    '''
    --------------------------------------------------------------------
    Given values for r and w, solve for equilibrium errors from the two
    first order conditions of the firm
    --------------------------------------------------------------------
    INPUTS:
    r    = scalar > 0, guess at steady-state interest rate
    w    = scalar > 0, guess at steady-state wage
    args = length 16 tuple, (c1_init, J, S, lambdas, emat, beta, sigma,
           l_tilde, b_ellip, upsilon, chi_n_vec, Z, gamma, delta,
           SS_tol, c1_options)

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        hh.c1_bSp1err()
        hh.get_cnb_mats()
        aggr.get_K()
        aggr.get_L()
        firms.get_r()
        firms.get_w()

    OBJECTS CREATED WITHIN FUNCTION:
    c1_init    = (J,) vector, initial guess for c1
    J          = integer >= 1, number of heterogeneous ability groups
    S          = integer in [3, 80], number of periods an individual
                 lives
    lambdas    = (J,) vector, income percentiles for distribution of
                 ability within each cohort
    emat       = (S, J) matrix, lifetime ability profiles for each
                 lifetime income group j
    beta       = scalar in (0,1), discount factor
    sigma      = scalar >= 1, coefficient of relative risk aversion
    l_tilde    = scalar > 0, per-period time endowment for every agent
    b_ellip    = scalar > 0, fitted value of b for elliptical disutility
                 of labor
    upsilon    = scalar > 1, fitted value of upsilon for elliptical
                 disutility of labor
    chi_n_vec  = (S,) vector, values for chi^n_s scales disutility of
                 labor supply
    Z          = scalar > 0, total factor productivity parameter in
                 firms' production function
    gamma      = scalar in (0,1), capital share of income
    delta      = scalar in [0,1], model-period depreciation rate of
                 capital
    SS_tol     = scalar > 0, tolerance level for steady-state fsolve
    c1_options = length 1 dict, options for c1_bSp1err()
    rpath      = (S,) vector, lifetime path of interest rates
    wpath      = (S,) vector, lifetime path of wages
    c1_args    = length 11 tuple, args to pass into hh.c1_bSp1err()
    results_c1 = results object, results from opt.root(c1_bSp1err,...)
    c1vec      = (J,) vector, optimal initial period consumption for all
                 J types given r and w
    cnb_args   = length 9 tuple, args to pass into get_cnb_mats()
    cmat       = (S, J) matrix, household lifetime consumption
                 (c_j1, c_j2, ...c_jS)
    nmat       = (S, J) matrix, household lifetime labor supply
                 (n_j1, n_j2, ...n_jS)
    bmat       = (S, J) matrix, household lifetime savings
                 (b_j1, b_j2, ...b_jS) with b1=0
    b_Sp1_vec  = (J,) vector, final period savings, should be close to 0
    n_err_mat  = (S, J) vector, labor supply Euler errors
    b_err_mat  = (S, J) vector, savings Euler errors
    K          = scalar > 0, aggregate capital stock
    K_cstr     = boolean, =True if K < epsilon
    L          = scalar > 0, aggregate labor
    L_cstr     = boolean, =True if L < epsilon
    rw_params  = length 3 tuple, (Z, gamma, delta)
    r_new      = scalar > 0, guess at steady-state interest rate
    w_new      = scalar > 0, guess at steady-state wage

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: K, L, cmat, nmat, bmat, b_Sp1_vec, r_new, w_new, n_err_mat,
             b_err_mat
    --------------------------------------------------------------------
    '''
    (c1_init, J, S, lambdas, emat, beta, sigma, l_tilde, b_ellip, upsilon,
     chi_n_vec, Z, gamma, delta, SS_tol, c1_options) = args

    rpath = r * np.ones(S)
    wpath = w * np.ones(S)
    c1_args = (np.zeros(J), emat, beta, sigma, l_tilde, b_ellip, upsilon,
               chi_n_vec, rpath, wpath, SS_tol)
    results_c1 = \
        opt.root(hh.c1_bSp1err, c1_init, args=(c1_args),
                 method='lm', tol=SS_tol, options=(c1_options))
    c1vec = results_c1.x
    cnb_args = (np.zeros(J), emat, beta, sigma, l_tilde, b_ellip, upsilon,
                chi_n_vec, SS_tol)
    cmat, nmat, bmat, b_Sp1_vec, n_err_mat, b_err_mat = \
        hh.get_cnb_mats(c1vec, rpath, wpath, cnb_args)
    K, K_cstr = aggr.get_K(bmat, lambdas)
    L, L_cstr = aggr.get_L(nmat, lambdas, emat)
    rw_params = (Z, gamma, delta)
    r_new = firms.get_r(K, L, rw_params)
    w_new = firms.get_w(r_new, rw_params)

    return (K, L, cmat, nmat, bmat, b_Sp1_vec, r_new, w_new, n_err_mat,
            b_err_mat)
Esempio n. 11
0
    tpi_paramsfile = os.path.join(tpi_output_dir, 'tpi_args.pkl')

    r_ss = ss_output['r_ss']
    K_ss = ss_output['K_ss']
    L_ss = ss_output['L_ss']
    C_ss = ss_output['C_ss']
    b_ss = ss_output['b_ss']
    n_ss = ss_output['n_ss']

    # Choose initial period distribution of wealth (bmat1), which
    # determines initial period aggregate capital stock
    init_wgts = 0.95 * np.ones((S, J))
    bmat1 = init_wgts * b_ss

    # Make sure init. period distribution is feasible in terms of K
    K1, K1_cstr = aggr.get_K(bmat1, lambdas)

    # If initial bvec1 is not feasible end program
    if K1_cstr:
        print('Initial savings distribution is not feasible because ' +
              'K1<epsilon. Some element(s) of bmat1 must increase.')
    else:
        tpi_params = (J, S, T1, T2, lambdas, emat, beta, sigma, l_tilde,
                      b_ellip, upsilon, chi_n_vec, A, alpha, delta,
                      r_ss, K_ss, L_ss, C_ss, b_ss, n_ss, maxiter_TPI,
                      mindist_TPI, TPI_tol, xi_TPI, TPI_EulDiff)
        tpi_output = tpi.get_TPI(tpi_params, bmat1, TPI_graphs)

        tpi_args = (J, S, T1, T2, lambdas, emat, beta, sigma, l_tilde,
                    b_ellip, upsilon, chi_n_vec, A, alpha, delta, r_ss,
                    K_ss, L_ss, C_ss, b_ss, n_ss, maxiter_TPI,
Esempio n. 12
0
def get_TPI(b1vec, ss_params, params):
    # r_guess: guess of interest rate path from period 1 to T1
    beta, sigma, S, ltilde, b, upsilon, chi_n_vec, A, alpha, delta, tpi_max_iter, tpi_tol, xi_tpi, T1, T2 = params
    r_ss, w_ss, c_ss, n_ss, b_ss, K_ss, L_ss = ss_params
    abs_tpi = 1
    tpi_iter = 0
    rpath_old = np.zeros(T2 + S - 1)
    rpath_old[:T1] = get_path(r_ss, r_ss, T1, 'quadratic')
    rpath_old[T1:] = r_ss
    while abs_tpi > tpi_tol and tpi_iter < tpi_max_iter:
        c1_guess = 1.0
        tpi_iter += 1
        wpath_old = firms.get_w(rpath_old, (A, alpha, delta))
        bmat = np.zeros((S, T2 + S - 1))
        bmat[:, 0] = b1vec
        bmat[:, T2:] = np.matlib.repmat(b_ss, S - 1, 1).T
        nmat = np.zeros((S, T2 + S - 1))
        nmat[:, T2:] = np.matlib.repmat(n_ss, S - 1, 1).T
        cmat = np.zeros((S, T2 + S - 1))
        cmat[:, T2:] = np.matlib.repmat(c_ss, S - 1, 1).T
        # Solve the incomplete remaining lifetime decisions of agents alive
        # in period t=1 but not born in period t=1
        for p in range(S): # p is remaining periods of life
            c1_args = (rpath_old[:p + 1], wpath_old[:p + 1], beta, sigma, ltilde, b, upsilon, chi_n_vec[S - p - 1:], p + 1, b1vec[S - p - 1])
            result_c1 = opt.root(hh.get_b_last, c1_guess, args = (c1_args))
            if result_c1.success:
                c1 = result_c1.x
            else:
                raise ValueError("failed to find an appropriate initial consumption")
            # Calculate aggregate supplies for capital and labor
            cvec = hh.get_c(c1, rpath_old[:p + 1], beta, sigma, p + 1)
            nvec = hh.get_n(cvec, sigma, ltilde, b, upsilon, chi_n_vec[S - p - 1: ], wpath_old[:p + 1], p + 1)
            bvec = hh.get_b(cvec, nvec, rpath_old[:p + 1], wpath_old[:p + 1], p + 1, bs = b1vec[S - p - 1])[1:]
            # Insert the vector lifetime solutions diagonally (twist donut)
            DiagMaskbp = np.eye(p)
            bp_path = DiagMaskbp * bvec
            bmat[S - p:, 1:p + 1] += bp_path

            DiagMasknp = np.eye(p + 1)
            np_path = DiagMasknp * nvec
            nmat[S - p - 1:, :p + 1] += np_path

            DiagMaskcp = np.eye(p + 1)
            cp_path = DiagMaskcp * cvec
            cmat[S - p - 1:, :p + 1] += cp_path
        # Solve for complete lifetime decisions of agents born in periods
        # 1 to T2 and insert the vector lifetime solutions diagonally (twist
        # donut) into the cpath, bpath, and EulErrPath matrices
        for t in range(1, T2):
            c1_args = (rpath_old[t: S + t], wpath_old[t: S + t], beta, sigma, ltilde, b, upsilon, chi_n_vec, S, 0.0)
            result_c1 = opt.root(hh.get_b_last, c1_guess, args = (c1_args))
            if result_c1.success:
                c1 = result_c1.x
            else:
                raise ValueError("failed to find an appropriate initial consumption")
            # Calculate aggregate supplies for capital and labor
            cvec = hh.get_c(c1, rpath_old[t : S + t], beta, sigma, S)
            nvec = hh.get_n(cvec, sigma, ltilde, b, upsilon, chi_n_vec, wpath_old[t: S + t], S)
            bvec = hh.get_b(cvec, nvec, rpath_old[t: S + t], wpath_old[t: S + t], S)
            DiagMaskbt = np.eye(S)
            bt_path = DiagMaskbt * bvec
            bmat[:, t: t + S] += bt_path

            DiagMasknt = np.eye(S)
            nt_path = DiagMasknt * nvec
            nmat[:, t: t + S] += nt_path

            DiagMaskct = np.eye(S)
            ct_path = DiagMaskct * cvec
            cmat[:, t: t + S] += ct_path

        bmat[:, T2:] = np.matlib.repmat(b_ss, S - 1, 1).T
        nmat[:, T2:] = np.matlib.repmat(n_ss, S - 1, 1).T
        cmat[:, T2:] = np.matlib.repmat(c_ss, S - 1, 1).T

        K = aggr.get_K(bmat)[0]
        L = aggr.get_L(nmat)[0]
        Y = aggr.get_Y(K, L, (A, alpha))
        C = aggr.get_C(cmat)
        rpath_new = firms.get_r(K, L, (A, alpha, delta))

        # Calculate the implied capital stock from conjecture and the error
        abs_tpi = ((rpath_old[:T2] - rpath_new[:T2]) ** 2).sum()
        # Update guess
        rpath_old[:T2] = xi_tpi * rpath_new[:T2] + (1 - xi_tpi) * rpath_old[:T2]
        b_err = np.zeros(T2 + S - 1)
        n_err = np.zeros(T2 + S - 1)
        b_last = bmat[S-1, :]
        for i in range(T2 + S - 1):
            b_err[i] = abs(hh.get_b_errors(cmat[:, i], rpath_old[i], beta, sigma)).max()
            n_err[i] = abs(hh.get_n_errors(nmat[:, i], cmat[:, i], sigma, ltilde, b, upsilon, chi_n_vec, wpath_old[i])).max()
        Rc_err = Y[:-1] - C[:-1] - K[1:] + (1 - delta) * K[:-1]
        print('iteration:', tpi_iter, ' squared distance: ', abs_tpi)

        k_first = [k for k in K if abs(k - K_ss) < 0.00001][0]
        T1 = np.where(K == k_first)[0][0]

    return cmat, nmat, bmat, rpath_old, wpath_old, K, L, Y, C, b_err, n_err, b_last, Rc_err, T1
Esempio n. 13
0
def get_SS(init_vals, args, graphs=False):
    '''
    --------------------------------------------------------------------
    Solve for the steady-state solution of the S-period-lived agent OG
    model with endogenous labor supply using the bisection method in K
    and L for the outer loop
    --------------------------------------------------------------------
    INPUTS:
    init_vals = length 3 tuple, (r_init, c1_init, factor_init)
    args      = length 19 tuple, (J, S, lambdas, emat, beta, sigma,
                l_tilde, b_ellip, upsilon, chi_n_vec_hat, Z, gamma,
                delta, Bsct_Tol, Eul_Tol, xi, maxiter, mean_ydata,
                init_calc)
    graphs    = boolean, =True if output steady-state graphs

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        firms.get_r()
        firms.get_w()
        utils.print_time()
        inner_loop()
        creat_graphs()

    OBJECTS CREATED WITHIN FUNCTION:
    start_time    = scalar > 0, clock time at beginning of program
    r_init        = scalar > -delta, initial guess for steady-state
                    interest rate
    c1_init       = (J,) vector, initial guess for first period
                    consumption by all J ability types
    factor_init   = scalar > 0, initial guess for factor that scales
                    model units to data units
    J             = integer >= 1, number of heterogeneous ability groups
    S             = integer in [3, 80], number of periods an individual
                    lives
    lambdas       = (J,) vector, income percentiles for distribution of
                    ability within each cohort
    emat          = (S, J) matrix, lifetime ability profiles for each
                    lifetime income group j
    beta          = scalar in (0,1), discount factor for each model per
    sigma         = scalar > 0, coefficient of relative risk aversion
    l_tilde       = scalar > 0, time endowment of each agent each period
    b_ellip       = scalar > 0, fitted value of b for elliptical
                    disutility of labor
    upsilon       = scalar > 1, fitted value of upsilon for elliptical
                    disutility of labor
    chi_n_vec_hat = (S,) vector, values for chi^n_s hat from data
    Z             = scalar > 0, total factor productivity parameter in
                    firms' production function
    gamma         = scalar in (0,1), capital share of income
    delta         = scalar in [0,1], model-period depreciation rate of
                    capital
    Bsct_Tol      = scalar > 0, tolerance level for outer-loop bisection
                    method
    Eul_Tol       = scalar > 0, tolerance level for inner-loop root
                    finder
    xi            = scalar in (0, 1], SS updating parameter in outer-
                    loop bisection method
    maxiter       = integer >= 1, maximum number of iterations in outer-
                    loop bisection method
    mean_ydata    = scalar > 0, average household income from the data
    init_calc     = boolean, =True if initial steady-state calculation
                    with chi_n_vec = 1 for all s
    iter_SS       = integer >= 0, index of iteration number
    dist          = scalar > 0, distance metric for current iteration
    c1_options    = length 1 dict, options to pass into
                    opt.root(c1_bSp1err,...)
    rw_params     = length 3 tuple, (Z, gamma, delta) args to pass into
                    firms.get_w()
    c1ss_init     = (J,) vector, initial guess for css_{j,1}, updates
                    each iteration
    lambda_mat    = (S, J) matrix, lambdas vector copied down S rows
    w_init        = scalar, initial value for wage
    chi_n_vec     = (S,) vector, chi^n_s values that scale the
                    disutility of labor supply
    inner_args    = length 16 tuple, args to pass into inner_loop()
    K_new         = scalar > 0, updated K given r_init and w_init
    L_new         = scalar > 0, updated L given r_init and w_init
    cmat          = (S, J) matrix, lifetime household consumption by age
                    s and ability j
    nmat          = (S, J) matrix, lifetime household labor supply by
                    age s and ability j
    bmat          = (S, J) matrix, lifetime household savings by age s
                    and ability j (b1, b2,...bS)
    b_Sp1_vec     = (J,) vector, household savings in last period for
                    each ability type, should be arbitrarily close to 0
    r_new         = scalar > 0, updated interest rate given nmat, bmat
    w_new         = scalar > 0, updated wage given nmat and bmat
    n_err_mat     = (S, J) matrix, labor supply Euler errors given
                    r_init and w_init
    b_err_mat     = (S, J) matrix, savings Euler errors given r_init
                    and w_init. First row is identically zeros
    all_errors    = (2JS + J,) vector, (n_errors, b_errors, b_Sp1_vec)
    avg_inc_model = scalar > 0, average household income in model
    factor_new    = scalar > 0, updated factor value given nmat, bmat,
                    r_new, and w_new
    c_ss          = (S, J) matrix, steady-state lifetime consumption
    n_ss          = (S, J) matrix, steady-state lifetime labor supply
    b_ss          = (S, J) matrix, steady-state wealth (savings) at
                    beginning of each period (b1, b2, ...bS)
    b_Sp1_ss      = (J,) vector, steady-state savings in last period of
                    life for all J ability types, approx. 0 in equilbrm
    n_err_ss      = (S, J) matrix, lifetime labor supply Euler errors
    b_err_ss      = (S, J) matrix, lifetime savings Euler errors
    r_ss          = scalar > 0, steady-state interest rate
    w_ss          = scalar > 0, steady-state wage
    K_ss          = scalar > 0, steady-state aggregate capital stock
    L_ss          = scalar > 0, steady-state aggregate labor
    Y_params      = length 2 tuple, (Z, gamma)
    Y_ss          = scalar > 0, steady-state aggregate output (GDP)
    C_ss          = scalar > 0, steady-state aggregate consumption
    RCerr_ss      = scalar, resource constraint error
    ss_time       = scalar, seconds elapsed for steady-state computation
    ss_output     = length 16 dict, steady-state objects {c_ss, n_ss,
                    b_ss, b_Sp1_ss, w_ss, r_ss, K_ss, L_ss, Y_ss, C_ss,
                    n_err_ss, b_err_ss, RCerr_ss, ss_time, chi_n_vec,
                    factor_ss}

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: ss_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    r_init, BQ_init, factor_init, bmat_init, nmat_init = init_vals
    (J, E, S, lambdas, emat, mort_rates, imm_rates, omega_SS, g_n_SS, zeta_mat,
     chi_n_vec_hat, chi_b_vec, beta, sigma, l_tilde, b_ellip, upsilon, g_y, Z,
     gamma, delta, SS_tol_outer, SS_tol_inner, xi, maxiter, mean_ydata,
     init_calc) = args
    iter_SS = 0
    dist = 10
    rw_params = (Z, gamma, delta)
    BQ_args = (lambdas, omega_SS, mort_rates, g_n_SS)
    lambda_mat = np.tile(lambdas.reshape((1, J)), (S, 1))
    omega_mat = np.tile(omega_SS.reshape((S, 1)), (1, J))

    while (iter_SS < maxiter) and (dist >= SS_tol_outer):
        iter_SS += 1
        w_init = firms.get_w(r_init, rw_params)
        if init_calc:
            print('Factor init is one. No modification performed to ' +
                  'chi_n_vec. Dist calculated without factor.')
            chi_n_vec = chi_n_vec_hat
        else:
            chi_n_vec = chi_n_vec_hat * (factor_init**(sigma - 1))

        rpath = r_init * np.ones(S)
        wpath = w_init * np.ones(S)
        BQpath = BQ_init * np.ones(S)
        cnb_args = (S, lambdas, emat, mort_rates, omega_SS, zeta_mat,
                    chi_n_vec, chi_b_vec, beta, sigma, l_tilde, b_ellip,
                    upsilon, g_y, g_n_SS, SS_tol_inner)
        cmat, nmat, bmat, n_err_mat, b_err_mat = \
            hh.get_cnb_mats(bmat_init, nmat_init, np.zeros(J), rpath,
                            wpath, BQpath, cnb_args)
        K_args = (lambdas, omega_SS, imm_rates, g_n_SS)
        K_new, K_cstr = aggr.get_K(bmat, K_args)
        L_args = (emat, lambdas, omega_SS)
        L_new, L_cstr = aggr.get_L(nmat, L_args)
        r_new = firms.get_r(K_new, L_new, rw_params)
        w_new = firms.get_w(r_new, rw_params)
        BQ_new = aggr.get_BQ(bmat, r_new, BQ_args)

        all_errors = \
            np.hstack((b_err_mat.flatten(), n_err_mat.flatten()))
        if init_calc:
            dist = max(np.absolute((r_new - r_init) / r_init),
                       np.absolute((BQ_new - BQ_init) / BQ_init))
        else:
            avg_inc_model = (omega_mat * lambda_mat *
                             (r_new * bmat + w_new * emat * nmat)).sum()
            factor_new = mean_ydata / avg_inc_model
            print('mean_ydata: ', mean_ydata, ', avg_inc_model: ',
                  avg_inc_model)
            print('r_new: ', r_new, 'BQ_new', BQ_new, 'factor_new: ',
                  factor_new)
            dist = max(np.absolute((r_new - r_init) / r_init),
                       np.absolute((BQ_new - BQ_init) / BQ_init),
                       np.absolute((factor_new - factor_init) / factor_init))
            factor_init = xi * factor_new + (1 - xi) * factor_init

        r_init = xi * r_new + (1 - xi) * r_init
        BQ_init = xi * BQ_new + (1 - xi) * BQ_init
        print('SS Iter=', iter_SS, ', SS Dist=', '%10.4e' % (dist),
              ', Max Abs Err=', '%10.4e' % (np.absolute(all_errors).max()))
        bmat_init = bmat
        nmat_init = nmat

    chi_n_vec = chi_n_vec_hat * (factor_init**(sigma - 1))
    c_ss = cmat.copy()
    n_ss = nmat.copy()
    b_ss = bmat.copy()
    n_err_ss = n_err_mat.copy()
    b_err_ss = b_err_mat.copy()
    r_ss = r_new.copy()
    w_ss = w_new.copy()
    BQ_ss = BQ_new.copy()
    K_ss = K_new.copy()
    L_ss = L_new.copy()
    factor_ss = factor_init
    I_args = (lambdas, omega_SS, imm_rates, g_n_SS, g_y, delta)
    I_ss = aggr.get_I(b_ss, I_args)
    NX_args = (lambdas, omega_SS, imm_rates, g_y)
    NX_ss = aggr.get_NX(b_ss, NX_args)
    Y_params = (Z, gamma)
    Y_ss = aggr.get_Y(K_ss, L_ss, Y_params)
    C_args = (lambdas, omega_SS)
    C_ss = aggr.get_C(c_ss, C_args)
    RCerr_ss = Y_ss - C_ss - I_ss - NX_ss

    ss_time = time.clock() - start_time

    ss_output = {
        'c_ss': c_ss,
        'n_ss': n_ss,
        'b_ss': b_ss,
        'BQ_ss': BQ_ss,
        'w_ss': w_ss,
        'r_ss': r_ss,
        'K_ss': K_ss,
        'L_ss': L_ss,
        'I_ss': I_ss,
        'Y_ss': Y_ss,
        'C_ss': C_ss,
        'NX_ss': NX_ss,
        'n_err_ss': n_err_ss,
        'b_err_ss': b_err_ss,
        'RCerr_ss': RCerr_ss,
        'ss_time': ss_time,
        'chi_n_vec': chi_n_vec,
        'factor_ss': factor_ss
    }
    print('n_ss is: ', n_ss)
    print('b_ss is: ', b_ss)
    print('c_ss is: ', c_ss)
    print('K_ss=', K_ss, ', L_ss=', L_ss, 'Y_ss=', Y_ss)
    print('r_ss=', r_ss, ', w_ss=', w_ss, 'C_ss=', C_ss)
    print('BQ_ss=', BQ_ss, ', I_ss=', I_ss, ', NX_ss=', NX_ss)
    print('Maximum abs. labor supply Euler error is: ',
          np.absolute(n_err_ss).max())
    print('Maximum abs. savings Euler error is: ', np.absolute(b_err_ss).max())
    print('Resource constraint error is: ', RCerr_ss)
    print('Final chi_n_vec from SS:', chi_n_vec)
    print('SS factor is: ', factor_ss)

    # Print SS computation time
    utils.print_time(ss_time, 'SS')

    if graphs:
        gr_args = (E, S, J, chi_n_vec, lambdas)
        create_graphs(c_ss, b_ss, n_ss, gr_args)

    return ss_output
Esempio n. 14
0
def inner_loop(r, w, args):
    '''
    --------------------------------------------------------------------
    Given values for r and w, solve for the households' optimal decisions
    --------------------------------------------------------------------
    INPUTS:
    r    = scalar > 0, guess at steady-state interest rate
    w    = scalar > 0, guess at steady-state wage
    args = length 14 tuple, (nvec_init, bvec_init, S, beta, sigma,
            l_tilde, b_ellip, upsilon, chi_n_vec, A, alpha, delta,
            EulDiff, SS_tol)

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        euler_sys()
        aggr.get_K()
        aggr.get_L()
        firms.get_r()
        firms.get_w()

    OBJECTS CREATED WITHIN FUNCTION:
    nvec_init  = (S,) vector, initial guesses at choice of labor supply
    bvec_init  = (S,) vector, initial guesses at choice of savings
    S          = integer >= 3, number of periods in individual lifetime
    beta       = scalar in (0,1), discount factor
    sigma      = scalar >= 1, coefficient of relative risk aversion
    l_tilde    = scalar > 0, per-period time endowment for every agent
    b_ellip    = scalar > 0, fitted value of b for elliptical disutility
                 of labor
    upsilon    = scalar > 1, fitted value of upsilon for elliptical
                 disutility of labor
    chi_n_vec  = (S,) vector, values for chi^n_s
    A          = scalar > 0, total factor productivity parameter in
                 firms' production function
    alpha      = scalar in (0,1), capital share of income
    delta      = scalar in [0,1], model-period depreciation rate of
                 capital
    EulDiff    = boolean, =True if simple difference Euler errors,
                 otherwise percent deviation Euler errors
    SS_tol     = scalar > 0, tolerance level for steady-state fsolve
    cvec       = (S,) vector, lifetime consumption (c1, c2, ...cS)
    nvec       = (S,) vector, lifetime labor supply (n1, n2, ...nS)
    bvec       = (S,) vector, lifetime savings (b1, b2, ...bS) with b1=0
    b_Sp1      = scalar, final period savings, should be close to zero
    n_errors   = (S,) vector, labor supply Euler errors
    b_errors   = (S-1,) vector, savings Euler errors
    K          = scalar > 0, aggregate capital stock
    K_cstr     = boolean, =True if K < epsilon
    L          = scalar > 0, aggregate labor
    L_cstr     = boolean, =True if L < epsilon
    r_params   = length 3 tuple, (A, alpha, delta)
    w_params   = length 2 tuple, (A, alpha)
    r_new      = scalar > 0, guess at steady-state interest rate
    w_new      = scalar > 0, guess at steady-state wage

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: K, L, cvec, nvec, bvec, b_Sp1, r_new, w_new, n_errors,
             b_errors
    --------------------------------------------------------------------
    '''
    (nmat_init, bmat_init, S, J, beta, sigma, emat, l_tilde, b_ellip, upsilon,
     chi_n_vec, A, alpha, delta, lambdas, EulDiff, SS_tol) = args

    nmat = np.zeros((S, J))
    bmat = np.zeros((S - 1, J))
    n_err_mat = np.zeros((S, J))
    b_err_mat = np.zeros((S - 1, J))
    for j in range(J):
        euler_args = (r, w, beta, sigma, emat[:, j], l_tilde, chi_n_vec,
                      b_ellip, upsilon, EulDiff, S, SS_tol)
        guesses = np.append(nmat_init[:, j], bmat_init[:, j])
        results_euler = opt.root(euler_sys,
                                 guesses,
                                 args=(euler_args),
                                 method='lm',
                                 tol=SS_tol)
        nmat[:, j] = results_euler.x[:S]
        bmat[:, j] = results_euler.x[S:]
        n_err_mat[:, j] = results_euler.fun[:S]
        b_err_mat[:, j] = results_euler.fun[S:]
    b_s_mat = np.append(np.zeros((1, J)), bmat, axis=0)
    b_sp1_mat = np.append(bmat, np.zeros((1, J)), axis=0)
    cmat = hh.get_cons(r, w, b_s_mat, b_sp1_mat, nmat, emat)
    b_Sp1_vec = np.zeros(J)
    K, K_cnstr = aggr.get_K(bmat, lambdas)
    L = aggr.get_L(nmat, emat, lambdas)
    r_params = (A, alpha, delta)
    r_new = firms.get_r(K, L, r_params)
    w_params = (A, alpha, delta)
    w_new = firms.get_w_from_r(r_new, w_params)

    return (K, L, cmat, nmat, bmat, b_Sp1_vec, r_new, w_new, n_err_mat,
            b_err_mat)
Esempio n. 15
0
def get_SS(args, graph=False):
    (KL_init, beta, sigma, emat, chi_n_vec, l_tilde, b, upsilon, lambdas, S, J,
     alpha, A, delta) = args
    dist = 10
    mindist = 1e-08
    maxiter = 500
    ss_iter = 0
    xi = 0.2

    r_params = (alpha, A, delta)
    w_params = (alpha, A)

    while dist > mindist and ss_iter < maxiter:
        ss_iter += 1
        K, L = KL_init
        r = firms.get_r(K, L, r_params)
        w = firms.get_w(K, L, w_params)
        cmat = np.zeros((S, J))
        nmat = np.zeros((S, J))
        bmat = np.zeros((S, J))
        c1 = 1.0
        for j in range(J):
            c1_guess = c1
            c1_args = (r, w, beta, sigma, chi_n_vec, l_tilde, b, upsilon,
                       emat[:, j], S)
            results_c1 = opt.root(hh.get_bSp1, c1_guess, args=(c1_args))
            c1 = results_c1.x
            cmat[:, j] = hh.get_recurs_c(c1, r, beta, sigma, S)
            nmat[:, j] = hh.get_n_s(cmat[:, j], w, sigma, chi_n_vec, l_tilde,
                                    b, upsilon, emat[:, j])
            bmat[:, j] = hh.get_recurs_b(cmat[:, j], nmat[:, j], r, w, emat[:,
                                                                            j])
        K_new = aggr.get_K(bmat[:-1, :], lambdas, S)
        L_new = aggr.get_L(nmat, emat, lambdas, S)
        KL_new = np.array([K_new, L_new])
        dist = ((KL_new - KL_init)**2).sum()
        KL_init = xi * KL_new + (1 - xi) * KL_init
        print('iter:', ss_iter, ' dist: ', dist)

    c_ss = cmat
    n_ss = nmat
    b_ss = bmat
    K_ss = K_new
    L_ss = L_new
    r_ss = r
    w_ss = w
    Y_params = (alpha, A)
    Y_ss = aggr.get_Y(K_ss, L_ss, Y_params)
    C_ss = aggr.get_C(c_ss, lambdas, S)

    ss_output = {
        'c_ss': c_ss,
        'n_ss': n_ss,
        'b_ss': b_ss,
        'K_ss': K_ss,
        'L_ss': L_ss,
        'r_ss': r_ss,
        'w_ss': w_ss,
        'Y_ss': Y_ss,
        'C_ss': C_ss
    }

    if graph:
        '''
        ----------------------------------------------------------------
        cur_path    = string, path name of current directory
        output_fldr = string, folder in current path to save files
        output_dir  = string, total path of images folder
        output_path = string, path of file name of figure to be saved
        sgrid       = (S,) vector, ages from 1 to S
        lamcumsum   = (J,) vector, cumulative sum of lambdas vector
        jmidgrid    = (J,) vector, midpoints of ability percentile bins
        smat        = (J, S) matrix, sgrid copied down J rows
        jmat        = (J, S) matrix, jmidgrid copied across S columns
        ----------------------------------------------------------------
        '''
        # Create directory if images directory does not already exist
        cur_path = os.path.split(os.path.abspath(__file__))[0]
        output_fldr = 'images'
        output_dir = os.path.join(cur_path, output_fldr)
        if not os.access(output_dir, os.F_OK):
            os.makedirs(output_dir)

        # Plot 3D steady-state consumption distribution
        sgrid = np.arange(1, S + 1)
        lamcumsum = lambdas.cumsum()
        jmidgrid = 0.5 * lamcumsum + 0.5 * (lamcumsum - lambdas)
        smat, jmat = np.meshgrid(sgrid, jmidgrid)
        cmap_c = cm.get_cmap('summer')
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'ability-$j$')
        ax.set_zlabel(r'indiv. consumption $c_{j,s}$')
        ax.plot_surface(smat, jmat, c_ss.T, rstride=1, cstride=6, cmap=cmap_c)
        output_path = os.path.join(output_dir, 'c_ss_3D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot 2D steady-state consumption distribution
        minorLocator = MultipleLocator(1)
        fig, ax = plt.subplots()
        linestyles = np.array(["-", "--", "-.", ":"])
        markers = np.array(["x", "v", "o", "d", ">", "|"])
        pct_lb = 0
        for j in range(J):
            this_label = (str(int(np.rint(pct_lb))) + " - " +
                          str(int(np.rint(pct_lb + 100 * lambdas[j]))) + "%")
            pct_lb += 100 * lambdas[j]
            if j <= 3:
                ax.plot(sgrid,
                        c_ss[:, j],
                        label=this_label,
                        linestyle=linestyles[j],
                        color='black')
            elif j > 3:
                ax.plot(sgrid,
                        c_ss[:, j],
                        label=this_label,
                        marker=markers[j - 4],
                        color='black')
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        box = ax.get_position()
        ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
        ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'indiv. consumption $c_{j,s}$')
        output_path = os.path.join(output_dir, 'c_ss_2D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot 3D steady-state labor supply distribution
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'ability-$j$')
        ax.set_zlabel(r'labor supply $n_{j,s}$')
        ax.plot_surface(smat, jmat, n_ss.T, rstride=1, cstride=6, cmap=cmap_c)
        output_path = os.path.join(output_dir, 'n_ss_3D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot 2D steady-state labor supply distribution
        minorLocator = MultipleLocator(1)
        fig, ax = plt.subplots()
        linestyles = np.array(["-", "--", "-.", ":"])
        markers = np.array(["x", "v", "o", "d", ">", "|"])
        pct_lb = 0
        for j in range(J):
            this_label = (str(int(np.rint(pct_lb))) + " - " +
                          str(int(np.rint(pct_lb + 100 * lambdas[j]))) + "%")
            pct_lb += 100 * lambdas[j]
            if j <= 3:
                ax.plot(sgrid,
                        n_ss[:, j],
                        label=this_label,
                        linestyle=linestyles[j],
                        color='black')
            elif j > 3:
                ax.plot(sgrid,
                        n_ss[:, j],
                        label=this_label,
                        marker=markers[j - 4],
                        color='black')
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        box = ax.get_position()
        ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
        ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'labor supply $n_{j,s}$')
        output_path = os.path.join(output_dir, 'n_ss_2D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot 3D steady-state savings/wealth distribution
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'ability-$j$')
        ax.set_zlabel(r'indiv. savings $b_{j,s}$')
        ax.plot_surface(smat, jmat, b_ss.T, rstride=1, cstride=6, cmap=cmap_c)
        output_path = os.path.join(output_dir, 'b_ss_3D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot 2D steady-state savings/wealth distribution
        fig, ax = plt.subplots()
        linestyles = np.array(["-", "--", "-.", ":"])
        markers = np.array(["x", "v", "o", "d", ">", "|"])
        pct_lb = 0
        for j in range(J):
            this_label = (str(int(np.rint(pct_lb))) + " - " +
                          str(int(np.rint(pct_lb + 100 * lambdas[j]))) + "%")
            pct_lb += 100 * lambdas[j]
            if j <= 3:
                ax.plot(sgrid,
                        b_ss[:, j],
                        label=this_label,
                        linestyle=linestyles[j],
                        color='black')
            elif j > 3:
                ax.plot(sgrid,
                        b_ss[:, j],
                        label=this_label,
                        marker=markers[j - 4],
                        color='black')
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        box = ax.get_position()
        ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
        ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'indiv. savings $b_{j,s}$')
        output_path = os.path.join(output_dir, 'b_ss_2D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

    return ss_output
Esempio n. 16
0
def feasible(bvec, params):
    '''
    --------------------------------------------------------------------
    Check whether a vector of steady-state savings is feasible in that
    it satisfies the nonnegativity constraints on consumption in every
    period c_s > 0 and that the aggregate capital stock is strictly
    positive K > 0
    --------------------------------------------------------------------
    INPUTS:
    bvec   = (S-1,) vector, household savings b_{s+1}
    params = length 4 tuple, (nvec, A, alpha, delta)

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        get_L()
        get_K()
        get_w()
        get_r()
        get_cvec()

    OBJECTS CREATED WITHIN FUNCTION:
    nvec     = (S,) vector, exogenous labor supply values n_s
    A        = scalar > 0, total factor productivity
    alpha    = scalar in (0, 1), capital share of income
    delta    = scalar in (0, 1), per-period depreciation rate
    S        = integer >= 3, number of periods in individual life
    L        = scalar > 0, aggregate labor
    K        = scalar, steady-state aggregate capital stock
    K_cstr   = boolean, =True if K <= 0
    w_params = length 2 tuple, (A, alpha)
    w        = scalar, steady-state wage
    r_params = length 3 tuple, (A, alpha, delta)
    r        = scalar, steady-state interest rate
    bvec2    = (S,) vector, steady-state savings distribution plus
               initial period wealth of zero
    cvec     = (S,) vector, steady-state consumption by age
    c_cnstr  = (S,) Boolean vector, =True for elements for which c_s<=0
    b_cnstr  = (S-1,) Boolean, =True for elements for which b_s causes a
               violation of the nonnegative consumption constraint

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: b_cnstr, c_cnstr, K_cnstr
    --------------------------------------------------------------------
    '''
    nvec, A, alpha, delta = params
    S = nvec.shape[0]
    L = aggr.get_L(nvec)
    K, K_cstr = aggr.get_K(bvec)
    if not K_cstr:
        w_params = (A, alpha)
        w = firms.get_w(K, L, w_params)
        r_params = (A, alpha, delta)
        r = firms.get_r(K, L, r_params)
        c_params = (nvec, r, w)
        cvec = hh.get_cons(bvec, 0.0, c_params)
        c_cstr = cvec <= 0
        b_cstr = c_cstr[:-1] + c_cstr[1:]

    else:
        c_cstr = np.ones(S, dtype=bool)
        b_cstr = np.ones(S - 1, dtype=bool)

    return c_cstr, K_cstr, b_cstr
Esempio n. 17
0
def get_TPI(bvec1, args, graphs):
    '''
    --------------------------------------------------------------------
    Solves for transition path equilibrium using time path iteration
    (TPI)
    --------------------------------------------------------------------
    INPUTS:
    bvec1  = (S,) vector, initial period savings distribution
    args   = length 22 tuple, (S, T1, T2, beta, sigma, l_tilde, b_ellip,
             upsilon, chi_n_vec, A, alpha, delta, r_ss, K_ss, L_ss,
             C_ss, b_ss, n_ss, maxiter, Out_Tol, In_Tol, EulDiff, xi)
    graphs = Boolean, =True if want graphs of TPI objects

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        aggr.get_K()
        get_path()
        firms.get_r()
        firms.get_w()
        inner_loop()
        solve_bn_path()
        aggr.get_L()
        aggr.get_Y()
        aggr.get_C()
        utils.print_time()

    OBJECTS CREATED WITHIN FUNCTION:
    start_time    = scalar, current processor time in seconds (float)
    S             = integer in [3,80], number of periods an individual
                    lives
    T1            = integer > S, number of time periods until steady
                    state is assumed to be reached
    T2            = integer > T1, number of time periods after which
                    steady-state is forced in TPI
    beta          = scalar in (0,1), discount factor for model period
    sigma         = scalar > 0, coefficient of relative risk aversion
    l_tilde       = scalar > 0, time endowment for each agent each
                    period
    b_ellip       = scalar > 0, fitted value of b for elliptical
                    disutility of labor
    upsilon       = scalar > 1, fitted value of upsilon for elliptical
                    disutility of labor
    chi_n_vec     = (S,) vector, values for chi^n_s
    A             = scalar > 0, total factor productivity parameter in
                    firms' production function
    alpha         = scalar in (0,1), capital share of income
    delta         = scalar in [0,1], per-period capital depreciation rt
    r_ss          = scalar > 0, steady-state aggregate interest rate
    K_ss          = scalar > 0, steady-state aggregate capital stock
    L_ss          = scalar > 0, steady-state aggregate labor
    C_ss          = scalar > 0, steady-state aggregate consumption
    b_ss          = (S,) vector, steady-state savings distribution
                    (b1, b2,... bS)
    n_ss          = (S,) vector, steady-state labor supply distribution
                    (n1, n2,... nS)
    maxiter       = integer >= 1, Maximum number of iterations for TPI
    mindist       = scalar > 0, convergence criterion for TPI
    TPI_tol       = scalar > 0, tolerance level for TPI root finders
    xi            = scalar in (0,1], TPI path updating parameter
    diff          = Boolean, =True if want difference version of Euler
                    errors beta*(1+r)*u'(c2) - u'(c1), =False if want
                    ratio version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1
    K1            = scalar > 0, initial aggregate capital stock
    K1_cnstr      = Boolean, =True if K1 <= 0
    rpath_init    = (T2+S-1,) vector, initial guess for the time path of
                    interest rates
    iter_TPI      = integer >= 0, current iteration of TPI
    dist          = scalar >= 0, distance measure between initial and
                    new paths
    rw_params     = length 3 tuple, (A, alpha, delta)
    Y_params      = length 2 tuple, (A, alpha)
    cnb_params    = length 11 tuple, args to pass into inner_loop()
    rpath         = (T2+S-1,) vector, time path of the interest rates
    wpath         = (T2+S-1,) vector, time path of the wages
    ind           = (S,) vector, integers from 0 to S
    bn_args       = length 14 tuple, arguments to be passed to
                    solve_bn_path()
    cpath         = (S, T2+S-1) matrix, time path of distribution of
                    individual consumption c_{s,t}
    npath         = (S, T2+S-1) matrix, time path of distribution of
                    individual labor supply n_{s,t}
    bpath         = (S, T2+S-1) matrix, time path of distribution of
                    individual savings b_{s,t}
    n_err_path    = (S, T2+S-1) matrix, time path of distribution of
                    individual labor supply Euler errors
    b_err_path    = (S, T2+S-1) matrix, time path of distribution of
                    individual savings Euler errors. First column and
                    first row are identically zero
    bSp1_err_path = (S, T2) matrix, residual last period savings, which
                    should be close to zero in equilibrium. Nonzero
                    elements of matrix should only be in first column
                    and first row
    Kpath_new     = (T2+S-1,) vector, new path of the aggregate capital
                    stock implied by household and firm optimization
    Kpath_cnstr   = (T2+S-1,) Boolean vector, =True if K_t<=0
    Lpath_new     = (T2+S-1,) vector, new path of the aggregate labor
    rpath_new     = (T2+S-1,) vector, updated time path of interest rate
    wpath_new     = (T2+S-1,) vector, updated time path of the wages
    Ypath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    output (GDP) Y_t
    Cpath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    consumption C_t
    RCerrPath     = (T2+S-2,) vector, equilibrium time path of the
                    resource constraint error:
                    Y_t - C_t - K_{t+1} + (1-delta)*K_t
    Kpath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    capital stock K_t
    Lpath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    labor L_t
    tpi_time      = scalar, time to compute TPI solution (seconds)
    tpi_output    = length 14 dictionary, {cpath, npath, bpath, wpath,
                    rpath, Kpath, Lpath, Ypath, Cpath, bSp1_err_path,
                    n_err_path, b_err_path, RCerrPath, tpi_time}

    FILES CREATED BY THIS FUNCTION:
        Kpath.png
        Lpath.png
        Ypath.png
        C_aggr_path.png
        wpath.png
        rpath.png
        cpath.png
        npath.png
        bpath.png

    RETURNS: tpi_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    (S, T1, T2, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec, A, alpha,
     delta, r_ss, K_ss, L_ss, C_ss, b_ss, n_ss, maxiter, Out_Tol, In_Tol,
     EulDiff, xi) = args
    K1, K1_cnstr = aggr.get_K(bvec1)

    # Create time path for r
    rpath_init = np.zeros(T2 + S - 1)
    rpath_init[:T1] = get_path(r_ss, r_ss, T1, 'quadratic')
    rpath_init[T1:] = r_ss

    iter_TPI = int(0)
    dist = 10.0
    rw_params = (A, alpha, delta)
    Y_params = (A, alpha)
    cnb_args = (S, T2, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec,
                bvec1, n_ss, In_Tol, EulDiff)
    while (iter_TPI < maxiter) and (dist >= Out_Tol):
        iter_TPI += 1
        rpath = rpath_init
        wpath = firms.get_w(rpath_init, rw_params)
        cpath, npath, bpath, n_err_path, b_err_path = \
            inner_loop(rpath, wpath, cnb_args)
        Kpath_new = np.zeros(T2 + S - 1)
        Kpath_new[:T2], Kpath_cstr = aggr.get_K(bpath[:, :T2])
        Kpath_new[T2:] = K_ss
        Kpath_cstr = np.append(Kpath_cstr, np.zeros(S - 1, dtype=bool))
        Lpath_new = np.zeros(T2 + S - 1)
        Lpath_new[:T2], Lpath_cstr = aggr.get_L(npath[:, :T2])
        Lpath_new[T2:] = L_ss
        Lpath_cstr = np.append(Lpath_cstr, np.zeros(S - 1, dtype=bool))
        rpath_new = firms.get_r(Kpath_new, Lpath_new, rw_params)
        wpath = firms.get_w(rpath_new, rw_params)
        Ypath = aggr.get_Y(Kpath_new, Lpath_new, Y_params)
        Cpath = np.zeros(T2 + S - 1)
        Cpath[:T2] = aggr.get_C(cpath[:, :T2])
        Cpath[T2:] = C_ss
        RCerrPath = (Ypath[:-1] - Cpath[:-1] - Kpath_new[1:] +
                     (1 - delta) * Kpath_new[:-1])
        # Check the distance of rpath_new
        dist = (np.absolute(rpath_new[:T2] - rpath_init[:T2])).sum()
        print(
            'TPI iter: ', iter_TPI, ', dist: ', "%10.4e" % (dist),
            ', max abs all errs: ', "%10.4e" % (np.absolute(
                np.hstack(
                    (b_err_path.max(axis=0), n_err_path.max(axis=0)))).max()))
        # The resource constraint does not bind across the transition
        # path until the equilibrium is solved
        rpath_init[:T2] = (xi * rpath_new[:T2] + (1 - xi) * rpath_init[:T2])
    if (iter_TPI == maxiter) and (dist > Out_Tol):
        print('TPI reached maxiter and did not converge.')
    elif (iter_TPI == maxiter) and (dist <= Out_Tol):
        print('TPI converged in the last iteration. ' +
              'Should probably increase maxiter_TPI.')
    Kpath = Kpath_new
    Lpath = Lpath_new

    tpi_time = time.clock() - start_time

    tpi_output = {
        'cpath': cpath,
        'npath': npath,
        'bpath': bpath,
        'wpath': wpath,
        'rpath': rpath,
        'Kpath': Kpath,
        'Lpath': Lpath,
        'Ypath': Ypath,
        'Cpath': Cpath,
        'n_err_path': n_err_path,
        'b_err_path': b_err_path,
        'RCerrPath': RCerrPath,
        'tpi_time': tpi_time
    }

    # Print maximum resource constraint error. Only look at resource
    # constraint up to period T2 - 1 because period T2 includes K_{t+1},
    # which was forced to be the steady-state
    print('Max abs. RC error: ',
          "%10.4e" % (np.absolute(RCerrPath[:T2 - 1]).max()))

    # Print TPI computation time
    utils.print_time(tpi_time, 'TPI')

    if graphs:
        graph_args = (S, T2)
        create_graphs(tpi_output, graph_args)

    return tpi_output
Esempio n. 18
0
def get_SS_bsct(init_vals, args, graphs=False):
    '''
    --------------------------------------------------------------------
    Solve for the steady-state solution of the S-period-lived agent OG
    model with endogenous labor supply using the bisection method for
    the outer loop
    --------------------------------------------------------------------
    INPUTS:
    init_vals = length 3 tuple, (Kss_init, Lss_init, c1_init)
    args      = length 15 tuple, (J, S, lambdas, emat, beta, sigma,
                l_tilde, b_ellip, upsilon, chi_n_vec, A, alpha, delta,
                SS_tol, EulDiff)
    graphs    = boolean, =True if output steady-state graphs

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        firms.get_r()
        firms.get_w()
        hh.bn_solve()
        hh.c1_bSp1err()
        hh.get_cnb_vecs()
        aggr.get_K()
        aggr.get_L()
        aggr.get_Y()
        aggr.get_C()
        hh.get_cons()
        hh.get_n_errors()
        hh.get_b_errors()
        utils.print_time()

    OBJECTS CREATED WITHIN FUNCTION:
    start_time   = scalar > 0, clock time at beginning of program
    Kss_init     = scalar > 0, initial guess for steady-state aggregate
                   capital stock
    Lss_init     = scalar > 0, initial guess for steady-state aggregate
                   labor
    rss_init     = scalar > 0, initial guess for steady-state interest
                   rate
    wss_init     = scalar > 0, initial guess for steady-state wage
    c1_init      = scalar > 0, initial guess for first period consumpt'n
    S            = integer in [3, 80], number of periods an individual
                   lives
    beta         = scalar in (0,1), discount factor for each model per
    sigma        = scalar > 0, coefficient of relative risk aversion
    l_tilde      = scalar > 0, time endowment for each agent each period
    b_ellip      = scalar > 0, fitted value of b for elliptical
                   disutility of labor
    upsilon      = scalar > 1, fitted value of upsilon for elliptical
                   disutility of labor
    chi_n_vec    = (S,) vector, values for chi^n_s
    A            = scalar > 0, total factor productivity parameter in
                   firms' production function
    alpha        = scalar in (0,1), capital share of income
    delta        = scalar in [0,1], model-period depreciation rate of
                   capital
    SS_tol       = scalar > 0, tolerance level for steady-state fsolve
    EulDiff      = Boolean, =True if want difference version of Euler
                   errors beta*(1+r)*u'(c2) - u'(c1), =False if want
                   ratio version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1
    hh_fsolve    = boolean, =True if solve inner-loop household problem
                   by choosing c_1 to set final period savings b_{S+1}=0
    KL_outer     = boolean, =True if guess K and L in outer loop
                   Otherwise, guess r and w in outer loop
    maxiter_SS   = integer >= 1, maximum number of iterations in outer
                   loop bisection method
    iter_SS      = integer >= 0, index of iteration number
    mindist_SS   = scalar > 0, minimum distance tolerance for
                   convergence
    dist_SS      = scalar > 0, distance metric for current iteration
    xi_SS        = scalar in (0,1], updating parameter
    KL_init      = (2,) vector, (K_init, L_init)
    c1_options   = length 1 dict, options to pass into
                   opt.root(c1_bSp1err,...)
    cnb_args     = length 8 tuple, args to pass into get_cnb_vecs()
    r_params     = length 3 tuple, args to pass into get_r()
    w_params     = length 2 tuple, args to pass into get_w()
    K_init       = scalar, initial value of aggregate capital stock
    L_init       = scalar, initial value of aggregate labor
    r_init       = scalar, initial value for interest rate
    w_init       = scalar, initial value for wage
    rpath        = (S,) vector, lifetime path of interest rates
    wpath        = (S,) vector, lifetime path of wages
    c1_args      = length 10 tuple, args to pass into c1_bSp1err()
    results_c1   = results object, root finder results from
                   opt.root(c1_bSp1err,...)
    c1_new       = scalar, updated value of optimal c1 given r_init and
                   w_init
    cvec_new     = (S,) vector, updated values for lifetime consumption
    nvec_new     = (S,) vector, updated values for lifetime labor supply
    bvec_new     = (S,) vector, updated values for lifetime savings
                   (b1, b2,...bS)
    b_Sp1_new    = scalar, updated value for savings in last period,
                   should be arbitrarily close to zero
    K_new        = scalar, updated K given bvec_new
    K_cnstr      = boolean, =True if K_new <= 0
    L_new        = scalar, updated L given nvec_new
    KL_new       = (2,) vector, updated K and L given bvec_new, nvec_new
    K_ss         = scalar > 0, steady-state aggregate capital stock
    L_ss         = scalar > 0, steady-state aggregate labor
    r_ss         = scalar > 0, steady-state interest rate
    w_ss         = scalar > 0, steady-state wage
    c1_ss        = scalar > 0, steady-state consumption in first period
    c_ss         = (S,) vector, steady-state lifetime consumption
    n_ss         = (S,) vector, steady-state lifetime labor supply
    b_ss         = (S,) vector, steady-state lifetime savings
                   (b1_ss, b2_ss, ...bS_ss) where b1_ss=0
    b_Sp1_ss     = scalar, steady-state savings for period after last
                   period of life. b_Sp1_ss approx. 0 in equilibrium
    Y_params     = length 2 tuple, (A, alpha)
    Y_ss         = scalar > 0, steady-state aggregate output (GDP)
    C_ss         = scalar > 0, steady-state aggregate consumption
    n_err_params = length 5 tuple, args to pass into get_n_errors()
    n_err_ss     = (S,) vector, lifetime labor supply Euler errors
    b_err_params = length 2 tuple, args to pass into get_b_errors()
    b_err_ss     = (S-1) vector, lifetime savings Euler errors
    RCerr_ss     = scalar, resource constraint error
    ss_time      = scalar, seconds elapsed to run steady-state comput'n
    ss_output    = length 14 dict, steady-state objects {n_ss, b_ss,
                   c_ss, b_Sp1_ss, w_ss, r_ss, K_ss, L_ss, Y_ss, C_ss,
                   n_err_ss, b_err_ss, RCerr_ss, ss_time}

    FILES CREATED BY THIS FUNCTION:
        SS_bc.png
        SS_n.png

    RETURNS: ss_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    Kss_init, Lss_init, c1_init = init_vals
    (J, S, lambdas, emat, beta, sigma, l_tilde, b_ellip, upsilon,
        chi_n_vec, A, alpha, delta, SS_tol, EulDiff) = args
    maxiter_SS = 200
    iter_SS = 0
    mindist_SS = 1e-12
    dist_SS = 10
    xi_SS = 0.2
    KL_init = np.array([Kss_init, Lss_init])
    c1_options = {'maxiter': 500}
    r_params = (A, alpha, delta)
    w_params = (A, alpha)
    while (iter_SS < maxiter_SS) and (dist_SS >= mindist_SS):
        iter_SS += 1
        K_init, L_init = KL_init
        r_init = firms.get_r(r_params, K_init, L_init)
        w_init = firms.get_w(w_params, K_init, L_init)
        rpath = r_init * np.ones(S)
        wpath = w_init * np.ones(S)
        cmat = np.zeros((S, J))
        nmat = np.zeros((S, J))
        bmat = np.zeros((S, J))
        b_Sp1_vec = np.zeros(J)
        for j in range(J):
            c1_args = (0.0, emat[:, j], beta, sigma, l_tilde, b_ellip,
                       upsilon, chi_n_vec, rpath, wpath, EulDiff)
            results_c1 = \
                opt.root(hh.c1_bSp1err, c1_init, args=(c1_args),
                         method='lm', tol=SS_tol, options=(c1_options))
            c1 = results_c1.x
            cnb_args = (0.0, emat[:, j], beta, sigma, l_tilde, b_ellip,
                        upsilon, chi_n_vec, EulDiff)
            cmat[:, j], nmat[:, j], bmat[:, j], b_Sp1_vec[j] = \
                hh.get_cnb_vecs(c1, rpath, wpath, cnb_args)
        K_new, K_cnstr = aggr.get_K(bmat, lambdas)
        L_new = aggr.get_L(nmat, emat, lambdas)
        KL_new = np.array([K_new, L_new])
        dist_SS = ((KL_new - KL_init) ** 2).sum()
        KL_init = xi_SS * KL_new + (1 - xi_SS) * KL_init
        print('SS Iteration=', iter_SS, ', SS Distance=',
              '%10.4e' % (dist_SS), ',K:', '%10.4e' % (K_new),
              'L:', '%10.4e' % (L_new))

    K_ss, L_ss = KL_init
    r_ss = firms.get_r(r_params, K_ss, L_ss)
    w_ss = firms.get_w(w_params, K_ss, L_ss)
    c_ss = cmat
    n_ss = nmat
    b_ss = bmat
    b_Sp1_ss = b_Sp1_vec
    Y_params = (A, alpha)
    Y_ss = aggr.get_Y(Y_params, K_ss, L_ss)
    C_ss = aggr.get_C(c_ss, lambdas)
    n_err_ss = np.zeros((S, J))
    b_err_ss = np.zeros((S - 1, J))
    for j in range(J):
        n_err_params = (emat[:, j], sigma, l_tilde, chi_n_vec, b_ellip,
                        upsilon)
        n_err_ss[:, j] = hh.get_n_errors(n_err_params, w_ss, c_ss[:, j],
                                         n_ss[:, j], EulDiff)
        b_err_params = (beta, sigma)
        b_err_ss[:, j] = hh.get_b_errors(b_err_params, r_ss, c_ss[:, j],
                                         EulDiff)
    RCerr_ss = Y_ss - C_ss - delta * K_ss

    ss_time = time.clock() - start_time

    ss_output = {
        'n_ss': n_ss, 'b_ss': b_ss, 'c_ss': c_ss, 'b_Sp1_ss': b_Sp1_ss,
        'w_ss': w_ss, 'r_ss': r_ss, 'K_ss': K_ss, 'L_ss': L_ss,
        'Y_ss': Y_ss, 'C_ss': C_ss, 'n_err_ss': n_err_ss,
        'b_err_ss': b_err_ss, 'RCerr_ss': RCerr_ss, 'ss_time': ss_time}
    print('K_ss=', K_ss, ', L_ss=', L_ss)
    print('r_ss=', r_ss, ', w_ss=', w_ss)
    print('Maximum abs. labor supply Euler error is: ',
          np.absolute(n_err_ss).max())
    print('Maximum abs. savings Euler error is: ',
          np.absolute(b_err_ss).max())
    print('Resource constraint error is: ', RCerr_ss)
    print('Max. absolute SS residual savings b_Sp1_j is: ',
          np.absolute(b_Sp1_ss).max())

    # Print SS computation time
    utils.print_time(ss_time, 'SS')

    if graphs:
        '''
        ----------------------------------------------------------------
        cur_path    = string, path name of current directory
        output_fldr = string, folder in current path to save files
        output_dir  = string, total path of images folder
        output_path = string, path of file name of figure to be saved
        sgrid       = (S,) vector, ages from 1 to S
        lamcumsum   = (J,) vector, cumulative sum of lambdas vector
        jmidgrid    = (J,) vector, midpoints of ability percentile bins
        smat        = (J, S) matrix, sgrid copied down J rows
        jmat        = (J, S) matrix, jmidgrid copied across S columns
        ----------------------------------------------------------------
        '''
        # Create directory if images directory does not already exist
        cur_path = os.path.split(os.path.abspath(__file__))[0]
        output_fldr = 'images'
        output_dir = os.path.join(cur_path, output_fldr)
        if not os.access(output_dir, os.F_OK):
            os.makedirs(output_dir)

        # Plot 3D steady-state consumption distribution
        sgrid = np.arange(1, S + 1)
        lamcumsum = lambdas.cumsum()
        jmidgrid = 0.5 * lamcumsum + 0.5 * (lamcumsum - lambdas)
        smat, jmat = np.meshgrid(sgrid, jmidgrid)
        cmap_c = cm.get_cmap('summer')
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'ability-$j$')
        ax.set_zlabel(r'indiv. consumption $c_{j,s}$')
        ax.plot_surface(smat, jmat, c_ss.T, rstride=1,
                        cstride=6, cmap=cmap_c)
        output_path = os.path.join(output_dir, 'c_ss_3D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot 2D steady-state consumption distribution
        minorLocator = MultipleLocator(1)
        fig, ax = plt.subplots()
        linestyles = np.array(["-", "--", "-.", ":"])
        markers = np.array(["x", "v", "o", "d", ">", "|"])
        pct_lb = 0
        for j in range(J):
            this_label = (str(int(np.rint(pct_lb))) + " - " +
                          str(int(np.rint(pct_lb + 100 * lambdas[j]))) +
                          "%")
            pct_lb += 100 * lambdas[j]
            if j <= 3:
                ax.plot(sgrid, c_ss[:, j], label=this_label,
                        linestyle=linestyles[j], color='black')
            elif j > 3:
                ax.plot(sgrid, c_ss[:, j], label=this_label,
                        marker=markers[j - 4], color='black')
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        box = ax.get_position()
        ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
        ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'indiv. consumption $c_{j,s}$')
        output_path = os.path.join(output_dir, 'c_ss_2D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()


        # Plot 3D steady-state labor supply distribution
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'ability-$j$')
        ax.set_zlabel(r'labor supply $n_{j,s}$')
        ax.plot_surface(smat, jmat, n_ss.T, rstride=1,
                        cstride=6, cmap=cmap_c)
        output_path = os.path.join(output_dir, 'n_ss_3D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot 2D steady-state labor supply distribution
        minorLocator = MultipleLocator(1)
        fig, ax = plt.subplots()
        linestyles = np.array(["-", "--", "-.", ":"])
        markers = np.array(["x", "v", "o", "d", ">", "|"])
        pct_lb = 0
        for j in range(J):
            this_label = (str(int(np.rint(pct_lb))) + " - " +
                          str(int(np.rint(pct_lb + 100 * lambdas[j]))) +
                          "%")
            pct_lb += 100 * lambdas[j]
            if j <= 3:
                ax.plot(sgrid, n_ss[:, j], label=this_label,
                        linestyle=linestyles[j], color='black')
            elif j > 3:
                ax.plot(sgrid, n_ss[:, j], label=this_label,
                        marker=markers[j - 4], color='black')
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        box = ax.get_position()
        ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
        ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'labor supply $n_{j,s}$')
        output_path = os.path.join(output_dir, 'n_ss_2D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()


        # Plot 3D steady-state savings/wealth distribution
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'ability-$j$')
        ax.set_zlabel(r'indiv. savings $b_{j,s}$')
        ax.plot_surface(smat, jmat, b_ss.T, rstride=1,
                        cstride=6, cmap=cmap_c)
        output_path = os.path.join(output_dir, 'b_ss_3D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot 2D steady-state savings/wealth distribution
        fig, ax = plt.subplots()
        linestyles = np.array(["-", "--", "-.", ":"])
        markers = np.array(["x", "v", "o", "d", ">", "|"])
        pct_lb = 0
        for j in range(J):
            this_label = (str(int(np.rint(pct_lb))) + " - " +
                          str(int(np.rint(pct_lb + 100 * lambdas[j]))) +
                          "%")
            pct_lb += 100 * lambdas[j]
            if j <= 3:
                ax.plot(sgrid, b_ss[:, j], label=this_label,
                        linestyle=linestyles[j], color='black')
            elif j > 3:
                ax.plot(sgrid, b_ss[:, j], label=this_label,
                        marker=markers[j - 4], color='black')
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        box = ax.get_position()
        ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
        ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
        ax.set_xlabel(r'age-$s$')
        ax.set_ylabel(r'indiv. savings $b_{j,s}$')
        output_path = os.path.join(output_dir, 'b_ss_2D')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

    return ss_output
Esempio n. 19
0
    b_ss = ss_output['b_ss']
    n_ss = ss_output['n_ss']
    chi_n_vec = ss_output['chi_n_vec']

    # Choose initial period distribution of wealth (bvec1), which
    # determines initial period aggregate capital stock
    ub_factor = 1.04
    lb_factor = 0.98
    init_wgts_vec = ((ub_factor - lb_factor) / (S - 1) *
                     (np.linspace(1, S, S) - 1) + lb_factor)
    init_wgts = np.tile(init_wgts_vec.reshape((S, 1)), (1, J))
    bmat1 = init_wgts * b_ss

    # Make sure init. period distribution is feasible in terms of K
    K_args = (lambdas, omega_preTP, imm_rates, g_n_path[0])
    K1, K1_cstr = aggr.get_K(bmat1, K_args)

    # If initial bvec1 is not feasible end program
    if K1_cstr:
        print('Initial savings distribution is not feasible because ' +
              'K1<=0. Some element(s) of bmat1 must increase.')
    else:
        tpi_params = (J, E, S, T1, T2, lambdas, emat, mort_rates,
                      imm_rates_mat, omega_path, omega_preTP, g_n_path,
                      zeta_mat, chi_n_vec, chi_b_vec, beta, sigma, l_tilde,
                      b_ellip, upsilon, g_y, Z, gamma, delta, r_ss, BQ_ss,
                      K_ss, K1, L_ss, C_ss, NX_ss, b_ss, n_ss, TPI_maxiter,
                      TPI_OutTol, TPI_InTol, xi_TPI)
        tpi_output = tpi.get_TPI(bmat1, tpi_params, TPI_graphs)

        tpi_args = (J, E, S, T1, T2, lambdas, emat, mort_rates, imm_rates_mat,
Esempio n. 20
0
def get_SS(bss_guess, args, graphs=False):
    '''
    --------------------------------------------------------------------
    Solve for the steady-state solution of the S-period-lived agent OG
    model with exogenous labor supply using one root finder in bvec
    --------------------------------------------------------------------
    INPUTS:
    bss_guess = (S-1,) vector, initial guess for b_ss
    args      = length 8 tuple,
                (nvec, beta, sigma, A, alpha, delta, SS_tol, SS_EulDiff)
    graphs    = boolean, =True if output steady-state graphs

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        SS_EulErrs()
        aggr.get_K()
        aggr.get_L()
        aggr.get_Y()
        aggr.get_C()
        firms.get_r()
        firms.get_w()
        hh.get_cons()
        utils.print_time()
        get_ss_graphs()

    OBJECTS CREATED WITHIN FUNCTION:
    start_time = scalar > 0, clock time at beginning of program
    nvec       = (S,) vector, exogenous lifetime labor supply n_s
    beta       = scalar in (0,1), discount factor for each model per
    sigma      = scalar > 0, coefficient of relative risk aversion
    A          = scalar > 0, total factor productivity parameter in
                 firms' production function
    alpha      = scalar in (0,1), capital share of income
    delta      = scalar in [0,1], model-period depreciation rate of
                 capital
    SS_tol     = scalar > 0, tolerance level for steady-state fsolve
    SS_EulDiff = Boolean, =True if want difference version of Euler
                 errors beta*(1+r)*u'(c2) - u'(c1), =False if want ratio
                 version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1
    b_args     = length 7 tuple, args passed to opt.root(SS_EulErrs,...)
    results_b  = results object, output from opt.root(SS_EulErrs,...)
    b_ss       = (S-1,) vector, steady-state savings b_{s+1}
    K_ss       = scalar > 0, steady-state aggregate capital stock
    Kss_cstr   = boolean, =True if K_ss < epsilon
    L          = scalar > 0, exogenous aggregate labor
    r_params   = length 3 tuple, (A, alpha, delta)
    r_ss       = scalar > 0, steady-state interest rate
    w_params   = length 2 tuple, (A, alpha)
    w_ss       = scalar > 0, steady-state wage
    c_args     = length 3 tuple, (nvec, r_ss, w_ss)
    c_ss       = (S,) vector, steady-state individual consumption c_s
    Y_params   = length 2 tuple, (A, alpha)
    Y_ss       = scalar > 0, steady-state aggregate output (GDP)
    C_ss       = scalar > 0, steady-state aggregate consumption
    b_err_ss   = (S-1,) vector, Euler errors associated with b_ss
    RCerr_ss   = scalar, steady-state resource constraint error
    ss_time    = scalar > 0, time elapsed during SS computation
                 (in seconds)
    ss_output  = length 10 dict, steady-state objects {b_ss, c_ss, w_ss,
                 r_ss, K_ss, Y_ss, C_ss, b_err_ss, RCerr_ss, ss_time}

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: ss_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    nvec, beta, sigma, A, alpha, delta, SS_tol, SS_EulDiff = args
    b_args = (nvec, beta, sigma, A, alpha, delta, SS_EulDiff)
    results_b = opt.root(SS_EulErrs, bss_guess, args=(b_args))
    b_ss = results_b.x
    K_ss, Kss_cstr = aggr.get_K(b_ss)
    L = aggr.get_L(nvec)
    r_params = (A, alpha, delta)
    r_ss = firms.get_r(K_ss, L, r_params)
    w_params = (A, alpha)
    w_ss = firms.get_w(K_ss, L, w_params)
    c_args = (nvec, r_ss, w_ss)
    c_ss = hh.get_cons(b_ss, 0.0, c_args)
    Y_params = (A, alpha)
    Y_ss = aggr.get_Y(K_ss, L, Y_params)
    C_ss = aggr.get_C(c_ss)
    b_err_ss = results_b.fun
    RCerr_ss = Y_ss - C_ss - delta * K_ss

    ss_time = time.clock() - start_time

    ss_output = {
        'b_ss': b_ss,
        'c_ss': c_ss,
        'w_ss': w_ss,
        'r_ss': r_ss,
        'K_ss': K_ss,
        'Y_ss': Y_ss,
        'C_ss': C_ss,
        'b_err_ss': b_err_ss,
        'RCerr_ss': RCerr_ss,
        'ss_time': ss_time
    }
    print('b_ss is: ', b_ss)
    print('K_ss=', K_ss, ', r_ss=', r_ss, ', w_ss=', w_ss)
    print('Max. abs. savings Euler error is: ', np.absolute(b_err_ss).max())
    print('Max. abs. resource constraint error is: ',
          np.absolute(RCerr_ss).max())

    # Print SS computation time
    utils.print_time(ss_time, 'SS')

    if graphs:
        get_ss_graphs(c_ss, b_ss)

    return ss_output
Esempio n. 21
0
def inner_loop(r, w, Y, x, params):
    '''
    --------------------------------------------------------------------
    Given values for r and w, solve for equilibrium errors from the two
    first order conditions of the firm
    --------------------------------------------------------------------
    INPUTS:
    r      = scalar > 0, guess at steady-state interest rate
    w      = scalar > 0, guess at steady-state wage
    Y      = scalar > 0, guess steady-state output
    x      = scalar > 0, guess as steady-state transfers per household
    params = length 16 tuple, (c1_init, S, beta, sigma, l_tilde, b_ellip,
                               upsilon, chi_n_vec, A, alpha, delta, tax_params,
                               fiscal_params, diff, hh_fsolve, SS_tol)


    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        hh.bn_solve()
        hh.c1_bSp1err()
        hh.get_cnb_vecs()
        aggr.get_K()
        aggr.get_L()
        firms.get_r()
        firms.get_w()

    OBJECTS CREATED WITHIN FUNCTION:
    c1_init       = scalar > 0, initial guess for c1
    S             = integer >= 3, number of periods in individual lifetime
    beta          = scalar in (0,1), discount factor
    sigma         = scalar >= 1, coefficient of relative risk aversion
    l_tilde       = scalar > 0, per-period time endowment for every agent
    b_ellip       = scalar > 0, fitted value of b for elliptical disutility
                    of labor
    upsilon       = scalar > 1, fitted value of upsilon for elliptical
                    disutility of labor
    chi_n_vec     = (S,) vector, values for chi^n_s
    A             = scalar > 0, total factor productivity parameter in
                    firms' production function
    alpha         = scalar in (0,1), capital share of income
    delta         = scalar in [0,1], model-period depreciation rate of
                    capital
    tax_params    = length 3 tuple, (tau_l, tau_k, tau_c)
    fiscal_params = length 7 tuple, (tG1, tG2, alpha_X, alpha_G, rho_G,
                                     alpha_D, alpha_D0)
    diff          = boolean, =True if simple difference Euler errors,
                    otherwise percent deviation Euler errors
    hh_fsolve     = boolean, =True if solve inner-loop household problem by
                    choosing c_1 to set final period savings b_{S+1}=0.
                    Otherwise, solve the household problem as multivariate
                    root finder with 2S-1 unknowns and equations
    SS_tol        = scalar > 0, tolerance level for steady-state fsolve
    tau_l         = scalar, marginal tax rate on labor income
    tau_k         = scalar, marginal tax rate on capital income
    tau_c         = scalar, marginal tax rate on corporate income
    tG1           = integer, model period when budget closure rule begins
    tG2           = integer, model period when budget is closed
    alpha_X       = scalar, ratio of lump sum transfers to GDP
    alpha_G       = scalar, ratio of government spending to GDP prior to
                            budget closure rule beginning
    rho_G         = scalar in (0,1), rate of convergence to SS budget
    alpha_D       = scalar, steady-state debt to GDP ratio
    alpha_D0      = scalar, debt to GDP ratio in the initial period
    r_params      = length 3 tuple, args to pass into get_r()
    w_params      = length 2 tuple, args to pass into get_w()
    Y_params      = length 2 tuple, args to pass into get_Y()
    b_init        = (S-1,) vector, initial guess at distribution of savings
    n_init        = (S,) vector, initial guess at distribution of labor supply
    guesses       = (2S-1,) vector, initial guesses at b and n
    bn_params     = length 12 tuple, parameters to pass to solve_bn_path()
                    (r, w, x, S, beta, sigma, l_tilde,
                        b_ellip, upsilon, chi_n_vec, tax_params, diff)
    euler_errors  = (2S-1,) vector, Euler errors for FOCs for b and n
    b_splus1_vec  = (S,) vector, optimal savings choice
    nvec          = (S,) vector, optimal labor supply choice
    b_Sp1         = scalar, last period savings
    b_s_vec       = (S,) vector, wealth enter period with
    cvec          = (S,) vector, optimal consumption
    rpath         = (S,) vector, lifetime path of interest rates
    wpath         = (S,) vector, lifetime path of wages
    c1_args       = length 10 tuple, args to pass into c1_bSp1err()
    c1_options    = length 1 dict, options for c1_bSp1err()
    results_c1    = results object, results from c1_bSp1err()
    c1            = scalar > 0, optimal initial period consumption given r
                    and w
    cnb_args      = length 8 tuple, args to pass into get_cnb_vecs()
    cvec          = (S,) vector, lifetime consumption (c1, c2, ...cS)
    nvec          = (S,) vector, lifetime labor supply (n1, n2, ...nS)
    bvec          = (S,) vector, lifetime savings (b1, b2, ...bS) with b1=0
    b_Sp1         = scalar, final period savings, should be close to zero
    B             = scalar > 0, aggregate savings
    B_cnstr       = boolean, =True if B < 0
    L             = scalar > 0, aggregate labor
    debt          = scalar, total government debt
    K             = scalar > 0, aggregate capital stock
    K_cnstr       = boolean, =True if K < 0
    r_new         = scalar > 0, implied steady-state interest rate
    w_new         = scalar > 0, implied steady-state wage
    Y_new         = scalar >0, implied steady-state output
    x_new         = scalar >=0, implied transfers per household


    FILES CREATED BY THIS FUNCTION: None

    RETURNS: B, K, L, Y_new, debt, cvec, nvec, b_s_vec, b_splus1_vec,
                b_Sp1, x_new, r_new, w_new
    --------------------------------------------------------------------
    '''
    c1_init, S, beta, sigma, l_tilde, b_ellip, upsilon,\
        chi_n_vec, A, alpha, delta, tax_params, fiscal_params,\
        diff, hh_fsolve, SS_tol = params
    tau_l, tau_k, tau_c = tax_params
    tG1, tG2, alpha_X, alpha_G, rho_G, alpha_D, alpha_D0 = fiscal_params

    r_params = (A, alpha, delta, tau_c)
    w_params = (A, alpha)
    Y_params = (A, alpha)

    if hh_fsolve:
        b_init = np.ones((S - 1, 1)) * 0.05
        n_init = np.ones((S, 1)) * 0.4
        guesses = np.append(b_init, n_init)
        bn_params = (r, w, x, S, beta, sigma, l_tilde, b_ellip, upsilon,
                     chi_n_vec, tax_params, diff)
        [solutions, infodict, ier, message] = \
            opt.fsolve(hh.bn_solve, guesses, args=bn_params,
                       xtol=SS_tol, full_output=True)
        euler_errors = infodict['fvec']
        print('Max Euler errors: ', np.absolute(euler_errors).max())
        b_splus1_vec = np.append(solutions[:S - 1], 0.0)
        nvec = solutions[S - 1:]
        b_Sp1 = 0.0
        b_s_vec = np.append(0.0, b_splus1_vec[:-1])
        cvec = hh.get_cons(r, w, b_s_vec, b_splus1_vec, nvec, x, tax_params)
    else:
        rpath = r * np.ones(S)
        wpath = w * np.ones(S)
        xpath = x * np.ones(S)
        c1_options = {'maxiter': 500}
        c1_args = (0.0, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec,
                   tax_params, xpath, rpath, wpath, diff)
        results_c1 = \
            opt.root(hh.c1_bSp1err, c1_init, args=(c1_args),
                     method='lm', tol=SS_tol,
                     options=(c1_options))
        c1_new = results_c1.x
        cnb_args = (0.0, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec,
                    tax_params, diff)
        cvec, nvec, b_s_vec, b_Sp1 = \
            hh.get_cnb_vecs(c1_new, rpath, wpath, xpath, cnb_args)
        b_splus1_vec = np.append(b_s_vec[1:], b_Sp1)

    B, B_cnstr = aggr.get_K(b_s_vec)
    L = aggr.get_L(nvec)
    L = np.maximum(0.0001, L)
    debt = alpha_D * Y
    K = B - debt
    K_cnstr = K < 0
    if K_cnstr:
        print('Aggregate capital constraint is violated K<=0 for ' +
              'in the steady state.')
    r_new = firms.get_r(r_params, K, L)
    w_new = firms.get_w(w_params, K, L)
    Y_new = aggr.get_Y(Y_params, K, L)
    x_new = (alpha_X * Y_new) / S


    return B, K, L, Y_new, debt, cvec, nvec, b_s_vec, b_splus1_vec, \
                b_Sp1, x_new, r_new, w_new
Esempio n. 22
0
def solve_tp(g_n_path, omega_S_preTP, rho_s, imm_rates_path, params):
    '''
    Solves for the time path equilibrium using TPI
    '''
    # Missing some elements of params
    b_ss, r_11, T, S = params
    dist = 8.0
    mindist = 1e-08
    maxiter = 300
    tpi_iter = 0
    xi = 0.2
    while dist > mindist and tpi_iter < maxiter:

        # Define paths
        b_11 = 1.1 * b_ss
        BQ_params = (g_n_path[0], omega_S_preTP, rho_s)
        K_params = (g_n_path[0], omega_S_preTP, imm_rates_path[0, :])
        BQ_11 = agg.get_BQ(b_11, r_11, BQ_params)
        K_11 = agg.get_K(b_11, K_params)
        BQpath_init = np.zeros(T + S - 1)
        BQpath_init[:T] = np.linspace(BQ_11, BQ_ss, T)
        BQpath_init[T:] = BQ_ss
        r_11 = firm.get_r(K_11, L_ss, r_params)
        r_path = firm.get_r(L_ss, r_params)
        w_path = firm.get_w(L_ss, w_params)
        bmat = np.zeros((S - 1, T + S - 1))
        bmat[:, 0] = b_1

        # Solve for households
        for p in range(2, S):
            b_guess = np.diagonal(bmat[S - p:, :p - 1])
            b_init = bmat[S - p - 1, 0]
            b_params = (b_init, n[-p:], r_path[:p], w_path[:p],
                        BQpath_init[:p], rho_s[-p:], beta, sigma)
            results_bp = opt.root(hh.FOCs, b_guess, args=(b_params))
            b_solve_p = results_bp.x
            DiagMaskbp = np.eye(p - 1, dtype=bool)
            bmat[S - p:, 1:p] = DiagMaskbp * b_solve_p + bmat[S - p:, 1:p]

        for t in range(1, T + 1):
            b_guess = np.diagonal(bmat[:, t - 1:t + S - 2])
            b_init = 0.0
            b_params = (b_init, n, r_path[t - 1:t + S - 1],
                        w_path[t - 1:t + S - 1], BQpath_init[t - 1:t + S - 1],
                        rho_s, beta, sigma)
            results_bt = opt.root(hh.FOCs, b_guess, args=(b_params))
            b_solve_t = results_bt.x
            DiagMaskbt = np.eye(S - 1, dtype=bool)
            bmat[:,
                 t:t + S - 1] = (DiagMaskbt * b_solve_t + bmat[:, t:t + S - 1])

        new_Kpath = np.zeros(T)
        new_Kpath[0] = K_1
        new_Kpath[1:] = \
            (1 / (omega_path_S[:T - 1, :-1]) *
                bmat[:, 1:T].T +
                imm_rates_path[:T - 1, 1:] *
                omega_path_S[:T - 1, 1:] * bmat[:, 1:T].T).sum(axis=1)
        new_BQpath = np.zeros(T)
        new_BQpath[0] = BQ_1
        new_BQpath[1:] = \
            ((1 + r_path[1:T]) / (rho_s[:-1]) *
                omega_path_S[:T - 1, :-1] * bmat[:, 1:T].T).sum(axis=1)

        dist = ((BQ_init - new_BQ)**2).sum()
        BQpath_init[:T] = xi * new_BQpath[:T] + (1 - xi) * BQpath_init[:T]
        # update iteration counter
        tpi_iter += 1

    if tpi_iter < maxiter:
        print('The time path solved! ->', ' iter:', tpi_iter, ', dist: ', dist)
    else:
        print('The time path did not solve.')

    return [new_Kpath, new_BQpath]
Esempio n. 23
0
def get_TPI(bvec1, params, graphs):
    '''
    --------------------------------------------------------------------
    Generates steady-state time path for all endogenous objects from
    initial state (K1, Gamma1) to the steady state.
    --------------------------------------------------------------------
    INPUTS:
    params = length 16 tuple, (S, T, beta, sigma, nvec, A, alpha, delta,
             b_ss, K_ss, C_ss, maxiter_TPI, mindist_TPI, TPI_tol, xi,
             EulDiff)
    bvec1  = (S-1,) vector, initial period distribution of savings
    graphs = Boolean, =True if want graphs of TPI objects

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        c5ssf.get_K()
        get_path()
        c5ssf.get_r()
        c5ssf.get_w()
        get_cbepath()
        c5ssf.get_Y()
        c5ssf.get_C()
        c5ssf.print_time()


    OBJECTS CREATED WITHIN FUNCTION:
    start_time  = scalar, current processor time in seconds (float)
    (S, T, beta, sigma, nvec, A, alpha, delta, b_ss,
                      K_ss, C_ss, maxiter_TPI, mindist_TPI, TPI_tol,
                      xi_TPI, TPI_EulDiff)
    S           = integer in [3,80], number of periods an individual
                  lives
    T           = integer > S, number of time periods until steady
                  state
    beta        = scalar in (0,1), discount factor for model period
    sigma       = scalar > 0, coefficient of relative risk aversion
    nvec        = (S,) vector, exogenous labor supply n_{s,t}
    A           = scalar > 0, total factor productivity parameter in
                  firms' production function
    alpha       = scalar in (0,1), capital share of income
    delta       = scalar in [0,1], model-period depreciation rate of
                  capital
    b_ss        = (S-1,) vector, steady-state distribution of savings
    K_ss        = scalar > 0, steady-state aggregate capital stock
    C_ss        = scalar > 0, steady-state aggregate consumption
    maxiter_TPI = integer >= 1, Maximum number of iterations for TPI
    mindist_TPI = scalar > 0, Convergence criterion for TPI
    TPI_tol     = scalar > 0, tolerance level for fsolve's in TPI
    xi          = scalar in (0,1], TPI path updating parameter
    EulDiff     = Boolean, =True if want difference version of Euler
                  errors beta*(1+r)*u'(c2) - u'(c1), =False if want
                  ratio version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1
    L           = scalar > 0, exogenous aggregate labor
    K1          = scalar > 0, initial aggregate capital stock
    K1_cstr     = boolean, =True if K1 <= 0
    Kpath_init  = (T+S-2,) vector, initial guess for the time path
                  of the aggregate capital stock
    iter_TPI    = integer >= 0, current iteration of TPI
    dist_TPI    = scalar >= 0, distance measure for fixed point
    Kpath_new   = (T+S-2,) vector, new path of the aggregate capital
                  stock implied by household and firm optimization
    r_params    = length 3 tuple, (A, alpha, delta)
    w_params    = length 2 tuple, (A, alpha)
    cbe_params  = length 9 tuple, (S, T, beta, sigma, nvec, bvec1, b_ss,
                  TPI_tol, EulDiff)
    rpath       = (T+S-2,) vector, time path of the interest rate
    wpath       = (T+S-2,) vector, time path of the wage
    cpath       = (S, T+S-2) matrix, time path values of distribution of
                  consumption c_{s,t}
    bpath       = (S-1, T+S-2) matrix, time path of distribution of
                  individual savings b_{s,t}
    EulErrPath  = (S-1, T+S-2) matrix, time path of individual Euler
                  errors corresponding to individual savings b_{s,t}
                  (first column is zeros)
    Kpath_cnstr = (T+S-2,) Boolean vector, =True if K_t<=0
    Kpath       = (T+S-2,) vector, equilibrium time path of aggregate
                  capital stock K_t
    Y_params    = length 2 tuple, (A, alpha)
    Ypath       = (T+S-2,) vector, equilibrium time path of aggregate
                  output (GDP) Y_t
    Cpath       = (T+S-2,) vector, equilibrium time path of aggregate
                  consumption C_t
    RCerrPath   = (T+S-1,) vector, equilibrium time path of the resource
                  constraint error: Y_t - C_t - K_{t+1} + (1-delta)*K_t
    tpi_time    = scalar, time to compute TPI solution (seconds)
    tpi_output  = length 10 dictionary, {bpath, cpath, wpath, rpath,
                  Kpath, Ypath, Cpath, EulErrPath, RCerrPath, tpi_time}

    FILES CREATED BY THIS FUNCTION:
        Kpath.png
        Ypath.png
        Cpath.png
        wpath.png
        rpath.png
        bpath.png
        cpath.png

    RETURNS: tpi_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    (S, T, beta, sigma, nvec, A, alpha, delta, b_ss, K_ss, C_ss,
        maxiter_TPI, mindist_TPI, TPI_tol, xi, EulDiff) = params
    L = aggr.get_L(nvec)
    K1, K1_cstr = aggr.get_K(bvec1)

    # Create time paths for K and L
    Kpath_init = np.zeros(T + S - 2)
    Kpath_init[:T] = get_path(K1, K_ss, T, "quadratic")
    Kpath_init[T:] = K_ss

    iter_TPI = int(0)
    dist_TPI = 10.
    Kpath_new = Kpath_init.copy()
    r_params = (A, alpha, delta)
    w_params = (A, alpha)
    cbe_params = (S, T, beta, sigma, nvec, bvec1, b_ss, TPI_tol,
                  EulDiff)

    while (iter_TPI < maxiter_TPI) and (dist_TPI >= mindist_TPI):
        iter_TPI += 1
        Kpath_init = xi * Kpath_new + (1 - xi) * Kpath_init
        rpath = firms.get_r(Kpath_init, L, r_params)
        wpath = firms.get_w(Kpath_init, L, w_params)
        cpath, bpath, EulErrPath = get_cbepath(cbe_params, rpath, wpath)
        Kpath_new = np.zeros(T + S - 2)
        Kpath_new[:T], Kpath_cstr = aggr.get_K(bpath[:, :T])
        Kpath_new[T:] = K_ss * np.ones(S - 2)
        Kpath_cstr = np.append(Kpath_cstr, np.zeros(S - 2, dtype=bool))
        Kpath_new[Kpath_cstr] = 0.1
        # Check the distance of Kpath_new1
        dist_TPI = ((Kpath_new[1:T] - Kpath_init[1:T]) ** 2).sum()
        # dist_TPI = np.absolute((Kpath_new[1:T] - Kpath_init[1:T]) /
        #                        Kpath_init[1:T]).max()
        print(
            'TPI iter: ', iter_TPI, ', dist: ', "%10.4e" % (dist_TPI),
            ', max. abs. Euler errs: ', "%10.4e" %
            (np.absolute(EulErrPath).max()))

    if iter_TPI == maxiter_TPI and dist_TPI > mindist_TPI:
        print('TPI reached maxiter and did not converge.')
    elif iter_TPI == maxiter_TPI and dist_TPI <= mindist_TPI:
        print('TPI converged in the last iteration. ' +
              'Should probably increase maxiter_TPI.')
    Kpath = Kpath_new
    Y_params = (A, alpha)
    Ypath = aggr.get_Y(Kpath, L, Y_params)
    Cpath = np.zeros(T + S - 2)
    Cpath[:T - 1] = aggr.get_C(cpath[:, :T - 1])
    Cpath[T - 1:] = C_ss * np.ones(S - 1)
    RCerrPath = (Ypath[:-1] - Cpath[:-1] - Kpath[1:] +
                 (1 - delta) * Kpath[:-1])
    tpi_time = time.clock() - start_time

    tpi_output = {
        'bpath': bpath, 'cpath': cpath, 'wpath': wpath, 'rpath': rpath,
        'Kpath': Kpath, 'Ypath': Ypath, 'Cpath': Cpath,
        'EulErrPath': EulErrPath, 'RCerrPath': RCerrPath,
        'tpi_time': tpi_time}

    # Print TPI computation time
    util.print_time(tpi_time, 'TPI')

    if graphs:
        '''
        ----------------------------------------------------------------
        cur_path    = string, path name of current directory
        output_fldr = string, folder in current path to save files
        output_dir  = string, total path of images folder
        output_path = string, path of file name of figure to be saved
        tvec        = (T+S-2,) vector, time period vector
        tgridTm1    = (T-1,) vector, time period vector to T-1
        tgridT      = (T,) vector, time period vector to T-1
        sgrid       = (S,) vector, all ages from 1 to S
        sgrid2      = (S-1,) vector, all ages from 2 to S
        tmatb       = (S-1, T) matrix, time periods for all savings
                      decisions ages (S-1) and time periods (T)
        smatb       = (S-1, T) matrix, ages for all savings decision
                      ages (S-1) and time periods (T)
        tmatc       = (3, T-1) matrix, time periods for all consumption
                      decisions ages (S) and time periods (T-1)
        smatc       = (3, T-1) matrix, ages for all consumption
                      decisions ages (S) and time periods (T-1)
        ----------------------------------------------------------------
        '''
        # Create directory if images directory does not already exist
        cur_path = os.path.split(os.path.abspath(__file__))[0]
        output_fldr = "images"
        output_dir = os.path.join(cur_path, output_fldr)
        if not os.access(output_dir, os.F_OK):
            os.makedirs(output_dir)

        # Plot time path of aggregate capital stock
        tvec = np.linspace(1, T + S - 2, T + S - 2)
        minorLocator = MultipleLocator(1)
        fig, ax = plt.subplots()
        plt.plot(tvec, Kpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate capital stock K')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate capital $K_{t}$')
        output_path = os.path.join(output_dir, "Kpath")
        plt.savefig(output_path)
        # plt.show()

        # Plot time path of aggregate output (GDP)
        fig, ax = plt.subplots()
        plt.plot(tvec, Ypath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate output (GDP) Y')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate output $Y_{t}$')
        output_path = os.path.join(output_dir, "Ypath")
        plt.savefig(output_path)
        # plt.show()

        # Plot time path of aggregate consumption
        fig, ax = plt.subplots()
        plt.plot(tvec, Cpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate consumption C')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate consumption $C_{t}$')
        output_path = os.path.join(output_dir, "C_aggr_path")
        plt.savefig(output_path)
        # plt.show()

        # Plot time path of real wage
        fig, ax = plt.subplots()
        plt.plot(tvec, wpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for real wage w')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Real wage $w_{t}$')
        output_path = os.path.join(output_dir, "wpath")
        plt.savefig(output_path)
        # plt.show()

        # Plot time path of real interest rate
        fig, ax = plt.subplots()
        plt.plot(tvec, rpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for real interest rate r')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Real interest rate $r_{t}$')
        output_path = os.path.join(output_dir, "rpath")
        plt.savefig(output_path)
        # plt.show()

        # Plot time path of individual savings distribution
        tgridT = np.linspace(1, T, T)
        sgrid2 = np.linspace(2, S, S - 1)
        tmatb, smatb = np.meshgrid(tgridT, sgrid2)
        cmap_bp = matplotlib.cm.get_cmap('summer')
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'period-$t$')
        ax.set_ylabel(r'age-$s$')
        ax.set_zlabel(r'individual savings $b_{s,t}$')
        strideval = max(int(1), int(round(S / 10)))
        ax.plot_surface(tmatb, smatb, bpath[:, :T], rstride=strideval,
                        cstride=strideval, cmap=cmap_bp)
        output_path = os.path.join(output_dir, "bpath")
        plt.savefig(output_path)
        # plt.show()

        # Plot time path of individual consumption distribution
        tgridTm1 = np.linspace(1, T - 1, T - 1)
        sgrid = np.linspace(1, S, S)
        tmatc, smatc = np.meshgrid(tgridTm1, sgrid)
        cmap_cp = matplotlib.cm.get_cmap('summer')
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'period-$t$')
        ax.set_ylabel(r'age-$s$')
        ax.set_zlabel(r'individual consumption $c_{s,t}$')
        strideval = max(int(1), int(round(S / 10)))
        ax.plot_surface(tmatc, smatc, cpath[:, :T - 1],
                        rstride=strideval, cstride=strideval,
                        cmap=cmap_cp)
        output_path = os.path.join(output_dir, "cpath")
        plt.savefig(output_path)
        # plt.show()

    return tpi_output
Esempio n. 24
0
def get_TPI(bmat1, args, graphs):
    '''
    --------------------------------------------------------------------
    Solves for transition path equilibrium using time path iteration
    (TPI)
    --------------------------------------------------------------------
    INPUTS:
    bmat1 = (S, J) matrix, initial period wealth (savings) distribution
    args  = length 25 tuple, (J, S, T1, T2, lambdas, emat, beta, sigma,
            l_tilde, b_ellip, upsilon, chi_n_vec, Z, gamma, delta, r_ss,
            K_ss, L_ss, C_ss, b_ss, n_ss, maxiter, Out_Tol, In_Tol, xi)
    graphs = Boolean, =True if want graphs of TPI objects

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        get_path()
        firms.get_r()
        firms.get_w()
        get_cnbpath()
        aggr.get_K()
        aggr.get_L()
        aggr.get_Y()
        aggr.get_C()
        utils.print_time()
        create_graphs()

    OBJECTS CREATED WITHIN FUNCTION:
    start_time   = scalar, current processor time in seconds (float)
    J            = integer >= 1, number of heterogeneous ability groups
    S            = integer in [3,80], number of periods an individual
                   lives
    T1           = integer > S, number of time periods until steady
                   state is assumed to be reached
    T2           = integer > T1, number of time periods after which
                   steady-state is forced in TPI
    lambdas      = (J,) vector, income percentiles for distribution of
                   ability within each cohort
    emat         = (S, J) matrix, lifetime ability profiles for each
                   lifetime income group j
    beta         = scalar in (0,1), discount factor for model period
    sigma        = scalar > 0, coefficient of relative risk aversion
    l_tilde      = scalar > 0, time endowment for each agent each
                   period
    b_ellip      = scalar > 0, fitted value of b for elliptical
                   disutility of labor
    upsilon      = scalar > 1, fitted value of upsilon for elliptical
                   disutility of labor
    chi_n_vec    = (S,) vector, values for chi^n_s
    Z            = scalar > 0, total factor productivity parameter in
                   firms' production function
    gamma        = scalar in (0,1), capital share of income
    delta        = scalar in [0,1], per-period capital depreciation rt
    r_ss         = scalar > 0, steady-state aggregate interest rate
    K_ss         = scalar > 0, steady-state aggregate capital stock
    L_ss         = scalar > 0, steady-state aggregate labor
    C_ss         = scalar > 0, steady-state aggregate consumption
    b_ss         = (S,) vector, steady-state savings distribution
                   (b1, b2,... bS)
    n_ss         = (S,) vector, steady-state labor supply distribution
                   (n1, n2,... nS)
    maxiter      = integer >= 1, Maximum number of iterations for TPI
    Out_Tol      = scalar > 0, convergence criterion for TPI outer loop
    In_Tol       = scalar > 0, tolerance level for TPI inner-loop root
                   finders
    xi           = scalar in (0,1], TPI path updating parameter
    K1           = scalar > 0, initial aggregate capital stock
    K1_cnstr     = Boolean, =True if K1 <= 0
    rpath_init   = (T2+S-1,) vector, initial guess for the time path of
                   interest rates
    iter_TPI     = integer >= 0, current iteration of TPI
    dist         = scalar >= 0, distance measure between initial and
                   new paths
    rw_params    = length 3 tuple, (Z, gamma, delta)
    Y_params     = length 2 tuple, (Z, gamma)
    cnb_args     = length 13 tuple, args to pass into get_cnbpath()
    rpath        = (T2+S-1,) vector, time path of the interest rates
    wpath        = (T2+S-1,) vector, time path of the wages
    cpath        = (S, J, T2+S-1) array, time path of distribution of
                   household consumption c_{j,s,t}
    npath        = (S, J, T2+S-1) matrix, time path of distribution of
                   household labor supply n_{j,s,t}
    bpath        = (S, J, T2+S-1) matrix, time path of distribution of
                   household savings b_{j,s,t}
    n_err_path   = (S, J, T2+S-1) matrix, time path of distribution of
                   household labor supply Euler errors
    b_err_path   = (S, J, T2+S-1) matrix, time path of distribution of
                   household savings Euler errors. b_{j,1,t} = 0 for all
                   j and t
    Kpath_new    = (T2+S-1,) vector, new path of aggregate capital stock
                   implied by household and firm optimization
    Kpath_cnstr  = (T2+S-1,) Boolean vector, =True if K_t<=epsilon
    Lpath_new    = (T2+S-1,) vector, new path of aggregate labor implied
                   by household and firm optimization
    Lpath_cstr   = (T2+S-1,) Boolean vector, =True if L_t<=epsilon
    rpath_new    = (T2+S-1,) vector, updated time path of interest rate
    Ypath        = (T2+S-1,) vector, equilibrium time path of aggregate
                   output (GDP) Y_t
    Cpath        = (T2+S-1,) vector, equilibrium time path of aggregate
                   consumption C_t
    RCerrPath    = (T2+S-2,) vector, equilibrium time path of the
                   resource constraint error. Should be 0 in eqlb'm
                   Y_t - C_t - K_{t+1} + (1-delta)*K_t
    MaxAbsEulErr = scalar > 0, maximum absolute Euler error. Includes
                   both labor supply and savings Euler errors
    Kpath        = (T2+S-1,) vector, equilibrium time path of aggregate
                   capital stock K_t
    Lpath        = (T2+S-1,) vector, equilibrium time path of aggregate
                   labor L_t
    tpi_time     = scalar, time to compute TPI solution (seconds)
    tpi_output   = length 13 dictionary, {cpath, npath, bpath, wpath,
                   rpath, Kpath, Lpath, Ypath, Cpath, n_err_path,
                   b_err_path, RCerrPath, tpi_time}
    graph_args   = length 4 tuple, (J, S, T2, lambdas)

    FILES CREATED BY THIS FUNCTION:
        Kpath.png
        Lpath.png
        rpath.png
        wpath.png
        Ypath.png
        C_aggr_path.png
        cpath_avg_s.png
        cpath_avg_j.png
        npath_avg_s.png
        npath_avg_j.png
        bpath_avg_s.png
        bpath_avg_j.png

    RETURNS: tpi_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    (J, E, S, T1, T2, lambdas, emat, mort_rates, imm_rates_mat, omega_path,
     g_n_path, zeta_mat, chi_n_vec, chi_b_vec, beta, sigma, l_tilde, b_ellip,
     upsilon, g_y, Z, gamma, delta, r_ss, BQ_ss, K_ss, L_ss, C_ss, b_ss, n_ss,
     maxiter, Out_Tol, In_Tol, xi) = args
    K1, K1_cnstr = aggr.get_K(bmat1, lambdas)

    # Create time paths for r and BQ
    rpath_init = np.zeros(T2 + S - 1)
    BQpath_init = np.zeros(T2 + S - 1)
    rpath_init[:T1] = get_path(r_ss, r_ss, T1, 'quadratic')
    rpath_init[T1:] = r_ss
    BQ_args = (lambdas, omega_path[0, :], mort_rates, g_n_path[0])
    BQ_1 = aggr.get_BQ(bmat1, r_ss, BQ_args)
    BQpath_init[:T1] = get_path(BQ_1, BQ_ss, T1, 'quadratic')
    BQpath_init[T1:] = BQ_ss

    iter_TPI = int(0)
    dist = 10.0
    rw_params = (Z, gamma, delta)
    Y_params = (Z, gamma)
    cnb_args = (J, S, T2, lambdas, emat, omega_path, beta, sigma, l_tilde,
                b_ellip, upsilon, chi_n_vec, bmat1, n_ss, In_Tol)
    while (iter_TPI < maxiter) and (dist >= Out_Tol):
        iter_TPI += 1
        rpath = rpath_init
        BQpath = BQpath_init
        wpath = firms.get_w(rpath_init, rw_params)
        cpath, npath, bpath, n_err_path, b_err_path = \
            get_cnbpath(rpath, wpath, cnb_args)
        Kpath_new = np.zeros(T2 + S - 1)
        Kpath_new[:T2], Kpath_cstr = aggr.get_K(bpath[:, :, :T2], lambdas)
        Kpath_new[T2:] = K_ss
        Kpath_cstr = np.append(Kpath_cstr, np.zeros(S - 1, dtype=bool))
        Lpath_new = np.zeros(T2 + S - 1)
        Lpath_new[:T2], Lpath_cstr = aggr.get_L(npath[:, :, :T2], lambdas,
                                                emat)
        Lpath_new[T2:] = L_ss
        Lpath_cstr = np.append(Lpath_cstr, np.zeros(S - 1, dtype=bool))
        rpath_new = firms.get_r(Kpath_new, Lpath_new, rw_params)
        BQpath_new = aggr.get_BQ()
        Ypath = aggr.get_Y(Kpath_new, Lpath_new, Y_params)
        Cpath = np.zeros(T2 + S - 1)
        Cpath[:T2] = aggr.get_C(cpath[:, :, :T2], lambdas)
        Cpath[T2:] = C_ss
        RCerrPath = np.zeros(T2 + S - 1)
        RCerrPath[:-1] = (Ypath[:-1] - Cpath[:-1] - Kpath_new[1:] +
                          (1 - delta) * Kpath_new[:-1])
        RCerrPath[-1] = RCerrPath[-2]
        # Check the distance of rpath_new
        dist = (np.absolute(rpath_new[:T2] - rpath_init[:T2])).max()
        MaxAbsEulErr = np.absolute(np.hstack((n_err_path, b_err_path))).max()
        print('TPI iter: ', iter_TPI, ', dist: ', "%10.4e" % (dist),
              ', max abs all errs: ', "%10.4e" % MaxAbsEulErr)
        # The resource constraint does not bind across the transition
        # path until the equilibrium is solved
        rpath_init[:T2] = (xi * rpath_new[:T2] + (1 - xi) * rpath_init[:T2])
    if (iter_TPI == maxiter) and (dist > Out_Tol):
        print('TPI reached maxiter and did not converge.')
    elif (iter_TPI == maxiter) and (dist <= Out_Tol):
        print('TPI converged in the last iteration. ' +
              'Should probably increase maxiter_TPI.')
    Kpath = Kpath_new
    Lpath = Lpath_new

    tpi_time = time.clock() - start_time

    tpi_output = {
        'cpath': cpath,
        'npath': npath,
        'bpath': bpath,
        'wpath': wpath,
        'rpath': rpath,
        'Kpath': Kpath,
        'Lpath': Lpath,
        'Ypath': Ypath,
        'Cpath': Cpath,
        'n_err_path': n_err_path,
        'b_err_path': b_err_path,
        'RCerrPath': RCerrPath,
        'tpi_time': tpi_time
    }

    # Print maximum resource constraint error. Only look at resource
    # constraint up to period T2 - 1 because period T2 includes K_{t+1},
    # which was forced to be the steady-state
    print('Max abs. RC error: ',
          "%10.4e" % (np.absolute(RCerrPath[:T2 - 1]).max()))

    # Print TPI computation time
    utils.print_time(tpi_time, 'TPI')

    if graphs:
        graph_args = (J, S, T2, lambdas)
        create_graphs(tpi_output, graph_args)

    return tpi_output
Esempio n. 25
0
def inner_loop(r, w, args):
    '''
    --------------------------------------------------------------------
    Given values for r and w, solve for equilibrium errors from the two
    first order conditions of the firm
    --------------------------------------------------------------------
    INPUTS:
    r    = scalar > 0, guess at steady-state interest rate
    w    = scalar > 0, guess at steady-state wage
    args = length 14 tuple, (c1_init, S, beta, sigma, l_tilde, b_ellip,
           upsilon, chi_n_vec, A, alpha, delta, EulDiff, Eul_Tol,
           c1_options)

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        hh.c1_bSp1err()
        hh.get_cnb_vecs()
        aggr.get_K()
        aggr.get_L()
        firms.get_r()
        firms.get_w()

    OBJECTS CREATED WITHIN FUNCTION:
    c1_init    = scalar > 0, initial guess for c1
    S          = integer >= 3, number of periods in individual lifetime
    beta       = scalar in (0,1), discount factor
    sigma      = scalar >= 1, coefficient of relative risk aversion
    l_tilde    = scalar > 0, per-period time endowment for every agent
    b_ellip    = scalar > 0, fitted value of b for elliptical disutility
                 of labor
    upsilon    = scalar > 1, fitted value of upsilon for elliptical
                 disutility of labor
    chi_n_vec  = (S,) vector, values for chi^n_s
    A          = scalar > 0, total factor productivity parameter in
                 firms' production function
    alpha      = scalar in (0,1), capital share of income
    delta      = scalar in [0,1], model-period depreciation rate of
                 capital
    EulDiff    = boolean, =True if simple difference Euler errors,
                 otherwise percent deviation Euler errors
    SS_tol     = scalar > 0, tolerance level for steady-state fsolve
    c1_options = length 1 dict, options for c1_bSp1err()
    rpath      = (S,) vector, lifetime path of interest rates
    wpath      = (S,) vector, lifetime path of wages
    c1_args    = length 10 tuple, args to pass into hh.c1_bSp1err()
    results_c1 = results object, results from c1_bSp1err()
    c1         = scalar > 0, optimal initial period consumption given r
                 and w
    cnb_args   = length 8 tuple, args to pass into get_cnb_vecs()
    cvec       = (S,) vector, lifetime consumption (c1, c2, ...cS)
    nvec       = (S,) vector, lifetime labor supply (n1, n2, ...nS)
    bvec       = (S,) vector, lifetime savings (b1, b2, ...bS) with b1=0
    b_Sp1      = scalar, final period savings, should be close to zero
    n_errors   = (S,) vector, labor supply Euler errors
    b_errors   = (S-1,) vector, savings Euler errors
    K          = scalar > 0, aggregate capital stock
    K_cstr     = boolean, =True if K < epsilon
    L          = scalar > 0, aggregate labor
    L_cstr     = boolean, =True if L < epsilon
    r_params   = length 3 tuple, (A, alpha, delta)
    w_params   = length 2 tuple, (A, alpha)
    r_new      = scalar > 0, guess at steady-state interest rate
    w_new      = scalar > 0, guess at steady-state wage

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: K, L, cvec, nvec, bvec, b_Sp1, r_new, w_new, n_errors,
             b_errors
    --------------------------------------------------------------------
    '''
    (c1_init, S, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec, A, alpha,
     delta, EulDiff, SS_tol, c1_options) = args

    rpath = r * np.ones(S)
    wpath = w * np.ones(S)
    c1_args = (0.0, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec, rpath,
               wpath, EulDiff)
    results_c1 = \
        opt.root(hh.c1_bSp1err, c1_init, args=(c1_args),
                 method='lm', tol=SS_tol, options=(c1_options))
    c1 = results_c1.x
    cnb_args = (0.0, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec,
                EulDiff)
    cvec, nvec, bvec, b_Sp1, n_errors, b_errors = \
        hh.get_cnb_vecs(c1, rpath, wpath, cnb_args)
    K, K_cstr = aggr.get_K(bvec)
    L, L_cstr = aggr.get_L(nvec)
    r_params = (A, alpha, delta)
    r_new = firms.get_r(K, L, r_params)
    w_params = (A, alpha, delta)
    w_new = firms.get_w(r_new, w_params)

    return (K, L, cvec, nvec, bvec, b_Sp1, r_new, w_new, n_errors, b_errors)
Esempio n. 26
0
def get_TPI(params, bmat1, graphs):
    '''
    --------------------------------------------------------------------
    Solves for transition path equilibrium using time path iteration
    (TPI)
    --------------------------------------------------------------------
    INPUTS:
    params = length 23 tuple, (J, S, T1, T2, lambdas, emat, beta, sigma,
             l_tilde, b_ellip, upsilon, chi_n_vec, A, alpha, delta,
             K_ss, L_ss, C_ss, maxiter, mindist, TPI_tol, xi, diff)
    bmat1  = (S, J) matrix, initial period savings distribution
    graphs = Boolean, =True if want graphs of TPI objects

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        aggr.get_K()
        get_path()
        firms.get_r()
        firms.get_w()
        get_cnbpath()
        aggr.get_L()
        aggr.get_Y()
        aggr.get_C()
        utils.print_time()

    OBJECTS CREATED WITHIN FUNCTION:
    start_time    = scalar, current processor time in seconds (float)
    J             = integer >= 1, number of heterogeneous ability groups
    S             = integer in [3,80], number of periods an individual
                    lives
    T1            = integer > S, number of time periods until steady
                    state is assumed to be reached
    T2            = integer > T1, number of time periods after which
                    steady-state is forced in TPI
    lambdas       = (J,) vector, income percentiles for distribution of
                    ability within each cohort
    emat          = (S, J) matrix, e_{j,s} ability by age and income
                    group
    beta          = scalar in (0,1), discount factor for model period
    sigma         = scalar > 0, coefficient of relative risk aversion
    l_tilde       = scalar > 0, time endowment for each agent each
                    period
    b_ellip       = scalar > 0, fitted value of b for elliptical
                    disutility of labor
    upsilon       = scalar > 1, fitted value of upsilon for elliptical
                    disutility of labor
    chi_n_vec     = (S,) vector, values for chi^n_s
    A             = scalar > 0, total factor productivity parameter in
                    firms' production function
    alpha         = scalar in (0,1), capital share of income
    delta         = scalar in [0,1], per-period capital depreciation rt
    K_ss          = scalar > 0, steady-state aggregate capital stock
    L_ss          = scalar > 0, steady-state aggregate labor supply
    C_ss          = scalar > 0, steady-state aggregate consumption
    maxiter       = integer >= 1, Maximum number of iterations for TPI
    mindist       = scalar > 0, convergence criterion for TPI
    TPI_tol       = scalar > 0, tolerance level for TPI root finders
    xi            = scalar in (0,1], TPI path updating parameter
    diff          = Boolean, =True if want difference version of Euler
                    errors beta*(1+r)*u'(c2) - u'(c1), =False if want
                    ratio version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1
    K1            = scalar > 0, initial aggregate capital stock
    K1_cstr       = Boolean, =True if K1 <= 0
    Kpath_init    = (T2+S-1,) vector, initial guess for the time path of
                    the aggregate capital stock
    Lpath_init    = (T2+S-1,) vector, initial guess for the time path of
                    aggregate labor
    iter_TPI      = integer >= 0, current iteration of TPI
    dist          = scalar >= 0, distance measure between initial and
                    new paths
    r_params      = length 3 tuple, (A, alpha, delta)
    w_params      = length 2 tuple, (A, alpha)
    Y_params      = length 2 tuple, (A, alpha)
    cnb_params    = length 14 tuple, args to pass into get_cnbpath()
    rpath         = (T2+S-1,) vector, time path of the interest rates
    wpath         = (T2+S-1,) vector, time path of the wages
    cpath         = (S, J, T2+S-1) array, time path of distribution of
                    individual consumption c_{j,s,t}
    npath         = (S, J, T2+S-1) array, time path of distribution of
                    individual labor supply n_{j,s,t}
    bpath         = (S, J, T2+S-1) array, time path of distribution of
                    individual savings b_{j,s,t}
    n_err_path    = (S, J, T2+S-1) array, time path of distribution of
                    individual labor supply Euler errors
    b_err_path    = (S, J, T2+S-1) array, time path of distribution of
                    individual savings Euler errors. First column and
                    first row are identically zero
    bSp1_err_path = (S, J, T2) array, residual last period savings,
                    should be close to zero in equilibrium. Nonzero
                    elements of matrix should only be in first matrix
                    [:, :, 0] and top plane [0, :, :]
    Kpath_new     = (T2+S-1,) vector, new path of the aggregate capital
                    stock implied by household and firm optimization
    Kpath_cstr    = (T2+S-1,) Boolean vector, =True if K_t<epsilon
    Lpath_new     = (T2+S-1,) vector, new path of the aggregate labor
    rpath_new     = (T2+S-1,) vector, updated time path of interest rate
    wpath_new     = (T2+S-1,) vector, updated time path of the wages
    Ypath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    output (GDP) Y_t
    Cpath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    consumption C_t
    RCerrPath     = (T2+S-2,) vector, equilibrium time path of the
                    resource constraint error:
                    Y_t - C_t - K_{t+1} + (1-delta)*K_t
    KL_path_new   = (2*T2,) vector, appended K_path_new and L_path_new
                    from observation 1 to T2
    KL_path_init  = (2*T2,) vector, appended K_path_init and L_path_init
                    from observation 1 to T2
    Kpath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    capital stock K_t
    Lpath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    labor L_t
    tpi_time      = scalar, time to compute TPI solution (seconds)
    tpi_output    = length 14 dictionary, {cpath, npath, bpath, wpath,
                    rpath, Kpath, Lpath, Ypath, Cpath, bSp1_err_path,
                    n_err_path, b_err_path, RCerrPath, tpi_time}

    FILES CREATED BY THIS FUNCTION:
        Kpath.png
        Lpath.png
        Ypath.png
        C_aggr_path.png
        wpath.png
        rpath.png
        cpath.png
        npath.png
        bpath.png

    RETURNS: tpi_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    (J, S, T1, T2, lambdas, emat, beta, sigma, l_tilde, b_ellip,
        upsilon, chi_n_vec, A, alpha, delta, K_ss, L_ss, C_ss, maxiter,
        mindist, TPI_tol, xi, diff) = params
    K1, K1_cstr = aggr.get_K(bmat1, lambdas)

    # Create time paths for K and L
    Kpath_init = np.zeros(T2 + S - 1)
    Kpath_init[:T1] = get_path(K1, K_ss, T1, 'quadratic')
    Kpath_init[T1:] = K_ss
    Lpath_init = L_ss * np.ones(T2 + S - 1)

    iter_TPI = int(0)
    dist = 10.0
    r_params = (A, alpha, delta)
    w_params = (A, alpha)
    Y_params = (A, alpha)
    cnb_params = (J, S, T2, lambdas, emat, beta, sigma, l_tilde,
                  b_ellip, upsilon, chi_n_vec, bmat1, TPI_tol, diff)
    while (iter_TPI < maxiter) and (dist >= mindist):
        iter_TPI += 1
        rpath = firms.get_r(r_params, Kpath_init, Lpath_init)
        wpath = firms.get_w(w_params, Kpath_init, Lpath_init)
        cpath, npath, bpath, n_err_path, b_err_path, bSp1_err_path = \
            get_cnbpath(cnb_params, rpath, wpath)
        Kpath_new = np.zeros(T2 + S - 1)
        Kpath_new[:T2], Kpath_cstr = aggr.get_K(bpath[:, :, :T2],
                                                lambdas)
        Kpath_new[T2:] = K_ss
        Kpath_cstr = np.append(Kpath_cstr, np.zeros(S - 1, dtype=bool))
        Kpath_new[Kpath_cstr] = 0.01
        Lpath_new = np.zeros(T2 + S - 1)
        Lpath_new[:T2] = aggr.get_L(npath[:, :, :T2], emat, lambdas)
        Lpath_new[T2:] = L_ss
        rpath_new = firms.get_r(r_params, Kpath_new, Lpath_new)
        wpath_new = firms.get_w(w_params, Kpath_new, Lpath_new)
        Ypath = aggr.get_Y(Y_params, Kpath_new, Lpath_new)
        Cpath = np.zeros(T2 + S - 1)
        Cpath[:T2] = aggr.get_C(cpath[:, :, :T2], lambdas)
        Cpath[T2:] = C_ss
        RCerrPath = (Ypath[:-1] - Cpath[:-1] - Kpath_new[1:] +
                     (1 - delta) * Kpath_new[:-1])
        # Check the distance of Kpath_new1
        KL_path_new = np.append(Kpath_new[:T2], Lpath_new[:T2])
        KL_path_init = np.append(Kpath_init[:T2], Lpath_init[:T2])
        dist = ((KL_path_new - KL_path_init) ** 2).sum()
        # dist = np.absolute(KL_path_new - KL_path_init).max()
        print(
            'TPI iter: ', iter_TPI, ', dist: ', "%10.4e" % (dist),
            ', max abs all errs: ', "%10.4e" %
            (np.hstack(np.absolute(b_err_path).max(),
             np.absolute(n_err_path).max(),
             np.absolute(bSp1_err_path).max())).max())
        # The resource constraint does not bind across the transition
        # path until the equilibrium is solved
        Kpath_init = xi * Kpath_new + (1 - xi) * Kpath_init
        Lpath_init = xi * Lpath_new + (1 - xi) * Lpath_init

    if (iter_TPI == maxiter) and (dist > mindist):
        print('TPI reached maxiter and did not converge.')
    elif (iter_TPI == maxiter) and (dist <= mindist):
        print('TPI converged in the last iteration. ' +
              'Should probably increase maxiter_TPI.')
    Kpath = Kpath_new
    Lpath = Lpath_new
    rpath = rpath_new
    wpath = wpath_new

    tpi_time = time.clock() - start_time

    tpi_output = {
        'cpath': cpath, 'npath': npath, 'bpath': bpath, 'wpath': wpath,
        'rpath': rpath, 'Kpath': Kpath, 'Lpath': Lpath, 'Ypath': Ypath,
        'Cpath': Cpath, 'bSp1_err_path': bSp1_err_path,
        'n_err_path': n_err_path, 'b_err_path': b_err_path,
        'RCerrPath': RCerrPath, 'tpi_time': tpi_time}

    # Print maximum resource constraint error. Only look at resource
    # constraint up to period T2 - 1 because period T2 includes K_{t+1},
    # which was forced to be the steady-state
    print('Max abs. labor supply Euler error: ', '%10.4e' %
          np.absolute(n_err_path[:T2 - 1]).max())
    print('Max abs. savings Euler error: ', '%10.4e' %
          np.absolute(b_err_path[:T2 - 1]).max())
    print('Max abs. final per savings: ', '%10.4e' %
          np.absolute(bSp1_err_path[:T2 - 1]).max())
    print('Max abs. RC error: ', '%10.4e' %
          (np.absolute(RCerrPath[:T2 - 1]).max()))

    # Print TPI computation time
    utils.print_time(tpi_time, 'TPI')

    if graphs:
        '''
        ----------------------------------------------------------------
        cur_path    = string, path name of current directory
        output_fldr = string, folder in current path to save files
        output_dir  = string, total path of images folder
        output_path = string, path of file name of figure to be saved
        tvec        = (T2+S-1,) vector, time period vector
        tgridT      = (T2,) vector, time period vector from 1 to T2
        sgrid       = (S,) vector, all ages from 1 to S
        tmat        = (S, T2) matrix, time periods for decisions ages
                      (S) and time periods (T2)
        smat        = (S, T2) matrix, ages for all decisions ages (S)
                      and time periods (T2)
        ----------------------------------------------------------------
        '''
        # Create directory if images directory does not already exist
        cur_path = os.path.split(os.path.abspath(__file__))[0]
        output_fldr = "images"
        output_dir = os.path.join(cur_path, output_fldr)
        if not os.access(output_dir, os.F_OK):
            os.makedirs(output_dir)

        # Plot time path of aggregate capital stock
        tvec = np.linspace(1, T2 + S - 1, T2 + S - 1)
        minorLocator = MultipleLocator(1)
        fig, ax = plt.subplots()
        plt.plot(tvec, Kpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate capital stock K')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate capital $K_{t}$')
        output_path = os.path.join(output_dir, 'Kpath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of aggregate labor
        fig, ax = plt.subplots()
        plt.plot(tvec, Lpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate labor L')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate labor $L_{t}$')
        output_path = os.path.join(output_dir, 'Lpath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of aggregate output (GDP)
        fig, ax = plt.subplots()
        plt.plot(tvec, Ypath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate output (GDP) Y')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate output $Y_{t}$')
        output_path = os.path.join(output_dir, 'Ypath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of aggregate consumption
        fig, ax = plt.subplots()
        plt.plot(tvec, Cpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate consumption C')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate consumption $C_{t}$')
        output_path = os.path.join(output_dir, 'C_aggr_path')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of real wage
        fig, ax = plt.subplots()
        plt.plot(tvec, wpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for real wage w')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Real wage $w_{t}$')
        output_path = os.path.join(output_dir, 'wpath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of real interest rate
        fig, ax = plt.subplots()
        plt.plot(tvec, rpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for real interest rate r')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Real interest rate $r_{t}$')
        output_path = os.path.join(output_dir, 'rpath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Come up with nice visualization for time paths of individual
        # decisions

    return tpi_output
Esempio n. 27
0
    r_ss = ss_output['r_ss']
    K_ss = ss_output['K_ss']
    L_ss = ss_output['L_ss']
    C_ss = ss_output['C_ss']
    b_ss = ss_output['b_ss']
    n_ss = ss_output['n_ss']

    # Choose initial period distribution of wealth (bvec1), which
    # determines initial period aggregate capital stock
    init_wgts = ((1.5 - 0.87) / (S - 1) *
                 (np.linspace(1, S, S) - 1) + 0.87)
    bvec1 = init_wgts * b_ss

    # Make sure init. period distribution is feasible in terms of K
    K1, K1_cstr = aggr.get_K(bvec1)

    # If initial bvec1 is not feasible end program
    if K1_cstr:
        print('Initial savings distribution is not feasible because ' +
              'K1<=0. Some element(s) of bvec1 must increase.')
    else:
        tpi_params = (S, T1, T2, beta, sigma, l_tilde, b_ellip, upsilon,
                      chi_n_vec, A, alpha, delta, r_ss, K_ss, L_ss, C_ss,
                      b_ss, n_ss, maxiter_TPI, TPI_OutTol, TPI_InTol,
                      TPI_EulDiff, xi_TPI)
        tpi_output = tpi.get_TPI(bvec1, tpi_params, TPI_graphs)

        tpi_args = (S, T1, T2, beta, sigma, l_tilde, b_ellip, upsilon,
                    chi_n_vec, A, alpha, delta, r_ss, K_ss, L_ss, C_ss,
                    b_ss, n_ss, maxiter_TPI, TPI_OutTol, TPI_InTol,
Esempio n. 28
0
def get_SS(args, graph=False):
    (KL_init, beta, sigma, chi_n_vec, l_tilde, b, upsilon, S, alpha, A,
     delta) = args
    dist = 10
    mindist = 1e-08
    maxiter = 500
    ss_iter = 0
    xi = 0.2

    r_params = (alpha, A, delta)
    w_params = (alpha, A)

    while dist > mindist and ss_iter < maxiter:
        ss_iter += 1
        K, L = KL_init
        r = firms.get_r(K, L, r_params)
        w = firms.get_w(K, L, w_params)
        c1_guess = 1.0
        c1_args = (r, w, beta, sigma, chi_n_vec, l_tilde, b, upsilon, S)
        results_c1 = opt.root(hh.get_bSp1, c1_guess, args=(c1_args))
        c1 = results_c1.x
        cvec = hh.get_recurs_c(c1, r, beta, sigma, S)
        nvec = hh.get_n_s(cvec, w, sigma, chi_n_vec, l_tilde, b, upsilon)
        bvec = hh.get_recurs_b(cvec, nvec, r, w)
        K_new = aggr.get_K(bvec[:-1])
        L_new = aggr.get_L(nvec)
        KL_new = np.array([K_new, L_new])
        dist = ((KL_new - KL_init)**2).sum()
        KL_init = xi * KL_new + (1 - xi) * KL_init
        print('iter:', ss_iter, ' dist: ', dist)

    c_ss = cvec
    n_ss = nvec
    b_ss = bvec
    K_ss = K_new
    L_ss = L_new
    r_ss = r
    w_ss = w
    Y_params = (alpha, A)
    Y_ss = aggr.get_Y(K_ss, L_ss, Y_params)
    C_ss = aggr.get_C(c_ss)

    ss_output = {
        'c_ss': c_ss,
        'n_ss': n_ss,
        'b_ss': b_ss,
        'K_ss': K_ss,
        'L_ss': L_ss,
        'r_ss': r_ss,
        'w_ss': w_ss,
        'Y_ss': Y_ss,
        'C_ss': C_ss
    }

    if graph:
        # Create directory if images directory does not already exist
        cur_path = os.path.split(os.path.abspath(__file__))[0]
        output_fldr = 'images'
        output_dir = os.path.join(cur_path, output_fldr)
        if not os.access(output_dir, os.F_OK):
            os.makedirs(output_dir)

        # Plot c_ss, n_ss, b_ss
        # Plot steady-state consumption and savings distributions
        age_pers = np.arange(1, S + 1)
        fig, ax = plt.subplots()
        plt.plot(age_pers, c_ss, marker='D', label='Consumption')
        plt.plot(age_pers,
                 np.append(0, b_ss[:-1]),
                 marker='D',
                 label='Savings')
        # for the minor ticks, use no labels; default NullFormatter
        minorLocator = MultipleLocator(1)
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        # plt.title('Steady-state consumption and savings', fontsize=20)
        plt.xlabel(r'Age $s$')
        plt.ylabel(r'Units of consumption')
        plt.xlim((0, S + 1))
        # plt.ylim((-1.0, 1.15 * (b_ss.max())))
        plt.legend(loc='upper left')
        output_path = os.path.join(output_dir, 'SS_bc')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot steady-state labor supply distributions
        fig, ax = plt.subplots()
        plt.plot(age_pers, n_ss, marker='D', label='Labor supply')
        # for the minor ticks, use no labels; default NullFormatter
        minorLocator = MultipleLocator(1)
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        # plt.title('Steady-state labor supply', fontsize=20)
        plt.xlabel(r'Age $s$')
        plt.ylabel(r'Labor supply')
        plt.xlim((0, S + 1))
        # plt.ylim((-0.1, 1.15 * (n_ss.max())))
        plt.legend(loc='upper right')
        output_path = os.path.join(output_dir, 'SS_n')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

    return ss_output
Esempio n. 29
0
def get_TPI(params, bvec1, graphs):
    '''
    --------------------------------------------------------------------
    Solves for transition path equilibrium using time path iteration
    (TPI)
    --------------------------------------------------------------------
    INPUTS:
    params = length 21 tuple, (S, T1, T2, beta, sigma, l_tilde, b_ellip,
             upsilon, chi_n_vec, A, alpha, delta, K_ss, L_ss, C_ss,
             maxiter, mindist, TPI_tol, xi, diff, hh_fsolve)
    bvec1  = (S,) vector, initial period savings distribution
    graphs = Boolean, =True if want graphs of TPI objects

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        aggr.get_K()
        get_path()
        firms.get_r()
        firms.get_w()
        get_cnbpath()
        solve_bn_path()
        aggr.get_L()
        aggr.get_Y()
        aggr.get_C()
        utils.print_time()

    OBJECTS CREATED WITHIN FUNCTION:
    start_time    = scalar, current processor time in seconds (float)
    S             = integer in [3,80], number of periods an individual
                    lives
    T1            = integer > S, number of time periods until steady
                    state is assumed to be reached
    T2            = integer > T1, number of time periods after which
                    steady-state is forced in TPI
    beta          = scalar in (0,1), discount factor for model period
    sigma         = scalar > 0, coefficient of relative risk aversion
    l_tilde       = scalar > 0, time endowment for each agent each
                    period
    b_ellip       = scalar > 0, fitted value of b for elliptical
                    disutility of labor
    upsilon       = scalar > 1, fitted value of upsilon for elliptical
                    disutility of labor
    chi_n_vec     = (S,) vector, values for chi^n_s
    A             = scalar > 0, total factor productivity parameter in
                    firms' production function
    alpha         = scalar in (0,1), capital share of income
    delta         = scalar in [0,1], per-period capital depreciation rt
    K_ss          = scalar > 0, steady-state aggregate capital stock
    L_ss          = scalar > 0, steady-state aggregate labor supply
    C_ss          = scalar > 0, steady-state aggregate consumption
    maxiter       = integer >= 1, Maximum number of iterations for TPI
    mindist       = scalar > 0, convergence criterion for TPI
    TPI_tol       = scalar > 0, tolerance level for TPI root finders
    xi            = scalar in (0,1], TPI path updating parameter
    diff          = Boolean, =True if want difference version of Euler
                    errors beta*(1+r)*u'(c2) - u'(c1), =False if want
                    ratio version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1
    hh_fsolve     = boolean, =True if solve inner-loop household problem by
                    choosing c_1 to set final period savings b_{S+1}=0.
                    Otherwise, solve the household problem as multivariate
                    root finder with 2S-1 unknowns and equations
    K1            = scalar > 0, initial aggregate capital stock
    K1_cnstr      = Boolean, =True if K1 <= 0
    Kpath_init    = (T2+S-1,) vector, initial guess for the time path of
                    the aggregate capital stock
    Lpath_init    = (T2+S-1,) vector, initial guess for the time path of
                    aggregate labor
    domain        = (T2,) vector, integers from 0 to T2-1
    domain2       = (T2,S) array, integers from 0 to T2-1 repeated S times
    ending_b      = (S,) vector, distribution of savings at end of time path
    initial_b     = (S,) vector, distribution of savings in initial period
    guesses_b     = (T2,S) array, initial guess at distribution of savings
                    over the time path
    ending_b_tail = (S,S) array, distribution of savings for S periods after
                     end of time path
    guesses_b     = (T2+S,S) array, guess at distribution of savings
                    for T2+S periods
    domain3       = (T2,S) array, integers from 0 to T2-1 repeated S times
    initial_n     = (S,) vector, distribution of labor supply in initial period
    guesses_n     = (T2,S) array, initial guess at distribution of labor
                    supply over the time path
    ending_n_tail = (S,S) array, distribution of labor supply for S periods after
                     end of time path
    guesses_n     = (T2+S,S) array, guess at distribution of labor supply
                    for T2+S periods
    guesses       = length 2 tuple, initial guesses at distributions of savings
                    and labor supply over the time path
    iter_TPI      = integer >= 0, current iteration of TPI
    dist          = scalar >= 0, distance measure between initial and
                    new paths
    r_params      = length 3 tuple, (A, alpha, delta)
    w_params      = length 2 tuple, (A, alpha)
    Y_params      = length 2 tuple, (A, alpha)
    cnb_params    = length 11 tuple, args to pass into get_cnbpath()
    rpath         = (T2+S-1,) vector, time path of the interest rates
    wpath         = (T2+S-1,) vector, time path of the wages
    ind           = (S,) vector, integers from 0 to S
    bn_args       = length 14 tuple, arguments to be passed to solve_bn_path()
    cpath         = (S, T2+S-1) matrix, time path of distribution of
                    individual consumption c_{s,t}
    npath         = (S, T2+S-1) matrix, time path of distribution of
                    individual labor supply n_{s,t}
    bpath         = (S, T2+S-1) matrix, time path of distribution of
                    individual savings b_{s,t}
    n_err_path    = (S, T2+S-1) matrix, time path of distribution of
                    individual labor supply Euler errors
    b_err_path    = (S, T2+S-1) matrix, time path of distribution of
                    individual savings Euler errors. First column and
                    first row are identically zero
    bSp1_err_path = (S, T2) matrix, residual last period savings, which
                    should be close to zero in equilibrium. Nonzero
                    elements of matrix should only be in first column
                    and first row
    Kpath_new     = (T2+S-1,) vector, new path of the aggregate capital
                    stock implied by household and firm optimization
    Kpath_cnstr   = (T2+S-1,) Boolean vector, =True if K_t<=0
    Lpath_new     = (T2+S-1,) vector, new path of the aggregate labor
    rpath_new     = (T2+S-1,) vector, updated time path of interest rate
    wpath_new     = (T2+S-1,) vector, updated time path of the wages
    Ypath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    output (GDP) Y_t
    Cpath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    consumption C_t
    RCerrPath     = (T2+S-2,) vector, equilibrium time path of the
                    resource constraint error:
                    Y_t - C_t - K_{t+1} + (1-delta)*K_t
    KL_path_new   = (2*T2,) vector, appended K_path_new and L_path_new
                    from observation 1 to T2
    KL_path_init  = (2*T2,) vector, appended K_path_init and L_path_init
                    from observation 1 to T2
    Kpath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    capital stock K_t
    Lpath         = (T2+S-1,) vector, equilibrium time path of aggregate
                    labor L_t
    tpi_time      = scalar, time to compute TPI solution (seconds)
    tpi_output    = length 14 dictionary, {cpath, npath, bpath, wpath,
                    rpath, Kpath, Lpath, Ypath, Cpath, bSp1_err_path,
                    n_err_path, b_err_path, RCerrPath, tpi_time}

    FILES CREATED BY THIS FUNCTION:
        Kpath.png
        Lpath.png
        Ypath.png
        C_aggr_path.png
        wpath.png
        rpath.png
        cpath.png
        npath.png
        bpath.png

    RETURNS: tpi_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    (S, T1, T2, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec, A, alpha,
     delta, K_ss, L_ss, C_ss, b_splus1_ss, n_ss, maxiter, mindist, TPI_tol, xi,
     diff, hh_fsolve) = params
    K1, K1_cnstr = aggr.get_K(bvec1)

    # Create time paths for K and L
    Kpath_init = np.zeros(T2 + S - 1)
    Kpath_init[:T1] = get_path(K1, K_ss, T1, 'quadratic')
    Kpath_init[T1:] = K_ss
    Lpath_init = L_ss * np.ones(T2 + S - 1)

    # Make arrays of initial guesses for labor supply and savings
    domain = np.linspace(0, T2, T2)
    domain2 = np.tile(domain.reshape(T2, 1), (1, S))
    ending_b = b_splus1_ss
    initial_b = bvec1
    guesses_b = (-1 / (domain2 + 1)) * (ending_b - initial_b) + ending_b
    ending_b_tail = np.tile(ending_b.reshape(1, S), (S, 1))
    guesses_b = np.append(guesses_b, ending_b_tail, axis=0)

    domain3 = np.tile(np.linspace(0, 1, T2).reshape(
        T2,
        1,
    ), (1, S))
    initial_n = n_ss
    guesses_n = domain3 * (n_ss - initial_n) + initial_n
    ending_n_tail = np.tile(n_ss.reshape(1, S), (S, 1))
    guesses_n = np.append(guesses_n, ending_n_tail, axis=0)
    guesses = (guesses_b, guesses_n)

    iter_TPI = int(0)
    dist = 10.0
    r_params = (A, alpha, delta)
    w_params = (A, alpha)
    Y_params = (A, alpha)
    cnb_params = (S, T2, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec,
                  bvec1, TPI_tol, diff)
    while (iter_TPI < maxiter) and (dist >= mindist):
        iter_TPI += 1
        rpath = firms.get_r(r_params, Kpath_init, Lpath_init)
        wpath = firms.get_w(w_params, Kpath_init, Lpath_init)
        if hh_fsolve:
            ind = np.arange(S)
            bn_args = (rpath, wpath, ind, S, T2, beta, sigma, l_tilde, b_ellip,
                       upsilon, chi_n_vec, bvec1, TPI_tol, diff)
            npath, b_splus1_path, n_err_path, b_err_path = solve_bn_path(
                guesses, bn_args)
            bSp1_err_path = np.zeros((S, T2 + S - 1))
            b_s_path = np.zeros((S, T2 + S - 1))
            b_s_path[:, 0] = bvec1
            b_s_path[1:, 1:] = b_splus1_path[:-1, :-1]
            cpath = hh.get_cons(rpath, wpath, b_s_path, b_splus1_path, npath)
            # update guesses for next iteration
            guesses = (np.transpose(b_splus1_path), np.transpose(npath))
        else:
            cpath, npath, b_s_path, n_err_path, b_err_path, bSp1_err_path = \
                get_cnbpath(cnb_params, rpath, wpath)
            b_splus1_path = np.append(b_s_path[1:, :T2],
                                      np.reshape(bSp1_err_path[-1, :],
                                                 (1, T2)),
                                      axis=0)
        Kpath_new = np.zeros(T2 + S - 1)
        Kpath_new[:T2], Kpath_cnstr = aggr.get_K(b_s_path[:, :T2])
        Kpath_new[T2:] = K_ss
        Kpath_cnstr = np.append(Kpath_cnstr, np.zeros(S - 1, dtype=bool))
        Kpath_new[Kpath_cnstr] = 0.01
        Lpath_new = np.zeros(T2 + S - 1)
        Lpath_new[:T2] = aggr.get_L(npath[:, :T2])
        Lpath_new[T2:] = L_ss
        rpath_new = firms.get_r(r_params, Kpath_new, Lpath_new)
        wpath_new = firms.get_w(w_params, Kpath_new, Lpath_new)
        Ypath = aggr.get_Y(Y_params, Kpath_new, Lpath_new)
        Cpath = np.zeros(T2 + S - 1)
        Cpath[:T2] = aggr.get_C(cpath[:, :T2])
        Cpath[T2:] = C_ss
        RCerrPath = (Ypath[:-1] - Cpath[:-1] - Kpath_new[1:] +
                     (1 - delta) * Kpath_new[:-1])
        # Check the distance of Kpath_new1
        KL_path_new = np.append(Kpath_new[:T2], Lpath_new[:T2])
        KL_path_init = np.append(Kpath_init[:T2], Lpath_init[:T2])
        dist = ((KL_path_new - KL_path_init)**2).sum()
        # dist = np.absolute(KL_path_new - KL_path_init).max()
        print(
            'TPI iter: ', iter_TPI, ', dist: ', "%10.4e" % (dist),
            ', max abs all errs: ', "%10.4e" % (np.absolute(
                np.hstack((b_err_path.max(axis=0), n_err_path.max(axis=0),
                           bSp1_err_path.max(axis=0)))).max()))
        # The resource constraint does not bind across the transition
        # path until the equilibrium is solved
        Kpath_init = xi * Kpath_new + (1 - xi) * Kpath_init
        Lpath_init = xi * Lpath_new + (1 - xi) * Lpath_init

    if (iter_TPI == maxiter) and (dist > mindist):
        print('TPI reached maxiter and did not converge.')
    elif (iter_TPI == maxiter) and (dist <= mindist):
        print('TPI converged in the last iteration. ' +
              'Should probably increase maxiter_TPI.')
    Kpath = Kpath_new
    Lpath = Lpath_new
    rpath = rpath_new
    wpath = wpath_new

    tpi_time = time.clock() - start_time

    tpi_output = {
        'cpath': cpath,
        'npath': npath,
        'b_s_path': b_s_path,
        'b_splus1_path': b_splus1_path,
        'wpath': wpath,
        'rpath': rpath,
        'Kpath': Kpath,
        'Lpath': Lpath,
        'Ypath': Ypath,
        'Cpath': Cpath,
        'bSp1_err_path': bSp1_err_path,
        'n_err_path': n_err_path,
        'b_err_path': b_err_path,
        'RCerrPath': RCerrPath,
        'tpi_time': tpi_time
    }

    # Print maximum resource constraint error. Only look at resource
    # constraint up to period T2 - 1 because period T2 includes K_{t+1},
    # which was forced to be the steady-state
    print('Max abs. RC error: ',
          "%10.4e" % (np.absolute(RCerrPath[:T2 - 1]).max()))

    # Print TPI computation time
    utils.print_time(tpi_time, 'TPI')

    if graphs:
        '''
        ----------------------------------------------------------------
        cur_path    = string, path name of current directory
        output_fldr = string, folder in current path to save files
        output_dir  = string, total path of images folder
        output_path = string, path of file name of figure to be saved
        tvec        = (T2+S-1,) vector, time period vector
        tgridT      = (T2,) vector, time period vector from 1 to T2
        sgrid       = (S,) vector, all ages from 1 to S
        tmat        = (S, T2) matrix, time periods for decisions ages
                      (S) and time periods (T2)
        smat        = (S, T2) matrix, ages for all decisions ages (S)
                      and time periods (T2)
        ----------------------------------------------------------------
        '''
        # Create directory if images directory does not already exist
        cur_path = os.path.split(os.path.abspath(__file__))[0]
        output_fldr = "images"
        output_dir = os.path.join(cur_path, output_fldr)
        if not os.access(output_dir, os.F_OK):
            os.makedirs(output_dir)

        # Plot time path of aggregate capital stock
        tvec = np.linspace(1, T2 + S - 1, T2 + S - 1)
        minorLocator = MultipleLocator(1)
        fig, ax = plt.subplots()
        plt.plot(tvec, Kpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate capital stock K')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate capital $K_{t}$')
        output_path = os.path.join(output_dir, 'Kpath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of aggregate capital stock
        fig, ax = plt.subplots()
        plt.plot(tvec, Lpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate labor L')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate labor $L_{t}$')
        output_path = os.path.join(output_dir, 'Lpath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of aggregate output (GDP)
        fig, ax = plt.subplots()
        plt.plot(tvec, Ypath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate output (GDP) Y')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate output $Y_{t}$')
        output_path = os.path.join(output_dir, 'Ypath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of aggregate consumption
        fig, ax = plt.subplots()
        plt.plot(tvec, Cpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for aggregate consumption C')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Aggregate consumption $C_{t}$')
        output_path = os.path.join(output_dir, 'C_aggr_path')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of real wage
        fig, ax = plt.subplots()
        plt.plot(tvec, wpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for real wage w')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Real wage $w_{t}$')
        output_path = os.path.join(output_dir, 'wpath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of real interest rate
        fig, ax = plt.subplots()
        plt.plot(tvec, rpath, marker='D')
        # for the minor ticks, use no labels; default NullFormatter
        ax.xaxis.set_minor_locator(minorLocator)
        plt.grid(b=True, which='major', color='0.65', linestyle='-')
        plt.title('Time path for real interest rate r')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Real interest rate $r_{t}$')
        output_path = os.path.join(output_dir, 'rpath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of individual consumption distribution
        tgridT = np.linspace(1, T2, T2)
        sgrid = np.linspace(1, S, S)
        tmat, smat = np.meshgrid(tgridT, sgrid)
        cmap_c = cm.get_cmap('summer')
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'period-$t$')
        ax.set_ylabel(r'age-$s$')
        ax.set_zlabel(r'individual consumption $c_{s,t}$')
        strideval = max(int(1), int(round(S / 10)))
        ax.plot_surface(tmat,
                        smat,
                        cpath[:, :T2],
                        rstride=strideval,
                        cstride=strideval,
                        cmap=cmap_c)
        output_path = os.path.join(output_dir, 'cpath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of individual labor supply distribution
        cmap_n = cm.get_cmap('summer')
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'period-$t$')
        ax.set_ylabel(r'age-$s$')
        ax.set_zlabel(r'individual labor supply $n_{s,t}$')
        strideval = max(int(1), int(round(S / 10)))
        ax.plot_surface(tmat,
                        smat,
                        npath[:, :T2],
                        rstride=strideval,
                        cstride=strideval,
                        cmap=cmap_n)
        output_path = os.path.join(output_dir, 'npath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

        # Plot time path of individual savings distribution
        cmap_b = cm.get_cmap('summer')
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        ax.set_xlabel(r'period-$t$')
        ax.set_ylabel(r'age-$s$')
        ax.set_zlabel(r'individual savings $b_{s,t}$')
        strideval = max(int(1), int(round(S / 10)))
        ax.plot_surface(tmat,
                        smat,
                        b_splus1_path[:, :T2],
                        rstride=strideval,
                        cstride=strideval,
                        cmap=cmap_b)
        output_path = os.path.join(output_dir, 'bpath')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

    return tpi_output
Esempio n. 30
0
def create_tpi_params(**sim_params):

    '''
    ------------------------------------------------------------------------
    Set factor and initial capital stock to SS from baseline
    ------------------------------------------------------------------------
    '''
    baseline_ss = os.path.join(sim_params['baseline_dir'], "SS/SS_vars.pkl")
    ss_baseline_vars = pickle.load(open(baseline_ss, "rb"))
    factor = ss_baseline_vars['factor_ss']
    initial_b = ss_baseline_vars['bssmat_splus1']
    initial_n = ss_baseline_vars['nssmat']
    if sim_params['baseline_spending']==True:
        baseline_tpi = os.path.join(sim_params['baseline_dir'], "TPI/TPI_vars.pkl")
        tpi_baseline_vars = pickle.load(open(baseline_tpi, "rb"))
        T_Hbaseline = tpi_baseline_vars['T_H']
        Gbaseline   = tpi_baseline_vars['G']

    theta_params = (sim_params['e'], sim_params['S'], sim_params['retire'])
    if sim_params['baseline']==True:
        SS_values = (ss_baseline_vars['Kss'], ss_baseline_vars['Bss'], ss_baseline_vars['Lss'], ss_baseline_vars['rss'],
                 ss_baseline_vars['wss'], ss_baseline_vars['BQss'], ss_baseline_vars['T_Hss'], ss_baseline_vars['revenue_ss'],
                 ss_baseline_vars['bssmat_splus1'], ss_baseline_vars['nssmat'], ss_baseline_vars['Yss'], ss_baseline_vars['Gss'])
        theta = tax.replacement_rate_vals(ss_baseline_vars['nssmat'], ss_baseline_vars['wss'], factor, theta_params)
    elif sim_params['baseline']==False:
        reform_ss = os.path.join(sim_params['input_dir'], "SS/SS_vars.pkl")
        ss_reform_vars = pickle.load(open(reform_ss, "rb"))
        SS_values = (ss_reform_vars['Kss'],ss_reform_vars['Bss'], ss_reform_vars['Lss'], ss_reform_vars['rss'],
                 ss_reform_vars['wss'], ss_reform_vars['BQss'], ss_reform_vars['T_Hss'], ss_reform_vars['revenue_ss'],
                 ss_reform_vars['bssmat_splus1'], ss_reform_vars['nssmat'], ss_reform_vars['Yss'], ss_reform_vars['Gss'])
        theta = tax.replacement_rate_vals(ss_reform_vars['nssmat'], ss_reform_vars['wss'], factor, theta_params)

    # Make a vector of all one dimensional parameters, to be used in the
    # following functions
    wealth_tax_params = [sim_params['h_wealth'], sim_params['p_wealth'], sim_params['m_wealth']]
    ellipse_params = [sim_params['b_ellipse'], sim_params['upsilon']]
    chi_params = [sim_params['chi_b_guess'], sim_params['chi_n_guess']]

    N_tilde = sim_params['omega'].sum(1) #this should just be one in each year given how we've constructed omega
    sim_params['omega'] = sim_params['omega'] / N_tilde.reshape(sim_params['T'] + sim_params['S'], 1)



    tpi_params = [sim_params['J'], sim_params['S'], sim_params['T'], sim_params['BW'],
                  sim_params['beta'], sim_params['sigma'], sim_params['alpha'],
                  sim_params['gamma'], sim_params['epsilon'],
                  sim_params['Z'], sim_params['delta'], sim_params['ltilde'],
                  sim_params['nu'], sim_params['g_y'], sim_params['g_n_vector'],
                  sim_params['tau_payroll'], sim_params['tau_bq'], sim_params['rho'], sim_params['omega'], N_tilde,
                  sim_params['lambdas'], sim_params['imm_rates'], sim_params['e'], sim_params['retire'], sim_params['mean_income_data'], factor] + \
                  wealth_tax_params + ellipse_params + chi_params + [theta]
    iterative_params = [sim_params['maxiter'], sim_params['mindist_SS'], sim_params['mindist_TPI']]
    small_open_params = [sim_params['small_open'], sim_params['tpi_firm_r'], sim_params['tpi_hh_r']]


    J, S, T, BW, beta, sigma, alpha, gamma, epsilon, Z, delta, ltilde, nu, g_y,\
                  g_n_vector, tau_payroll, tau_bq, rho, omega, N_tilde, lambdas, imm_rates, e, retire, mean_income_data,\
                  factor, h_wealth, p_wealth, m_wealth, b_ellipse, upsilon, chi_b, chi_n, theta = tpi_params

    ## Assumption for tax functions is that policy in last year of BW is
    # extended permanently
    etr_params_TP = np.zeros((S,T+S,sim_params['etr_params'].shape[2]))
    etr_params_TP[:,:BW,:] = sim_params['etr_params']
    etr_params_TP[:,BW:,:] = np.reshape(sim_params['etr_params'][:,BW-1,:],(S,1,sim_params['etr_params'].shape[2]))

    mtrx_params_TP = np.zeros((S,T+S,sim_params['mtrx_params'].shape[2]))
    mtrx_params_TP[:,:BW,:] = sim_params['mtrx_params']
    mtrx_params_TP[:,BW:,:] = np.reshape(sim_params['mtrx_params'][:,BW-1,:],(S,1,sim_params['mtrx_params'].shape[2]))

    mtry_params_TP = np.zeros((S,T+S,sim_params['mtry_params'].shape[2]))
    mtry_params_TP[:,:BW,:] = sim_params['mtry_params']
    mtry_params_TP[:,BW:,:] = np.reshape(sim_params['mtry_params'][:,BW-1,:],(S,1,sim_params['mtry_params'].shape[2]))

    income_tax_params = (sim_params['analytical_mtrs'], etr_params_TP, mtrx_params_TP, mtry_params_TP)

    '''
    ------------------------------------------------------------------------
    Set government finance parameters
    ------------------------------------------------------------------------
    '''
    budget_balance = sim_params['budget_balance']
    ALPHA_T        = sim_params['ALPHA_T']
    ALPHA_G        = sim_params['ALPHA_G']
    tG1            = sim_params['tG1']
    tG2            = sim_params['tG2']
    rho_G          = sim_params['rho_G']
    debt_ratio_ss  = sim_params['debt_ratio_ss']
    if sim_params['baseline_spending']==False:
        fiscal_params  = (budget_balance, ALPHA_T, ALPHA_G, tG1, tG2, rho_G, debt_ratio_ss)
    else:
        fiscal_params  = (budget_balance, ALPHA_T, ALPHA_G, tG1, tG2, rho_G, debt_ratio_ss, T_Hbaseline, Gbaseline)

    initial_debt  = sim_params['initial_debt']

    '''
    ------------------------------------------------------------------------
    Set business tax parameters
    ------------------------------------------------------------------------
    '''
    tau_b = sim_params['tau_b']
    delta_tau = sim_params['delta_tau']
    biz_tax_params  = (tau_b, delta_tau)

    initial_debt  = sim_params['initial_debt']

    '''
    ------------------------------------------------------------------------
    Set other parameters and initial values
    ------------------------------------------------------------------------
    '''
    # Get an initial distribution of wealth with the initial population
    # distribution. When small_open=True, the value of K0 is used as a placeholder for first-period wealth (B0)
    omega_S_preTP = sim_params['omega_S_preTP']
    B0_params = (omega_S_preTP.reshape(S, 1), lambdas, imm_rates[0].reshape(S,1), g_n_vector[0], 'SS')
    B0 = aggr.get_K(initial_b, B0_params)

    b_sinit = np.array(list(np.zeros(J).reshape(1, J)) + list(initial_b[:-1]))
    b_splus1init = initial_b

    initial_values = (B0, b_sinit, b_splus1init, factor, initial_b, initial_n, omega_S_preTP, initial_debt)

    return (income_tax_params, tpi_params, iterative_params, small_open_params, initial_values, SS_values, fiscal_params, biz_tax_params)