示例#1
0
def FOC_savings(r, w, b, b_splus1, b_splus2, n, BQ, factor, T_H, params):
    '''
    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 holdings
        b_splus1    = [S,J] array, distribution of wealth/capital holdings one period ahead
        b_splus2    = [S,J] array, distribution of wealth/capital holdings 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,10] array, parameters of effective income tax rate function
        mtry_params = [S,10] 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_capital

    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
    '''
    e, sigma, beta, g_y, chi_b, theta, tau_bq, rho, lambdas, J, S, \
        analytical_mtrs, etr_params, mtry_params, h_wealth, p_wealth, m_wealth, tau_payroll, retire, method = params

    # In order to not have 2 savings euler equations (one that solves the first S-1 equations, and one that solves the last one),
    # we combine them.  In order to do this, we have to compute a consumption term in period t+1, which requires us to have a shifted
    # e and n matrix.  We append a zero on the end of both of these so they will be the right size.  We could append any value to them,
    # since in the euler equation, the coefficient on the marginal utility of
    # consumption for this term will be zero (since rho is one).
    if method == 'TPI_scalar':
        e_extended = np.array([e] + [0])
        n_extended = np.array([n] + [0])
        etr_params_to_use = etr_params
        mtry_params_to_use = mtry_params
    else:
        e_extended = np.array(list(e) + [0])
        n_extended = np.array(list(n) + [0])
        etr_params_to_use = np.append(etr_params,
                                      np.reshape(etr_params[-1, :],
                                                 (1, etr_params.shape[1])),
                                      axis=0)[1:, :]
        mtry_params_to_use = np.append(mtry_params,
                                       np.reshape(mtry_params[-1, :],
                                                  (1, mtry_params.shape[1])),
                                       axis=0)[1:, :]

    # tax1_params = (e, lambdas, method, retire, etr_params, h_wealth, p_wealth, m_wealth, tau_payroll, theta, tau_bq, J, S)
    # tax1 = tax.total_taxes(r, w, b, n, BQ, factor, T_H, None, False, tax1_params)
    # tax2_params = (e_extended[1:], lambdas, method, retire,
    #                np.append(etr_params,np.reshape(etr_params[-1,:],(1,etr_params.shape[1])),axis=0)[1:,:],
    #                h_wealth, p_wealth, m_wealth, tau_payroll, theta, tau_bq, J, S)
    # tax2 = tax.total_taxes(r, w, b_splus1, n_extended[1:], BQ, factor, T_H, None, True, tax2_params)
    # cons1_params = (e, lambdas, g_y)
    # cons1 = get_cons(r, w, b, b_splus1, n, BQ, tax1, cons1_params)
    # cons2_params = (e_extended[1:], lambdas, g_y)
    # cons2 = get_cons(r, w, b_splus1, b_splus2, n_extended[1:], BQ, tax2, cons2_params)

    # mtr_cap_params = (e_extended[1:], np.append(etr_params,np.reshape(etr_params[-1,:],(1,etr_params.shape[1])),axis=0)[1:,:],
    #                   np.append(mtry_params,np.reshape(mtry_params[-1,:],(1,mtry_params.shape[1])),axis=0)[1:,:],analytical_mtrs)
    # deriv = (1+r) - r*(tax.MTR_capital(r, w, b_splus1, n_extended[1:], factor, mtr_cap_params))

    tax1_params = (e, lambdas, method, retire, etr_params, h_wealth, p_wealth,
                   m_wealth, tau_payroll, theta, tau_bq, J, S)
    tax1 = tax.total_taxes(r, w, b, n, BQ, factor, T_H, None, False,
                           tax1_params)
    tax2_params = (e_extended[1:], lambdas, method, retire, etr_params_to_use,
                   h_wealth, p_wealth, m_wealth, tau_payroll, theta, tau_bq, J,
                   S)
    tax2 = tax.total_taxes(r, w, b_splus1, n_extended[1:], BQ, factor, T_H,
                           None, True, tax2_params)
    cons1_params = (e, lambdas, g_y)
    cons1 = get_cons(r, w, b, b_splus1, n, BQ, tax1, cons1_params)
    cons2_params = (e_extended[1:], lambdas, g_y)
    cons2 = get_cons(r, w, b_splus1, b_splus2, n_extended[1:], BQ, tax2,
                     cons2_params)

    mtr_cap_params = (e_extended[1:], etr_params_to_use, mtry_params_to_use,
                      analytical_mtrs)
    deriv = (1 + r) - r * (tax.MTR_capital(r, w, b_splus1, n_extended[1:],
                                           factor, mtr_cap_params))

    savings_ut = rho * np.exp(-sigma * g_y) * chi_b * b_splus1**(-sigma)

    # Again, note timing in this equation, the (1-rho) term will zero out in the last period, so the last entry of cons2 can be complete
    # gibberish (which it is).  It just has to exist so cons2 is the right
    # size to match all other arrays in the equation.
    euler = marg_ut_cons(cons1,
                         sigma) - beta * (1 - rho) * deriv * marg_ut_cons(
                             cons2, sigma) * np.exp(-sigma * g_y) - savings_ut

    return euler
