Пример #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
Пример #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
Пример #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
Пример #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, :]
Пример #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
Пример #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
Пример #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
Пример #8
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)
Пример #9
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
Пример #10
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)
Пример #11
0
def get_SS(rh_ss_guess, rf_ss_guess, q_ss_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:
    rh_ss_guess = scalar > 0, initial guess for rh_ss
    rf_ss_guess = scalar > 0, initial guess for rf_ss
    q_ss_guess  = scalar > 0, initial guess for q_ss
    args        = length 19 tuple, arguments passed in to get_SS()
    graphs      = boolean, =True if output steady-state graphs

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        outer_loop()
        firms.get_comp_r()
        firms.get_KLratio()
        firms.get_w_KL()
        hh.get_cbvec()
        aggr.get_L()
        aggr.get_Y()
        firms.get_K_ownown()
        aggr.get_C()
        aggr.get_I()
        aggr.get_NX()
        utils.print_time()
        get_ss_graphs()

    OBJECTS CREATED WITHIN FUNCTION:
    start_time  = scalar > 0, clock time at beginning of program
    S           = integer in [3,80], number of periods an individual
                  lives
    nhvec       = (S,) vector, exogenous Home labor supply n_{h,s,t}
    nfvec       = (S,) vector, exogenous Foreign labor supply n_{h,s,t}
    beta        = scalar in (0,1), discount factor for each model period
    sigma       = scalar > 0, coefficient of relative risk aversion
    alpha_h     = scalar in (0, 1), share parameter in CES production
                  function of Home intermediate goods producer
    phi_h       = scalar >= 1, elasticity of substitution in CES
                  production function of Home intermediate goods
                  producer
    Z_h         = scalar > 0, total factor productivity parameter in
                  Home final goods producer production function
    gamma_h     = scalar in (0, 1), capital share of income in Home
                  Cobb-Douglas production function
    delta_h     = scalar in [0,1], model-period depreciation rate of
                  Home final goods capital
    alpha_f     = scalar in (0, 1), share parameter in CES production
                  function of Foreign intermediate goods producer
    phi_f       = scalar >= 1, elasticity of substitution in CES
                  production function of Foreign intermediate goods
                  producer
    Z_f         = scalar > 0, total factor productivity parameter in
                  Foreign final goods producer production function
    gamma_f     = scalar in (0, 1), capital share of income in Foreign
                  Cobb-Douglas production function
    delta_f     = scalar in [0,1], model-period depreciation rate of
                  Foreign final goods capital
    tol_outer   = scalar > 0, tolerance level for steady-state outer-
                  loop convergence
    tol_inner   = scalar > 0, tolerance level for inner-loop root finder
    xi          = scalar in (0, 1], outer loop updating parameter
    maxiter     = integer >= 1, maximum number of iterations for outer
                  loop fixed point algorithm
    EulDiff     = boolean, =True if use simple differences in Euler
                  errors. Otherwise, use percent deviation form
    results_ol  = length 5 tuple, results from outer_loop() function
    rh_ss       = scalar > 0, steady-state return on Home savings
    rf_ss       = scalar > 0, steady-state return on Foreign savings
    q_ss        = scalar > 0, real exchange rate # Foreign consumption
                  goods per 1 Domestic consumption good
    ol_dist     = scalar > 0, outer loop distance measure
    ol_success  = boolean, =True if outer loop converged
    r_ss        = scalar > -delta_h, steady-state Home composite
                  interest rate
    rstar_ss    = scalar > -delta_f, steady-state Foreign composite
                  interest rate
    KL_rat_h    = scalar > 0, Home final goods capital labor ratio
    KL_rat_f    = scalar > 0, Foreign final goods capital labor ratio
    wh_ss       = scalar > 0, steady-state Home wage
    wf_ss       = scalar > 0, steady-state Foreign wage
    r_h_path    = (S,) vector, steady-state Home composite interest rate
                  over the periods of an agent's life
    w_h_path    = (S,) vector, steady-state Home wage over the periods
                  of an agent's life
    cbh_args    = length 6 tuple, arguments to pass into hh.get_cbvec()
    ch_ss       = (S,) vector, steady-state Home household consumption
                  for each age (c_1, c_2, ...c_S)
    bh_ss       = (S-1,) vector, steady-state Home household savings
                  for each age (b_2, b_3, ...b_S)
    bhss_errors = (S-1,) vector, steady-state Home household Euler
                  equation errors for savings decision
    success_h   = boolean, =True if root finder for inner loop Home
                  household savings decision converged
    r_f_path    = (S,) vector, steady-state Foreign composite interest
                  rate over the periods of an agent's life
    w_f_path    = (S,) vector, steady-state Foreign wage over the
                  periods of an agent's life
    cbf_args    = length 6 tuple, arguments to pass into hh.get_cbvec()
    cf_ss       = (S,) vector, steady-state Foreign household
                  consumption for each age (c_1, c_2, ...c_S)
    bf_ss       = (S-1,) vector, steady-state Foreign household savings
                  for each age (b_2, b_3, ...b_S)
    bfss_errors = (S-1,) vector, steady-state Foreign household Euler
                  equation errors for savings decision
    success_f   = boolean, =True if root finder for inner loop Foreign
                  household savings decision converged
    L_h_ss      = scalar > 0, steady-state Home aggregate labor
    L_f_ss      = scalar > 0, steady-state Foreign aggregate labor
    K_h_ss      = scalar > 0, steady-state Home final goods capital
                  stock
    K_f_ss      = scalar > 0, steady-state Foreign final goods capital
                  stock
    Yh_ss       = scalar > 0, steady-state Home aggregate final goods
                  output (GDP)
    Yf_ss       = scalar > 0, steady-state Foreign aggregate final goods
                  output (GDP)
    K_hh_ss     = scalar > 0, steady-state total Home country savings
                  allocated to Home country intermed't goods production
    K_ff_ss     = scalar > 0, steady-state total Foreign country savings
                  allocated to Foreign country int'd't goods production
    K_fh_ss     = scalar > 0, steady-state total Home country savings
                  allocated to Foreign country int'd't goods production
    K_hf_ss     = scalar > 0, steady-state total Foreign country savings
                  allocated to Home country intermed't goods production
    Ch_ss       = scalar > 0, steady-state Home aggregate consumption
    Cf_ss       = scalar > 0, steady-state Foreign aggregate consumption
    Ih_ss       = scalar, steady-state Home aggregate investment
    If_ss       = scalar, steady-state Foreign aggregate investment
    NXh_ss      = scalar, steady-state Home net exports
    NXf_ss      = scalar, steady-state Foreign net exports
    RC_h_err_ss = scalar, steady-state Home goods market clearing
                  (resource constraint) error
    RC_f_err_ss = scalar, steady-state Foreign goods market clearing
                  (resource constraint) error
    ss_time     = scalar > 0, time elapsed during SS computation
                  (in seconds)
    ss_output   = length 30 dict, steady-state equilibrium objects
                  {bh_ss, ch_ss, bhss_errors, bf_ss, cf_ss, bfss_errors,
                  wh_ss, rh_ss, r_ss, q_ss, wf_ss, rf_ss, rstar_ss,
                  L_h_ss, K_h_ss, K_hh_ss, K_fh_ss, Yh_ss, Ih_ss,
                  NXh_ss, L_f_ss, K_f_ss, K_ff_ss, K_hf_ss, Yf_ss,
                  If_ss, NXf_ss, RC_h_err_ss, RC_f_err_ss, ss_time}

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: ss_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    (nhvec, nfvec, beta, sigma, alpha_h, phi_h, Z_h, gamma_h, delta_h, alpha_f,
     phi_f, Z_f, gamma_f, delta_f, tol_outer, tol_inner, xi, maxiter,
     EulDiff) = args
    S = nhvec.shape[0]
    results_ol = outer_loop(rh_ss_guess, rf_ss_guess, q_ss_guess, args)
    rh_ss, rf_ss, q_ss, ol_dist, ol_success = results_ol
    # Solve for composite r and rstar
    r_ss = firms.get_comp_r(rh_ss, rf_ss, q_ss, alpha_h, phi_h, home=True)
    rstar_ss = firms.get_comp_r(rf_ss, rh_ss, q_ss, alpha_f, phi_f, home=False)
    # Solve for capital-labor ratios and wages in both countries
    KL_rat_h = firms.get_KLratio(r_ss, gamma_h, Z_h, delta_h)
    KL_rat_f = firms.get_KLratio(rstar_ss, gamma_f, Z_f, delta_f)
    wh_ss = firms.get_w_KL(KL_rat_h, gamma_h, Z_h)
    wf_ss = firms.get_w_KL(KL_rat_f, gamma_f, Z_f)
    # Solve for household decisions in Home country
    r_h_path = rh_ss * np.ones(S)
    w_h_path = wh_ss * np.ones(S)
    bhvec_init = 0.02 * np.ones(S - 1)
    cbh_args = (0.0, nhvec, beta, sigma, EulDiff, tol_inner)
    bh_ss, ch_ss, bhss_errors, success_h = \
        hh.get_cbvec(bhvec_init, r_h_path, w_h_path, cbh_args)
    # Solve for household decisions in Foreign country
    r_f_path = rf_ss * np.ones(S)
    w_f_path = wf_ss * np.ones(S)
    bfvec_init = 0.02 * np.ones(S - 1)
    cbf_args = (0.0, nfvec, beta, sigma, EulDiff, tol_inner)
    bf_ss, cf_ss, bfss_errors, success_f = \
        hh.get_cbvec(bfvec_init, r_f_path, w_f_path, cbf_args)
    # Solve for Home and Foreign aggregate labor supply
    L_h_ss = aggr.get_L(nhvec)
    L_f_ss = aggr.get_L(nfvec)
    # Solve for Home and Foreign aggregate final goods capital stock
    K_h_ss = KL_rat_h * L_h_ss
    K_f_ss = KL_rat_f * L_f_ss
    # Solve for Home and Foreign aggregate final goods output (GDP)
    Yh_ss = aggr.get_Y(K_h_ss, L_h_ss, gamma_h, Z_h)
    Yf_ss = aggr.get_Y(K_f_ss, L_f_ss, gamma_f, Z_f)
    # Solve for Home and Foreign savings invested in own-country
    # intermediate goods production
    K_hh_ss = firms.get_K_ownown(K_h_ss, r_ss, rh_ss, alpha_h, phi_h)
    K_ff_ss = firms.get_K_ownown(K_f_ss, rstar_ss, rf_ss, alpha_f, phi_f)
    # Solve for Home and Foreign savings invested in other-country
    # intermediate goods production
    K_fh_ss = bh_ss.sum() - K_hh_ss
    K_hf_ss = bf_ss.sum() - K_ff_ss
    # Solve for Home and Foreign aggregate consumption
    Ch_ss = aggr.get_C(ch_ss)
    Cf_ss = aggr.get_C(cf_ss)
    # Solve for Home and Foreign aggregate investment
    Ih_ss = aggr.get_I(K_h_ss, K_h_ss, delta_h)
    If_ss = aggr.get_I(K_f_ss, K_f_ss, delta_f)
    # Solve for Home and Foreign net exports
    NXh_ss = aggr.get_NX(K_hh_ss, K_fh_ss, K_hh_ss, K_fh_ss, K_h_ss, K_h_ss,
                         r_ss, rh_ss)
    NXf_ss = aggr.get_NX(K_ff_ss, K_hf_ss, K_ff_ss, K_hf_ss, K_f_ss, K_f_ss,
                         rstar_ss, rf_ss)
    # NXh_ss = r_ss * K_h_ss - rh_ss * (K_hh_ss + K_fh_ss)
    # NXf_ss = rstar_ss * K_f_ss - rf_ss * (K_ff_ss + K_hf_ss)
    # Solve for Home and Foreign goods market clearing (resource
    # constraint) errors
    RC_h_err_ss = Yh_ss - Ch_ss - Ih_ss - NXh_ss
    RC_f_err_ss = Yf_ss - Cf_ss - If_ss - NXf_ss

    ss_time = time.clock() - start_time

    ss_output = \
        {'bh_ss': bh_ss, 'ch_ss': ch_ss, 'bhss_errors': bhss_errors,
         'bf_ss': bf_ss, 'cf_ss': cf_ss, 'bfss_errors': bfss_errors,
         'wh_ss': wh_ss, 'rh_ss': rh_ss, 'r_ss': r_ss, 'q_ss': q_ss,
         'wf_ss': wf_ss, 'rf_ss': rf_ss, 'rstar_ss': rstar_ss,
         'L_h_ss': L_h_ss, 'K_h_ss': K_h_ss, 'K_hh_ss': K_hh_ss,
         'K_fh_ss': K_fh_ss, 'Yh_ss': Yh_ss, 'Ih_ss': Ih_ss,
         'NXh_ss': NXh_ss, 'L_f_ss': L_f_ss, 'K_f_ss': K_f_ss,
         'K_ff_ss': K_ff_ss, 'K_hf_ss': K_hf_ss, 'Yf_ss': Yf_ss,
         'If_ss': If_ss, 'NXf_ss': NXf_ss, 'RC_h_err_ss': RC_h_err_ss,
         'RC_f_err_ss': RC_f_err_ss, 'ss_time': ss_time}

    with np.printoptions(precision=4):
        print('bh_ss is: ', bh_ss)
        print('bf_ss is: ', bf_ss)
    print('K_h_ss=', '%10.4f' % K_h_ss, ', rh_ss=', '%10.4f' % rh_ss,
          ', r_ss=', '%10.4f' % r_ss, ', wh_ss=', '%10.4f' % wh_ss)
    print('K_f_ss=', '%10.4f' % K_f_ss, ', rf_ss=', '%10.4f' % rf_ss,
          ', r*_ss=', '%10.4f' % rstar_ss, ', wf_ss=', '%10.4f' % wf_ss)
    print('Real exchange rate=', '%10.4f' % q_ss)
    print('Max. abs. savings Euler error is: ',
          '%10.4e' % np.absolute(np.append(bhss_errors, bfss_errors)).max())
    print('Max. abs. resource constraint error is: ',
          '%10.4e' % np.absolute(np.append(RC_h_err_ss, RC_f_err_ss)).max())

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

    if graphs:
        get_ss_graphs(ch_ss, bh_ss, home=True)
        get_ss_graphs(cf_ss, bf_ss, home=False)

    return ss_output
Пример #12
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
Пример #13
0
def outer_loop(rh_init, rf_init, q_init, args):
    '''
    --------------------------------------------------------------------
    Bisection method solving for rh, rf, and q that solves for the
    outer-loop
    --------------------------------------------------------------------
    INPUTS:
    rh_init = scalar > 0, initial guess for rh_ss
    rf_init = scalar > 0, initial guess for rf_ss
    q_init  = scalar > 0, initial guess for q_ss
    args    = length 19 tuple, arguments for function

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        firms.get_comp_r()
        firms.get_KLratio()
        firms.get_w_KL()
        hh.get_cbvec()
        aggr.get_L()
        firms.get_K_ownown()
        firms.get_r_own_new()

    OBJECTS CREATED WITHIN FUNCTION:
    S          = integer in [3,80], number of periods an individual
                 lives
    nhvec      = (S,) vector, exogenous Home labor supply n_{h,s,t}
    nfvec      = (S,) vector, exogenous Foreign labor supply n_{h,s,t}
    beta       = scalar in (0,1), discount factor for each model period
    sigma      = scalar > 0, coefficient of relative risk aversion
    alpha_h    = scalar in (0, 1), share parameter in CES production
                 function of Home intermediate goods producer
    phi_h      = scalar >= 1, elasticity of substitution in CES
                 production function of Home intermediate goods producer
    Z_h        = scalar > 0, total factor productivity parameter in Home
                 final goods producer production function
    gamma_h    = scalar in (0, 1), capital share of income in Home Cobb-
                 Douglas production function
    delta_h    = scalar in [0,1], model-period depreciation rate of Home
                 final goods capital
    alpha_f    = scalar in (0, 1), share parameter in CES production
                 function of Foreign intermediate goods producer
    phi_f      = scalar >= 1, elasticity of substitution in CES
                 production function of Foreign intermediate goods
                 producer
    Z_f        = scalar > 0, total factor productivity parameter in
                 Foreign final goods producer production function
    gamma_f    = scalar in (0, 1), capital share of income in Foreign
                 Cobb-Douglas production function
    delta_f    = scalar in [0,1], model-period depreciation rate of
                 Foreign final goods capital
    tol_outer  = scalar > 0, tolerance level for steady-state outer-loop
                 convergence
    tol_inner  = scalar > 0, tolerance level for inner-loop root finder
    xi         = scalar in (0, 1], outer loop updating parameter
    maxiter    = integer >= 1, maximum number of iterations for outer
                 loop fixed point algorithm
    EulDiff    = boolean, =True if use simple differences in Euler
                 errors. Otherwise, use percent deviation form
    dist       = scalar > 0, distance measure between initial guess and
                 predicted value
    SS_iter    = integer >= 0, iteration number of fixed point algorithm
    rhrfq_init = (3,) vector, initial values of (rh, rf, q)
    rh_comp    = scalar > -delta_h, Home composite consumption
    rf_comp    = scalar > -delta_f, Foreign composite consumption
    KL_rat_h   = scalar > 0, Home final goods capital labor ratio
    KL_rat_f   = scalar > 0, Foreign final goods capital labor ratio
    w_h        = scalar > 0, steady-state Home wage
    w_f        = scalar > 0, steady-state Foreign wage
    r_h_path   = (S,) vector, steady-state Home composite interest rate
                 over the periods of an agent's life
    w_h_path   = (S,) vector, steady-state Home wage over the periods
                 of an agent's life
    bhvec_init = (S-1,) vector, initial guess for Home steady-state
                 lifetime savings vector
    cbh_args   = length 6 tuple, arguments to pass in to hh.get_cbvec()
    bhvec      = (S-1,) vector, steady-state Home household savings for
                 each age (b_2, b_3, ...b_S)
    chvec      = (S,) vector, steady-state Home household consumption
                 for each age (c_1, c_2, ...c_S)
    bh_errors  = (S-1,) vector, steady-state Home household Euler
                 equation errors for savings decision
    success_h  = boolean, =True if root finder for inner loop Home
                 household savings decision converged
    r_f_path   = (S,) vector, steady-state Foreign composite interest
                 rate over the periods of an agent's life
    w_f_path   = (S,) vector, steady-state Foreign wage over the periods
                 of an agent's life
    bfvec_init = (S-1,) vector, initial guess for Foreign steady-state
                 lifetime savings vector
    cbf_args   = length 6 tuple, arguments to pass in to hh.get_cbvec()
    bfvec      = (S-1,) vector, steady-state Foreign household savings
                 for each age (b_2, b_3, ...b_S)
    cfvec      = (S,) vector, steady-state Foreign household consumption
                 for each age (c_1, c_2, ...c_S)
    bf_errors  = (S-1,) vector, steady-state Foreign household Euler
                 equation errors for savings decision
    success_f  = boolean, =True if root finder for inner loop Foreign
                 household savings decision converged
    L_h        = scalar > 0, steady-state Home aggregate labor
    L_f        = scalar > 0, steady-state Foreign aggregate labor
    K_h        = scalar > 0, steady-state Home final goods capital stock
    K_f        = scalar > 0, steady-state Foreign final goods capital
                 stock
    K_hh       = scalar > 0, steady-state total Home country savings
                 allocated to Home country intermed't goods production
    K_ff       = scalar > 0, steady-state total Foreign country savings
                 allocated to Foreign country int'd't goods production
    K_fh       = scalar > 0, steady-state total Home country savings
                 allocated to Foreign country int'd't goods production
    K_hf       = scalar > 0, steady-state total Foreign country savings
                 allocated to Home country intermed't goods production
    rh_new     = scalar > 0, new predicted value for rh_ss
    rf_new     = scalar > 0, new predicted value for rf_ss
    q_new      = scalar > 0, new predicted value for q_ss
    rhrfq_new  = (3,) vector, new values of (rh, rf, q)
    success    = boolean, =True if outer loop algorithm converged
    rh_ss      = scalar > 0, steady-state return on Home savings
    rf_ss      = scalar > 0, steady-state return on Foreign savings
    q_ss       = scalar > 0, real exchange rate # Foreign consumption
                 goods per 1 Domestic consumption good

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: rh_ss, rf_ss, q_ss, dist, success
    --------------------------------------------------------------------
    '''
    (nhvec, nfvec, beta, sigma, alpha_h, phi_h, Z_h, gamma_h, delta_h, alpha_f,
     phi_f, Z_f, gamma_f, delta_f, tol_outer, tol_inner, xi, maxiter,
     EulDiff) = args

    S = nhvec.shape[0]
    dist = 10.0
    SS_iter = 0
    rhrfq_init = np.array([rh_init, rf_init, q_init])
    print('SS iter=', SS_iter, ', Dist=', dist, ', (r_h, r_f, q)=', rhrfq_init)
    while dist >= tol_outer and SS_iter <= maxiter:
        SS_iter += 1
        # Solve for composite r and rstar
        rh_comp = firms.get_comp_r(rh_init,
                                   rf_init,
                                   q_init,
                                   alpha_h,
                                   phi_h,
                                   home=True)
        rf_comp = firms.get_comp_r(rf_init,
                                   rh_init,
                                   q_init,
                                   alpha_f,
                                   phi_f,
                                   home=False)
        # Solve for capital-labor ratios and wages in both countries
        KL_rat_h = firms.get_KLratio(rh_comp, gamma_h, Z_h, delta_h)
        KL_rat_f = firms.get_KLratio(rf_comp, gamma_f, Z_f, delta_f)
        w_h = firms.get_w_KL(KL_rat_h, gamma_h, Z_h)
        w_f = firms.get_w_KL(KL_rat_f, gamma_f, Z_f)
        # Solve for household decisions in Home country
        r_h_path = rh_init * np.ones(S)
        w_h_path = w_h * np.ones(S)
        bhvec_init = 0.02 * np.ones(S - 1)
        cbh_args = (0.0, nhvec, beta, sigma, EulDiff, tol_inner)
        bhvec, chvec, bh_errors, success_h = \
            hh.get_cbvec(bhvec_init, r_h_path, w_h_path, cbh_args)
        # Solve for household decisions in Foreign country
        r_f_path = rf_init * np.ones(S)
        w_f_path = w_f * np.ones(S)
        bfvec_init = 0.02 * np.ones(S - 1)
        cbf_args = (0.0, nfvec, beta, sigma, EulDiff, tol_inner)
        bfvec, cfvec, bf_errors, success_f = \
            hh.get_cbvec(bfvec_init, r_f_path, w_f_path, cbf_args)
        # Solve for Home and Foreign aggregate labor supply
        L_h = aggr.get_L(nhvec)
        L_f = aggr.get_L(nfvec)
        # Solve for Home and Foreign aggregate final goods capital stock
        K_h = KL_rat_h * L_h
        K_f = KL_rat_f * L_f
        # Solve for Home and Foreign savings invested in own-country
        # intermediate goods production
        K_hh = firms.get_K_ownown(K_h, rh_comp, rh_init, alpha_h, phi_h)
        K_ff = firms.get_K_ownown(K_f, rf_comp, rf_init, alpha_f, phi_f)
        # Solve for Home and Foreign savings invested in other-country
        # intermediate goods production
        K_fh = bhvec.sum() - K_hh
        K_hf = bfvec.sum() - K_ff
        # Compute new values for r_h, r_f, and q and calulate distance
        rh_new = firms.get_r_own_new(K_f,
                                     K_fh,
                                     rf_comp,
                                     q_init,
                                     alpha_f,
                                     phi_f,
                                     home=True)
        rf_new = firms.get_r_own_new(K_h,
                                     K_hf,
                                     rh_comp,
                                     q_init,
                                     alpha_h,
                                     phi_h,
                                     home=False)
        q_new = (rf_init * K_hf) / (rh_init * K_fh)
        rhrfq_new = np.array([rh_new, rf_new, q_new])
        dist = ((rhrfq_new - rhrfq_init)**2).sum()
        # Update initial values of outer loop variables
        rhrfq_init = xi * rhrfq_new + (1 - xi) * rhrfq_init
        print('SS iter=', SS_iter, ', Dist=', '%10.4e' % (dist))
        # print(', (r_h, r_f, q)=', rhrfq_init)

    if dist >= tol_outer:
        success = False
    else:
        success = True
    rh_ss, rf_ss, q_ss = rhrfq_init

    return rh_ss, rf_ss, q_ss, dist, success
Пример #14
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]
Пример #15
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)
Пример #16
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
Пример #17
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
Пример #18
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
Пример #19
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
Пример #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
Пример #21
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
Пример #22
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
Пример #23
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
Пример #24
0
def outer_loop(rh_init, rf_init, q_init, args):
    '''
    --------------------------------------------------------------------
    Bisection method solving for rh, rf, and q that solves for the outer-loop
    --------------------------------------------------------------------
    '''
    (nhvec, nfvec, beta, sigma, alpha_h, phi_h, Z_h, gamma_h, delta_h, alpha_f,
     phi_f, Z_f, gamma_f, delta_f, tol_outer, tol_inner, xi, maxiter,
     EulDiff) = args

    S = nhvec.shape[0]
    dist = 10.0
    SS_iter = 0
    rhrfq_init = np.array([rh_init, rf_init, q_init])
    print('SS iter=', SS_iter, ', Dist=', dist, ', (r_h, r_f, q)=', rhrfq_init)
    while dist >= tol_outer and SS_iter <= maxiter:
        SS_iter += 1
        # Solve for composite r and rstar
        rh_comp = firms.get_comp_r(rh_init,
                                   rf_init,
                                   q_init,
                                   alpha_h,
                                   phi_h,
                                   home=True)
        rf_comp = firms.get_comp_r(rf_init,
                                   rh_init,
                                   q_init,
                                   alpha_f,
                                   phi_f,
                                   home=False)
        # Solve for capital-labor ratios and wages in both countries
        KL_rat_h = firms.get_KLratio(rh_comp, gamma_h, Z_h, delta_h)
        KL_rat_f = firms.get_KLratio(rf_comp, gamma_f, Z_f, delta_f)
        w_h = firms.get_w_KL(KL_rat_h, gamma_h, Z_h)
        w_f = firms.get_w_KL(KL_rat_f, gamma_f, Z_f)
        # Solve for household decisions in Home country
        r_h_path = rh_init * np.ones(S)
        w_h_path = w_h * np.ones(S)
        bhvec_init = 0.02 * np.ones(S - 1)
        cbh_args = (0.0, nhvec, beta, sigma, EulDiff, tol_inner)
        bhvec, chvec, bh_errors, success_h = \
            hh.get_cbvec(bhvec_init, r_h_path, w_h_path, cbh_args)
        # Solve for household decisions in Foreign country
        r_f_path = rf_init * np.ones(S)
        w_f_path = w_f * np.ones(S)
        bfvec_init = 0.02 * np.ones(S - 1)
        cbf_args = (0.0, nfvec, beta, sigma, EulDiff, tol_inner)
        bfvec, cfvec, bf_errors, success_f = \
            hh.get_cbvec(bfvec_init, r_f_path, w_f_path, cbf_args)
        # Solve for Home and Foreign aggregate labor supply
        L_h = aggr.get_L(nhvec)
        L_f = aggr.get_L(nfvec)
        # Solve for Home and Foreign aggregate final goods capital stock
        K_h = KL_rat_h * L_h
        K_f = KL_rat_f * L_f
        # Solve for Home and Foreign savings invested in own-country
        # intermediate goods production
        K_hh = firms.get_K_ownown(K_h, rh_comp, rh_init, alpha_h, phi_h)
        K_ff = firms.get_K_ownown(K_f, rf_comp, rf_init, alpha_f, phi_f)
        # Solve for Home and Foreign savings invested in other-country
        # intermediate goods production
        K_fh = bhvec.sum() - K_hh
        K_hf = bfvec.sum() - K_ff
        # Compute new values for r_h, r_f, and q and calulate distance
        rh_new = firms.get_r_own_new(K_f,
                                     K_fh,
                                     rf_comp,
                                     q_init,
                                     alpha_f,
                                     phi_f,
                                     home=True)
        rf_new = firms.get_r_own_new(K_h,
                                     K_hf,
                                     rh_comp,
                                     q_init,
                                     alpha_h,
                                     phi_h,
                                     home=False)
        q_new = (rf_init * K_hf) / (rh_init * K_fh)
        rhrfq_new = np.array([rh_new, rf_new, q_new])
        dist = ((rhrfq_new - rhrfq_init)**2).sum()
        # Update initial values of outer loop variables
        rhrfq_init = xi * rhrfq_new + (1 - xi) * rhrfq_init
        print('SS iter=', SS_iter, ', Dist=', dist, ', (r_h, r_f, q)=',
              rhrfq_init)

    if dist >= tol_outer:
        success = False
    else:
        success = True
    rh_ss, rf_ss, q_ss = rhrfq_init

    return rh_ss, rf_ss, q_ss, dist, success
