Exemple #1
0
def income_tax_liab(r, w, b, n, factor, t, j, method, e, etr_params, p):
    '''
    Calculate income and payroll tax liability for each household

    Args:
        r (array_like): real interest rate
        w (array_like): real wage rate
        b (Numpy array): savings
        n (Numpy array): labor supply
        factor (scalar): scaling factor converting model units to
            dollars
        t (int): time period
        j (int): index of lifetime income group
        method (str): adjusts calculation dimensions based on 'SS' or
            'TPI'
        e (Numpy array): effective labor units
        etr_params (Numpy array): effective tax rate function parameters
        p (OG-USA Specifications object): model parameters

    Returns:
        T_I (Numpy array): total income and payroll taxes paid for each
            household

    '''
    if j is not None:
        if method == 'TPI':
            if b.ndim == 2:
                r = r.reshape(r.shape[0], 1)
                w = w.reshape(w.shape[0], 1)
    else:
        if method == 'TPI':
            r = utils.to_timepath_shape(r)
            w = utils.to_timepath_shape(w)

    income = r * b + w * e * n
    labor_income = w * e * n
    T_I = ETR_income(r, w, b, n, factor, e, etr_params, p) * income
    if method == 'SS':
        T_P = p.tau_payroll[-1] * labor_income
    elif method == 'TPI':
        length = w.shape[0]
        if len(b.shape) == 1:
            T_P = p.tau_payroll[t:t + length] * labor_income
        elif len(b.shape) == 2:
            T_P = (p.tau_payroll[t:t + length].reshape(length, 1) *
                   labor_income)
        else:
            T_P = (p.tau_payroll[t:t + length].reshape(length, 1, 1) *
                   labor_income)
    elif method == 'TPI_scalar':
        T_P = p.tau_payroll[0] * labor_income

    income_payroll_tax_liab = T_I + T_P

    return income_payroll_tax_liab
Exemple #2
0
def test_to_timepath_shape():
    '''
    Test of function that converts vector to time path conformable array
    '''
    in_array = np.ones(40)
    test_array = utils.to_timepath_shape(in_array)
    assert test_array.shape == (40, 1, 1)
Exemple #3
0
def get_bq(BQ, j, p, method):
    '''
    Calculation of bequests to each lifetime income group.

    Inputs:
        r           = [T,] vector, interest rates
        b_splus1    = [T,S,J] array, distribution of wealth/capital
                      holdings one period ahead
        params      = length 5 tuple, (omega, lambdas, rho, g_n, method)
        omega       = [S,T] array, population weights
        lambdas     = [J,] vector, fraction in each lifetime income group
        rho         = [S,] vector, mortality rates
        g_n         = scalar, population growth rate
        method      = string, 'SS' or 'TPI'

    Functions called: None

    Objects in function:
        BQ_presum = [T,S,J] array, weighted distribution of
                    wealth/capital holdings one period ahead
        BQ        = [T,J] array, aggregate bequests by lifetime income group

    Returns: BQ
    '''
    if p.use_zeta:
        if j is not None:
            if method == 'SS':
                bq = (p.zeta[:, j] * BQ) / (p.lambdas[j] * p.omega_SS)
            else:
                len_T = BQ.shape[0]
                bq = ((np.reshape(p.zeta[:, j], (1, p.S)) * BQ.reshape(
                    (len_T, 1))) / (p.lambdas[j] * p.omega[:len_T, :]))
        else:
            if method == 'SS':
                bq = ((p.zeta * BQ) / (p.lambdas.reshape(
                    (1, p.J)) * p.omega_SS.reshape((p.S, 1))))
            else:
                len_T = BQ.shape[0]
                bq = ((np.reshape(p.zeta, (1, p.S, p.J)) *
                       utils.to_timepath_shape(BQ, p)) / (p.lambdas.reshape(
                           (1, 1, p.J)) * p.omega[:len_T, :].reshape(
                               (len_T, p.S, 1))))
    else:
        if j is not None:
            if method == 'SS':
                bq = np.tile(BQ[j], p.S) / p.lambdas[j]
            if method == 'TPI':
                len_T = BQ.shape[0]
                bq = np.tile(np.reshape(BQ[:, j] / p.lambdas[j], (len_T, 1)),
                             (1, p.S))
        else:
            if method == 'SS':
                BQ_per = BQ / np.squeeze(p.lambdas)
                bq = np.tile(np.reshape(BQ_per, (1, p.J)), (p.S, 1))
            if method == 'TPI':
                len_T = BQ.shape[0]
                BQ_per = BQ / p.lambdas.reshape(1, p.J)
                bq = np.tile(np.reshape(BQ_per, (len_T, 1, p.J)), (1, p.S, 1))
    return bq
Exemple #4
0
def get_bq(BQ, j, p, method):
    r'''
    Calculate bequests to each household.

    .. math::
        bq_{j,s,t} = zeta_{j,s}\frac{BQ_{t}}{\lambda_{j}\omega_{s,t}}

    Args:
        BQ (array_like): aggregate bequests
        j (int): index of lifetime ability group
        p (OG-USA Specifications object): model parameters
        method (str): adjusts calculation dimensions based on 'SS' or
            'TPI'

    Returns:
        bq (array_like): bequests received by each household

    '''
    if p.use_zeta:
        if j is not None:
            if method == 'SS':
                bq = (p.zeta[:, j] * BQ) / (p.lambdas[j] * p.omega_SS)
            else:
                len_T = BQ.shape[0]
                bq = ((np.reshape(p.zeta[:, j], (1, p.S)) * BQ.reshape(
                    (len_T, 1))) / (p.lambdas[j] * p.omega[:len_T, :]))
        else:
            if method == 'SS':
                bq = ((p.zeta * BQ) / (p.lambdas.reshape(
                    (1, p.J)) * p.omega_SS.reshape((p.S, 1))))
            else:
                len_T = BQ.shape[0]
                bq = (
                    (np.reshape(p.zeta,
                                (1, p.S, p.J)) * utils.to_timepath_shape(BQ)) /
                    (p.lambdas.reshape(
                        (1, 1, p.J)) * p.omega[:len_T, :].reshape(
                            (len_T, p.S, 1))))
    else:
        if j is not None:
            if method == 'SS':
                bq = np.tile(BQ[j], p.S) / p.lambdas[j]
            if method == 'TPI':
                len_T = BQ.shape[0]
                bq = np.tile(np.reshape(BQ[:, j] / p.lambdas[j], (len_T, 1)),
                             (1, p.S))
        else:
            if method == 'SS':
                BQ_per = BQ / np.squeeze(p.lambdas)
                bq = np.tile(np.reshape(BQ_per, (1, p.J)), (p.S, 1))
            if method == 'TPI':
                len_T = BQ.shape[0]
                BQ_per = BQ / p.lambdas.reshape(1, p.J)
                bq = np.tile(np.reshape(BQ_per, (len_T, 1, p.J)), (1, p.S, 1))
    return bq
Exemple #5
0
def wealth_tax_liab(r, b, t, j, method, p):
    '''
    Calculate wealth tax liability for each household.

    Args:
        r (array_like): real interest rate
        b (Numpy array): savings
        t (int): time period
        j (int): index of lifetime income group
        method (str): adjusts calculation dimensions based on 'SS' or
            'TPI'
        p (OG-USA Specifications object): model parameters

    Returns:
        T_W (Numpy array): wealth tax liability for each household

    '''
    if j is not None:
        if method == 'TPI':
            if b.ndim == 2:
                r = r.reshape(r.shape[0], 1)
    else:
        if method == 'TPI':
            r = utils.to_timepath_shape(r)

    if method == 'SS':
        T_W = (ETR_wealth(b, p.h_wealth[-1], p.m_wealth[-1], p.p_wealth[-1]) *
               b)
    elif method == 'TPI':
        length = r.shape[0]
        if len(b.shape) == 1:
            T_W = (ETR_wealth(b, p.h_wealth[t:t + length],
                              p.m_wealth[t:t + length],
                              p.p_wealth[t:t + length]) * b)
        elif len(b.shape) == 2:
            T_W = (ETR_wealth(b, p.h_wealth[t:t + length],
                              p.m_wealth[t:t + length],
                              p.p_wealth[t:t + length]) * b)
        else:
            T_W = (ETR_wealth(b, p.h_wealth[t:t + length].reshape(
                length, 1, 1), p.m_wealth[t:t + length].reshape(length, 1, 1),
                              p.p_wealth[t:t + length].reshape(length, 1, 1)) *
                   b)
    elif method == 'TPI_scalar':
        T_W = (ETR_wealth(b, p.h_wealth[0], p.m_wealth[0], p.p_wealth[0]) * b)

    return T_W
Exemple #6
0
def bequest_tax_liab(r, b, bq, t, j, method, p):
    '''
    Calculate liability due from taxes on bequests for each household.

    Args:
        r (array_like): real interest rate
        b (Numpy array): savings
        bq (Numpy array): bequests received
        t (int): time period
        j (int): index of lifetime income group
        method (str): adjusts calculation dimensions based on 'SS' or
            'TPI'
        p (OG-USA Specifications object): model parameters

    Returns:
        T_BQ (Numpy array): bequest tax liability for each household

    '''
    if j is not None:
        lambdas = p.lambdas[j]
        if method == 'TPI':
            if b.ndim == 2:
                r = r.reshape(r.shape[0], 1)
    else:
        lambdas = np.transpose(p.lambdas)
        if method == 'TPI':
            r = utils.to_timepath_shape(r)

    if method == 'SS':
        T_BQ = p.tau_bq[-1] * bq
    elif method == 'TPI':
        length = r.shape[0]
        if len(b.shape) == 1:
            T_BQ = p.tau_bq[t:t + length] * bq
        elif len(b.shape) == 2:
            T_BQ = p.tau_bq[t:t + length].reshape(length, 1) * bq / lambdas
        else:
            T_BQ = p.tau_bq[t:t + length].reshape(length, 1, 1) * bq
    elif method == 'TPI_scalar':
        # The above methods won't work if scalars are used.  This option
        # is only called by the SS_TPI_firstdoughnutring function in TPI.
        T_BQ = p.tau_bq[0] * bq

    return T_BQ
Exemple #7
0
def get_tr(TR, j, p, method):
    r'''
    Calculate transfers to each household.

    .. math::
        tr_{j,s,t} = zeta_{j,s}\frac{TR_{t}}{\lambda_{j}\omega_{s,t}}

    Args:
        TR (array_like): aggregate transfers
        j (int): index of lifetime ability group
        p (OG-USA Specifications object): model parameters
        method (str): adjusts calculation dimensions based on 'SS' or
            'TPI'

    Returns:
        tr (array_like): bequests received by each household

    '''
    if j is not None:
        if method == 'SS':
            tr = (p.eta[-1, :, j] * TR) / (p.lambdas[j] * p.omega_SS)
        else:
            len_T = TR.shape[0]
            tr = ((p.eta[:len_T, :, j] *
                  TR.reshape((len_T, 1))) /
                  (p.lambdas[j] * p.omega[:len_T, :]))
    else:
        if method == 'SS':
            tr = ((p.eta[-1, :, :] * TR) /
                  (p.lambdas.reshape((1, p.J)) *
                   p.omega_SS.reshape((p.S, 1))))
        else:
            len_T = TR.shape[0]
            tr = ((p.eta[:len_T, :, :] *
                   utils.to_timepath_shape(TR)) /
                  (p.lambdas.reshape((1, 1, p.J)) *
                   p.omega[:len_T, :].reshape((len_T, p.S, 1))))

    return tr