示例#2
0
def FOC_savings(r, w, b, b_splus1, b_splus2, n, BQ, factor, T_H,
                params):
    '''
    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_capital

    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
    '''
    (e, sigma, beta, g_y, chi_b, theta, tau_bq, rho, lambdas, j, J, S,
     analytical_mtrs, etr_params, mtry_params, h_wealth, p_wealth,
     m_wealth, tau_payroll, retire, method) = params

    # In order to not have 2 savings euler equations (one that solves
    # the first S-1 equations, and one that solves the last one), we
    # combine them.  In order to do this, we have to compute a
    # consumption term in period t+1, which requires us to have a shifted
    # e and n matrix.  We append a zero on the end of both of these so
    # they will be the right size.  We could append any value to them,
    # since in the euler equation, the coefficient on the marginal
    # utility of consumption for this term will be zero (since rho is
    # one).
    e_extended = np.array(list(e) + [0])
    n_extended = np.array(list(n) + [0])
    etr_params_extended = np.append(etr_params,
                                    np.reshape(etr_params[-1, :],
                                               (1, etr_params.shape[1])),
                                    axis=0)[1:, :]
    mtry_params_extended = np.append(mtry_params,
                                     np.reshape(mtry_params[-1, :],
                                                (1, mtry_params.shape[1])),
                                     axis=0)[1:, :]
    if method == 'TPI':
        r_extended = np.append(r, r[-1])
        w_extended = np.append(w, w[-1])
        BQ_extended = np.append(BQ, BQ[-1])
        T_H_extended = np.append(T_H, T_H[-1])
    elif method == 'SS':
        r_extended = np.array([r, r])
        w_extended = np.array([w, w])
        BQ_extended = np.array([BQ, BQ])
        T_H_extended = np.array([T_H, T_H])

    tax1_params = (e, lambdas, method, retire, etr_params, h_wealth,
                   p_wealth, m_wealth, tau_payroll, theta, tau_bq, J, S)
    tax1 = tax.total_taxes(r, w, b, n, BQ, factor, T_H, j, False,
                           tax1_params)
    tax2_params = (e_extended[1:], lambdas, method, retire,
                   etr_params_extended, h_wealth, p_wealth, m_wealth,
                   tau_payroll, theta, tau_bq, J, S)
    tax2 = tax.total_taxes(r_extended[1:], w_extended[1:], b_splus1,
                           n_extended[1:], BQ_extended[1:], factor,
                           T_H_extended[1:], j, True, tax2_params)
    cons1_params = (e, lambdas, g_y)
    cons1 = get_cons(r, w, b, b_splus1, n, BQ, tax1, cons1_params)
    cons2_params = (e_extended[1:], lambdas, g_y)
    cons2 = get_cons(r_extended[1:], w_extended[1:], b_splus1, b_splus2,
                     n_extended[1:], BQ_extended[1:], tax2,
                     cons2_params)
    cons2[-1] = 0.01  # set to small positive number to avoid exception
    # errors when negative b/c this period value doesn't matter -
    # it's consumption after the last period of life
    mtr_cap_params = (e_extended[1:], etr_params_extended,
                      mtry_params_extended, analytical_mtrs)
    deriv = ((1 + r_extended[1:]) - r_extended[1:] *
             (tax.MTR_capital(r_extended[1:], w_extended[1:], b_splus1,
                              n_extended[1:], factor, mtr_cap_params)) -
             (tax.tau_w_prime(b_splus1, (h_wealth, p_wealth, m_wealth)) *
             b_splus1) - tax.tau_wealth(b_splus1, (h_wealth, p_wealth,
                                                   m_wealth)))

    savings_ut = (rho * np.exp(-sigma * g_y) * chi_b * b_splus1 **
                  (-sigma))

    euler_error = (marg_ut_cons(cons1, sigma) - beta * (1 - rho) *
                   deriv * marg_ut_cons(cons2, sigma) *
                   np.exp(-sigma * g_y) - savings_ut)

    return euler_error