Пример #25
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
Пример #26
0
def get_SS(rh_ss_guess, rf_ss_guess, q_ss_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()
    (nhvec, nfvec, beta, sigma, alpha_h, phi_h, Z_h, gamma_h, delta_h, alpha_f,
     phi_f, Z_f, gamma_f, delta_f, tol_outer, tol_inner, xi, maxiter,
     EulDiff) = args
    S = nhvec.shape[0]
    results_ol = outer_loop(rh_ss_guess, rf_ss_guess, q_ss_guess, args)
    rh_ss, rf_ss, q_ss, ol_dist, ol_success = results_ol
    # Solve for composite r and rstar
    r_ss = firms.get_comp_r(rh_ss, rf_ss, q_ss, alpha_h, phi_h, home=True)
    rstar_ss = firms.get_comp_r(rf_ss, rh_ss, q_ss, alpha_f, phi_f, home=False)
    # Solve for capital-labor ratios and wages in both countries
    KL_rat_h = firms.get_KLratio(r_ss, gamma_h, Z_h, delta_h)
    KL_rat_f = firms.get_KLratio(rstar_ss, gamma_f, Z_f, delta_f)
    wh_ss = firms.get_w_KL(KL_rat_h, gamma_h, Z_h)
    wf_ss = firms.get_w_KL(KL_rat_f, gamma_f, Z_f)
    # Solve for household decisions in Home country
    r_h_path = rh_ss * np.ones(S)
    w_h_path = wh_ss * np.ones(S)
    bhvec_init = 0.02 * np.ones(S - 1)
    cbh_args = (0.0, nhvec, beta, sigma, EulDiff, tol_inner)
    bh_ss, ch_ss, bhss_errors, success_h = \
        hh.get_cbvec(bhvec_init, r_h_path, w_h_path, cbh_args)
    # Solve for household decisions in Foreign country
    r_f_path = rf_ss * np.ones(S)
    w_f_path = wf_ss * np.ones(S)
    bfvec_init = 0.02 * np.ones(S - 1)
    cbf_args = (0.0, nfvec, beta, sigma, EulDiff, tol_inner)
    bf_ss, cf_ss, bfss_errors, success_f = \
        hh.get_cbvec(bfvec_init, r_f_path, w_f_path, cbf_args)
    # Solve for Home and Foreign aggregate labor supply
    L_h_ss = aggr.get_L(nhvec)
    L_f_ss = aggr.get_L(nfvec)
    # Solve for Home and Foreign aggregate final goods capital stock
    K_h_ss = KL_rat_h * L_h_ss
    K_f_ss = KL_rat_f * L_f_ss
    # Solve for Home and Foreign aggregate final goods output (GDP)
    Yh_ss = aggr.get_Y(K_h_ss, L_h_ss, gamma_h, Z_h)
    Yf_ss = aggr.get_Y(K_f_ss, L_f_ss, gamma_f, Z_f)
    # Solve for Home and Foreign savings invested in own-country
    # intermediate goods production
    K_hh_ss = firms.get_K_ownown(K_h_ss, r_ss, rh_ss, alpha_h, phi_h)
    K_ff_ss = firms.get_K_ownown(K_f_ss, rstar_ss, rf_ss, alpha_f, phi_f)
    # Solve for Home and Foreign savings invested in other-country
    # intermediate goods production
    K_fh_ss = bh_ss.sum() - K_hh_ss
    K_hf_ss = bf_ss.sum() - K_ff_ss
    # Solve for Home and Foreign aggregate consumption
    Ch_ss = ch_ss.sum()
    Cf_ss = cf_ss.sum()
    # Solve for Home and Foreign goods market clearing (resource
    # constraint) errors
    # RC_h_err_ss = Yh_ss - Ch_ss - delta_h * K_h_ss
    # RC_f_err_ss = Yf_ss - Cf_ss - delta_f * K_f_ss
    RC_h_err_ss = (Yh_ss - Ch_ss - (r_ss + delta_h) * K_h_ss + rh_ss *
                   (K_hh_ss + K_fh_ss))
    RC_f_err_ss = (Yf_ss - Cf_ss - (rstar_ss + delta_f) * K_f_ss + rf_ss *
                   (K_ff_ss + K_hf_ss))

    ss_time = time.clock() - start_time

    ss_output = \
        {'bh_ss': bh_ss, 'ch_ss': ch_ss, 'bhss_errors': bhss_errors,
         'bf_ss': bf_ss, 'cf_ss': cf_ss, 'bfss_errors': bfss_errors,
         'wh_ss': wh_ss, 'rh_ss': rh_ss, 'r_ss': r_ss, 'q_ss': q_ss,
         'wf_ss': wf_ss, 'rf_ss': rf_ss, 'rstar_ss': rstar_ss,
         'L_h_ss': L_h_ss, 'K_h_ss': K_h_ss, 'K_hh_ss': K_hh_ss,
         'K_fh_ss': K_fh_ss, 'Yh_ss': Yh_ss, 'L_f_ss': L_f_ss,
         'K_f_ss': K_f_ss, 'K_ff_ss': K_ff_ss, 'K_hf_ss': K_hf_ss,
         'Yf_ss': Yf_ss, 'RC_h_err_ss': RC_h_err_ss,
         'RC_f_err_ss': RC_f_err_ss, 'ss_time': ss_time}

    print('bh_ss is: ', bh_ss)
    print('bf_ss is: ', bf_ss)
    print('K_h_ss=', K_h_ss, ', rh_ss=', rh_ss, ', r_ss=', r_ss, ', wh_ss=',
          wh_ss)
    print('K_f_ss=', K_f_ss, ', rf_ss=', rf_ss, ', rstar_ss=', rstar_ss,
          ', wf_ss=', wf_ss)
    print('Max. abs. savings Euler error is: ',
          np.absolute(np.append(bhss_errors, bfss_errors)).max())
    print('Max. abs. resource constraint error is: ',
          np.absolute(np.append(RC_h_err_ss, RC_f_err_ss)).max())

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

    if graphs:
        get_ss_graphs(ch_ss, bh_ss, home=True)
        get_ss_graphs(cf_ss, bf_ss, home=False)

    return ss_output
Пример #27
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
Пример #28
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
Пример #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
Пример #30
0
def run_TPI(income_tax_params, tpi_params, iterative_params, small_open_params, initial_values, SS_values, fiscal_params, biz_tax_params, output_dir="./OUTPUT", baseline_spending=False):

    # unpack tuples of parameters
    analytical_mtrs, etr_params, mtrx_params, mtry_params = income_tax_params
    maxiter, mindist_SS, mindist_TPI = iterative_params
    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
    # K0, b_sinit, b_splus1init, L0, Y0,\
    #         w0, r0, BQ0, T_H_0, factor, tax0, c0, initial_b, initial_n, omega_S_preTP = initial_values
    small_open, tpi_firm_r, tpi_hh_r = small_open_params
    B0, b_sinit, b_splus1init, factor, initial_b, initial_n, omega_S_preTP, initial_debt = initial_values
    Kss, Bss, Lss, rss, wss, BQss, T_Hss, revenue_ss, bssmat_splus1, nssmat, Yss, Gss = SS_values
    tau_b, delta_tau = biz_tax_params
    if baseline_spending==False:
        budget_balance, ALPHA_T, ALPHA_G, tG1, tG2, rho_G, debt_ratio_ss = fiscal_params
    else:
        budget_balance, ALPHA_T, ALPHA_G, tG1, tG2, rho_G, debt_ratio_ss, T_Hbaseline, Gbaseline = fiscal_params

    print 'Government spending breakpoints are tG1: ', tG1, '; and tG2:', tG2

    TPI_FIG_DIR = output_dir
    # Initialize guesses at time paths
    # Make array of initial guesses for labor supply and savings
    domain = np.linspace(0, T, T)
    domain2 = np.tile(domain.reshape(T, 1, 1), (1, S, J))
    ending_b = bssmat_splus1
    guesses_b = (-1 / (domain2 + 1)) * (ending_b - initial_b) + ending_b
    ending_b_tail = np.tile(ending_b.reshape(1, S, J), (S, 1, 1))
    guesses_b = np.append(guesses_b, ending_b_tail, axis=0)

    domain3 = np.tile(np.linspace(0, 1, T).reshape(T, 1, 1), (1, S, J))
    guesses_n = domain3 * (nssmat - initial_n) + initial_n
    ending_n_tail = np.tile(nssmat.reshape(1, S, J), (S, 1, 1))
    guesses_n = np.append(guesses_n, ending_n_tail, axis=0)
    b_mat = guesses_b#np.zeros((T + S, S, J))
    n_mat = guesses_n#np.zeros((T + S, S, J))
    ind = np.arange(S)

    L_init = np.ones((T+S,))*Lss
    B_init = np.ones((T+S,))*Bss
    L_params = (e.reshape(1, S, J), omega[:T, :].reshape(T, S, 1), lambdas.reshape(1, 1, J), 'TPI')
    L_init[:T]  = aggr.get_L(n_mat[:T], L_params)
    B_params = (omega[:T-1].reshape(T-1, S, 1), lambdas.reshape(1, 1, J), imm_rates[:T-1].reshape(T-1,S,1), g_n_vector[1:T], 'TPI')
    B_init[1:T] = aggr.get_K(b_mat[:T-1], B_params)
    B_init[0] = B0

    if small_open == False:
        if budget_balance:
            K_init = B_init
        else:
            K_init = B_init * Kss/Bss
    else:
        K_params = (Z, gamma, epsilon, delta, tau_b, delta_tau)
        K_init = firm.get_K(L_init, tpi_firm_r, K_params)

    K = K_init
#    if np.any(K < 0):
#        print 'K_init has negative elements. Setting them positive to prevent NAN.'
#        K[:T] = np.fmax(K[:T], 0.05*B[:T])

    L = L_init
    B = B_init
    Y_params = (Z, gamma, epsilon)
    Y = firm.get_Y(K, L, Y_params)
    w_params = (Z, gamma, epsilon)
    w = firm.get_w(Y, L, w_params)
    if small_open == False:
        r_params = (Z, gamma, epsilon, delta, tau_b, delta_tau)
        r = firm.get_r(Y, K, r_params)
    else:
        r = tpi_hh_r

    BQ = np.zeros((T + S, J))
    BQ0_params = (omega_S_preTP.reshape(S, 1), lambdas, rho.reshape(S, 1), g_n_vector[0], 'SS')
    BQ0 = aggr.get_BQ(r[0], initial_b, BQ0_params)
    for j in xrange(J):
        BQ[:, j] = list(np.linspace(BQ0[j], BQss[j], T)) + [BQss[j]] * S
    BQ = np.array(BQ)
    if budget_balance:
        if np.abs(T_Hss) < 1e-13 :
            T_Hss2 = 0.0 # sometimes SS is very small but not zero, even if taxes are zero, this get's rid of the approximation error, which affects the perc changes below
        else:
            T_Hss2 = T_Hss
        T_H = np.ones(T + S) * T_Hss2
        REVENUE = T_H
        G = np.zeros(T + S)
    elif baseline_spending==False:
        T_H = ALPHA_T * Y
    elif baseline_spending==True:
        T_H = T_Hbaseline
        T_H_new = T_H   # Need to set T_H_new for later reference
        G   = Gbaseline
        G_0 = Gbaseline[0]

    # Initialize some inputs
    # D = np.zeros(T + S)
    D = debt_ratio_ss*Y
    omega_shift = np.append(omega_S_preTP.reshape(1,S),omega[:T-1,:],axis=0)
    BQ_params = (omega_shift.reshape(T, S, 1), lambdas.reshape(1, 1, J), rho.reshape(1, S, 1),
                     g_n_vector[:T].reshape(T, 1), 'TPI')
    tax_params = np.zeros((T,S,J,etr_params.shape[2]))
    for i in range(etr_params.shape[2]):
        tax_params[:,:,:,i] = np.tile(np.reshape(np.transpose(etr_params[:,:T,i]),(T,S,1)),(1,1,J))
    REVENUE_params = (np.tile(e.reshape(1, S, J),(T,1,1)), lambdas.reshape(1, 1, J), omega[:T].reshape(T, S, 1), 'TPI',
                      tax_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau)


    # print 'D/Y:', D[:T]/Y[:T]
    # print 'T/Y:', T_H[:T]/Y[:T]
    # print 'G/Y:', G[:T]/Y[:T]
    # print 'Int payments to GDP:', (r[:T]*D[:T])/Y[:T]
    # quit()


    TPIiter = 0
    TPIdist = 10
    PLOT_TPI = False
    report_tG1 = False

    euler_errors = np.zeros((T, 2 * S, J))
    TPIdist_vec = np.zeros(maxiter)

    print 'analytical mtrs in tpi = ', analytical_mtrs


    while (TPIiter < maxiter) and (TPIdist >= mindist_TPI):

        # Plot TPI for K for each iteration, so we can see if there is a
        # problem
        if PLOT_TPI is True:
            #K_plot = list(K) + list(np.ones(10) * Kss)
            D_plot = list(D) + list(np.ones(10) * Yss * debt_ratio_ss)
            plt.figure()
            plt.axhline(
                y=Kss, color='black', linewidth=2, label=r"Steady State $\hat{K}$", ls='--')
            plt.plot(np.arange(
                T + 10), D_plot[:T + 10], 'b', linewidth=2, label=r"TPI time path $\hat{K}_t$")
            plt.savefig(os.path.join(TPI_FIG_DIR, "TPI_D"))

        if report_tG1 is True:
            print '\tAt time tG1-1:'
            print '\t\tG = ', G[tG1-1]
            print '\t\tK = ', K[tG1-1]
            print '\t\tr = ', r[tG1-1]
            print '\t\tD = ', D[tG1-1]


        guesses = (guesses_b, guesses_n)
        outer_loop_vars = (r, w, K, BQ, T_H)
        inner_loop_params = (income_tax_params, tpi_params, initial_values, ind)

        # Solve HH problem in inner loop
        euler_errors, b_mat, n_mat = inner_loop(guesses, outer_loop_vars, inner_loop_params)

        bmat_s = np.zeros((T, S, J))
        bmat_s[0, 1:, :] = initial_b[:-1, :]
        bmat_s[1:, 1:, :] = b_mat[:T-1, :-1, :]
        bmat_splus1 = np.zeros((T, S, J))
        bmat_splus1[:, :, :] = b_mat[:T, :, :]

        #L_params = (e.reshape(1, S, J), omega[:T, :].reshape(T, S, 1), lambdas.reshape(1, 1, J), 'TPI') # defined above
        L[:T]  = aggr.get_L(n_mat[:T], L_params)
        #B_params = (omega[:T-1].reshape(T-1, S, 1), lambdas.reshape(1, 1, J), imm_rates[:T-1].reshape(T-1,S,1), g_n_vector[1:T], 'TPI') # defined above
        B[1:T] = aggr.get_K(bmat_splus1[:T-1], B_params)
        if np.any(B) < 0:
            print 'B has negative elements. B[0:9]:', B[0:9]
            print 'B[T-2:T]:', B[T-2,T]

        if small_open == False:
            if budget_balance:
                K[:T] = B[:T]
            else:
                if baseline_spending == False:
                    Y = T_H/ALPHA_T  #SBF 3/3: This seems totally unnecessary as both these variables are defined above.

#                tax_params = np.zeros((T,S,J,etr_params.shape[2]))
#                for i in range(etr_params.shape[2]):
#                    tax_params[:,:,:,i] = np.tile(np.reshape(np.transpose(etr_params[:,:T,i]),(T,S,1)),(1,1,J))

#                REVENUE_params = (np.tile(e.reshape(1, S, J),(T,1,1)), lambdas.reshape(1, 1, J), omega[:T].reshape(T, S, 1), 'TPI',
#                        tax_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau) # define above
                REVENUE = np.array(list(aggr.revenue(np.tile(r[:T].reshape(T, 1, 1),(1,S,J)), np.tile(w[:T].reshape(T, 1, 1),(1,S,J)),
                       bmat_s, n_mat[:T,:,:], BQ[:T].reshape(T, 1, J), Y[:T], L[:T], K[:T], factor, REVENUE_params)) + [revenue_ss] * S)

                D_0    = initial_debt * Y[0]
                other_dg_params = (T, r, g_n_vector, g_y)
                if baseline_spending==False:
                    G_0    = ALPHA_G[0] * Y[0]
                dg_fixed_values = (Y, REVENUE, T_H, D_0,G_0)
                Dnew, G = fiscal.D_G_path(dg_fixed_values, fiscal_params, other_dg_params, baseline_spending=baseline_spending)
                K[:T] = B[:T] - Dnew[:T]
                if np.any(K < 0):
                    print 'K has negative elements. Setting them positive to prevent NAN.'
                    K[:T] = np.fmax(K[:T], 0.05*B[:T])
        else:
            # K_params previously set to =  (Z, gamma, epsilon, delta, tau_b, delta_tau)
            K[:T] = firm.get_K(L[:T], tpi_firm_r[:T], K_params)
        Y_params = (Z, gamma, epsilon)
        Ynew = firm.get_Y(K[:T], L[:T], Y_params)
        Y = Ynew
        w_params = (Z, gamma, epsilon)
        wnew = firm.get_w(Ynew[:T], L[:T], w_params)
        if small_open == False:
            r_params = (Z, gamma, epsilon, delta, tau_b, delta_tau)
            rnew = firm.get_r(Ynew[:T], K[:T], r_params)
        else:
            rnew = r.copy()

        print 'Y and T_H: ', Y[3], T_H[3]
#        omega_shift = np.append(omega_S_preTP.reshape(1,S),omega[:T-1,:],axis=0)  # defined above
#        BQ_params = (omega_shift.reshape(T, S, 1), lambdas.reshape(1, 1, J), rho.reshape(1, S, 1),
#                     g_n_vector[:T].reshape(T, 1), 'TPI')  # defined above
        b_mat_shift = np.append(np.reshape(initial_b,(1,S,J)),b_mat[:T-1,:,:],axis=0)
        BQnew = aggr.get_BQ(rnew[:T].reshape(T, 1), b_mat_shift, BQ_params)

#        tax_params = np.zeros((T,S,J,etr_params.shape[2]))
#        for i in range(etr_params.shape[2]):
#            tax_params[:,:,:,i] = np.tile(np.reshape(np.transpose(etr_params[:,:T,i]),(T,S,1)),(1,1,J))

#        REVENUE_params = (np.tile(e.reshape(1, S, J),(T,1,1)), lambdas.reshape(1, 1, J), omega[:T].reshape(T, S, 1), 'TPI',
#                tax_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau) # defined above
        REVENUE = np.array(list(aggr.revenue(np.tile(rnew[:T].reshape(T, 1, 1),(1,S,J)), np.tile(wnew[:T].reshape(T, 1, 1),(1,S,J)),
               bmat_s, n_mat[:T,:,:], BQnew[:T].reshape(T, 1, J), Y[:T], L[:T], K[:T], factor, REVENUE_params)) + [revenue_ss] * S)

        if budget_balance:
            T_H_new = REVENUE
        elif baseline_spending==False:
            T_H_new = ALPHA_T[:T] * Y[:T]
        # If baseline_spending==True, no need to update T_H, which remains fixed.

        if small_open==True and budget_balance==False:
            # Loop through years to calculate debt and gov't spending. This is done earlier when small_open=False.
            D_0    = initial_debt * Y[0]
            other_dg_params = (T, r, g_n_vector, g_y)
            if baseline_spending==False:
                G_0    = ALPHA_G[0] * Y[0]
            dg_fixed_values = (Y, REVENUE, T_H, D_0,G_0)
            Dnew, G = fiscal.D_G_path(dg_fixed_values, fiscal_params, other_dg_params, baseline_spending=baseline_spending)

        w[:T] = utils.convex_combo(wnew[:T], w[:T], nu)
        r[:T] = utils.convex_combo(rnew[:T], r[:T], nu)
        BQ[:T] = utils.convex_combo(BQnew[:T], BQ[:T], nu)
        # D[:T] = utils.convex_combo(Dnew[:T], D[:T], nu)
        D = Dnew
        Y[:T] = utils.convex_combo(Ynew[:T], Y[:T], nu)
        if baseline_spending==False:
            T_H[:T] = utils.convex_combo(T_H_new[:T], T_H[:T], nu)
        guesses_b = utils.convex_combo(b_mat, guesses_b, nu)
        guesses_n = utils.convex_combo(n_mat, guesses_n, nu)

        print 'r diff: ', (rnew[:T]-r[:T]).max(), (rnew[:T]-r[:T]).min()
        print 'w diff: ', (wnew[:T]-w[:T]).max(), (wnew[:T]-w[:T]).min()
        print 'BQ diff: ', (BQnew[:T]-BQ[:T]).max(), (BQnew[:T]-BQ[:T]).min()
        print 'T_H diff: ', (T_H_new[:T]-T_H[:T]).max(), (T_H_new[:T]-T_H[:T]).min()

        if baseline_spending==False:
            if T_H.all() != 0:
                TPIdist = np.array(list(utils.pct_diff_func(rnew[:T], r[:T])) + list(utils.pct_diff_func(BQnew[:T], BQ[:T]).flatten()) + list(
                    utils.pct_diff_func(wnew[:T], w[:T])) + list(utils.pct_diff_func(T_H_new[:T], T_H[:T]))).max()
            else:
                TPIdist = np.array(list(utils.pct_diff_func(rnew[:T], r[:T])) + list(utils.pct_diff_func(BQnew[:T], BQ[:T]).flatten()) + list(
                    utils.pct_diff_func(wnew[:T], w[:T])) + list(np.abs(T_H[:T]))).max()
        else:
            # TPIdist = np.array(list(utils.pct_diff_func(rnew[:T], r[:T])) + list(utils.pct_diff_func(BQnew[:T], BQ[:T]).flatten()) + list(
            #     utils.pct_diff_func(wnew[:T], w[:T])) + list(utils.pct_diff_func(Dnew[:T], D[:T]))).max()
            TPIdist = np.array(list(utils.pct_diff_func(rnew[:T], r[:T])) + list(utils.pct_diff_func(BQnew[:T], BQ[:T]).flatten()) + list(
                utils.pct_diff_func(wnew[:T], w[:T])) + list(utils.pct_diff_func(Ynew[:T], Y[:T]))).max()

        TPIdist_vec[TPIiter] = TPIdist
        # After T=10, if cycling occurs, drop the value of nu
        # wait til after T=10 or so, because sometimes there is a jump up
        # in the first couple iterations
        # if TPIiter > 10:
        #     if TPIdist_vec[TPIiter] - TPIdist_vec[TPIiter - 1] > 0:
        #         nu /= 2
        #         print 'New Value of nu:', nu
        TPIiter += 1
        print 'Iteration:', TPIiter
        print '\tDistance:', TPIdist

        # print 'D/Y:', (D[:T]/Ynew[:T]).max(), (D[:T]/Ynew[:T]).min(), np.median(D[:T]/Ynew[:T])
        # print 'T/Y:', (T_H_new[:T]/Ynew[:T]).max(), (T_H_new[:T]/Ynew[:T]).min(), np.median(T_H_new[:T]/Ynew[:T])
        # print 'G/Y:', (G[:T]/Ynew[:T]).max(), (G[:T]/Ynew[:T]).min(), np.median(G[:T]/Ynew[:T])
        # print 'Int payments to GDP:', ((r[:T]*D[:T])/Ynew[:T]).max(), ((r[:T]*D[:T])/Ynew[:T]).min(), np.median((r[:T]*D[:T])/Ynew[:T])
        #
        # print 'D/Y:', (D[:T]/Ynew[:T])
        # print 'T/Y:', (T_H_new[:T]/Ynew[:T])
        # print 'G/Y:', (G[:T]/Ynew[:T])
        #
        # print 'deficit: ', REVENUE[:T] - T_H_new[:T] - G[:T]

    # Loop through years to calculate debt and gov't spending. The re-assignment of G0 & D0 is necessary because Y0 may change in the TPI loop.
    if budget_balance == False:
        D_0    = initial_debt * Y[0]
        other_dg_params = (T, r, g_n_vector, g_y)
        if baseline_spending==False:
            G_0    = ALPHA_G[0] * Y[0]
        dg_fixed_values = (Y, REVENUE, T_H, D_0,G_0)
        D, G = fiscal.D_G_path(dg_fixed_values, fiscal_params, other_dg_params, baseline_spending=baseline_spending)

    # Solve HH problem in inner loop
    guesses = (guesses_b, guesses_n)
    outer_loop_vars = (r, w, K, BQ, T_H)
    inner_loop_params = (income_tax_params, tpi_params, initial_values, ind)
    euler_errors, b_mat, n_mat = inner_loop(guesses, outer_loop_vars, inner_loop_params)

    bmat_s = np.zeros((T, S, J))
    bmat_s[0, 1:, :] = initial_b[:-1, :]
    bmat_s[1:, 1:, :] = b_mat[:T-1, :-1, :]
    bmat_splus1 = np.zeros((T, S, J))
    bmat_splus1[:, :, :] = b_mat[:T, :, :]

    #L_params = (e.reshape(1, S, J), omega[:T, :].reshape(T, S, 1), lambdas.reshape(1, 1, J), 'TPI') # defined above
    L[:T]  = aggr.get_L(n_mat[:T], L_params)
    #B_params = (omega[:T-1].reshape(T-1, S, 1), lambdas.reshape(1, 1, J), imm_rates[:T-1].reshape(T-1,S,1), g_n_vector[1:T], 'TPI') # defined above
    B[1:T] = aggr.get_K(bmat_splus1[:T-1], B_params)

    if small_open == False:
        K[:T] = B[:T] - D[:T]
    else:
        # K_params previously set to = (Z, gamma, epsilon, delta, tau_b, delta_tau)
        K[:T] = firm.get_K(L[:T], tpi_firm_r[:T], K_params)
    # Y_params previously set to = (Z, gamma, epsilon)
    Ynew = firm.get_Y(K[:T], L[:T], Y_params)

    # testing for change in Y
    ydiff = Ynew[:T] - Y[:T]
    ydiff_max = np.amax(np.abs(ydiff))
    print 'ydiff_max = ', ydiff_max

    w_params = (Z, gamma, epsilon)
    wnew = firm.get_w(Ynew[:T], L[:T], w_params)
    if small_open == False:
        # r_params previously set to = (Z, gamma, epsilon, delta, tau_b, delta_tau)
        rnew = firm.get_r(Ynew[:T], K[:T], r_params)
    else:
        rnew = r

    # Note: previously, Y was not reassigned to equal Ynew at this point.
    Y = Ynew[:]

#    omega_shift = np.append(omega_S_preTP.reshape(1,S),omega[:T-1,:],axis=0)
#    BQ_params = (omega_shift.reshape(T, S, 1), lambdas.reshape(1, 1, J), rho.reshape(1, S, 1),
#                 g_n_vector[:T].reshape(T, 1), 'TPI')
    b_mat_shift = np.append(np.reshape(initial_b,(1,S,J)),b_mat[:T-1,:,:],axis=0)
    BQnew = aggr.get_BQ(rnew[:T].reshape(T, 1), b_mat_shift, BQ_params)

#    tax_params = np.zeros((T,S,J,etr_params.shape[2]))
#    for i in range(etr_params.shape[2]):
#        tax_params[:,:,:,i] = np.tile(np.reshape(np.transpose(etr_params[:,:T,i]),(T,S,1)),(1,1,J))

#    REVENUE_params = (np.tile(e.reshape(1, S, J),(T,1,1)), lambdas.reshape(1, 1, J), omega[:T].reshape(T, S, 1), 'TPI',
#            tax_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau)
    REVENUE = np.array(list(aggr.revenue(np.tile(rnew[:T].reshape(T, 1, 1),(1,S,J)), np.tile(wnew[:T].reshape(T, 1, 1),(1,S,J)),
           bmat_s, n_mat[:T,:,:], BQnew[:T].reshape(T, 1, J), Ynew[:T], L[:T], K[:T], factor, REVENUE_params)) + [revenue_ss] * S)

    etr_params_path = np.zeros((T,S,J,etr_params.shape[2]))
    for i in range(etr_params.shape[2]):
        etr_params_path[:,:,:,i] = np.tile(np.reshape(np.transpose(etr_params[:,:T,i]),(T,S,1)),(1,1,J))
    tax_path_params = (np.tile(e.reshape(1, S, J),(T,1,1)), lambdas, 'TPI', retire, etr_params_path, h_wealth,
                       p_wealth, m_wealth, tau_payroll, theta, tau_bq, J, S)
    tax_path = tax.total_taxes(np.tile(r[:T].reshape(T, 1, 1),(1,S,J)), np.tile(w[:T].reshape(T, 1, 1),(1,S,J)), bmat_s,
                               n_mat[:T,:,:], BQ[:T, :].reshape(T, 1, J), factor, T_H[:T].reshape(T, 1, 1), None, False, tax_path_params)

    cons_params = (e.reshape(1, S, J), lambdas.reshape(1, 1, J), g_y)
    c_path = household.get_cons(r[:T].reshape(T, 1, 1), w[:T].reshape(T, 1, 1), bmat_s, bmat_splus1, n_mat[:T,:,:],
                   BQ[:T].reshape(T, 1, J), tax_path, cons_params)
    C_params = (omega[:T].reshape(T, S, 1), lambdas, 'TPI')
    C = aggr.get_C(c_path, C_params)

    if budget_balance==False:
        D_0    = initial_debt * Y[0]
        other_dg_params = (T, r, g_n_vector, g_y)
        if baseline_spending==False:
            G_0    = ALPHA_G[0] * Y[0]
        dg_fixed_values = (Y, REVENUE, T_H, D_0,G_0)
        D, G = fiscal.D_G_path(dg_fixed_values, fiscal_params, other_dg_params, baseline_spending=baseline_spending)


    if small_open == False:
        I_params = (delta, g_y, omega[:T].reshape(T, S, 1), lambdas, imm_rates[:T].reshape(T, S, 1), g_n_vector[1:T+1], 'TPI')
        I = aggr.get_I(bmat_splus1[:T], K[1:T+1], K[:T], I_params)
        rc_error = Y[:T] - C[:T] - I[:T] - G[:T]
    else:
        #InvestmentPlaceholder = np.zeros(bmat_splus1[:T].shape)
        #I_params = (delta, g_y, omega[:T].reshape(T, S, 1), lambdas, imm_rates[:T].reshape(T, S, 1), g_n_vector[1:T+1], 'TPI')
        I = (1+g_n_vector[:T])*np.exp(g_y)*K[1:T+1] - (1.0 - delta) * K[:T] #aggr.get_I(InvestmentPlaceholder, K[1:T+1], K[:T], I_params)
        BI_params = (0.0, g_y, omega[:T].reshape(T, S, 1), lambdas, imm_rates[:T].reshape(T, S, 1), g_n_vector[1:T+1], 'TPI')
        BI = aggr.get_I(bmat_splus1[:T], B[1:T+1], B[:T], BI_params)
        new_borrowing = D[1:T]*(1+g_n_vector[1:T])*np.exp(g_y) - D[:T-1]
        rc_error = Y[:T-1] + new_borrowing - (C[:T-1] + BI[:T-1] + G[:T-1] ) + (tpi_hh_r[:T-1] * B[:T-1] - (delta + tpi_firm_r[:T-1])*K[:T-1] - tpi_hh_r[:T-1]*D[:T-1])
        #print 'Y(T-1):', Y[T-1], '\n','C(T-1):', C[T-1], '\n','K(T-1):', K[T-1], '\n','B(T-1):', B[T-1], '\n','BI(T-1):', BI[T-1], '\n','I(T-1):', I[T-1]

    rce_max = np.amax(np.abs(rc_error))
    print 'Max absolute value resource constraint error:', rce_max

    print'Checking time path for violations of constraints.'
    for t in xrange(T):
        household.constraint_checker_TPI(
            b_mat[t], n_mat[t], c_path[t], t, ltilde)

    eul_savings = euler_errors[:, :S, :].max(1).max(1)
    eul_laborleisure = euler_errors[:, S:, :].max(1).max(1)

   # print 'Max Euler error, savings: ', eul_savings
   # print 'Max Euler error labor supply: ', eul_laborleisure



    '''
    ------------------------------------------------------------------------
    Save variables/values so they can be used in other modules
    ------------------------------------------------------------------------
    '''

    output = {'Y': Y, 'K': K, 'L': L, 'C': C, 'I': I, 'BQ': BQ,
              'REVENUE': REVENUE, 'T_H': T_H, 'G': G, 'D': D,
              'r': r, 'w': w, 'b_mat': b_mat, 'n_mat': n_mat,
              'c_path': c_path, 'tax_path': tax_path,
              'eul_savings': eul_savings, 'eul_laborleisure': eul_laborleisure}

    tpi_dir = os.path.join(output_dir, "TPI")
    utils.mkdirs(tpi_dir)
    tpi_vars = os.path.join(tpi_dir, "TPI_vars.pkl")
    pickle.dump(output, open(tpi_vars, "wb"))

    macro_output = {'Y': Y, 'K': K, 'L': L, 'C': C, 'I': I,
                    'BQ': BQ, 'REVENUE': REVENUE, 'T_H': T_H, 'r': r, 'w': w,
                    'tax_path': tax_path}

    growth = (1+g_n_vector)*np.exp(g_y)
    with open('TPI_output.csv', 'wb') as csvfile:
        tpiwriter = csv.writer(csvfile)
        tpiwriter.writerow(Y)
        tpiwriter.writerow(D)
        tpiwriter.writerow(REVENUE)
        tpiwriter.writerow(G)
        tpiwriter.writerow(T_H)
        tpiwriter.writerow(C)
        tpiwriter.writerow(K)
        tpiwriter.writerow(I)
        tpiwriter.writerow(r)
        if small_open == True:
            tpiwriter.writerow(B)
            tpiwriter.writerow(BI)
            tpiwriter.writerow(new_borrowing)
        tpiwriter.writerow(growth)
        tpiwriter.writerow(rc_error)
        tpiwriter.writerow(ydiff)


    if np.any(G) < 0:
        print 'Government spending is negative along transition path to satisfy budget'

    if ((TPIiter >= maxiter) or (np.absolute(TPIdist) > mindist_TPI)) and ENFORCE_SOLUTION_CHECKS :
        raise RuntimeError("Transition path equlibrium not found (TPIdist)")

    if ((np.any(np.absolute(rc_error) >= mindist_TPI))
        and ENFORCE_SOLUTION_CHECKS):
        raise RuntimeError("Transition path equlibrium not found (rc_error)")

    if ((np.any(np.absolute(eul_savings) >= mindist_TPI) or
        (np.any(np.absolute(eul_laborleisure) > mindist_TPI)))
        and ENFORCE_SOLUTION_CHECKS):
        raise RuntimeError("Transition path equlibrium not found (eulers)")

    # Non-stationary output
    # macro_ns_output = {'K_ns_path': K_ns_path, 'C_ns_path': C_ns_path, 'I_ns_path': I_ns_path,
    #           'L_ns_path': L_ns_path, 'BQ_ns_path': BQ_ns_path,
    #           'rinit': rinit, 'Y_ns_path': Y_ns_path, 'T_H_ns_path': T_H_ns_path,
    #           'w_ns_path': w_ns_path}


    return output, macro_output