Exemple #8
0
def run_TPI(p, client=None):

    # unpack tuples of parameters
    initial_values, SS_values, baseline_values = get_initial_SS_values(p)
    (B0, b_sinit, b_splus1init, factor, initial_b, initial_n,
     D0) = initial_values
    (Kss, Bss, Lss, rss, wss, BQss, T_Hss, total_revenue_ss, bssmat_splus1,
     nssmat, Yss, Gss, theta) = SS_values
    (T_Hbaseline, Gbaseline) = baseline_values

    print('Government spending breakpoints are tG1: ', p.tG1,
          '; and tG2:', p.tG2)

    # Initialize guesses at time paths
    # Make array of initial guesses for labor supply and savings
    domain = np.linspace(0, p.T, p.T)
    domain2 = np.tile(domain.reshape(p.T, 1, 1), (1, p.S, p.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, p.S, p.J), (p.S, 1, 1))
    guesses_b = np.append(guesses_b, ending_b_tail, axis=0)

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

    L_init = np.ones((p.T + p.S,)) * Lss
    B_init = np.ones((p.T + p.S,)) * Bss
    L_init[:p.T] = aggr.get_L(n_mat[:p.T], p, 'TPI')
    B_init[1:p.T] = aggr.get_K(b_mat[:p.T], p, 'TPI', False)[:p.T - 1]
    B_init[0] = B0

    if not p.small_open:
        if p.budget_balance:
            K_init = B_init
        else:
            K_init = B_init * Kss / Bss
    else:
        K_init = firm.get_K(L_init, p.firm_r, p, 'TPI')

    K = K_init

    L = L_init
    B = B_init
    Y = np.zeros_like(K)
    Y[:p.T] = firm.get_Y(K[:p.T], L[:p.T], p, 'TPI')
    Y[p.T:] = Yss
    r = np.zeros_like(Y)
    if not p.small_open:
        r[:p.T] = firm.get_r(Y[:p.T], K[:p.T], p, 'TPI')
        r[p.T:] = rss
    else:
        r = p.firm_r
    # compute w
    w = np.zeros_like(r)
    w[:p.T] = firm.get_w_from_r(r[:p.T], p, 'TPI')
    w[p.T:] = wss
    r_gov = fiscal.get_r_gov(r, p)
    if p.budget_balance:
        r_hh = r
    else:
        r_hh = aggr.get_r_hh(r, r_gov, K, p.debt_ratio_ss * Y)
    if p.small_open:
        r_hh = p.hh_r

    BQ0 = aggr.get_BQ(r[0], initial_b, None, p, 'SS', True)
    if not p.use_zeta:
        BQ = np.zeros((p.T + p.S, p.J))
        for j in range(p.J):
            BQ[:, j] = (list(np.linspace(BQ0[j], BQss[j], p.T)) +
                        [BQss[j]] * p.S)
        BQ = np.array(BQ)
    else:
        BQ = (list(np.linspace(BQ0, BQss, p.T)) + [BQss] * p.S)
        BQ = np.array(BQ)
    if p.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(p.T + p.S) * T_Hss2
        total_revenue = T_H
        G = np.zeros(p.T + p.S)
    elif not p.baseline_spending:
        T_H = p.alpha_T * Y
    elif p.baseline_spending:
        T_H = T_Hbaseline
        T_H_new = p.T_H   # Need to set T_H_new for later reference
        G = Gbaseline
        G_0 = Gbaseline[0]

    # Initialize some starting value
    if p.budget_balance:
        D = 0.0 * Y
    else:
        D = p.debt_ratio_ss * Y
    TPIiter = 0
    TPIdist = 10
    euler_errors = np.zeros((p.T, 2 * p.S, p.J))
    TPIdist_vec = np.zeros(p.maxiter)

    print('analytical mtrs in tpi = ', p.analytical_mtrs)
    print('tax function type in tpi = ', p.tax_func_type)

    # TPI loop
    while (TPIiter < p.maxiter) and (TPIdist >= p.mindist_TPI):
        r_gov[:p.T] = fiscal.get_r_gov(r[:p.T], p)
        if p.budget_balance:
            r_hh[:p.T] = r[:p.T]
        else:
            K[:p.T] = firm.get_K_from_Y(Y[:p.T], r[:p.T], p, 'TPI')
            r_hh[:p.T] = aggr.get_r_hh(r[:p.T], r_gov[:p.T], K[:p.T], D[:p.T])
        if p.small_open:
            r_hh[:p.T] = p.hh_r[:p.T]

        outer_loop_vars = (r, w, r_hh, BQ, T_H, theta)

        euler_errors = np.zeros((p.T, 2 * p.S, p.J))
        lazy_values = []
        for j in range(p.J):
            guesses = (guesses_b[:, :, j], guesses_n[:, :, j])
            lazy_values.append(
                delayed(inner_loop)(guesses, outer_loop_vars,
                                    initial_values, j, ind, p))
        results = compute(*lazy_values, scheduler=dask.multiprocessing.get,
                          num_workers=p.num_workers)
        for j, result in enumerate(results):
            euler_errors[:, :, j], b_mat[:, :, j], n_mat[:, :, j] = result

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

        L[:p.T] = aggr.get_L(n_mat[:p.T], p, 'TPI')
        B[1:p.T] = aggr.get_K(bmat_splus1[:p.T], p, 'TPI',
                              False)[:p.T - 1]
        if np.any(B) < 0:
            print('B has negative elements. B[0:9]:', B[0:9])
            print('B[T-2:T]:', B[p.T - 2, p.T])

        etr_params_4D = np.tile(
            p.etr_params.reshape(p.T, p.S, 1, p.etr_params.shape[2]),
            (1, 1, p.J, 1))
        bqmat = household.get_bq(BQ, None, p, 'TPI')
        tax_mat = tax.total_taxes(r_hh[:p.T], w[:p.T], bmat_s,
                                  n_mat[:p.T, :, :], bqmat[:p.T, :, :],
                                  factor, T_H[:p.T], theta, 0, None,
                                  False, 'TPI', p.e, etr_params_4D, p)
        r_hh_path = utils.to_timepath_shape(r_hh, p)
        wpath = utils.to_timepath_shape(w, p)
        c_mat = household.get_cons(r_hh_path[:p.T, :, :], wpath[:p.T, :, :],
                                   bmat_s, bmat_splus1,
                                   n_mat[:p.T, :, :], bqmat[:p.T, :, :],
                                   tax_mat, p.e, p.tau_c[:p.T, :, :], p)

        if not p.small_open:
            if p.budget_balance:
                K[:p.T] = B[:p.T]
            else:
                if not p.baseline_spending:
                    Y = T_H / p.alpha_T  # maybe unecessary

                    (total_rev, T_Ipath, T_Ppath, T_BQpath, T_Wpath,
                     T_Cpath, business_revenue) = aggr.revenue(
                        r_hh[:p.T], w[:p.T], bmat_s, n_mat[:p.T, :, :],
                        bqmat[:p.T, :, :], c_mat[:p.T, :, :], Y[:p.T],
                        L[:p.T], K[:p.T], factor, theta, etr_params_4D,
                        p, 'TPI')
                    total_revenue = np.array(list(total_rev) +
                                             [total_revenue_ss] * p.S)

                # set intial debt value
                if p.baseline:
                    D_0 = p.initial_debt_ratio * Y[0]
                else:
                    D_0 = D0
                if not p.baseline_spending:
                    G_0 = p.alpha_G[0] * Y[0]
                dg_fixed_values = (Y, total_revenue, T_H, D_0, G_0)
                Dnew, G = fiscal.D_G_path(r_gov, dg_fixed_values,
                                          Gbaseline, p)

                K[:p.T] = B[:p.T] - Dnew[:p.T]
                if np.any(K < 0):
                    print('K has negative elements. Setting them ' +
                          'positive to prevent NAN.')
                    K[:p.T] = np.fmax(K[:p.T], 0.05 * B[:p.T])
        else:
            K[:p.T] = firm.get_K(L[:p.T], p.firm_r[:p.T], p, 'TPI')
        Ynew = firm.get_Y(K[:p.T], L[:p.T], p, 'TPI')
        if not p.small_open:
            rnew = firm.get_r(Ynew[:p.T], K[:p.T], p, 'TPI')
        else:
            rnew = r.copy()
        r_gov_new = fiscal.get_r_gov(rnew, p)
        if p.budget_balance:
            r_hh_new = rnew[:p.T]
        else:
            r_hh_new = aggr.get_r_hh(rnew, r_gov_new, K[:p.T],
                                     Dnew[:p.T])
        if p.small_open:
            r_hh_new = p.hh_r[:p.T]
        # compute w
        wnew = firm.get_w_from_r(rnew[:p.T], p, 'TPI')

        b_mat_shift = np.append(np.reshape(initial_b, (1, p.S, p.J)),
                                b_mat[:p.T - 1, :, :], axis=0)
        BQnew = aggr.get_BQ(r_hh_new[:p.T], b_mat_shift, None, p,
                            'TPI', False)
        bqmat_new = household.get_bq(BQnew, None, p, 'TPI')
        (total_rev, T_Ipath, T_Ppath, T_BQpath, T_Wpath, T_Cpath,
         business_revenue) = aggr.revenue(
                r_hh_new[:p.T], wnew[:p.T], bmat_s, n_mat[:p.T, :, :],
                bqmat_new[:p.T, :, :], c_mat[:p.T, :, :], Ynew[:p.T],
                L[:p.T], K[:p.T], factor, theta, etr_params_4D, p, 'TPI')
        total_revenue = np.array(list(total_rev) +
                                 [total_revenue_ss] * p.S)

        if p.budget_balance:
            T_H_new = total_revenue
        elif not p.baseline_spending:
            T_H_new = p.alpha_T[:p.T] * Ynew[:p.T]
        # If baseline_spending==True, no need to update T_H, it's fixed

        if p.small_open and not p.budget_balance:
            # Loop through years to calculate debt and gov't spending.
            # This is done earlier when small_open=False.
            if p.baseline:
                D_0 = p.initial_debt_ratio * Y[0]
            else:
                D_0 = D0
            if not p.baseline_spending:
                G_0 = p.alpha_G[0] * Ynew[0]
            dg_fixed_values = (Ynew, total_revenue, T_H, D_0, G_0)
            Dnew, G = fiscal.D_G_path(r_gov_new, dg_fixed_values, Gbaseline, p)

        if p.budget_balance:
            Dnew = D

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

        print('r diff: ', (rnew[:p.T] - r[:p.T]).max(),
              (rnew[:p.T] - r[:p.T]).min())
        print('BQ diff: ', (BQnew[:p.T] - BQ[:p.T]).max(),
              (BQnew[:p.T] - BQ[:p.T]).min())
        print('T_H diff: ', (T_H_new[:p.T]-T_H[:p.T]).max(),
              (T_H_new[:p.T] - T_H[:p.T]).min())
        print('Y diff: ', (Ynew[:p.T]-Y[:p.T]).max(),
              (Ynew[:p.T] - Y[:p.T]).min())
        if not p.baseline_spending:
            if T_H.all() != 0:
                TPIdist = np.array(
                    list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) +
                    list(utils.pct_diff_func(BQnew[:p.T],
                                             BQ[:p.T]).flatten()) +
                    list(utils.pct_diff_func(wnew[:p.T], w[:p.T])) +
                    list(utils.pct_diff_func(T_H_new[:p.T],
                                             T_H[:p.T]))).max()
            else:
                TPIdist = np.array(
                    list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) +
                    list(utils.pct_diff_func(BQnew[:p.T],
                                             BQ[:p.T]).flatten()) +
                    list(utils.pct_diff_func(wnew[:p.T], w[:p.T])) +
                    list(np.abs(T_H[:p.T]))).max()
        else:
            TPIdist = np.array(
                list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) +
                list(utils.pct_diff_func(BQnew[:p.T], BQ[:p.T]).flatten())
                + list(utils.pct_diff_func(wnew[:p.T], w[:p.T])) +
                list(utils.pct_diff_func(Ynew[:p.T], Y[:p.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)

    # Compute effective and marginal tax rates for all agents
    mtrx_params_4D = np.tile(
        p.mtrx_params.reshape(p.T, p.S, 1, p.mtrx_params.shape[2]),
        (1, 1, p.J, 1))
    mtry_params_4D = np.tile(
        p.mtry_params.reshape(p.T, p.S, 1, p.mtry_params.shape[2]),
        (1, 1, p.J, 1))

    e_3D = np.tile(p.e.reshape(1, p.S, p.J), (p.T, 1, 1))
    mtry_path = tax.MTR_income(r_hh_path[:p.T], wpath[:p.T],
                               bmat_s[:p.T, :, :],
                               n_mat[:p.T, :, :], factor, True,
                               e_3D, etr_params_4D, mtry_params_4D, p)
    mtrx_path = tax.MTR_income(r_hh_path[:p.T], wpath[:p.T],
                               bmat_s[:p.T, :, :],
                               n_mat[:p.T, :, :], factor, False,
                               e_3D, etr_params_4D, mtrx_params_4D, p)
    etr_path = tax.ETR_income(r_hh_path[:p.T], wpath[:p.T],
                              bmat_s[:p.T, :, :],
                              n_mat[:p.T, :, :], factor, e_3D,
                              etr_params_4D, p)

    C = aggr.get_C(c_mat, p, 'TPI')

    if not p.small_open:
        I = aggr.get_I(bmat_splus1[:p.T], K[1:p.T + 1], K[:p.T], p, 'TPI')
        rc_error = Y[:p.T] - C[:p.T] - I[:p.T] - G[:p.T]
    else:
        I = ((1 + np.squeeze(np.hstack((p.g_n[1:p.T], p.g_n_ss)))) *
             np.exp(p.g_y) * K[1:p.T + 1] - (1.0 - p.delta) * K[:p.T])
        BI = aggr.get_I(bmat_splus1[:p.T], B[1:p.T + 1], B[:p.T], p, 'TPI')
        new_borrowing = (D[1:p.T] * (1 + p.g_n[1:p.T]) *
                         np.exp(p.g_y) - D[:p.T - 1])
        rc_error = (Y[:p.T - 1] + new_borrowing - (
            C[:p.T - 1] + BI[:p.T - 1] + G[:p.T - 1]) +
                    (p.hh_r[:p.T - 1] * B[:p.T - 1] - (
                        p.delta + p.firm_r[:p.T - 1]) * K[:p.T - 1] -
                     p.hh_r[:p.T - 1] * D[:p.T - 1]))

    # Compute total investment (not just domestic)
    I_total = ((1 + p.g_n[:p.T]) * np.exp(p.g_y) * K[1:p.T + 1] -
               (1.0 - p.delta) * K[:p.T])

    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 range(p.T):
        household.constraint_checker_TPI(
            b_mat[t], n_mat[t], c_mat[t], t, p.ltilde)

    eul_savings = euler_errors[:, :p.S, :].max(1).max(1)
    eul_laborleisure = euler_errors[:, p.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[:p.T], 'B': B, 'K': K, 'L': L, 'C': C, 'I': I,
              'I_total': I_total, 'BQ': BQ, 'total_revenue': total_revenue,
              'business_revenue': business_revenue,
              'IITpayroll_revenue': T_Ipath, 'T_H': T_H,
              'T_P': T_Ppath, 'T_BQ': T_BQpath, 'T_W': T_Wpath,
              'T_C': T_Cpath, 'G': G, 'D': D, 'r': r, 'r_gov': r_gov,
              'r_hh': r_hh, 'w': w, 'bmat_splus1': bmat_splus1,
              'bmat_s': bmat_s[:p.T, :, :], 'n_mat': n_mat[:p.T, :, :],
              'c_path': c_mat, 'bq_path': bqmat,
              'tax_path': tax_mat, 'eul_savings': eul_savings,
              'eul_laborleisure': eul_laborleisure,
              'resource_constraint_error': rc_error,
              'etr_path': etr_path, 'mtrx_path': mtrx_path,
              'mtry_path': mtry_path}

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

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

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

    if ((np.any(np.absolute(rc_error) >= p.mindist_TPI * 10)) and
        ENFORCE_SOLUTION_CHECKS):
        raise RuntimeError('Transition path equlibrium not found ' +
                           '(rc_error)')

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

    return output
Exemple #9
0
def FOC_savings(r, w, b, b_splus1, n, bq, factor, tr, theta, e, rho,
                tau_c, etr_params, mtry_params, t, j, p, method):
    r'''
    Computes Euler errors for the FOC for savings in the steady state.
    This function is usually looped through over J, so it does one
    lifetime income group at a time.

    .. math::
        c_{j,s,t}^{-\sigma} = e^{-\sigma g_y}\biggl[\chi^b_j\rho_s(b_{j,s+1,t+1})^{-\sigma} + \beta\bigl(1 - \rho_s\bigr)\Bigl(1 + r_{t+1}\bigl[1 - \tau^{mtry}_{s+1,t+1}\bigr]\Bigr)(c_{j,s+1,t+1})^{-\sigma}\biggr]

    Args:
        r (array_like): the real interest rate
        w (array_like): the real wage rate
        b (Numpy array): household savings
        b_splus1 (Numpy array): household savings one period ahead
        b_splus2 (Numpy array): household savings two periods ahead
        n (Numpy array): household labor supply
        bq (Numpy array): household bequests received
        factor (scalar): scaling factor converting model units to dollars
        tr (Numpy array): government tranfers to household
        theta (Numpy array): social security replacement rate for each
            lifetime income group
        e (Numpy array): effective labor units
        rho (Numpy array): mortality rates
        tau_c (array_like): consumption tax rates
        etr_params (Numpy array): parameters of the effective tax rate
            functions
        mtry_params (Numpy array): parameters of the marginal tax rate
            on capital income functions
        t (int): model period
        j (int): index of ability type
        p (OG-USA Specifications object): model parameters
        method (str): adjusts calculation dimensions based on 'SS' or
            'TPI'

    Returns:
        euler (Numpy array): Euler error from FOC for savings

    '''
    if j is not None:
        chi_b = p.chi_b[j]
    else:
        chi_b = p.chi_b
        if method == 'TPI':
            r = utils.to_timepath_shape(r)
            w = utils.to_timepath_shape(w)
    if method == 'SS':
        h_wealth = p.h_wealth[-1]
        m_wealth = p.m_wealth[-1]
        p_wealth = p.p_wealth[-1]
    else:
        h_wealth = p.h_wealth[t]
        m_wealth = p.m_wealth[t]
        p_wealth = p.p_wealth[t]

    taxes = tax.total_taxes(r, w, b, n, bq, factor, tr, theta, t, j,
                            False, method, e, etr_params, p)
    cons = get_cons(r, w, b, b_splus1, n, bq, taxes, e, tau_c, p)
    deriv = ((1 + r) - (
        r * tax.MTR_income(r, w, b, n, factor, True, e, etr_params,
                           mtry_params, p)) -
             tax.MTR_wealth(b, h_wealth, m_wealth, p_wealth))
    savings_ut = (rho * np.exp(-p.sigma * p.g_y) * chi_b *
                  b_splus1 ** (-p.sigma))
    euler_error = np.zeros_like(n)
    if n.shape[0] > 1:
        euler_error[:-1] = (marg_ut_cons(cons[:-1], p.sigma) *
                            (1 / (1 + tau_c[:-1])) - p.beta *
                            (1 - rho[:-1]) * deriv[1:] *
                            marg_ut_cons(cons[1:], p.sigma) *
                            (1 / (1 + tau_c[1:])) * np.exp(-p.sigma * p.g_y)
                            - savings_ut[:-1])
        euler_error[-1] = (marg_ut_cons(cons[-1], p.sigma) *
                           (1 / (1 + tau_c[-1])) - savings_ut[-1])
    else:
        euler_error[-1] = (marg_ut_cons(cons[-1], p.sigma) *
                           (1 / (1 + tau_c[-1])) - savings_ut[-1])

    return euler_error
Exemple #10
0
def pension_amount(w, n, theta, t, j, shift, method, e, p):
    '''
    Calculate public pension benefit amounts for each household.

    Args:
        w (array_like): real wage rate
        n (Numpy array): labor supply
        theta (Numpy array): social security replacement rate value for
            lifetime income group j
        t (int): time period
        j (int): index of lifetime income group
        shift (bool): whether computing for periods 0--s or 1--(s+1),
            =True for 1--(s+1)
        method (str): adjusts calculation dimensions based on 'SS' or
            'TPI'
        e (Numpy array): effective labor units
        p (OG-USA Specifications object): model parameters

    Returns:
        pension (Numpy array): pension amount for each household

    '''
    if j is not None:
        if method == 'TPI':
            if n.ndim == 2:
                w = w.reshape(w.shape[0], 1)
    else:
        if method == 'TPI':
            w = utils.to_timepath_shape(w)

    pension = np.zeros_like(n)
    if method == 'SS':
        # Depending on if we are looking at b_s or b_s+1, the
        # entry for retirement will change (it shifts back one).
        # The shift boolean makes sure we start replacement rates
        # at the correct age.
        if shift is False:
            pension[p.retire[-1]:] = theta * w
        else:
            pension[p.retire[-1] - 1:] = theta * w
    elif method == 'TPI':
        length = w.shape[0]
        if not shift:
            # retireTPI is different from retire, because in TP income
            # we are counting backwards with different length lists.
            # This will always be the correct location of retirement,
            # depending on the shape of the lists.
            retireTPI = (p.retire[t:t + length] - p.S)
        else:
            retireTPI = (p.retire[t:t + length] - 1 - p.S)
        if len(n.shape) == 1:
            if not shift:
                retireTPI = p.retire[t] - p.S
            else:
                retireTPI = p.retire[t] - 1 - p.S
            pension[retireTPI:] = (theta[j] * p.replacement_rate_adjust[t] *
                                   w[retireTPI:])
        elif len(n.shape) == 2:
            for tt in range(pension.shape[0]):
                pension[tt,
                        retireTPI[tt]:] = (theta *
                                           p.replacement_rate_adjust[t + tt] *
                                           w[tt])
        else:
            for tt in range(pension.shape[0]):
                pension[tt, retireTPI[tt]:, :] = (
                    theta.reshape(1, p.J) * p.replacement_rate_adjust[t + tt] *
                    w[tt])
    elif method == 'TPI_scalar':
        # The above methods won't work if scalars are used.  This option
        # is only called by the SS_TPI_firstdoughnutring function in TPI.
        pension = theta * p.replacement_rate_adjust[0] * w

    return pension
Exemple #11
0
def FOC_labor(r, w, b, b_splus1, n, bq, factor, tr, theta, chi_n, e,
              tau_c, etr_params, mtrx_params, t, j, p, method):
    r'''
    Computes errors for the FOC for labor supply in the steady
    state.  This function is usually looped through over J, so it does
    one lifetime income group at a time.

    .. math::
        w_t e_{j,s}\bigl(1 - \tau^{mtrx}_{s,t}\bigr)(c_{j,s,t})^{-\sigma} = \chi^n_{s}\biggl(\frac{b}{\tilde{l}}\biggr)\biggl(\frac{n_{j,s,t}}{\tilde{l}}\biggr)^{\upsilon-1}\Biggl[1 - \biggl(\frac{n_{j,s,t}}{\tilde{l}}\biggr)^\upsilon\Biggr]^{\frac{1-\upsilon}{\upsilon}}

    Args:
        r (array_like): the real interest rate
        w (array_like): the real wage rate
        b (Numpy array): household savings
        b_splus1 (Numpy array): household savings one period ahead
        n (Numpy array): household labor supply
        bq (Numpy array): household bequests received
        factor (scalar): scaling factor converting model units to dollars
        tr (Numpy array): government tranfers to household
        theta (Numpy array): social security replacement rate for each
            lifetime income group
        chi_n (Numpy array): utility weight on the disutility of labor
            supply
        e (Numpy array): effective labor units
        tau_c (array_like): consumption tax rates
        etr_params (Numpy array): parameters of the effective tax rate
            functions
        mtrx_params (Numpy array): parameters of the marginal tax rate
            on labor income functions
        t (int): model period
        j (int): index of ability type
        p (OG-USA Specifications object): model parameters
        method (str): adjusts calculation dimensions based on 'SS' or
            'TPI'

    Returns:
        FOC_error (Numpy array): error from FOC for labor supply

    '''
    if method == 'SS':
        tau_payroll = p.tau_payroll[-1]
    elif method == 'TPI_scalar':  # for 1st donut ring onlye
        tau_payroll = p.tau_payroll[0]
    else:
        length = r.shape[0]
        tau_payroll = p.tau_payroll[t:t + length]
    if method == 'TPI':
        if b.ndim == 2:
            r = r.reshape(r.shape[0], 1)
            w = w.reshape(w.shape[0], 1)
            tau_payroll = tau_payroll.reshape(tau_payroll.shape[0], 1)
        elif b.ndim == 3:
            r = utils.to_timepath_shape(r)
            w = utils.to_timepath_shape(w)
            tau_payroll = utils.to_timepath_shape(tau_payroll)

    taxes = tax.total_taxes(r, w, b, n, bq, factor, tr, theta, t, j,
                            False, method, e, etr_params, p)
    cons = get_cons(r, w, b, b_splus1, n, bq, taxes, e, tau_c, p)
    deriv = (1 - tau_payroll - tax.MTR_income(r, w, b, n, factor,
                                              False, e, etr_params,
                                              mtrx_params, p))
    FOC_error = (marg_ut_cons(cons, p.sigma) * (1 / (1 + tau_c)) * w *
                 deriv * e - marg_ut_labor(n, chi_n, p))

    return FOC_error
Exemple #12
0
def total_taxes(r, w, b, n, bq, factor, T_H, theta, t, j, shift, method, e,
                etr_params, p):
    '''
    Gives net taxes paid values.
    Inputs:
        r          = [T,] vector, interest rate
        w          = [T,] vector, wage rate
        b          = [T,S,J] array, wealth holdings
        n          = [T,S,J] array, labor supply
        BQ         = [T,J] vector,  bequest amounts
        factor     = scalar, model income scaling factor
        T_H        = [T,] vector, lump sum transfer amount(s)
        j          = integer, lifetime incoem group being computed
        shift      = boolean, computing for periods 0--s or 1--(s+1)
                              (bool) (True for 1--(s+1))
        params = length 13 tuple, (e, lambdas, method, retire,
                                   etr_params, h_wealth, p_wealth,
                                   m_wealth, tau_payroll, theta, tau_bq,
                                   J, S)
        e           = [T,S,J] array, effective labor units
        lambdas     = [J,] vector, population weights by lifetime income group
        method      = string, 'SS' or 'TPI'
        retire      = integer, retirement age
        etr_params  = [T,S,J] array, effective tax rate function parameters
        h_wealth    = scalar, wealth tax function parameter
        p_wealth    = scalar, wealth tax function parameter
        m_wealth    = scalar, wealth tax function parameter
        tau_payroll = scalar, payroll tax rate
        theta       = [J,] vector, replacement rate values by lifetime
                                   income group
        tau_bq      = scalar, bequest tax rate
        S           = integer, number of age groups
        J           = integer, number of lifetime income groups
    Functions called:
        ETR_income
        ETR_wealth
    Objects in function:
        income          = [T,S,J] array, total income
        T_I        = [T,S,J] array, total income taxes
        T_P         = [T,S,J] array, total payroll taxes
        T_W         = [T,S,J] array, total wealth taxes
        T_BQ        = [T,S,J] array, total bequest taxes
        retireTPI  = integer, =(retire - S)
        total_taxes = [T,] vector, net taxes
    Returns: total_taxes

    '''
    if j is not None:
        lambdas = p.lambdas[j]
        if method == 'TPI':
            if b.ndim == 2:
                r = r.reshape(r.shape[0], 1)
                w = w.reshape(w.shape[0], 1)
                T_H = T_H.reshape(T_H.shape[0], 1)
    else:
        lambdas = np.transpose(p.lambdas)
        if method == 'TPI':
            r = utils.to_timepath_shape(r, p)
            w = utils.to_timepath_shape(w, p)
            T_H = utils.to_timepath_shape(T_H, p)

    income = r * b + w * e * n
    T_I = ETR_income(r, w, b, n, factor, e, etr_params, p) * income

    if method == 'SS':
        # Depending on if we are looking at b_s or b_s+1, the
        # entry for retirement will change (it shifts back one).
        # The shift boolean makes sure we start replacement rates
        # at the correct age.
        T_P = p.tau_payroll[-1] * w * e * n
        if shift is False:
            T_P[p.retire[-1]:] -= theta * w
        else:
            T_P[p.retire[-1] - 1:] -= theta * w
        T_BQ = p.tau_bq[-1] * bq
        T_W = (ETR_wealth(b, p.h_wealth[-1], p.m_wealth[-1], p.p_wealth[-1]) *
               b)
    elif method == 'TPI':
        length = w.shape[0]
        if not shift:
            # retireTPIis different from retire, because in TPincomewe are
            # counting backwards with different length lists.  This will
            # always be the correct location of retirement, depending
            # on the shape of the lists.
            retireTPI = (p.retire[t:t + length] - p.S)
        else:
            retireTPI = (p.retire[t:t + length] - 1 - p.S)
        if len(b.shape) == 1:
            T_P = p.tau_payroll[t:t + length] * w * e * n
            if not shift:
                retireTPI = p.retire[t] - p.S
            else:
                retireTPI = p.retire[t] - 1 - p.S
            T_P[retireTPI:] -= (theta[j] * p.replacement_rate_adjust[t] *
                                w[retireTPI:])
            T_W = (ETR_wealth(b, p.h_wealth[t:t + length],
                              p.m_wealth[t:t + length],
                              p.p_wealth[t:t + length]) * b)
            T_BQ = p.tau_bq[t:t + length] * bq
        elif len(b.shape) == 2:
            T_P = p.tau_payroll[t:t + length].reshape(length, 1) * w * e * n
            for tt in range(T_P.shape[0]):
                T_P[tt, retireTPI[tt]:] -= (theta *
                                            p.replacement_rate_adjust[t + tt] *
                                            w[tt])
            T_W = (ETR_wealth(b, p.h_wealth[t:t + length],
                              p.m_wealth[t:t + length],
                              p.p_wealth[t:t + length]) * b)
            T_BQ = p.tau_bq[t:t + length].reshape(length, 1) * bq / lambdas
        else:
            T_P = p.tau_payroll[t:t + length].reshape(length, 1, 1) * w * e * n
            for tt in range(T_P.shape[0]):
                T_P[tt,
                    retireTPI[tt]:, :] -= (theta.reshape(1, p.J) *
                                           p.replacement_rate_adjust[t + tt] *
                                           w[tt])
            T_W = (ETR_wealth(b, p.h_wealth[t:t + length].reshape(
                length, 1, 1), p.m_wealth[t:t + length].reshape(length, 1, 1),
                              p.p_wealth[t:t + length].reshape(length, 1, 1)) *
                   b)
            T_BQ = p.tau_bq[t:t + length].reshape(length, 1, 1) * bq
    elif method == 'TPI_scalar':
        # The above methods won't work if scalars are used.  This option
        # is only called by the SS_TPI_firstdoughnutring function in TPI.
        T_P = p.tau_payroll[0] * w * e * n
        T_P -= theta * p.replacement_rate_adjust[0] * w
        T_BQ = p.tau_bq[0] * bq
        T_W = (ETR_wealth(b, p.h_wealth[0], p.m_wealth[0], p.p_wealth[0]) * b)
    total_tax = T_I + T_P + T_BQ + T_W - T_H

    return total_tax
Exemple #13
0
def FOC_labor(r, w, b, b_splus1, n, bq, factor, T_H, theta, chi_n, e, tau_c,
              etr_params, mtrx_params, t, j, p, method):
    '''
    Computes Euler errors for the FOC for labor supply in the steady
    state.  This function is usually looped through over J, so it does
    one lifetime income group at a time.

    Inputs:
        r           = scalar, interest rate
        w           = scalar, wage rate
        b           = [S,J] array, distribution of wealth/capital
                        holdings
        b_splus1    = [S,J] array, distribution of wealth/capital
                        holdings one period ahead
        n           = [S,J] array, distribution of labor supply
        BQ          = [J,] vector, aggregate bequests by lifetime
                        income group
        factor      = scalar, scaling factor to convert model income to
                        dollars
        T_H         = scalar, lump sum transfer
        params      = length 19 tuple (e, sigma, g_y, theta, b_ellipse,
                                       upsilon, ltilde, chi_n, tau_bq,
                                       lambdas, J, S, etr_params,
                                       mtrx_params, h_wealth, p_wealth,
                                       m_wealth, tau_payroll, tau_bq)
        e           = [S,J] array, effective labor units
        sigma       = scalar, coefficient of relative risk aversion
        g_y         = scalar, exogenous labor augmenting technological
                        growth
        theta       = [J,] vector, replacement rate for each lifetime
                        income group
        b_ellipse   = scalar, scaling parameter in elliptical utility
                        function
        upsilon     = curvature parameter in elliptical utility function
        chi_n       = [S,] vector, utility weights on disutility of labor
        ltilde      = scalar, upper bound of household labor supply
        tau_bq      = scalar, bequest tax rate (scalar)
        lambdas     = [J,] vector, ability weights
        J           = integer, number of lifetime income groups
        S           = integer, number of economically active periods in
                        lifetime
        etr_params  = [S,10] array, parameters of effective income tax
                        rate function
        mtrx_params = [S,10] array, parameters of marginal tax rate on
                        labor income function
        h_wealth    = scalar, parameter in wealth tax function
        p_wealth    = scalar, parameter in wealth tax function
        m_wealth    = scalar, parameter in wealth tax function
        tau_payroll = scalar, payroll tax rate
        tau_bq      = scalar, bequest tax rate

    Functions called:
        get_cons
        marg_ut_cons
        marg_ut_labor
        tax.total_taxes
        tax.MTR_income

    Objects in function:
        tax = [S,J] array, net taxes in the current period
        cons = [S,J] array, consumption in the current period
        deriv = [S,J] array, net of tax share of labor income
        euler = [S,J] array, Euler error from FOC for labor supply

    Returns: euler

        if j is not None:
            chi_b = p.chi_b[j]
            if method == 'TPI':
                r = r.reshape(r.shape[0], 1)
                w = w.reshape(w.shape[0], 1)
                T_H = T_H.reshape(T_H.shape[0], 1)
        else:
            chi_b = p.chi_b
            if method == 'TPI':
                r = utils.to_timepath_shape(r, p)
                w = utils.to_timepath_shape(w, p)
                T_H = utils.to_timepath_shape(T_H, p)
    '''
    if method == 'SS':
        tau_payroll = p.tau_payroll[-1]
    elif method == 'TPI_scalar':  # for 1st donut ring onlye
        tau_payroll = p.tau_payroll[0]
    else:
        length = r.shape[0]
        tau_payroll = p.tau_payroll[t:t + length]
    if method == 'TPI':
        if b.ndim == 2:
            r = r.reshape(r.shape[0], 1)
            w = w.reshape(w.shape[0], 1)
            T_H = T_H.reshape(T_H.shape[0], 1)
            tau_payroll = tau_payroll.reshape(tau_payroll.shape[0], 1)
        elif b.ndim == 3:
            r = utils.to_timepath_shape(r, p)
            w = utils.to_timepath_shape(w, p)
            T_H = utils.to_timepath_shape(T_H, p)
            tau_payroll = utils.to_timepath_shape(tau_payroll, p)

    taxes = tax.total_taxes(r, w, b, n, bq, factor, T_H, theta, t, j, False,
                            method, e, etr_params, p)
    cons = get_cons(r, w, b, b_splus1, n, bq, taxes, e, tau_c, p)
    deriv = (1 - tau_payroll - tax.MTR_income(r, w, b, n, factor, False, e,
                                              etr_params, mtrx_params, p))
    FOC_error = (marg_ut_cons(cons, p.sigma) * (1 /
                                                (1 + tau_c)) * w * deriv * e -
                 marg_ut_labor(n, chi_n, p))

    return FOC_error
Exemple #14
0
def FOC_savings(r, w, b, b_splus1, n, bq, factor, T_H, theta, e, rho, tau_c,
                etr_params, mtry_params, t, j, p, method):
    '''
    Computes Euler errors for the FOC for savings in the steady state.
    This function is usually looped through over J, so it does one
    lifetime income group at a time.

    Inputs:
        r           = scalar, interest rate
        w           = scalar, wage rate
        b           = [S,J] array, distribution of wealth/capital
        b_splus1    = [S,J] array, distribution of wealth/capital,
                        one period ahead
        b_splus2    = [S,J] array, distribution of wealth/capital, two
                        periods ahead
        n           = [S,J] array, distribution of labor supply
        BQ          = [J,] vector, aggregate bequests by lifetime income
                        group
        factor      = scalar, scaling factor to convert model income to
                        dollars
        T_H         = scalar, lump sum transfer
        params      = length 18 tuple (e, sigma, beta, g_y, chi_b,
                                       theta, tau_bq, rho, lambdas, J,
                                       S, etr_params, mtry_params,
                                       h_wealth, p_wealth, m_wealth,
                                       tau_payroll, tau_bq)
        e           = [S,J] array, effective labor units
        sigma       = scalar, coefficient of relative risk aversion
        beta        = scalar, discount factor
        g_y         = scalar, exogenous labor augmenting technological
                        growth
        chi_b       = [J,] vector, utility weight on bequests for each
                        lifetime income group
        theta       = [J,] vector, replacement rate for each lifetime
                        income group
        tau_bq      = scalar, bequest tax rate (scalar)
        rho         = [S,] vector, mortality rates
        lambdas     = [J,] vector, ability weights
        J           = integer, number of lifetime income groups
        S           = integer, number of economically active periods in
                        lifetime
        etr_params  = [S,12] array, parameters of effective income tax
                        rate function
        mtry_params = [S,12] array, parameters of marginal tax rate on
                        capital income function
        h_wealth    = scalar, parameter in wealth tax function
        p_wealth    = scalar, parameter in wealth tax function
        m_wealth    = scalar, parameter in wealth tax function
        tau_payroll = scalar, payroll tax rate
        tau_bq      = scalar, bequest tax rate

    Functions called:
        get_cons
        marg_ut_cons
        tax.total_taxes
        tax.MTR_income

    Objects in function:
        tax1 = [S,J] array, net taxes in the current period
        tax2 = [S,J] array, net taxes one period ahead
        cons1 = [S,J] array, consumption in the current period
        cons2 = [S,J] array, consumption one period ahead
        deriv = [S,J] array, after-tax return on capital
        savings_ut = [S,J] array, marginal utility from savings
        euler = [S,J] array, Euler error from FOC for savings

    Returns: euler
    '''
    if j is not None:
        chi_b = p.chi_b[j]
    else:
        chi_b = p.chi_b
        if method == 'TPI':
            r = utils.to_timepath_shape(r, p)
            w = utils.to_timepath_shape(w, p)
            T_H = utils.to_timepath_shape(T_H, p)

    taxes = tax.total_taxes(r, w, b, n, bq, factor, T_H, theta, t, j, False,
                            method, e, etr_params, p)
    cons = get_cons(r, w, b, b_splus1, n, bq, taxes, e, tau_c, p)
    deriv = ((1 + r) - r * (tax.MTR_income(r, w, b, n, factor, True, e,
                                           etr_params, mtry_params, p)))
    savings_ut = (rho * np.exp(-p.sigma * p.g_y) * chi_b *
                  b_splus1**(-p.sigma))
    euler_error = np.zeros_like(n)
    if n.shape[0] > 1:
        euler_error[:-1] = (
            marg_ut_cons(cons[:-1], p.sigma) * (1 /
                                                (1 + tau_c[:-1])) - p.beta *
            (1 - rho[:-1]) * deriv[1:] * marg_ut_cons(cons[1:], p.sigma) *
            (1 / (1 + tau_c[1:])) * np.exp(-p.sigma * p.g_y) - savings_ut[:-1])
        euler_error[-1] = (marg_ut_cons(cons[-1], p.sigma) *
                           (1 / (1 + tau_c[-1])) - savings_ut[-1])
    else:
        euler_error[-1] = (marg_ut_cons(cons[-1], p.sigma) *
                           (1 / (1 + tau_c[-1])) - savings_ut[-1])

    return euler_error
Exemple #15
0
def run_TPI(p, client=None):

    # unpack tuples of parameters
    initial_values, SS_values, baseline_values = get_initial_SS_values(p)
    (B0, b_sinit, b_splus1init, factor, initial_b, initial_n,
     D0) = initial_values
    (Kss, Bss, Lss, rss, wss, BQss, T_Hss, total_revenue_ss, bssmat_splus1,
     nssmat, Yss, Gss, theta) = SS_values
    (T_Hbaseline, Gbaseline) = baseline_values

    print('Government spending breakpoints are tG1: ', p.tG1, '; and tG2:',
          p.tG2)

    # Initialize guesses at time paths
    # Make array of initial guesses for labor supply and savings
    domain = np.linspace(0, p.T, p.T)
    domain2 = np.tile(domain.reshape(p.T, 1, 1), (1, p.S, p.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, p.S, p.J), (p.S, 1, 1))
    guesses_b = np.append(guesses_b, ending_b_tail, axis=0)

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

    L_init = np.ones((p.T + p.S, )) * Lss
    B_init = np.ones((p.T + p.S, )) * Bss
    L_init[:p.T] = aggr.get_L(n_mat[:p.T], p, 'TPI')
    B_init[1:p.T] = aggr.get_K(b_mat[:p.T], p, 'TPI', False)[:p.T - 1]
    B_init[0] = B0

    if not p.small_open:
        if p.budget_balance:
            K_init = B_init
        else:
            K_init = B_init * Kss / Bss
    else:
        K_init = firm.get_K(L_init, p.firm_r, p, 'TPI')

    K = K_init

    L = L_init
    B = B_init
    Y = np.zeros_like(K)
    Y[:p.T] = firm.get_Y(K[:p.T], L[:p.T], p, 'TPI')
    Y[p.T:] = Yss
    r = np.zeros_like(Y)
    if not p.small_open:
        r[:p.T] = firm.get_r(Y[:p.T], K[:p.T], p, 'TPI')
        r[p.T:] = rss
    else:
        r = p.firm_r
    # compute w
    w = np.zeros_like(r)
    w[:p.T] = firm.get_w_from_r(r[:p.T], p, 'TPI')
    w[p.T:] = wss
    r_gov = fiscal.get_r_gov(r, p)
    if p.budget_balance:
        r_hh = r
    else:
        r_hh = aggr.get_r_hh(r, r_gov, K, p.debt_ratio_ss * Y)
    if p.small_open:
        r_hh = p.hh_r

    BQ0 = aggr.get_BQ(r[0], initial_b, None, p, 'SS', True)
    if not p.use_zeta:
        BQ = np.zeros((p.T + p.S, p.J))
        for j in range(p.J):
            BQ[:,
               j] = (list(np.linspace(BQ0[j], BQss[j], p.T)) + [BQss[j]] * p.S)
        BQ = np.array(BQ)
    else:
        BQ = (list(np.linspace(BQ0, BQss, p.T)) + [BQss] * p.S)
        BQ = np.array(BQ)
    if p.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(p.T + p.S) * T_Hss2
        total_revenue = T_H
        G = np.zeros(p.T + p.S)
    elif not p.baseline_spending:
        T_H = p.alpha_T * Y
    elif p.baseline_spending:
        T_H = T_Hbaseline
        T_H_new = p.T_H  # Need to set T_H_new for later reference
        G = Gbaseline
        G_0 = Gbaseline[0]

    # Initialize some starting value
    if p.budget_balance:
        D = 0.0 * Y
    else:
        D = p.debt_ratio_ss * Y
    TPIiter = 0
    TPIdist = 10
    euler_errors = np.zeros((p.T, 2 * p.S, p.J))
    TPIdist_vec = np.zeros(p.maxiter)

    print('analytical mtrs in tpi = ', p.analytical_mtrs)
    print('tax function type in tpi = ', p.tax_func_type)

    # TPI loop
    while (TPIiter < p.maxiter) and (TPIdist >= p.mindist_TPI):
        r_gov[:p.T] = fiscal.get_r_gov(r[:p.T], p)
        if p.budget_balance:
            r_hh[:p.T] = r[:p.T]
        else:
            K[:p.T] = firm.get_K_from_Y(Y[:p.T], r[:p.T], p, 'TPI')
            r_hh[:p.T] = aggr.get_r_hh(r[:p.T], r_gov[:p.T], K[:p.T], D[:p.T])
        if p.small_open:
            r_hh[:p.T] = p.hh_r[:p.T]

        outer_loop_vars = (r, w, r_hh, BQ, T_H, theta)

        euler_errors = np.zeros((p.T, 2 * p.S, p.J))
        lazy_values = []
        for j in range(p.J):
            guesses = (guesses_b[:, :, j], guesses_n[:, :, j])
            lazy_values.append(
                delayed(inner_loop)(guesses, outer_loop_vars, initial_values,
                                    j, ind, p))
        results = compute(*lazy_values,
                          scheduler=dask.multiprocessing.get,
                          num_workers=p.num_workers)
        for j, result in enumerate(results):
            euler_errors[:, :, j], b_mat[:, :, j], n_mat[:, :, j] = result

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

        L[:p.T] = aggr.get_L(n_mat[:p.T], p, 'TPI')
        B[1:p.T] = aggr.get_K(bmat_splus1[:p.T], p, 'TPI', False)[:p.T - 1]
        if np.any(B) < 0:
            print('B has negative elements. B[0:9]:', B[0:9])
            print('B[T-2:T]:', B[p.T - 2, p.T])

        etr_params_4D = np.tile(
            p.etr_params.reshape(p.T, p.S, 1, p.etr_params.shape[2]),
            (1, 1, p.J, 1))
        bqmat = household.get_bq(BQ, None, p, 'TPI')
        tax_mat = tax.total_taxes(r_hh[:p.T], w[:p.T], bmat_s,
                                  n_mat[:p.T, :, :], bqmat[:p.T, :, :], factor,
                                  T_H[:p.T], theta, 0, None, False, 'TPI', p.e,
                                  etr_params_4D, p)
        r_hh_path = utils.to_timepath_shape(r_hh, p)
        wpath = utils.to_timepath_shape(w, p)
        c_mat = household.get_cons(r_hh_path[:p.T, :, :], wpath[:p.T, :, :],
                                   bmat_s, bmat_splus1, n_mat[:p.T, :, :],
                                   bqmat[:p.T, :, :], tax_mat, p.e,
                                   p.tau_c[:p.T, :, :], p)

        if not p.small_open:
            if p.budget_balance:
                K[:p.T] = B[:p.T]
            else:
                if not p.baseline_spending:
                    Y = T_H / p.alpha_T  # maybe unecessary

                    (total_rev, T_Ipath, T_Ppath, T_BQpath, T_Wpath,
                     T_Cpath, business_revenue) = aggr.revenue(
                         r_hh[:p.T], w[:p.T], bmat_s, n_mat[:p.T, :, :],
                         bqmat[:p.T, :, :], c_mat[:p.T, :, :], Y[:p.T],
                         L[:p.T], K[:p.T], factor, theta, etr_params_4D, p,
                         'TPI')
                    total_revenue = np.array(
                        list(total_rev) + [total_revenue_ss] * p.S)

                # set intial debt value
                if p.baseline:
                    D_0 = p.initial_debt_ratio * Y[0]
                else:
                    D_0 = D0
                if not p.baseline_spending:
                    G_0 = p.alpha_G[0] * Y[0]
                dg_fixed_values = (Y, total_revenue, T_H, D_0, G_0)
                Dnew, G = fiscal.D_G_path(r_gov, dg_fixed_values, Gbaseline, p)

                K[:p.T] = B[:p.T] - Dnew[:p.T]
                if np.any(K < 0):
                    print('K has negative elements. Setting them ' +
                          'positive to prevent NAN.')
                    K[:p.T] = np.fmax(K[:p.T], 0.05 * B[:p.T])
        else:
            K[:p.T] = firm.get_K(L[:p.T], p.firm_r[:p.T], p, 'TPI')
        Ynew = firm.get_Y(K[:p.T], L[:p.T], p, 'TPI')
        if not p.small_open:
            rnew = firm.get_r(Ynew[:p.T], K[:p.T], p, 'TPI')
        else:
            rnew = r.copy()
        r_gov_new = fiscal.get_r_gov(rnew, p)
        if p.budget_balance:
            r_hh_new = rnew[:p.T]
        else:
            r_hh_new = aggr.get_r_hh(rnew, r_gov_new, K[:p.T], Dnew[:p.T])
        if p.small_open:
            r_hh_new = p.hh_r[:p.T]
        # compute w
        wnew = firm.get_w_from_r(rnew[:p.T], p, 'TPI')

        b_mat_shift = np.append(np.reshape(initial_b, (1, p.S, p.J)),
                                b_mat[:p.T - 1, :, :],
                                axis=0)
        BQnew = aggr.get_BQ(r_hh_new[:p.T], b_mat_shift, None, p, 'TPI', False)
        bqmat_new = household.get_bq(BQnew, None, p, 'TPI')
        (total_rev, T_Ipath, T_Ppath, T_BQpath,
         T_Wpath, T_Cpath, business_revenue) = aggr.revenue(
             r_hh_new[:p.T], wnew[:p.T], bmat_s, n_mat[:p.T, :, :],
             bqmat_new[:p.T, :, :], c_mat[:p.T, :, :], Ynew[:p.T], L[:p.T],
             K[:p.T], factor, theta, etr_params_4D, p, 'TPI')
        total_revenue = np.array(list(total_rev) + [total_revenue_ss] * p.S)

        if p.budget_balance:
            T_H_new = total_revenue
        elif not p.baseline_spending:
            T_H_new = p.alpha_T[:p.T] * Ynew[:p.T]
        # If baseline_spending==True, no need to update T_H, it's fixed

        if p.small_open and not p.budget_balance:
            # Loop through years to calculate debt and gov't spending.
            # This is done earlier when small_open=False.
            if p.baseline:
                D_0 = p.initial_debt_ratio * Y[0]
            else:
                D_0 = D0
            if not p.baseline_spending:
                G_0 = p.alpha_G[0] * Ynew[0]
            dg_fixed_values = (Ynew, total_revenue, T_H, D_0, G_0)
            Dnew, G = fiscal.D_G_path(r_gov_new, dg_fixed_values, Gbaseline, p)

        if p.budget_balance:
            Dnew = D

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

        print('r diff: ', (rnew[:p.T] - r[:p.T]).max(),
              (rnew[:p.T] - r[:p.T]).min())
        print('BQ diff: ', (BQnew[:p.T] - BQ[:p.T]).max(),
              (BQnew[:p.T] - BQ[:p.T]).min())
        print('T_H diff: ', (T_H_new[:p.T] - T_H[:p.T]).max(),
              (T_H_new[:p.T] - T_H[:p.T]).min())
        print('Y diff: ', (Ynew[:p.T] - Y[:p.T]).max(),
              (Ynew[:p.T] - Y[:p.T]).min())
        if not p.baseline_spending:
            if T_H.all() != 0:
                TPIdist = np.array(
                    list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) + list(
                        utils.pct_diff_func(BQnew[:p.T], BQ[:p.T]).flatten()) +
                    list(utils.pct_diff_func(wnew[:p.T], w[:p.T])) +
                    list(utils.pct_diff_func(T_H_new[:p.T], T_H[:p.T]))).max()
            else:
                TPIdist = np.array(
                    list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) + list(
                        utils.pct_diff_func(BQnew[:p.T], BQ[:p.T]).flatten()) +
                    list(utils.pct_diff_func(wnew[:p.T], w[:p.T])) +
                    list(np.abs(T_H[:p.T]))).max()
        else:
            TPIdist = np.array(
                list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) +
                list(utils.pct_diff_func(BQnew[:p.T], BQ[:p.T]).flatten()) +
                list(utils.pct_diff_func(wnew[:p.T], w[:p.T])) +
                list(utils.pct_diff_func(Ynew[:p.T], Y[:p.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)

    # Compute effective and marginal tax rates for all agents
    mtrx_params_4D = np.tile(
        p.mtrx_params.reshape(p.T, p.S, 1, p.mtrx_params.shape[2]),
        (1, 1, p.J, 1))
    mtry_params_4D = np.tile(
        p.mtry_params.reshape(p.T, p.S, 1, p.mtry_params.shape[2]),
        (1, 1, p.J, 1))

    e_3D = np.tile(p.e.reshape(1, p.S, p.J), (p.T, 1, 1))
    mtry_path = tax.MTR_income(r_hh_path[:p.T], wpath[:p.T],
                               bmat_s[:p.T, :, :], n_mat[:p.T, :, :], factor,
                               True, e_3D, etr_params_4D, mtry_params_4D, p)
    mtrx_path = tax.MTR_income(r_hh_path[:p.T], wpath[:p.T],
                               bmat_s[:p.T, :, :], n_mat[:p.T, :, :], factor,
                               False, e_3D, etr_params_4D, mtrx_params_4D, p)
    etr_path = tax.ETR_income(r_hh_path[:p.T], wpath[:p.T], bmat_s[:p.T, :, :],
                              n_mat[:p.T, :, :], factor, e_3D, etr_params_4D,
                              p)

    C = aggr.get_C(c_mat, p, 'TPI')

    if not p.small_open:
        I = aggr.get_I(bmat_splus1[:p.T], K[1:p.T + 1], K[:p.T], p, 'TPI')
        rc_error = Y[:p.T] - C[:p.T] - I[:p.T] - G[:p.T]
    else:
        I = ((1 + np.squeeze(np.hstack(
            (p.g_n[1:p.T], p.g_n_ss)))) * np.exp(p.g_y) * K[1:p.T + 1] -
             (1.0 - p.delta) * K[:p.T])
        BI = aggr.get_I(bmat_splus1[:p.T], B[1:p.T + 1], B[:p.T], p, 'TPI')
        new_borrowing = (D[1:p.T] * (1 + p.g_n[1:p.T]) * np.exp(p.g_y) -
                         D[:p.T - 1])
        rc_error = (Y[:p.T - 1] + new_borrowing -
                    (C[:p.T - 1] + BI[:p.T - 1] + G[:p.T - 1]) +
                    (p.hh_r[:p.T - 1] * B[:p.T - 1] -
                     (p.delta + p.firm_r[:p.T - 1]) * K[:p.T - 1] -
                     p.hh_r[:p.T - 1] * D[:p.T - 1]))

    # Compute total investment (not just domestic)
    I_total = ((1 + p.g_n[:p.T]) * np.exp(p.g_y) * K[1:p.T + 1] -
               (1.0 - p.delta) * K[:p.T])

    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 range(p.T):
        household.constraint_checker_TPI(b_mat[t], n_mat[t], c_mat[t], t,
                                         p.ltilde)

    eul_savings = euler_errors[:, :p.S, :].max(1).max(1)
    eul_laborleisure = euler_errors[:, p.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[:p.T],
        'B': B,
        'K': K,
        'L': L,
        'C': C,
        'I': I,
        'I_total': I_total,
        'BQ': BQ,
        'total_revenue': total_revenue,
        'business_revenue': business_revenue,
        'IITpayroll_revenue': T_Ipath,
        'T_H': T_H,
        'T_P': T_Ppath,
        'T_BQ': T_BQpath,
        'T_W': T_Wpath,
        'T_C': T_Cpath,
        'G': G,
        'D': D,
        'r': r,
        'r_gov': r_gov,
        'r_hh': r_hh,
        'w': w,
        'bmat_splus1': bmat_splus1,
        'bmat_s': bmat_s[:p.T, :, :],
        'n_mat': n_mat[:p.T, :, :],
        'c_path': c_mat,
        'bq_path': bqmat,
        'tax_path': tax_mat,
        'eul_savings': eul_savings,
        'eul_laborleisure': eul_laborleisure,
        'resource_constraint_error': rc_error,
        'etr_path': etr_path,
        'mtrx_path': mtrx_path,
        'mtry_path': mtry_path
    }

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

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

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

    if ((np.any(np.absolute(rc_error) >= p.mindist_TPI * 10))
            and ENFORCE_SOLUTION_CHECKS):
        raise RuntimeError('Transition path equlibrium not found ' +
                           '(rc_error)')

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

    return output
Exemple #16
0
def total_taxes(r, w, b, n, bq, factor, tr, theta, t, j, shift, method,
                e, etr_params, p):
    '''
    Calculate net taxes paid for each household.

    Args:
        r (array_like): real interest rate
        w (array_like): real wage rate
        b (Numpy array): savings
        n (Numpy array): labor supply
        bq (Numpy array): bequests received
        factor (scalar): scaling factor converting model units to
            dollars
        tr (Numpy array): government transfers to the household
        theta (Numpy array): social security replacement rate value for
            lifetime income group j
        t (int): time period
        j (int): index of lifetime income group
        shift (bool): whether computing for periods 0--s or 1--(s+1),
            =True for 1--(s+1)
        method (str): adjusts calculation dimensions based on 'SS' or
            'TPI'
        e (Numpy array): effective labor units
        etr_params (Numpy array): effective tax rate function parameters
        p (OG-USA Specifications object): model parameters

    Returns:
        total_taxes (Numpy array): net taxes paid for each household

    '''
    if j is not None:
        lambdas = p.lambdas[j]
        if method == 'TPI':
            if b.ndim == 2:
                r = r.reshape(r.shape[0], 1)
                w = w.reshape(w.shape[0], 1)
    else:
        lambdas = np.transpose(p.lambdas)
        if method == 'TPI':
            r = utils.to_timepath_shape(r)
            w = utils.to_timepath_shape(w)

    income = r * b + w * e * n
    T_I = ETR_income(r, w, b, n, factor, e, etr_params, p) * income

    if method == 'SS':
        # Depending on if we are looking at b_s or b_s+1, the
        # entry for retirement will change (it shifts back one).
        # The shift boolean makes sure we start replacement rates
        # at the correct age.
        T_P = p.tau_payroll[-1] * w * e * n
        if shift is False:
            T_P[p.retire[-1]:] -= theta * w
        else:
            T_P[p.retire[-1] - 1:] -= theta * w
        T_BQ = p.tau_bq[-1] * bq
        T_W = (ETR_wealth(b, p.h_wealth[-1], p.m_wealth[-1],
                          p.p_wealth[-1]) * b)
    elif method == 'TPI':
        length = w.shape[0]
        if not shift:
            # retireTPIis different from retire, because in TPincomewe are
            # counting backwards with different length lists.  This will
            # always be the correct location of retirement, depending
            # on the shape of the lists.
            retireTPI = (p.retire[t: t + length] - p.S)
        else:
            retireTPI = (p.retire[t: t + length] - 1 - p.S)
        if len(b.shape) == 1:
            T_P = p.tau_payroll[t: t + length] * w * e * n
            if not shift:
                retireTPI = p.retire[t] - p.S
            else:
                retireTPI = p.retire[t] - 1 - p.S
            T_P[retireTPI:] -= (theta[j] * p.replacement_rate_adjust[t]
                                * w[retireTPI:])
            T_W = (ETR_wealth(b, p.h_wealth[t:t + length],
                              p.m_wealth[t:t + length],
                              p.p_wealth[t:t + length]) * b)
            T_BQ = p.tau_bq[t:t + length] * bq
        elif len(b.shape) == 2:
            T_P = p.tau_payroll[t: t + length].reshape(length, 1) * w * e * n
            for tt in range(T_P.shape[0]):
                T_P[tt, retireTPI[tt]:] -= (
                    theta * p.replacement_rate_adjust[t + tt] * w[tt])
            T_W = (ETR_wealth(b, p.h_wealth[t:t + length],
                              p.m_wealth[t:t + length],
                              p.p_wealth[t:t + length]) * b)
            T_BQ = p.tau_bq[t:t + length].reshape(length, 1) * bq / lambdas
        else:
            T_P = p.tau_payroll[t:t + length].reshape(length, 1, 1) * w * e * n
            for tt in range(T_P.shape[0]):
                T_P[tt, retireTPI[tt]:, :] -= (
                    theta.reshape(1, p.J) *
                    p.replacement_rate_adjust[t + tt] * w[tt])
            T_W = (ETR_wealth(
                b, p.h_wealth[t:t + length].reshape(length, 1, 1),
                p.m_wealth[t:t + length].reshape(length, 1, 1),
                p.p_wealth[t:t + length].reshape(length, 1, 1)) * b)
            T_BQ = p.tau_bq[t:t + length].reshape(length, 1, 1) * bq
    elif method == 'TPI_scalar':
        # The above methods won't work if scalars are used.  This option
        # is only called by the SS_TPI_firstdoughnutring function in TPI.
        T_P = p.tau_payroll[0] * w * e * n
        T_P -= theta * p.replacement_rate_adjust[0] * w
        T_BQ = p.tau_bq[0] * bq
        T_W = (ETR_wealth(b, p.h_wealth[0], p.m_wealth[0],
                          p.p_wealth[0]) * b)
    total_tax = T_I + T_P + T_BQ + T_W - tr

    return total_tax
Exemple #17
0
def revenue(r, w, b, n, bq, c, Y, L, K, factor, theta, etr_params,
            p, method):
    r'''
    Calculate aggregate tax revenue.

    .. math::
        R_{t} = \sum_{s=E}^{E+S}\sum_{j=0}^{J}\omega_{s,t}\lambda_{j}(T_{j,s,t} + \tau^{p}_{t}w_{t}e_{j,s}n_{j,s,t} - \theta_{j}w_{t} + \tau^{bq}bq_{j,s,t} + \tau^{c}_{s,t}c_{j,s,t} + \tau^{w}_{t}b_{j,s,t}) + \tau^{b}_{t}(Y_{t}-w_{t}L_{t}) - \tau^{b}_{t}\delta^{\tau}_{t}K^{\tau}_{t}

    Args:
        r (array_like): the real interest rate
        w (array_like): the real wage rate
        b (Numpy array): household savings
        n (Numpy array): household labor supply
        bq (Numpy array): household bequests received
        c (Numpy array): household consumption
        Y (array_like): aggregate output
        L (array_like): aggregate labor
        K (array_like): aggregate capital
        factor (scalar): factor (scalar): scaling factor converting
            model units to dollars
        theta (Numpy array): social security replacement rate for each
            lifetime income group
        etr_params (Numpy array): paramters of the effective tax rate
            functions
        p (OG-USA Specifications object): model parameters
        method (str): adjusts calculation dimensions based on 'SS' or
            'TPI'

    Returns:
        REVENUE (array_like): aggregate tax revenue
        T_I (array_like): aggregate income tax revenue
        T_P (array_like): aggregate net payroll tax revenue, revenues
            minus social security benefits paid
        T_BQ (array_like): aggregate bequest tax revenue
        T_W (array_like): aggregate wealth tax revenue
        T_C (array_like): aggregate consumption tax revenue
        business_revenue (array_like): aggregate business tax revenue

    '''
    if method == 'SS':
        I = r * b + w * p.e * n
        T_I = np.zeros_like(I)
        T_I = tax.ETR_income(r, w, b, n, factor, p.e, etr_params, p) * I
        T_P = p.tau_payroll[-1] * w * p.e * n
        T_P[p.retire[-1]:] -= theta * w
        T_W = (tax.ETR_wealth(b, p.h_wealth[-1], p.m_wealth[-1],
                              p.p_wealth[-1]) * b)
        T_BQ = p.tau_bq[-1] * bq
        T_C = p.tau_c[-1, :, :] * c
        business_revenue = tax.get_biz_tax(w, Y, L, K, p, method)
        REVENUE = ((np.transpose(p.omega_SS * p.lambdas) *
                    (T_I + T_P + T_BQ + T_W + T_C)).sum() +
                   business_revenue)
    elif method == 'TPI':
        r_array = utils.to_timepath_shape(r)
        w_array = utils.to_timepath_shape(w)
        I = r_array * b + w_array * n * p.e
        T_I = np.zeros_like(I)
        T_I = tax.ETR_income(r_array, w_array, b, n, factor, p.e,
                             etr_params, p) * I
        T_P = p.tau_payroll[:p.T].reshape(p.T, 1, 1) * w_array * n * p.e
        for t in range(T_P.shape[0]):
            T_P[t, p.retire[t]:, :] -= (theta.reshape(1, p.J) *
                                        p.replacement_rate_adjust[t] *
                                        w_array[t])
        T_W = (tax.ETR_wealth(b, p.h_wealth[:p.T].reshape(p.T, 1, 1),
                              p.m_wealth[:p.T].reshape(p.T, 1, 1),
                              p.p_wealth[:p.T].reshape(p.T, 1, 1)) * b)
        T_BQ = p.tau_bq[:p.T].reshape(p.T, 1, 1) * bq
        T_C = p.tau_c[:p.T, :, :] * c
        business_revenue = tax.get_biz_tax(w, Y, L, K, p, method)
        REVENUE = ((((np.squeeze(p.lambdas)) *
                   np.tile(np.reshape(p.omega[:p.T, :], (p.T, p.S, 1)),
                           (1, 1, p.J)))
                   * (T_I + T_P + T_BQ + T_W + T_C)).sum(1).sum(1) +
                   business_revenue)

    return REVENUE, T_I, T_P, T_BQ, T_W, T_C, business_revenue
Exemple #18
0
def run_TPI(p, client=None):

    # unpack tuples of parameters
    initial_values, ss_vars, theta, baseline_values = get_initial_SS_values(p)
    (B0, b_sinit, b_splus1init, factor, initial_b, initial_n,
     D0) = initial_values
    (T_Hbaseline, Gbaseline) = baseline_values

    print('Government spending breakpoints are tG1: ', p.tG1, '; and tG2:',
          p.tG2)

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

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

    L_init = np.ones((p.T + p.S, )) * ss_vars['Lss']
    B_init = np.ones((p.T + p.S, )) * ss_vars['Bss']
    L_init[:p.T] = aggr.get_L(n_mat[:p.T], p, 'TPI')
    B_init[1:p.T] = aggr.get_K(b_mat[:p.T], p, 'TPI', False)[:p.T - 1]
    B_init[0] = B0

    if not p.small_open:
        if p.budget_balance:
            K_init = B_init
        else:
            K_init = B_init * ss_vars['Kss'] / ss_vars['Bss']
    else:
        K_init = firm.get_K(L_init, p.firm_r, p, 'TPI')

    K = K_init
    K_d = K_init * ss_vars['K_d_ss'] / ss_vars['Kss']
    K_f = K_init * ss_vars['K_f_ss'] / ss_vars['Kss']

    L = L_init
    B = B_init
    Y = np.zeros_like(K)
    Y[:p.T] = firm.get_Y(K[:p.T], L[:p.T], p, 'TPI')
    Y[p.T:] = ss_vars['Yss']
    r = np.zeros_like(Y)
    if not p.small_open:
        r[:p.T] = firm.get_r(Y[:p.T], K[:p.T], p, 'TPI')
        r[p.T:] = ss_vars['rss']
    else:
        r = p.firm_r
    # compute w
    w = np.zeros_like(r)
    w[:p.T] = firm.get_w_from_r(r[:p.T], p, 'TPI')
    w[p.T:] = ss_vars['wss']
    r_gov = fiscal.get_r_gov(r, p)
    if p.budget_balance:
        r_hh = r
    else:
        r_hh = aggr.get_r_hh(r, r_gov, K, ss_vars['Dss'])
    if p.small_open:
        r_hh = p.hh_r

    BQ0 = aggr.get_BQ(r[0], initial_b, None, p, 'SS', True)
    if not p.use_zeta:
        BQ = np.zeros((p.T + p.S, p.J))
        for j in range(p.J):
            BQ[:, j] = (list(np.linspace(BQ0[j], ss_vars['BQss'][j], p.T)) +
                        [ss_vars['BQss'][j]] * p.S)
        BQ = np.array(BQ)
    else:
        BQ = (list(np.linspace(BQ0, ss_vars['BQss'], p.T)) +
              [ss_vars['BQss']] * p.S)
        BQ = np.array(BQ)
    if p.budget_balance:
        if np.abs(ss_vars['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 = ss_vars['T_Hss']
        T_H = np.ones(p.T + p.S) * T_Hss2
        total_revenue = T_H
        G = np.zeros(p.T + p.S)
    elif not p.baseline_spending:
        T_H = p.alpha_T * Y
        G = np.ones(p.T + p.S) * ss_vars['Gss']
    elif p.baseline_spending:
        T_H = T_Hbaseline
        T_H_new = p.T_H  # Need to set T_H_new for later reference
        G = Gbaseline
        G_0 = Gbaseline[0]

    # Initialize some starting values
    if p.budget_balance:
        D = np.zeros(p.T + p.S)
    else:
        D = np.ones(p.T + p.S) * ss_vars['Dss']
    if ss_vars['Dss'] == 0:
        D_d = np.zeros(p.T + p.S)
        D_f = np.zeros(p.T + p.S)
    else:
        D_d = D * ss_vars['D_d_ss'] / ss_vars['Dss']
        D_f = D * ss_vars['D_f_ss'] / ss_vars['Dss']
    total_revenue = np.ones(p.T + p.S) * ss_vars['total_revenue_ss']

    TPIiter = 0
    TPIdist = 10
    euler_errors = np.zeros((p.T, 2 * p.S, p.J))
    TPIdist_vec = np.zeros(p.maxiter)

    # TPI loop
    while (TPIiter < p.maxiter) and (TPIdist >= p.mindist_TPI):
        r_gov[:p.T] = fiscal.get_r_gov(r[:p.T], p)
        if p.budget_balance:
            r_hh[:p.T] = r[:p.T]
        else:
            K[:p.T] = firm.get_K_from_Y(Y[:p.T], r[:p.T], p, 'TPI')
            r_hh[:p.T] = aggr.get_r_hh(r[:p.T], r_gov[:p.T], K[:p.T], D[:p.T])
        if p.small_open:
            r_hh[:p.T] = p.hh_r[:p.T]

        outer_loop_vars = (r, w, r_hh, BQ, T_H, theta)

        euler_errors = np.zeros((p.T, 2 * p.S, p.J))
        lazy_values = []
        for j in range(p.J):
            guesses = (guesses_b[:, :, j], guesses_n[:, :, j])
            lazy_values.append(
                delayed(inner_loop)(guesses, outer_loop_vars, initial_values,
                                    j, ind, p))
        results = compute(*lazy_values,
                          scheduler=dask.multiprocessing.get,
                          num_workers=p.num_workers)
        for j, result in enumerate(results):
            euler_errors[:, :, j], b_mat[:, :, j], n_mat[:, :, j] = result

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

        etr_params_4D = np.tile(
            p.etr_params.reshape(p.T, p.S, 1, p.etr_params.shape[2]),
            (1, 1, p.J, 1))
        bqmat = household.get_bq(BQ, None, p, 'TPI')
        tax_mat = tax.total_taxes(r_hh[:p.T], w[:p.T], bmat_s,
                                  n_mat[:p.T, :, :], bqmat[:p.T, :, :], factor,
                                  T_H[:p.T], theta, 0, None, False, 'TPI', p.e,
                                  etr_params_4D, p)
        r_hh_path = utils.to_timepath_shape(r_hh, p)
        wpath = utils.to_timepath_shape(w, p)
        c_mat = household.get_cons(r_hh_path[:p.T, :, :], wpath[:p.T, :, :],
                                   bmat_s, bmat_splus1, n_mat[:p.T, :, :],
                                   bqmat[:p.T, :, :], tax_mat, p.e,
                                   p.tau_c[:p.T, :, :], p)
        y_before_tax_mat = (r_hh_path[:p.T, :, :] * bmat_s[:p.T, :, :] +
                            wpath[:p.T, :, :] * p.e * n_mat[:p.T, :, :])

        if not p.baseline_spending and not p.budget_balance:
            Y[:p.T] = T_H[:p.T] / p.alpha_T[:p.T]  # maybe unecessary

            (total_rev, T_Ipath, T_Ppath, T_BQpath,
             T_Wpath, T_Cpath, business_revenue) = aggr.revenue(
                 r_hh[:p.T], w[:p.T], bmat_s, n_mat[:p.T, :, :],
                 bqmat[:p.T, :, :], c_mat[:p.T, :, :], Y[:p.T], L[:p.T],
                 K[:p.T], factor, theta, etr_params_4D, p, 'TPI')
            total_revenue[:p.T] = total_rev
            # set intial debt value
            if p.baseline:
                D0 = p.initial_debt_ratio * Y[0]
            if not p.baseline_spending:
                G_0 = p.alpha_G[0] * Y[0]
            dg_fixed_values = (Y, total_revenue, T_H, D0, G_0)
            Dnew, G[:p.T] = fiscal.D_G_path(r_gov, dg_fixed_values, Gbaseline,
                                            p)
            # Fix initial amount of foreign debt holding
            D_f[0] = p.initial_foreign_debt_ratio * Dnew[0]
            for t in range(1, p.T):
                D_f[t + 1] = (D_f[t] / (np.exp(p.g_y) * (1 + p.g_n[t + 1])) +
                              p.zeta_D[t] * (Dnew[t + 1] -
                                             (Dnew[t] / (np.exp(p.g_y) *
                                                         (1 + p.g_n[t + 1])))))
            D_d[:p.T] = Dnew[:p.T] - D_f[:p.T]
        else:  # if budget balance
            Dnew = np.zeros(p.T + 1)
            G[:p.T] = np.zeros(p.T)
            D_f[:p.T] = np.zeros(p.T)
            D_d[:p.T] = np.zeros(p.T)

        L[:p.T] = aggr.get_L(n_mat[:p.T], p, 'TPI')
        B[1:p.T] = aggr.get_K(bmat_splus1[:p.T], p, 'TPI', False)[:p.T - 1]
        K_demand_open = firm.get_K(L[:p.T], p.firm_r[:p.T], p, 'TPI')
        K_d[:p.T] = B[:p.T] - D_d[:p.T]
        if np.any(K_d < 0):
            print('K_d has negative elements. Setting them ' +
                  'positive to prevent NAN.')
            K_d[:p.T] = np.fmax(K_d[:p.T], 0.05 * B[:p.T])
        K_f[:p.T] = p.zeta_K[:p.T] * (K_demand_open - B[:p.T] + D_d[:p.T])
        K = K_f + K_d
        if np.any(B) < 0:
            print('B has negative elements. B[0:9]:', B[0:9])
            print('B[T-2:T]:', B[p.T - 2, p.T])
        if p.small_open:
            K[:p.T] = K_demand_open
        Ynew = firm.get_Y(K[:p.T], L[:p.T], p, 'TPI')
        rnew = r.copy()
        if not p.small_open:
            rnew[:p.T] = firm.get_r(Ynew[:p.T], K[:p.T], p, 'TPI')
        else:
            rnew[:p.T] = r[:p.T].copy()
        r_gov_new = fiscal.get_r_gov(rnew, p)
        if p.budget_balance:
            r_hh_new = rnew[:p.T]
        else:
            r_hh_new = aggr.get_r_hh(rnew[:p.T], r_gov_new[:p.T], K[:p.T],
                                     Dnew[:p.T])
        if p.small_open:
            r_hh_new = p.hh_r[:p.T]
        # compute w
        wnew = firm.get_w_from_r(rnew[:p.T], p, 'TPI')

        b_mat_shift = np.append(np.reshape(initial_b, (1, p.S, p.J)),
                                b_mat[:p.T - 1, :, :],
                                axis=0)
        BQnew = aggr.get_BQ(r_hh_new[:p.T], b_mat_shift, None, p, 'TPI', False)
        bqmat_new = household.get_bq(BQnew, None, p, 'TPI')
        (total_rev, T_Ipath, T_Ppath, T_BQpath,
         T_Wpath, T_Cpath, business_revenue) = aggr.revenue(
             r_hh_new[:p.T], wnew[:p.T], bmat_s, n_mat[:p.T, :, :],
             bqmat_new[:p.T, :, :], c_mat[:p.T, :, :], Ynew[:p.T], L[:p.T],
             K[:p.T], factor, theta, etr_params_4D, p, 'TPI')
        total_revenue[:p.T] = total_rev

        if p.budget_balance:
            T_H_new = total_revenue
        elif not p.baseline_spending:
            T_H_new = p.alpha_T[:p.T] * Ynew[:p.T]
        # If baseline_spending==True, no need to update T_H, it's fixed

        # update vars for next iteration
        w[:p.T] = wnew[:p.T]
        r[:p.T] = utils.convex_combo(rnew[:p.T], r[:p.T], p.nu)
        BQ[:p.T] = utils.convex_combo(BQnew[:p.T], BQ[:p.T], p.nu)
        D[:p.T] = Dnew[:p.T]
        Y[:p.T] = utils.convex_combo(Ynew[:p.T], Y[:p.T], p.nu)
        if not p.baseline_spending:
            T_H[:p.T] = utils.convex_combo(T_H_new[:p.T], T_H[:p.T], p.nu)
        guesses_b = utils.convex_combo(b_mat, guesses_b, p.nu)
        guesses_n = utils.convex_combo(n_mat, guesses_n, p.nu)
        print('r diff: ', (rnew[:p.T] - r[:p.T]).max(),
              (rnew[:p.T] - r[:p.T]).min())
        print('BQ diff: ', (BQnew[:p.T] - BQ[:p.T]).max(),
              (BQnew[:p.T] - BQ[:p.T]).min())
        print('T_H diff: ', (T_H_new[:p.T] - T_H[:p.T]).max(),
              (T_H_new[:p.T] - T_H[:p.T]).min())
        print('Y diff: ', (Ynew[:p.T] - Y[:p.T]).max(),
              (Ynew[:p.T] - Y[:p.T]).min())
        if not p.baseline_spending:
            if T_H.all() != 0:
                TPIdist = np.array(
                    list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) + list(
                        utils.pct_diff_func(BQnew[:p.T], BQ[:p.T]).flatten()) +
                    list(utils.pct_diff_func(T_H_new[:p.T], T_H[:p.T]))).max()
            else:
                TPIdist = np.array(
                    list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) + list(
                        utils.pct_diff_func(BQnew[:p.T], BQ[:p.T]).flatten()) +
                    list(np.abs(T_H[:p.T]))).max()
        else:
            TPIdist = np.array(
                list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) +
                list(utils.pct_diff_func(BQnew[:p.T], BQ[:p.T]).flatten()) +
                list(utils.pct_diff_func(Ynew[:p.T], Y[:p.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)

    # Compute effective and marginal tax rates for all agents
    mtrx_params_4D = np.tile(
        p.mtrx_params.reshape(p.T, p.S, 1, p.mtrx_params.shape[2]),
        (1, 1, p.J, 1))
    mtry_params_4D = np.tile(
        p.mtry_params.reshape(p.T, p.S, 1, p.mtry_params.shape[2]),
        (1, 1, p.J, 1))

    e_3D = np.tile(p.e.reshape(1, p.S, p.J), (p.T, 1, 1))
    mtry_path = tax.MTR_income(r_hh_path[:p.T], wpath[:p.T],
                               bmat_s[:p.T, :, :], n_mat[:p.T, :, :], factor,
                               True, e_3D, etr_params_4D, mtry_params_4D, p)
    mtrx_path = tax.MTR_income(r_hh_path[:p.T], wpath[:p.T],
                               bmat_s[:p.T, :, :], n_mat[:p.T, :, :], factor,
                               False, e_3D, etr_params_4D, mtrx_params_4D, p)
    etr_path = tax.ETR_income(r_hh_path[:p.T], wpath[:p.T], bmat_s[:p.T, :, :],
                              n_mat[:p.T, :, :], factor, e_3D, etr_params_4D,
                              p)

    C = aggr.get_C(c_mat, p, 'TPI')
    # Note that implicity in this computation is that immigrants'
    # wealth is all in the form of private capital
    I_d = aggr.get_I(bmat_splus1[:p.T], K_d[1:p.T + 1], K_d[:p.T], p, 'TPI')
    I = aggr.get_I(bmat_splus1[:p.T], K[1:p.T + 1], K[:p.T], p, 'TPI')
    # solve resource constraint
    # net foreign borrowing
    new_borrowing_f = (D_f[1:p.T + 1] * np.exp(p.g_y) *
                       (1 + p.g_n[1:p.T + 1]) - D_f[:p.T])
    debt_service_f = D_f * r_hh
    RC_error = aggr.resource_constraint(Y[:p.T - 1], C[:p.T - 1], G[:p.T - 1],
                                        I_d[:p.T - 1], K_f[:p.T - 1],
                                        new_borrowing_f[:p.T - 1],
                                        debt_service_f[:p.T - 1],
                                        r_hh[:p.T - 1], p)

    # Compute total investment (not just domestic)
    I_total = ((1 + p.g_n[:p.T]) * np.exp(p.g_y) * K[1:p.T + 1] -
               (1.0 - p.delta) * K[:p.T])

    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 range(p.T):
        household.constraint_checker_TPI(b_mat[t], n_mat[t], c_mat[t], t,
                                         p.ltilde)

    eul_savings = euler_errors[:, :p.S, :].max(1).max(1)
    eul_laborleisure = euler_errors[:, p.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[:p.T],
        'B': B,
        'K': K,
        'K_f': K_f,
        'K_d': K_d,
        'L': L,
        'C': C,
        'I': I,
        'I_total': I_total,
        'I_d': I_d,
        'BQ': BQ,
        'total_revenue': total_revenue,
        'business_revenue': business_revenue,
        'IITpayroll_revenue': T_Ipath,
        'T_H': T_H,
        'T_P': T_Ppath,
        'T_BQ': T_BQpath,
        'T_W': T_Wpath,
        'T_C': T_Cpath,
        'G': G,
        'D': D,
        'D_f': D_f,
        'D_d': D_d,
        'r': r,
        'r_gov': r_gov,
        'r_hh': r_hh,
        'w': w,
        'bmat_splus1': bmat_splus1,
        'bmat_s': bmat_s[:p.T, :, :],
        'n_mat': n_mat[:p.T, :, :],
        'c_path': c_mat,
        'bq_path': bqmat,
        'y_before_tax_mat': y_before_tax_mat,
        'tax_path': tax_mat,
        'eul_savings': eul_savings,
        'eul_laborleisure': eul_laborleisure,
        'resource_constraint_error': RC_error,
        'new_borrowing_f': new_borrowing_f,
        'debt_service_f': debt_service_f,
        'etr_path': etr_path,
        'mtrx_path': mtrx_path,
        'mtry_path': mtry_path
    }

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

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

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

    if ((np.any(np.absolute(RC_error) >= p.mindist_TPI * 10))
            and ENFORCE_SOLUTION_CHECKS):
        raise RuntimeError('Transition path equlibrium not found ' +
                           '(RC_error)')

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

    return output
Exemple #19
0
def revenue(r, w, b, n, bq, c, Y, L, K, factor, theta, etr_params, p, method):
    '''
    Gives lump sum transfer value.
    Inputs:
        r           = [T,] vector, interest rate
        w           = [T,] vector, wage rate
        b           = [T,S,J] array, wealth holdings
        n           = [T,S,J] array, labor supply
        BQ          = [T,J] array, bequest amounts
        factor      = scalar, model income scaling factor
        params      = length 12 tuple, (e, lambdas, omega, method, etr_params,
                                        theta, tau_bq, tau_payroll, h_wealth,
                                        p_wealth, m_wealth, retire, T, S, J)
        e           = [T,S,J] array, effective labor units
        lambdas     = [J,] vector, population weights by lifetime income group
        omega       = [T,S] array, population weights by age
        method      = string, 'SS' or 'TPI'
        etr_params  = [T,S,J] array, effective tax rate function parameters
        tax_func_types = string, type of tax function used
        theta       = [J,] vector, replacement rate values by lifetime
                      income group
        tau_bq      = scalar, bequest tax rate
        h_wealth    = scalar, wealth tax function parameter
        p_wealth    = scalar, wealth tax function parameter
        m_wealth    = scalar, wealth tax function parameter
        tau_payroll = scalar, payroll tax rate
        retire      = integer, retirement age
        T           = integer, number of periods in transition path
        S           = integer, number of age groups
        J           = integer, number of lifetime income groups
    Functions called:
        ETR_income
        ETR_wealth
    Objects in function:
        I    = [T,S,J] array, total income
        T_I  = [T,S,J] array, total income taxes
        T_P  = [T,S,J] array, total payroll taxes
        T_W  = [T,S,J] array, total wealth taxes
        T_BQ = [T,S,J] array, total bequest taxes
        T_H  = [T,] vector, lump sum transfer amount(s)
    Returns: T_H

    '''
    if method == 'SS':
        I = r * b + w * p.e * n
        T_I = np.zeros_like(I)
        T_I = tax.ETR_income(r, w, b, n, factor, p.e, etr_params, p) * I
        T_P = p.tau_payroll[-1] * w * p.e * n
        T_P[p.retire[-1]:] -= theta * w
        T_W = (
            tax.ETR_wealth(b, p.h_wealth[-1], p.m_wealth[-1], p.p_wealth[-1]) *
            b)
        T_BQ = p.tau_bq[-1] * bq
        T_C = p.tau_c[-1, :, :] * c
        business_revenue = tax.get_biz_tax(w, Y, L, K, p, method)
        REVENUE = ((np.transpose(p.omega_SS * p.lambdas) *
                    (T_I + T_P + T_BQ + T_W + T_C)).sum() + business_revenue)
    elif method == 'TPI':
        r_array = utils.to_timepath_shape(r, p)
        w_array = utils.to_timepath_shape(w, p)
        I = r_array * b + w_array * n * p.e
        T_I = np.zeros_like(I)
        T_I = tax.ETR_income(r_array, w_array, b, n, factor, p.e, etr_params,
                             p) * I
        T_P = p.tau_payroll[:p.T].reshape(p.T, 1, 1) * w_array * n * p.e
        for t in range(T_P.shape[0]):
            T_P[t,
                p.retire[t]:, :] -= (theta.reshape(1, p.J) *
                                     p.replacement_rate_adjust[t] * w_array[t])
        T_W = (tax.ETR_wealth(
            b, p.h_wealth[:p.T].reshape(p.T, 1, 1), p.m_wealth[:p.T].reshape(
                p.T, 1, 1), p.p_wealth[:p.T].reshape(p.T, 1, 1)) * b)
        T_BQ = p.tau_bq[:p.T].reshape(p.T, 1, 1) * bq
        T_C = p.tau_c[:p.T, :, :] * c
        business_revenue = tax.get_biz_tax(w, Y, L, K, p, method)
        REVENUE = ((((np.squeeze(p.lambdas)) *
                     np.tile(np.reshape(p.omega[:p.T, :], (p.T, p.S, 1)),
                             (1, 1, p.J))) *
                    (T_I + T_P + T_BQ + T_W + T_C)).sum(1).sum(1) +
                   business_revenue)

    return REVENUE, T_I, T_P, T_BQ, T_W, T_C, business_revenue
Exemple #20
0
def run_TPI(p, client=None):
    '''
    Solve for transition path equilibrium of OG-USA.

    Args:
        p (OG-USA Specifications object): model parameters
        client (Dask client object): client

    Returns:
        output (dictionary): dictionary with transition path solution
            results

    '''
    # unpack tuples of parameters
    initial_values, ss_vars, theta, baseline_values = get_initial_SS_values(p)
    (B0, b_sinit, b_splus1init, factor, initial_b, initial_n) =\
        initial_values
    (TRbaseline, Gbaseline, D0_baseline) = baseline_values

    print('Government spending breakpoints are tG1: ', p.tG1, '; and tG2:',
          p.tG2)

    # Initialize guesses at time paths
    # Make array of initial guesses for labor supply and savings
    guesses_b = utils.get_initial_path(initial_b, ss_vars['bssmat_splus1'], p,
                                       'ratio')
    guesses_n = utils.get_initial_path(initial_n, ss_vars['nssmat'], p,
                                       'ratio')
    b_mat = guesses_b
    n_mat = guesses_n
    ind = np.arange(p.S)

    # Get path for aggregate savings and labor supply`
    L_init = np.ones((p.T + p.S, )) * ss_vars['Lss']
    B_init = np.ones((p.T + p.S, )) * ss_vars['Bss']
    L_init[:p.T] = aggr.get_L(n_mat[:p.T], p, 'TPI')
    B_init[1:p.T] = aggr.get_B(b_mat[:p.T], p, 'TPI', False)[:p.T - 1]
    B_init[0] = B0
    K_init = B_init * ss_vars['Kss'] / ss_vars['Bss']
    K = K_init
    K_d = K_init * ss_vars['K_d_ss'] / ss_vars['Kss']
    K_f = K_init * ss_vars['K_f_ss'] / ss_vars['Kss']
    L = L_init
    B = B_init
    Y = np.zeros_like(K)
    Y[:p.T] = firm.get_Y(K[:p.T], L[:p.T], p, 'TPI')
    Y[p.T:] = ss_vars['Yss']
    r = np.zeros_like(Y)
    r[:p.T] = firm.get_r(Y[:p.T], K[:p.T], p, 'TPI')
    r[p.T:] = ss_vars['rss']
    # For case where economy is small open econ
    r[p.zeta_K == 1] = p.world_int_rate[p.zeta_K == 1]
    # Compute other interest rates
    r_gov = fiscal.get_r_gov(r, p)
    r_hh = aggr.get_r_hh(r, r_gov, K, ss_vars['Dss'])

    # compute w
    w = np.zeros_like(r)
    w[:p.T] = firm.get_w_from_r(r[:p.T], p, 'TPI')
    w[p.T:] = ss_vars['wss']

    # initial guesses at fiscal vars
    if p.budget_balance:
        if np.abs(ss_vars['TR_ss']) < 1e-13:
            TR_ss2 = 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 pct changes below
        else:
            TR_ss2 = ss_vars['TR_ss']
        TR = np.ones(p.T + p.S) * TR_ss2
        total_tax_revenue = TR - ss_vars['agg_pension_outlays']
        G = np.zeros(p.T + p.S)
        D = np.zeros(p.T + p.S)
        D_d = np.zeros(p.T + p.S)
        D_f = np.zeros(p.T + p.S)
    else:
        if p.baseline_spending:
            TR = TRbaseline
            G = Gbaseline
            G[p.T:] = ss_vars['Gss']
        else:
            TR = p.alpha_T * Y
            G = np.ones(p.T + p.S) * ss_vars['Gss']
        D = np.ones(p.T + p.S) * ss_vars['Dss']
        D_d = D * ss_vars['D_d_ss'] / ss_vars['Dss']
        D_f = D * ss_vars['D_f_ss'] / ss_vars['Dss']
    total_tax_revenue = np.ones(p.T + p.S) * ss_vars['total_tax_revenue']

    # Initialize bequests
    BQ0 = aggr.get_BQ(r_hh[0], initial_b, None, p, 'SS', True)
    if not p.use_zeta:
        BQ = np.zeros((p.T + p.S, p.J))
        for j in range(p.J):
            BQ[:, j] = (list(np.linspace(BQ0[j], ss_vars['BQss'][j], p.T)) +
                        [ss_vars['BQss'][j]] * p.S)
        BQ = np.array(BQ)
    else:
        BQ = (list(np.linspace(BQ0, ss_vars['BQss'], p.T)) +
              [ss_vars['BQss']] * p.S)
        BQ = np.array(BQ)

    TPIiter = 0
    TPIdist = 10
    euler_errors = np.zeros((p.T, 2 * p.S, p.J))
    TPIdist_vec = np.zeros(p.maxiter)

    # TPI loop
    while (TPIiter < p.maxiter) and (TPIdist >= p.mindist_TPI):
        r_gov[:p.T] = fiscal.get_r_gov(r[:p.T], p)
        if not p.budget_balance:
            K[:p.T] = firm.get_K_from_Y(Y[:p.T], r[:p.T], p, 'TPI')

        r_hh[:p.T] = aggr.get_r_hh(r[:p.T], r_gov[:p.T], K[:p.T], D[:p.T])

        outer_loop_vars = (r, w, r_hh, BQ, TR, theta)

        euler_errors = np.zeros((p.T, 2 * p.S, p.J))
        lazy_values = []
        for j in range(p.J):
            guesses = (guesses_b[:, :, j], guesses_n[:, :, j])
            lazy_values.append(
                delayed(inner_loop)(guesses, outer_loop_vars, initial_values,
                                    j, ind, p))
        if client:
            futures = client.compute(lazy_values, num_workers=p.num_workers)
            results = client.gather(futures)
        else:
            results = results = compute(*lazy_values,
                                        scheduler=dask.multiprocessing.get,
                                        num_workers=p.num_workers)

        for j, result in enumerate(results):
            euler_errors[:, :, j], b_mat[:, :, j], n_mat[:, :, j] = result

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

        etr_params_4D = np.tile(
            p.etr_params.reshape(p.T, p.S, 1, p.etr_params.shape[2]),
            (1, 1, p.J, 1))
        bqmat = household.get_bq(BQ, None, p, 'TPI')
        trmat = household.get_tr(TR, None, p, 'TPI')
        tax_mat = tax.net_taxes(r_hh[:p.T], w[:p.T], bmat_s, n_mat[:p.T, :, :],
                                bqmat[:p.T, :, :], factor, trmat[:p.T, :, :],
                                theta, 0, None, False, 'TPI', p.e,
                                etr_params_4D, p)
        r_hh_path = utils.to_timepath_shape(r_hh)
        wpath = utils.to_timepath_shape(w)
        c_mat = household.get_cons(r_hh_path[:p.T, :, :], wpath[:p.T, :, :],
                                   bmat_s, bmat_splus1, n_mat[:p.T, :, :],
                                   bqmat[:p.T, :, :], tax_mat, p.e,
                                   p.tau_c[:p.T, :, :], p)
        y_before_tax_mat = household.get_y(r_hh_path[:p.T, :, :],
                                           wpath[:p.T, :, :],
                                           bmat_s[:p.T, :, :],
                                           n_mat[:p.T, :, :], p)

        (total_tax_rev, iit_payroll_tax_revenue, agg_pension_outlays,
         bequest_tax_revenue, wealth_tax_revenue, cons_tax_revenue,
         business_tax_revenue, payroll_tax_revenue,
         iit_revenue) = aggr.revenue(r_hh[:p.T], w[:p.T], bmat_s,
                                     n_mat[:p.T, :, :], bqmat[:p.T, :, :],
                                     c_mat[:p.T, :, :], Y[:p.T], L[:p.T],
                                     K[:p.T], factor, theta, etr_params_4D, p,
                                     'TPI')
        total_tax_revenue[:p.T] = total_tax_rev
        dg_fixed_values = (Y, total_tax_revenue, agg_pension_outlays, TR,
                           Gbaseline, D0_baseline)
        (Dnew, G[:p.T], D_d[:p.T], D_f[:p.T], new_borrowing,
         debt_service, new_borrowing_f) =\
            fiscal.D_G_path(r_gov, dg_fixed_values, p)
        L[:p.T] = aggr.get_L(n_mat[:p.T], p, 'TPI')
        B[1:p.T] = aggr.get_B(bmat_splus1[:p.T], p, 'TPI', False)[:p.T - 1]
        K_demand_open = firm.get_K(L[:p.T], p.world_int_rate[:p.T], p, 'TPI')
        K[:p.T], K_d[:p.T], K_f[:p.T] = aggr.get_K_splits(
            B[:p.T], K_demand_open, D_d[:p.T], p.zeta_K[:p.T])
        Ynew = firm.get_Y(K[:p.T], L[:p.T], p, 'TPI')
        rnew = r.copy()
        rnew[:p.T] = firm.get_r(Ynew[:p.T], K[:p.T], p, 'TPI')
        # For case where economy is small open econ
        r[p.zeta_K == 1] = p.world_int_rate[p.zeta_K == 1]
        r_gov_new = fiscal.get_r_gov(rnew, p)
        r_hh_new = aggr.get_r_hh(rnew[:p.T], r_gov_new[:p.T], K[:p.T],
                                 Dnew[:p.T])
        # compute w
        wnew = firm.get_w_from_r(rnew[:p.T], p, 'TPI')

        b_mat_shift = np.append(np.reshape(initial_b, (1, p.S, p.J)),
                                b_mat[:p.T - 1, :, :],
                                axis=0)
        BQnew = aggr.get_BQ(r_hh_new[:p.T], b_mat_shift, None, p, 'TPI', False)
        bqmat_new = household.get_bq(BQnew, None, p, 'TPI')
        (total_tax_rev, iit_payroll_tax_revenue, agg_pension_outlays,
         bequest_tax_revenue, wealth_tax_revenue, cons_tax_revenue,
         business_tax_revenue, payroll_tax_revenue,
         iit_revenue) = aggr.revenue(r_hh_new[:p.T], wnew[:p.T], bmat_s,
                                     n_mat[:p.T, :, :], bqmat_new[:p.T, :, :],
                                     c_mat[:p.T, :, :], Ynew[:p.T], L[:p.T],
                                     K[:p.T], factor, theta, etr_params_4D, p,
                                     'TPI')
        total_tax_revenue[:p.T] = total_tax_rev
        TR_new = fiscal.get_TR(Ynew[:p.T], TR[:p.T], G[:p.T],
                               total_tax_revenue[:p.T],
                               agg_pension_outlays[:p.T], p, 'TPI')

        # update vars for next iteration
        w[:p.T] = wnew[:p.T]
        r[:p.T] = utils.convex_combo(rnew[:p.T], r[:p.T], p.nu)
        BQ[:p.T] = utils.convex_combo(BQnew[:p.T], BQ[:p.T], p.nu)
        D[:p.T] = Dnew[:p.T]
        Y[:p.T] = utils.convex_combo(Ynew[:p.T], Y[:p.T], p.nu)
        if not p.baseline_spending:
            TR[:p.T] = utils.convex_combo(TR_new[:p.T], TR[:p.T], p.nu)
        guesses_b = utils.convex_combo(b_mat, guesses_b, p.nu)
        guesses_n = utils.convex_combo(n_mat, guesses_n, p.nu)
        print('r diff: ', (rnew[:p.T] - r[:p.T]).max(),
              (rnew[:p.T] - r[:p.T]).min())
        print('BQ diff: ', (BQnew[:p.T] - BQ[:p.T]).max(),
              (BQnew[:p.T] - BQ[:p.T]).min())
        print('TR diff: ', (TR_new[:p.T] - TR[:p.T]).max(),
              (TR_new[:p.T] - TR[:p.T]).min())
        print('Y diff: ', (Ynew[:p.T] - Y[:p.T]).max(),
              (Ynew[:p.T] - Y[:p.T]).min())
        if not p.baseline_spending:
            if TR.all() != 0:
                TPIdist = np.array(
                    list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) + list(
                        utils.pct_diff_func(BQnew[:p.T], BQ[:p.T]).flatten()) +
                    list(utils.pct_diff_func(TR_new[:p.T], TR[:p.T]))).max()
            else:
                TPIdist = np.array(
                    list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) + list(
                        utils.pct_diff_func(BQnew[:p.T], BQ[:p.T]).flatten()) +
                    list(np.abs(TR[:p.T]))).max()
        else:
            TPIdist = np.array(
                list(utils.pct_diff_func(rnew[:p.T], r[:p.T])) +
                list(utils.pct_diff_func(BQnew[:p.T], BQ[:p.T]).flatten()) +
                list(utils.pct_diff_func(Ynew[:p.T], Y[:p.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)

    # Compute effective and marginal tax rates for all agents
    mtrx_params_4D = np.tile(
        p.mtrx_params.reshape(p.T, p.S, 1, p.mtrx_params.shape[2]),
        (1, 1, p.J, 1))
    mtry_params_4D = np.tile(
        p.mtry_params.reshape(p.T, p.S, 1, p.mtry_params.shape[2]),
        (1, 1, p.J, 1))

    e_3D = np.tile(p.e.reshape(1, p.S, p.J), (p.T, 1, 1))
    mtry_path = tax.MTR_income(r_hh_path[:p.T], wpath[:p.T],
                               bmat_s[:p.T, :, :], n_mat[:p.T, :, :], factor,
                               True, e_3D, etr_params_4D, mtry_params_4D, p)
    mtrx_path = tax.MTR_income(r_hh_path[:p.T], wpath[:p.T],
                               bmat_s[:p.T, :, :], n_mat[:p.T, :, :], factor,
                               False, e_3D, etr_params_4D, mtrx_params_4D, p)
    etr_path = tax.ETR_income(r_hh_path[:p.T], wpath[:p.T], bmat_s[:p.T, :, :],
                              n_mat[:p.T, :, :], factor, e_3D, etr_params_4D,
                              p)

    C = aggr.get_C(c_mat, p, 'TPI')
    # Note that implicity in this computation is that immigrants'
    # wealth is all in the form of private capital
    I_d = aggr.get_I(bmat_splus1[:p.T], K_d[1:p.T + 1], K_d[:p.T], p, 'TPI')
    I = aggr.get_I(bmat_splus1[:p.T], K[1:p.T + 1], K[:p.T], p, 'TPI')
    # solve resource constraint
    # foreign debt service costs
    debt_service_f = fiscal.get_debt_service_f(r_hh, D_f)
    RC_error = aggr.resource_constraint(Y[:p.T - 1], C[:p.T - 1], G[:p.T - 1],
                                        I_d[:p.T - 1], K_f[:p.T - 1],
                                        new_borrowing_f[:p.T - 1],
                                        debt_service_f[:p.T - 1],
                                        r_hh[:p.T - 1], p)
    # Compute total investment (not just domestic)
    I_total = aggr.get_I(None, K[1:p.T + 1], K[:p.T], p, 'total_tpi')

    # Compute resource constraint error
    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 range(p.T):
        household.constraint_checker_TPI(b_mat[t], n_mat[t], c_mat[t], t,
                                         p.ltilde)

    eul_savings = euler_errors[:, :p.S, :].max(1).max(1)
    eul_laborleisure = euler_errors[:, p.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[:p.T],
        'B': B,
        'K': K,
        'K_f': K_f,
        'K_d': K_d,
        'L': L,
        'C': C,
        'I': I,
        'I_total': I_total,
        'I_d': I_d,
        'BQ': BQ,
        'total_tax_revenue': total_tax_revenue,
        'business_tax_revenue': business_tax_revenue,
        'iit_payroll_tax_revenue': iit_payroll_tax_revenue,
        'iit_revenue': iit_revenue,
        'payroll_tax_revenue': payroll_tax_revenue,
        'TR': TR,
        'agg_pension_outlays': agg_pension_outlays,
        'bequest_tax_revenue': bequest_tax_revenue,
        'wealth_tax_revenue': wealth_tax_revenue,
        'cons_tax_revenue': cons_tax_revenue,
        'G': G,
        'D': D,
        'D_f': D_f,
        'D_d': D_d,
        'r': r,
        'r_gov': r_gov,
        'r_hh': r_hh,
        'w': w,
        'bmat_splus1': bmat_splus1,
        'bmat_s': bmat_s[:p.T, :, :],
        'n_mat': n_mat[:p.T, :, :],
        'c_path': c_mat,
        'bq_path': bqmat,
        'tr_path': trmat,
        'y_before_tax_mat': y_before_tax_mat,
        'tax_path': tax_mat,
        'eul_savings': eul_savings,
        'eul_laborleisure': eul_laborleisure,
        'resource_constraint_error': RC_error,
        'new_borrowing_f': new_borrowing_f,
        'debt_service_f': debt_service_f,
        'etr_path': etr_path,
        'mtrx_path': mtrx_path,
        'mtry_path': mtry_path
    }

    tpi_dir = os.path.join(p.output_base, "TPI")
    utils.mkdirs(tpi_dir)
    tpi_vars = os.path.join(tpi_dir, "TPI_vars.pkl")
    with open(tpi_vars, "wb") as f:
        pickle.dump(output, f)

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

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

    if ((np.any(np.absolute(RC_error) >= p.mindist_TPI * 10))
            and ENFORCE_SOLUTION_CHECKS):
        raise RuntimeError('Transition path equlibrium not found ' +
                           '(RC_error)')

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

    return output
Exemple #21
0
def revenue(r, w, b, n, bq, c, Y, L, K, factor, theta, etr_params,
            p, method):
    '''
    Gives lump sum transfer value.
    Inputs:
        r           = [T,] vector, interest rate
        w           = [T,] vector, wage rate
        b           = [T,S,J] array, wealth holdings
        n           = [T,S,J] array, labor supply
        BQ          = [T,J] array, bequest amounts
        factor      = scalar, model income scaling factor
        params      = length 12 tuple, (e, lambdas, omega, method, etr_params,
                                        theta, tau_bq, tau_payroll, h_wealth,
                                        p_wealth, m_wealth, retire, T, S, J)
        e           = [T,S,J] array, effective labor units
        lambdas     = [J,] vector, population weights by lifetime income group
        omega       = [T,S] array, population weights by age
        method      = string, 'SS' or 'TPI'
        etr_params  = [T,S,J] array, effective tax rate function parameters
        tax_func_types = string, type of tax function used
        theta       = [J,] vector, replacement rate values by lifetime
                      income group
        tau_bq      = scalar, bequest tax rate
        h_wealth    = scalar, wealth tax function parameter
        p_wealth    = scalar, wealth tax function parameter
        m_wealth    = scalar, wealth tax function parameter
        tau_payroll = scalar, payroll tax rate
        retire      = integer, retirement age
        T           = integer, number of periods in transition path
        S           = integer, number of age groups
        J           = integer, number of lifetime income groups
    Functions called:
        ETR_income
        ETR_wealth
    Objects in function:
        I    = [T,S,J] array, total income
        T_I  = [T,S,J] array, total income taxes
        T_P  = [T,S,J] array, total payroll taxes
        T_W  = [T,S,J] array, total wealth taxes
        T_BQ = [T,S,J] array, total bequest taxes
        T_H  = [T,] vector, lump sum transfer amount(s)
    Returns: T_H

    '''
    if method == 'SS':
        I = r * b + w * p.e * n
        T_I = np.zeros_like(I)
        T_I = tax.ETR_income(r, w, b, n, factor, p.e, etr_params, p) * I
        T_P = p.tau_payroll[-1] * w * p.e * n
        T_P[p.retire[-1]:] -= theta * w
        T_W = (tax.ETR_wealth(b, p.h_wealth[-1], p.m_wealth[-1],
                              p.p_wealth[-1]) * b)
        T_BQ = p.tau_bq[-1] * bq
        T_C = p.tau_c[-1, :, :] * c
        business_revenue = tax.get_biz_tax(w, Y, L, K, p, method)
        REVENUE = ((np.transpose(p.omega_SS * p.lambdas) *
                    (T_I + T_P + T_BQ + T_W + T_C)).sum() +
                   business_revenue)
    elif method == 'TPI':
        r_array = utils.to_timepath_shape(r, p)
        w_array = utils.to_timepath_shape(w, p)
        I = r_array * b + w_array * n * p.e
        T_I = np.zeros_like(I)
        T_I = tax.ETR_income(r_array, w_array, b, n, factor, p.e,
                             etr_params, p) * I
        T_P = p.tau_payroll[:p.T].reshape(p.T, 1, 1) * w_array * n * p.e
        for t in range(T_P.shape[0]):
            T_P[t, p.retire[t]:, :] -= (theta.reshape(1, p.J) *
                                        p.replacement_rate_adjust[t] *
                                        w_array[t])
        T_W = (tax.ETR_wealth(b, p.h_wealth[:p.T].reshape(p.T, 1, 1),
                              p.m_wealth[:p.T].reshape(p.T, 1, 1),
                              p.p_wealth[:p.T].reshape(p.T, 1, 1)) * b)
        T_BQ = p.tau_bq[:p.T].reshape(p.T, 1, 1) * bq
        T_C = p.tau_c[:p.T, :, :] * c
        business_revenue = tax.get_biz_tax(w, Y, L, K, p, method)
        REVENUE = ((((np.squeeze(p.lambdas)) *
                   np.tile(np.reshape(p.omega[:p.T, :], (p.T, p.S, 1)),
                           (1, 1, p.J)))
                   * (T_I + T_P + T_BQ + T_W + T_C)).sum(1).sum(1) +
                   business_revenue)

    return REVENUE, T_I, T_P, T_BQ, T_W, T_C, business_revenue