示例#3
0
def twist_doughnut(guesses, r, w, BQ, T_H, j, s, t, params):
    '''
    Parameters:
        guesses = distribution of capital and labor (various length list)
        w   = wage rate ((T+S)x1 array)
        r   = rental rate ((T+S)x1 array)
        BQ = aggregate bequests ((T+S)x1 array)
        T_H = lump sum tax over time ((T+S)x1 array)
        factor = scaling factor (scalar)
        j = which ability type is being solved for (scalar)
        s = which upper triangle loop is being solved for (scalar)
        t = which diagonal is being solved for (scalar)
        params = list of parameters (list)
        theta = replacement rates (Jx1 array)
        tau_bq = bequest tax rate (Jx1 array)
        rho = mortalit rate (Sx1 array)
        lambdas = ability weights (Jx1 array)
        e = ability type (SxJ array)
        initial_b = capital stock distribution in period 0 (SxJ array)
        chi_b = chi^b_j (Jx1 array)
        chi_n = chi^n_s (Sx1 array)
    Output:
        Value of Euler error (various length list)
    '''

    income_tax_params, tpi_params, initial_b = params
    analytical_mtrs, etr_params, mtrx_params, mtry_params = income_tax_params
    J, S, T, BW, beta, sigma, alpha, Z, delta, ltilde, nu, g_y,\
                  g_n_vector, tau_payroll, tau_bq, rho, omega, N_tilde, lambdas, e, retire, mean_income_data,\
                  factor, h_wealth, p_wealth, m_wealth, b_ellipse, upsilon, chi_b, chi_n = tpi_params

    length = len(guesses) / 2
    b_guess = np.array(guesses[:length])
    n_guess = np.array(guesses[length:])

    if length == S:
        b_s = np.array([0] + list(b_guess[:-1]))
    else:
        b_s = np.array([(initial_b[-(s + 3), j])] + list(b_guess[:-1]))

    b_splus1 = b_guess
    b_splus2 = np.array(list(b_guess[1:]) + [0])
    w_s = w[t:t + length]
    w_splus1 = w[t + 1:t + length + 1]
    r_s = r[t:t + length]
    r_splus1 = r[t + 1:t + length + 1]
    n_s = n_guess
    n_extended = np.array(list(n_guess[1:]) + [0])
    e_s = e[-length:, j]
    e_extended = np.array(list(e[-length + 1:, j]) + [0])
    BQ_s = BQ[t:t + length]
    BQ_splus1 = BQ[t + 1:t + length + 1]
    T_H_s = T_H[t:t + length]
    T_H_splus1 = T_H[t + 1:t + length + 1]
    # Savings euler equations

    # theta_params = (e[-1, j], 1, omega[0].reshape(S, 1), lambdas[j])
    # theta = tax.replacement_rate_vals(n, w, factor, theta_params)
    theta = np.zeros((J, ))

    tax_s_params = (e_s, lambdas[j], 'TPI', retire, etr_params, h_wealth,
                    p_wealth, m_wealth, tau_payroll, theta, tau_bq, J, S)
    tax_s = tax.total_taxes(r_s, w_s, b_s, n_s, BQ_s, factor, T_H_s, j, False,
                            tax_s_params)

    etr_params_sp1 = np.append(etr_params,
                               np.reshape(etr_params[-1, :],
                                          (1, etr_params.shape[1])),
                               axis=0)[1:, :]
    taxsp1_params = (e_extended, lambdas[j], 'TPI', retire, etr_params_sp1,
                     h_wealth, p_wealth, m_wealth, tau_payroll, theta, tau_bq,
                     J, S)
    tax_splus1 = tax.total_taxes(r_splus1, w_splus1, b_splus1, n_extended,
                                 BQ_splus1, factor, T_H_splus1, j, True,
                                 taxsp1_params)

    cons_s_params = (e_s, lambdas[j], g_y)
    cons_s = household.get_cons(r_s, w_s, b_s, b_splus1, n_s, BQ_s, tax_s,
                                cons_s_params)

    cons_sp1_params = (e_extended, lambdas[j], g_y)
    cons_splus1 = household.get_cons(r_splus1, w_splus1, b_splus1, b_splus2,
                                     n_extended, BQ_splus1, tax_splus1,
                                     cons_sp1_params)

    income_splus1 = (r_splus1 * b_splus1 +
                     w_splus1 * e_extended * n_extended) * factor
    savings_ut = rho[-(length):] * np.exp(-sigma * g_y) * \
        chi_b[j] * b_splus1 ** (-sigma)

    mtry_params_sp1 = np.append(mtry_params,
                                np.reshape(mtry_params[-1, :],
                                           (1, mtry_params.shape[1])),
                                axis=0)[1:, :]
    mtr_capital_params = (e_extended, etr_params_sp1, mtry_params_sp1,
                          analytical_mtrs)
    deriv_savings = 1 + r_splus1 * (1 - tax.MTR_capital(
        r_splus1, w_splus1, b_splus1, n_extended, factor, mtr_capital_params))

    error1 = household.marg_ut_cons(
        cons_s, sigma) - beta * (1 - rho[-(length):]) * np.exp(
            -sigma * g_y) * deriv_savings * household.marg_ut_cons(
                cons_splus1, sigma) - savings_ut
    # Labor leisure euler equations
    income_s = (r_s * b_s + w_s * e_s * n_s) * factor

    mtr_labor_params = (e_s, etr_params, mtrx_params, analytical_mtrs)
    deriv_laborleisure = 1 - tau_payroll - tax.MTR_labor(
        r_s, w_s, b_s, n_s, factor, mtr_labor_params)

    mu_labor_params = (b_ellipse, upsilon, ltilde, chi_n[-length:])
    error2 = household.marg_ut_cons(cons_s, sigma) * w_s * e[
        -(length):, j] * deriv_laborleisure - household.marg_ut_labor(
            n_s, mu_labor_params)
    # Check and punish constraint violations
    mask1 = n_guess < 0
    error2[mask1] += 1e12
    mask2 = n_guess > ltilde
    error2[mask2] += 1e12
    mask3 = cons_s < 0
    error2[mask3] += 1e12
    mask4 = b_guess <= 0
    error2[mask4] += 1e12
    mask5 = cons_splus1 < 0
    error2[mask5] += 1e12
    return list(error1.flatten()) + list(error2.flatten())
示例#4
0
def euler_savings_func(w, r, e, n_guess, b_s, b_splus1, b_splus2, BQ, factor,
                       T_H, chi_b, tax_params, params, theta, tau_bq, rho,
                       lambdas):
    '''
    This function is usually looped through over J, so it does one ability group at a time.
    Inputs:
        w = wage rate (scalar)
        r = rental rate (scalar)
        e = ability levels (Sx1 array)
        n_guess = labor distribution (Sx1 array)
        b_s = wealth holdings at the start of a period (Sx1 array)
        b_splus1 = wealth holdings for the next period (Sx1 array)
        b_splus2 = wealth holdings for 2 periods ahead (Sx1 array)
        BQ = aggregate bequests for a certain ability (scalar)
        factor = scaling factor to convert to dollars (scalar)
        T_H = lump sum tax (scalar)
        chi_b = chi^b_j for a certain ability (scalar)
        params = parameter list (list)
        theta = replacement rate for a certain ability (scalar)
        tau_bq = bequest tax rate (scalar)
        rho = mortality rate (Sx1 array)
        lambdas = ability weight (scalar)
    Output:
        euler = Value of savings euler error (Sx1 array)
    '''
    J, S, T, BW, beta, sigma, alpha, Z, delta, ltilde, nu, g_y,\
                  g_n_ss, tau_payroll, retire, mean_income_data,\
                  h_wealth, p_wealth, m_wealth, b_ellipse, upsilon = params

    analytical_mtrs, etr_params, mtrx_params, mtry_params = tax_params
    # In order to not have 2 savings euler equations (one that solves the first S-1 equations, and one that solves the last one),
    # we combine them.  In order to do this, we have to compute a consumption term in period t+1, which requires us to have a shifted
    # e and n matrix.  We append a zero on the end of both of these so they will be the right size.  We could append any value to them,
    # since in the euler equation, the coefficient on the marginal utility of
    # consumption for this term will be zero (since rho is one).
    e_extended = np.array(list(e) + [0])
    n_extended = np.array(list(n_guess) + [0])
    tax1_params = (J, S, retire, etr_params, h_wealth, p_wealth, m_wealth,
                   tau_payroll)
    tax1 = tax.total_taxes(r, b_s, w, e, n_guess, BQ, lambdas, factor, T_H,
                           None, 'SS', False, tax1_params, theta, tau_bq)
    etr_params_extended = np.append(etr_params,
                                    np.reshape(etr_params[-1, :],
                                               (1, etr_params.shape[1])),
                                    axis=0)[1:, :]
    tax2_params = (J, S, retire, etr_params_extended, h_wealth, p_wealth,
                   m_wealth, tau_payroll)
    tax2 = tax.total_taxes(r, b_splus1, w, e_extended[1:], n_extended[1:], BQ,
                           lambdas, factor, T_H, None, 'SS', True, tax2_params,
                           theta, tau_bq)
    cons1 = get_cons(r, b_s, w, e, n_guess, BQ, lambdas, b_splus1, params,
                     tax1)
    cons2 = get_cons(r, b_splus1, w, e_extended[1:], n_extended[1:], BQ,
                     lambdas, b_splus2, params, tax2)
    income = (r * b_splus1 + w * e_extended[1:] * n_extended[1:]) * factor

    mtr_cap_params = np.append(mtry_params,
                               np.reshape(mtry_params[-1, :],
                                          (1, mtry_params.shape[1])),
                               axis=0)[1:, :]
    deriv = (1 + r) - r * (tax.MTR_capital(
        r, b_splus1, w, e_extended[1:], n_extended[1:], factor,
        analytical_mtrs, etr_params_extended, mtr_cap_params))

    savings_ut = rho * np.exp(-sigma * g_y) * chi_b * b_splus1**(-sigma)

    # Again, note timing in this equation, the (1-rho) term will zero out in the last period, so the last entry of cons2 can be complete
    # gibberish (which it is).  It just has to exist so cons2 is the right
    # size to match all other arrays in the equation.
    euler = marg_ut_cons(cons1,
                         params) - beta * (1 - rho) * deriv * marg_ut_cons(
                             cons2, params) * np.exp(-sigma * g_y) - savings_ut

    return euler