Ejemplo n.º 1
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
Ejemplo n.º 2
0
def inner_loop(guesses, outer_loop_vars, initial_values, j, ind, p):
    '''
    Solves inner loop of TPI.  Given path of economic aggregates and
    factor prices, solves household problem.

    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)

    Functions called:
        firstdoughnutring()
        twist_doughnut()

    Objects in function:

    Returns: euler_errors, b_mat, n_mat
    '''
    # unpack variables and parameters pass to function
    (K0, b_sinit, b_splus1init, factor, initial_b, initial_n,
     D0) = initial_values
    guesses_b, guesses_n = guesses
    r, w, r_hh, BQ, T_H, theta = outer_loop_vars

    # compute w
    w[:p.T] = firm.get_w_from_r(r[:p.T], p, 'TPI')
    # compute bq
    bq = household.get_bq(BQ, None, p, 'TPI')

    # initialize arrays
    b_mat = np.zeros((p.T + p.S, p.S))
    n_mat = np.zeros((p.T + p.S, p.S))
    euler_errors = np.zeros((p.T, 2 * p.S))

    b_mat[0, -1], n_mat[0, -1] =\
        np.array(opt.fsolve(firstdoughnutring, [guesses_b[0, -1],
                                                guesses_n[0, -1]],
                            args=(r_hh[0], w[0], bq[0, -1, j], T_H[0],
                                  theta * p.replacement_rate_adjust[0],
                                  factor, j, initial_b, p),
                            xtol=MINIMIZER_TOL))

    for s in range(p.S - 2):  # Upper triangle
        ind2 = np.arange(s + 2)
        b_guesses_to_use = np.diag(guesses_b[:p.S, :], p.S - (s + 2))
        n_guesses_to_use = np.diag(guesses_n[:p.S, :], p.S - (s + 2))
        theta_to_use = theta[j] * p.replacement_rate_adjust[:p.S]
        bq_to_use = np.diag(bq[:p.S, :, j], p.S - (s + 2))
        tau_c_to_use = np.diag(p.tau_c[:p.S, :, j], p.S - (s + 2))

        length_diag =\
            np.diag(p.etr_params[:p.S, :, 0], p.S-(s + 2)).shape[0]
        etr_params_to_use = np.zeros((length_diag, p.etr_params.shape[2]))
        mtrx_params_to_use = np.zeros((length_diag, p.mtrx_params.shape[2]))
        mtry_params_to_use = np.zeros((length_diag, p.mtry_params.shape[2]))
        for i in range(p.etr_params.shape[2]):
            etr_params_to_use[:, i] =\
                np.diag(p.etr_params[:p.S, :, i], p.S - (s + 2))
            mtrx_params_to_use[:, i] =\
                np.diag(p.mtrx_params[:p.S, :, i], p.S - (s + 2))
            mtry_params_to_use[:, i] =\
                np.diag(p.mtry_params[:p.S, :, i], p.S - (s + 2))

        solutions = opt.fsolve(twist_doughnut,
                               list(b_guesses_to_use) + list(n_guesses_to_use),
                               args=(r_hh, w, bq_to_use, T_H, theta_to_use,
                                     factor, j, s, 0, tau_c_to_use,
                                     etr_params_to_use, mtrx_params_to_use,
                                     mtry_params_to_use, initial_b, p),
                               xtol=MINIMIZER_TOL)

        b_vec = solutions[:int(len(solutions) / 2)]
        b_mat[ind2, p.S - (s + 2) + ind2] = b_vec
        n_vec = solutions[int(len(solutions) / 2):]
        n_mat[ind2, p.S - (s + 2) + ind2] = n_vec

    for t in range(0, p.T):
        b_guesses_to_use = .75 * \
            np.diag(guesses_b[t:t + p.S, :])
        n_guesses_to_use = np.diag(guesses_n[t:t + p.S, :])
        theta_to_use = theta[j] * p.replacement_rate_adjust[t:t + p.S]
        bq_to_use = np.diag(bq[t:t + p.S, :, j])
        tau_c_to_use = np.diag(p.tau_c[t:t + p.S, :, j])

        # initialize array of diagonal elements
        etr_params_TP = np.zeros((p.T + p.S, p.S, p.etr_params.shape[2]))
        etr_params_TP[:p.T, :, :] = p.etr_params
        etr_params_TP[p.T:, :, :] = p.etr_params[-1, :, :]

        mtrx_params_TP = np.zeros((p.T + p.S, p.S, p.mtrx_params.shape[2]))
        mtrx_params_TP[:p.T, :, :] = p.mtrx_params
        mtrx_params_TP[p.T:, :, :] = p.mtrx_params[-1, :, :]

        mtry_params_TP = np.zeros((p.T + p.S, p.S, p.mtry_params.shape[2]))
        mtry_params_TP[:p.T, :, :] = p.mtry_params
        mtry_params_TP[p.T:, :, :] = p.mtry_params[-1, :, :]

        length_diag =\
            np.diag(etr_params_TP[t:t + p.S, :, 0]).shape[0]
        etr_params_to_use = np.zeros((length_diag, p.etr_params.shape[2]))
        mtrx_params_to_use = np.zeros((length_diag, p.mtrx_params.shape[2]))
        mtry_params_to_use = np.zeros((length_diag, p.mtry_params.shape[2]))

        for i in range(p.etr_params.shape[2]):
            etr_params_to_use[:, i] = np.diag(etr_params_TP[t:t + p.S, :, i])
            mtrx_params_to_use[:, i] = np.diag(mtrx_params_TP[t:t + p.S, :, i])
            mtry_params_to_use[:, i] = np.diag(mtry_params_TP[t:t + p.S, :, i])
        #
        # TPI_solver_params = (inc_tax_params_TP, tpi_params, None)
        [solutions, infodict, ier, message] =\
            opt.fsolve(twist_doughnut, list(b_guesses_to_use) +
                       list(n_guesses_to_use),
                       args=(r_hh, w, bq_to_use, T_H,
                             theta_to_use, factor,
                             j, None, t, tau_c_to_use,
                             etr_params_to_use, mtrx_params_to_use,
                             mtry_params_to_use, initial_b, p),
                       xtol=MINIMIZER_TOL, full_output=True)
        euler_errors[t, :] = infodict['fvec']

        b_vec = solutions[:p.S]
        b_mat[t + ind, ind] = b_vec
        n_vec = solutions[p.S:]
        n_mat[t + ind, ind] = n_vec

    print('Type ', j, ' max euler error = ', euler_errors.max())

    return euler_errors, b_mat, n_mat
Ejemplo n.º 3
0
def test_get_bq(BQ, j, p, method, expected):
    # Test the get_bq function
    test_value = household.get_bq(BQ, j, p, method)
    print('Test value = ', test_value)
    assert np.allclose(test_value, expected)
Ejemplo n.º 4
0
def inner_loop(guesses, outer_loop_vars, initial_values, j, ind, p):
    '''
    Given path of economic aggregates and factor prices, solves
    household problem.  This has been termed the inner-loop (in
    constrast to the outer fixed point loop that soves for GE factor
    prices and economic aggregates).

    Args:
        guesses (tuple): initial guesses for b and n, (guesses_b,
            guesses_n)
        outer_loop_vars (tuple): values for factor prices and economic
            aggregates used in household problem (r, w, r_hh, BQ, TR,
            theta)
        r (Numpy array): real interest rate on private capital
        w (Numpy array): real wage rate
        r (Numpy array): real interest rate on household portfolio
        BQ (array_like): aggregate bequest amounts
        TR (Numpy array): lump sum transfer amount
        theta (Numpy array): retirement replacement rates, length J
        initial_values (tuple): initial period variable values,
            (b_sinit, b_splus1init, factor, initial_b, initial_n,
            D0_baseline)
        j (int): index of ability type
        ind (Numpy array): integers from 0 to S-1
        p (OG-USA Specifications object): model parameters

    Returns:
        (tuple): household solution results:

            * euler_errors (Numpy array): errors from FOCs, size = Tx2S
            * b_mat (Numpy array): savings amounts, size = TxS
            * n_mat (Numpy array): labor supply amounts, size = TxS

    '''
    # unpack variables and parameters pass to function
    (K0, b_sinit, b_splus1init, factor, initial_b, initial_n) =\
        initial_values
    guesses_b, guesses_n = guesses
    r, w, r_hh, BQ, TR, theta = outer_loop_vars

    # compute w
    w[:p.T] = firm.get_w_from_r(r[:p.T], p, 'TPI')
    # compute bq
    bq = household.get_bq(BQ, None, p, 'TPI')
    # compute tr
    tr = household.get_tr(TR, None, p, 'TPI')

    # initialize arrays
    b_mat = np.zeros((p.T + p.S, p.S))
    n_mat = np.zeros((p.T + p.S, p.S))
    euler_errors = np.zeros((p.T, 2 * p.S))

    b_mat[0, -1], n_mat[0, -1] =\
        np.array(opt.fsolve(firstdoughnutring, [guesses_b[0, -1],
                                                guesses_n[0, -1]],
                            args=(r_hh[0], w[0], bq[0, -1, j],
                                  tr[0, -1, j],
                                  theta * p.replacement_rate_adjust[0],
                                  factor, j, initial_b, p),
                            xtol=MINIMIZER_TOL))

    for s in range(p.S - 2):  # Upper triangle
        ind2 = np.arange(s + 2)
        b_guesses_to_use = np.diag(guesses_b[:p.S, :], p.S - (s + 2))
        n_guesses_to_use = np.diag(guesses_n[:p.S, :], p.S - (s + 2))
        theta_to_use = theta[j] * p.replacement_rate_adjust[:p.S]
        bq_to_use = np.diag(bq[:p.S, :, j], p.S - (s + 2))
        tr_to_use = np.diag(tr[:p.S, :, j], p.S - (s + 2))
        tau_c_to_use = np.diag(p.tau_c[:p.S, :, j], p.S - (s + 2))

        length_diag =\
            np.diag(p.etr_params[:p.S, :, 0], p.S-(s + 2)).shape[0]
        etr_params_to_use = np.zeros((length_diag, p.etr_params.shape[2]))
        mtrx_params_to_use = np.zeros((length_diag, p.mtrx_params.shape[2]))
        mtry_params_to_use = np.zeros((length_diag, p.mtry_params.shape[2]))
        for i in range(p.etr_params.shape[2]):
            etr_params_to_use[:, i] =\
                np.diag(p.etr_params[:p.S, :, i], p.S - (s + 2))
            mtrx_params_to_use[:, i] =\
                np.diag(p.mtrx_params[:p.S, :, i], p.S - (s + 2))
            mtry_params_to_use[:, i] =\
                np.diag(p.mtry_params[:p.S, :, i], p.S - (s + 2))

        solutions = opt.fsolve(
            twist_doughnut,
            list(b_guesses_to_use) + list(n_guesses_to_use),
            args=(r_hh, w, bq_to_use, tr_to_use, theta_to_use, factor, j, s, 0,
                  tau_c_to_use, etr_params_to_use, mtrx_params_to_use,
                  mtry_params_to_use, initial_b, p),
            xtol=MINIMIZER_TOL)

        b_vec = solutions[:int(len(solutions) / 2)]
        b_mat[ind2, p.S - (s + 2) + ind2] = b_vec
        n_vec = solutions[int(len(solutions) / 2):]
        n_mat[ind2, p.S - (s + 2) + ind2] = n_vec

    for t in range(0, p.T):
        b_guesses_to_use = .75 * \
            np.diag(guesses_b[t:t + p.S, :])
        n_guesses_to_use = np.diag(guesses_n[t:t + p.S, :])
        theta_to_use = theta[j] * p.replacement_rate_adjust[t:t + p.S]
        bq_to_use = np.diag(bq[t:t + p.S, :, j])
        tr_to_use = np.diag(tr[t:t + p.S, :, j])
        tau_c_to_use = np.diag(p.tau_c[t:t + p.S, :, j])

        # initialize array of diagonal elements
        etr_params_TP = np.zeros((p.T + p.S, p.S, p.etr_params.shape[2]))
        etr_params_TP[:p.T, :, :] = p.etr_params
        etr_params_TP[p.T:, :, :] = p.etr_params[-1, :, :]

        mtrx_params_TP = np.zeros((p.T + p.S, p.S, p.mtrx_params.shape[2]))
        mtrx_params_TP[:p.T, :, :] = p.mtrx_params
        mtrx_params_TP[p.T:, :, :] = p.mtrx_params[-1, :, :]

        mtry_params_TP = np.zeros((p.T + p.S, p.S, p.mtry_params.shape[2]))
        mtry_params_TP[:p.T, :, :] = p.mtry_params
        mtry_params_TP[p.T:, :, :] = p.mtry_params[-1, :, :]

        length_diag =\
            np.diag(etr_params_TP[t:t + p.S, :, 0]).shape[0]
        etr_params_to_use = np.zeros((length_diag, p.etr_params.shape[2]))
        mtrx_params_to_use = np.zeros((length_diag, p.mtrx_params.shape[2]))
        mtry_params_to_use = np.zeros((length_diag, p.mtry_params.shape[2]))

        for i in range(p.etr_params.shape[2]):
            etr_params_to_use[:, i] = np.diag(etr_params_TP[t:t + p.S, :, i])
            mtrx_params_to_use[:, i] = np.diag(mtrx_params_TP[t:t + p.S, :, i])
            mtry_params_to_use[:, i] = np.diag(mtry_params_TP[t:t + p.S, :, i])

        [solutions, infodict, ier, message] =\
            opt.fsolve(twist_doughnut, list(b_guesses_to_use) +
                       list(n_guesses_to_use),
                       args=(r_hh, w, bq_to_use, tr_to_use,
                             theta_to_use, factor,
                             j, None, t, tau_c_to_use,
                             etr_params_to_use, mtrx_params_to_use,
                             mtry_params_to_use, initial_b, p),
                       xtol=MINIMIZER_TOL, full_output=True)
        euler_errors[t, :] = infodict['fvec']

        b_vec = solutions[:p.S]
        b_mat[t + ind, ind] = b_vec
        n_vec = solutions[p.S:]
        n_mat[t + ind, ind] = n_vec

    print('Type ', j, ' max euler error = ', np.absolute(euler_errors).max())

    return euler_errors, b_mat, n_mat
Ejemplo n.º 5
0
def inner_loop(guesses, outer_loop_vars, initial_values, j, ind, p):
    '''
    Solves inner loop of TPI.  Given path of economic aggregates and
    factor prices, solves household problem.

    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)

    Functions called:
        firstdoughnutring()
        twist_doughnut()

    Objects in function:

    Returns: euler_errors, b_mat, n_mat
    '''
    # unpack variables and parameters pass to function
    (K0, b_sinit, b_splus1init, factor, initial_b, initial_n,
     D0) = initial_values
    guesses_b, guesses_n = guesses
    r, w, r_hh, BQ, T_H, theta = outer_loop_vars

    # compute w
    w[:p.T] = firm.get_w_from_r(r[:p.T], p, 'TPI')
    # compute bq
    bq = household.get_bq(BQ, None, p, 'TPI')

    # initialize arrays
    b_mat = np.zeros((p.T + p.S, p.S))
    n_mat = np.zeros((p.T + p.S, p.S))
    euler_errors = np.zeros((p.T, 2 * p.S))

    b_mat[0, -1], n_mat[0, -1] =\
        np.array(opt.fsolve(firstdoughnutring, [guesses_b[0, -1],
                                                guesses_n[0, -1]],
                            args=(r_hh[0], w[0], bq[0, -1, j], T_H[0],
                                  theta * p.replacement_rate_adjust[0],
                                  factor, j, initial_b, p),
                            xtol=MINIMIZER_TOL))

    for s in range(p.S - 2):  # Upper triangle
        ind2 = np.arange(s + 2)
        b_guesses_to_use = np.diag(guesses_b[:p.S, :], p.S - (s + 2))
        n_guesses_to_use = np.diag(guesses_n[:p.S, :], p.S - (s + 2))
        theta_to_use = theta[j] * p.replacement_rate_adjust[:p.S]
        bq_to_use = np.diag(bq[:p.S, :, j], p.S - (s + 2))
        tau_c_to_use = np.diag(p.tau_c[:p.S, :, j], p.S - (s + 2))

        length_diag =\
            np.diag(p.etr_params[:p.S, :, 0], p.S-(s + 2)).shape[0]
        etr_params_to_use = np.zeros((length_diag, p.etr_params.shape[2]))
        mtrx_params_to_use = np.zeros((length_diag, p.mtrx_params.shape[2]))
        mtry_params_to_use = np.zeros((length_diag, p.mtry_params.shape[2]))
        for i in range(p.etr_params.shape[2]):
            etr_params_to_use[:, i] =\
                np.diag(p.etr_params[:p.S, :, i], p.S - (s + 2))
            mtrx_params_to_use[:, i] =\
                np.diag(p.mtrx_params[:p.S, :, i], p.S - (s + 2))
            mtry_params_to_use[:, i] =\
                np.diag(p.mtry_params[:p.S, :, i], p.S - (s + 2))

        solutions = opt.fsolve(twist_doughnut,
                               list(b_guesses_to_use) +
                               list(n_guesses_to_use),
                               args=(r_hh, w, bq_to_use, T_H, theta_to_use,
                                     factor, j, s, 0, tau_c_to_use,
                                     etr_params_to_use,
                                     mtrx_params_to_use,
                                     mtry_params_to_use, initial_b, p),
                               xtol=MINIMIZER_TOL)

        b_vec = solutions[:int(len(solutions) / 2)]
        b_mat[ind2, p.S - (s + 2) + ind2] = b_vec
        n_vec = solutions[int(len(solutions) / 2):]
        n_mat[ind2, p.S - (s + 2) + ind2] = n_vec

    for t in range(0, p.T):
        b_guesses_to_use = .75 * \
            np.diag(guesses_b[t:t + p.S, :])
        n_guesses_to_use = np.diag(guesses_n[t:t + p.S, :])
        theta_to_use = theta[j] * p.replacement_rate_adjust[t:t + p.S]
        bq_to_use = np.diag(bq[t:t + p.S, :, j])
        tau_c_to_use = np.diag(p.tau_c[t:t + p.S, :, j])

        # initialize array of diagonal elements
        etr_params_TP = np.zeros((p.T + p.S, p.S,  p.etr_params.shape[2]))
        etr_params_TP[:p.T, :, :] = p.etr_params
        etr_params_TP[p.T:, :, :] = p.etr_params[-1, :, :]

        mtrx_params_TP = np.zeros((p.T + p.S, p.S,  p.mtrx_params.shape[2]))
        mtrx_params_TP[:p.T, :, :] = p.mtrx_params
        mtrx_params_TP[p.T:, :, :] = p.mtrx_params[-1, :, :]

        mtry_params_TP = np.zeros((p.T + p.S, p.S,  p.mtry_params.shape[2]))
        mtry_params_TP[:p.T, :, :] = p.mtry_params
        mtry_params_TP[p.T:, :, :] = p.mtry_params[-1, :, :]

        length_diag =\
            np.diag(etr_params_TP[t:t + p.S, :, 0]).shape[0]
        etr_params_to_use = np.zeros((length_diag, p.etr_params.shape[2]))
        mtrx_params_to_use = np.zeros((length_diag, p.mtrx_params.shape[2]))
        mtry_params_to_use = np.zeros((length_diag, p.mtry_params.shape[2]))

        for i in range(p.etr_params.shape[2]):
            etr_params_to_use[:, i] = np.diag(etr_params_TP[t:t + p.S, :, i])
            mtrx_params_to_use[:, i] = np.diag(mtrx_params_TP[t:t + p.S, :, i])
            mtry_params_to_use[:, i] = np.diag(mtry_params_TP[t:t + p.S, :, i])
        #
        # TPI_solver_params = (inc_tax_params_TP, tpi_params, None)
        [solutions, infodict, ier, message] =\
            opt.fsolve(twist_doughnut, list(b_guesses_to_use) +
                       list(n_guesses_to_use),
                       args=(r_hh, w, bq_to_use, T_H,
                             theta_to_use, factor,
                             j, None, t, tau_c_to_use,
                             etr_params_to_use, mtrx_params_to_use,
                             mtry_params_to_use, initial_b, p),
                       xtol=MINIMIZER_TOL, full_output=True)
        euler_errors[t, :] = infodict['fvec']

        b_vec = solutions[:p.S]
        b_mat[t + ind, ind] = b_vec
        n_vec = solutions[p.S:]
        n_mat[t + ind, ind] = n_vec

    print('Type ', j, ' max euler error = ', euler_errors.max())

    return euler_errors, b_mat, n_mat
Ejemplo n.º 6
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
Ejemplo n.º 7
0
def inner_loop(outer_loop_vars, p, client):
    '''
    This function solves for the inner loop of
    the SS.  That is, given the guesses of the
    outer loop variables (r, w, Y, factor)
    this function solves the households'
    problems in the SS.

    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
        Y        = [T,] vector, lump sum transfer amount(s)


    Functions called:
        euler_equation_solver()
        aggr.get_K()
        aggr.get_L()
        firm.get_Y()
        firm.get_r()
        firm.get_w()
        aggr.get_BQ()
        tax.replacement_rate_vals()
        aggr.revenue()

    Objects in function:


    Returns: euler_errors, bssmat, nssmat, new_r, new_w
             new_T_H, new_factor, new_BQ

    '''
    # unpack variables to pass to function
    if p.budget_balance:
        bssmat, nssmat, r, BQ, T_H, factor = outer_loop_vars
    else:
        bssmat, nssmat, r, BQ, Y, T_H, factor = outer_loop_vars

    euler_errors = np.zeros((2 * p.S, p.J))

    w = firm.get_w_from_r(r, p, 'SS')
    r_gov = fiscal.get_r_gov(r, p)
    if p.budget_balance:
        r_hh = r
        D = 0
    else:
        D = p.debt_ratio_ss * Y
        K = firm.get_K_from_Y(Y, r, p, 'SS')
        r_hh = aggr.get_r_hh(r, r_gov, K, D)
    if p.small_open:
        r_hh = p.hh_r[-1]
    bq = household.get_bq(BQ, None, p, 'SS')

    lazy_values = []
    for j in range(p.J):
        guesses = np.append(bssmat[:, j], nssmat[:, j])
        euler_params = (r_hh, w, bq[:, j], T_H, factor, j, p)
        lazy_values.append(delayed(opt.fsolve)(euler_equation_solver,
                                               guesses * .9,
                                               args=euler_params,
                                               xtol=MINIMIZER_TOL,
                                               full_output=True))
    results = compute(*lazy_values, scheduler=dask.multiprocessing.get,
                      num_workers=p.num_workers)

    # for j, result in results.items():
    for j, result in enumerate(results):
        [solutions, infodict, ier, message] = result
        euler_errors[:, j] = infodict['fvec']
        bssmat[:, j] = solutions[:p.S]
        nssmat[:, j] = solutions[p.S:]

    L = aggr.get_L(nssmat, p, 'SS')
    B = aggr.get_K(bssmat, p, 'SS', False)
    K_demand_open = firm.get_K(L, p.firm_r[-1], p, 'SS')
    D_f = p.zeta_D[-1] * D
    D_d = D - D_f
    if not p.small_open:
        K_d = B - D_d
        K_f = p.zeta_K[-1] * (K_demand_open - B + D_d)
        K = K_f + K_d
    else:
        # can remove this else statement by making small open the case where zeta_K = 1
        K_d = B - D_d
        K_f = K_demand_open - B + D_d
        K = K_f + K_d
    new_Y = firm.get_Y(K, L, p, 'SS')
    if p.budget_balance:
        Y = new_Y
    if not p.small_open:
        new_r = firm.get_r(Y, K, p, 'SS')
    else:
        new_r = p.firm_r[-1]
    new_w = firm.get_w_from_r(new_r, p, 'SS')

    b_s = np.array(list(np.zeros(p.J).reshape(1, p.J)) +
                   list(bssmat[:-1, :]))
    new_r_gov = fiscal.get_r_gov(new_r, p)
    new_r_hh = aggr.get_r_hh(new_r, new_r_gov, K, D)
    average_income_model = ((new_r_hh * b_s + new_w * p.e * nssmat) *
                            p.omega_SS.reshape(p.S, 1) *
                            p.lambdas.reshape(1, p.J)).sum()
    if p.baseline:
        new_factor = p.mean_income_data / average_income_model
    else:
        new_factor = factor
    new_BQ = aggr.get_BQ(new_r_hh, bssmat, None, p, 'SS', False)
    new_bq = household.get_bq(new_BQ, None, p, 'SS')
    theta = tax.replacement_rate_vals(nssmat, new_w, new_factor, None, p)

    if p.budget_balance:
        etr_params_3D = np.tile(np.reshape(
            p.etr_params[-1, :, :], (p.S, 1, p.etr_params.shape[2])),
                                (1, p.J, 1))
        taxss = tax.total_taxes(new_r_hh, new_w, b_s, nssmat, new_bq,
                                factor, T_H, theta, None, None, False,
                                'SS', p.e, etr_params_3D, p)
        cssmat = household.get_cons(new_r_hh, new_w, b_s, bssmat,
                                    nssmat, new_bq, taxss,
                                    p.e, p.tau_c[-1, :, :], p)
        new_T_H, _, _, _, _, _, _ = aggr.revenue(
            new_r_hh, new_w, b_s, nssmat, new_bq, cssmat, new_Y, L, K,
            factor, theta, etr_params_3D, p, 'SS')
    elif p.baseline_spending:
        new_T_H = T_H
    else:
        new_T_H = p.alpha_T[-1] * new_Y

    return euler_errors, bssmat, nssmat, new_r, new_r_gov, new_r_hh, \
        new_w, new_T_H, new_Y, new_factor, new_BQ, average_income_model
Ejemplo n.º 8
0
Archivo: SS.py Proyecto: prrathi/OG-USA
def inner_loop(outer_loop_vars, p, client):
    '''
    This function solves for the inner loop of the SS.  That is, given
    the guesses of the outer loop variables (r, w, TR, factor) this
    function solves the households' problems in the SS.

    Args:
        outer_loop_vars (tuple): tuple of outer loop variables,
            (bssmat, nssmat, r, BQ, TR, factor) or
            (bssmat, nssmat, r, BQ, Y, TR, factor)
        bssmat (Numpy array): initial guess at savings, size = SxJ
        nssmat (Numpy array): initial guess at labor supply, size = SxJ
        BQ (array_like): aggregate bequest amount(s)
        Y (scalar): real GDP
        TR (scalar): lump sum transfer amount
        factor (scalar): scaling factor converting model units to dollars
        w (scalar): real wage rate
        p (OG-USA Specifications object): model parameters
        client (Dask client object): client

    Returns:
        (tuple): results from household solution:

            * euler_errors (Numpy array): errors terms from FOCs,
                size = 2SxJ
            * bssmat (Numpy array): savings, size = SxJ
            * nssmat (Numpy array): labor supply, size = SxJ
            * new_r (scalar): real interest rate on firm capital
            * new_r_gov (scalar): real interest rate on government debt
            * new_r_hh (scalar): real interest rate on household
                portfolio
            * new_w (scalar): real wage rate
            * new_TR (scalar): lump sum transfer amount
            * new_Y (scalar): real GDP
            * new_factor (scalar): scaling factor converting model
                units to dollars
            * new_BQ (array_like): aggregate bequest amount(s)
            * average_income_model (scalar): average income in model
                units

    '''
    # unpack variables to pass to function
    if p.budget_balance:
        bssmat, nssmat, r, BQ, TR, factor = outer_loop_vars
        r_hh = r
        Y = 1.0  # placeholder
        K = 1.0  # placeholder
    else:
        bssmat, nssmat, r, BQ, Y, TR, factor = outer_loop_vars
        K = firm.get_K_from_Y(Y, r, p, 'SS')
    # initialize array for euler errors
    euler_errors = np.zeros((2 * p.S, p.J))

    w = firm.get_w_from_r(r, p, 'SS')
    r_gov = fiscal.get_r_gov(r, p)
    D, D_d, D_f, new_borrowing, debt_service, new_borrowing_f =\
        fiscal.get_D_ss(r_gov, Y, p)
    r_hh = aggr.get_r_hh(r, r_gov, K, D)
    bq = household.get_bq(BQ, None, p, 'SS')
    tr = household.get_tr(TR, None, p, 'SS')

    lazy_values = []
    for j in range(p.J):
        guesses = np.append(bssmat[:, j], nssmat[:, j])
        euler_params = (r_hh, w, bq[:, j], tr[:, j], factor, j, p)
        lazy_values.append(delayed(opt.fsolve)(euler_equation_solver,
                                               guesses * .9,
                                               args=euler_params,
                                               xtol=MINIMIZER_TOL,
                                               full_output=True))
    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 results.items():
    for j, result in enumerate(results):
        [solutions, infodict, ier, message] = result
        euler_errors[:, j] = infodict['fvec']
        bssmat[:, j] = solutions[:p.S]
        nssmat[:, j] = solutions[p.S:]

    L = aggr.get_L(nssmat, p, 'SS')
    B = aggr.get_B(bssmat, p, 'SS', False)
    K_demand_open = firm.get_K(L, p.world_int_rate[-1], p, 'SS')
    K, K_d, K_f = aggr.get_K_splits(B, K_demand_open, D_d, p.zeta_K[-1])
    Y = firm.get_Y(K, L, p, 'SS')
    if p.zeta_K[-1] == 1.0:
        new_r = p.world_int_rate[-1]
    else:
        new_r = firm.get_r(Y, K, p, 'SS')
    new_w = firm.get_w_from_r(new_r, p, 'SS')

    b_s = np.array(list(np.zeros(p.J).reshape(1, p.J)) +
                   list(bssmat[:-1, :]))
    new_r_gov = fiscal.get_r_gov(new_r, p)
    new_r_hh = aggr.get_r_hh(new_r, new_r_gov, K, D)
    average_income_model = ((new_r_hh * b_s + new_w * p.e * nssmat) *
                            p.omega_SS.reshape(p.S, 1) *
                            p.lambdas.reshape(1, p.J)).sum()
    if p.baseline:
        new_factor = p.mean_income_data / average_income_model
    else:
        new_factor = factor
    new_BQ = aggr.get_BQ(new_r_hh, bssmat, None, p, 'SS', False)
    new_bq = household.get_bq(new_BQ, None, p, 'SS')
    tr = household.get_tr(TR, None, p, 'SS')
    theta = tax.replacement_rate_vals(nssmat, new_w, new_factor, None, p)
    etr_params_3D = np.tile(
        np.reshape(p.etr_params[-1, :, :],
                   (p.S, 1, p.etr_params.shape[2])), (1, p.J, 1))
    taxss = tax.net_taxes(
        new_r_hh, new_w, b_s, nssmat, new_bq, factor, tr, theta, None,
        None, False, 'SS', p.e, etr_params_3D, p)
    cssmat = household.get_cons(
        new_r_hh, new_w, b_s, bssmat, nssmat, new_bq, taxss, p.e,
        p.tau_c[-1, :, :], p)
    total_tax_revenue, _, agg_pension_outlays, _, _, _, _, _, _ =\
        aggr.revenue(new_r_hh, new_w, b_s, nssmat, new_bq, cssmat, Y, L,
                     K, factor, theta, etr_params_3D, p, 'SS')
    G = fiscal.get_G_ss(Y, total_tax_revenue, agg_pension_outlays, TR,
                        new_borrowing, debt_service, p)
    new_TR = fiscal.get_TR(Y, TR, G, total_tax_revenue,
                           agg_pension_outlays, p, 'SS')

    return euler_errors, bssmat, nssmat, new_r, new_r_gov, new_r_hh, \
        new_w, new_TR, Y, new_factor, new_BQ, average_income_model
Ejemplo n.º 9
0
def inner_loop(outer_loop_vars, p, client):
    '''
    This function solves for the inner loop of the SS.  That is, given
    the guesses of the outer loop variables (r, w, TR, factor) this
    function solves the households' problems in the SS.

    Args:
        outer_loop_vars (tuple): tuple of outer loop variables,
            (bssmat, nssmat, r, BQ, TR, factor) or
            (bssmat, nssmat, r, BQ, Y, TR, factor)
        bssmat (Numpy array): initial guess at savings, size = SxJ
        nssmat (Numpy array): initial guess at labor supply, size = SxJ
        BQ (array_like): aggregate bequest amount(s)
        Y (scalar): real GDP
        TR (scalar): lump sum transfer amount
        factor (scalar): scaling factor converting model units to dollars
        w (scalar): real wage rate
        p (OG-USA Specifications object): model parameters
        client (Dask client object): client

    Returns:
        (tuple): results from household solution:

            * euler_errors (Numpy array): errors terms from FOCs,
                size = 2SxJ
            * bssmat (Numpy array): savings, size = SxJ
            * nssmat (Numpy array): labor supply, size = SxJ
            * new_r (scalar): real interest rate on firm capital
            * new_r_gov (scalar): real interest rate on government debt
            * new_r_hh (scalar): real interest rate on household
                portfolio
            * new_w (scalar): real wage rate
            * new_TR (scalar): lump sum transfer amount
            * new_Y (scalar): real GDP
            * new_factor (scalar): scaling factor converting model
                units to dollars
            * new_BQ (array_like): aggregate bequest amount(s)
            * average_income_model (scalar): average income in model
                units

    '''
    # unpack variables to pass to function
    if p.budget_balance:
        bssmat, nssmat, r, BQ, TR, factor = outer_loop_vars
    else:
        bssmat, nssmat, r, BQ, Y, TR, factor = outer_loop_vars

    euler_errors = np.zeros((2 * p.S, p.J))

    w = firm.get_w_from_r(r, p, 'SS')
    r_gov = fiscal.get_r_gov(r, p)
    if p.budget_balance:
        r_hh = r
        D = 0
    else:
        D = p.debt_ratio_ss * Y
        K = firm.get_K_from_Y(Y, r, p, 'SS')
        r_hh = aggr.get_r_hh(r, r_gov, K, D)
    if p.small_open:
        r_hh = p.hh_r[-1]
    bq = household.get_bq(BQ, None, p, 'SS')
    tr = household.get_tr(TR, None, p, 'SS')

    lazy_values = []
    for j in range(p.J):
        guesses = np.append(bssmat[:, j], nssmat[:, j])
        euler_params = (r_hh, w, bq[:, j], tr[:, j], factor, j, p)
        lazy_values.append(delayed(opt.fsolve)(euler_equation_solver,
                                               guesses * .9,
                                               args=euler_params,
                                               xtol=MINIMIZER_TOL,
                                               full_output=True))
    results = compute(*lazy_values, scheduler=dask.multiprocessing.get,
                      num_workers=p.num_workers)

    # for j, result in results.items():
    for j, result in enumerate(results):
        [solutions, infodict, ier, message] = result
        euler_errors[:, j] = infodict['fvec']
        bssmat[:, j] = solutions[:p.S]
        nssmat[:, j] = solutions[p.S:]

    L = aggr.get_L(nssmat, p, 'SS')
    B = aggr.get_B(bssmat, p, 'SS', False)
    K_demand_open = firm.get_K(L, p.firm_r[-1], p, 'SS')
    D_f = p.zeta_D[-1] * D
    D_d = D - D_f
    if not p.small_open:
        K_d = B - D_d
        K_f = p.zeta_K[-1] * (K_demand_open - B + D_d)
        K = K_f + K_d
    else:
        # can remove this else statement by making small open the case
        # where zeta_K = 1
        K_d = B - D_d
        K_f = K_demand_open - B + D_d
        K = K_f + K_d
    new_Y = firm.get_Y(K, L, p, 'SS')
    if p.budget_balance:
        Y = new_Y
    if not p.small_open:
        new_r = firm.get_r(Y, K, p, 'SS')
    else:
        new_r = p.firm_r[-1]
    new_w = firm.get_w_from_r(new_r, p, 'SS')

    b_s = np.array(list(np.zeros(p.J).reshape(1, p.J)) +
                   list(bssmat[:-1, :]))
    new_r_gov = fiscal.get_r_gov(new_r, p)
    new_r_hh = aggr.get_r_hh(new_r, new_r_gov, K, D)
    average_income_model = ((new_r_hh * b_s + new_w * p.e * nssmat) *
                            p.omega_SS.reshape(p.S, 1) *
                            p.lambdas.reshape(1, p.J)).sum()
    if p.baseline:
        new_factor = p.mean_income_data / average_income_model
    else:
        new_factor = factor
    new_BQ = aggr.get_BQ(new_r_hh, bssmat, None, p, 'SS', False)
    new_bq = household.get_bq(new_BQ, None, p, 'SS')
    tr = household.get_tr(TR, None, p, 'SS')
    theta = tax.replacement_rate_vals(nssmat, new_w, new_factor, None, p)

    if p.budget_balance:
        etr_params_3D = np.tile(np.reshape(
            p.etr_params[-1, :, :], (p.S, 1, p.etr_params.shape[2])),
                                (1, p.J, 1))
        taxss = tax.total_taxes(new_r_hh, new_w, b_s, nssmat, new_bq,
                                factor, tr, theta, None, None, False,
                                'SS', p.e, etr_params_3D, p)
        cssmat = household.get_cons(new_r_hh, new_w, b_s, bssmat,
                                    nssmat, new_bq, taxss,
                                    p.e, p.tau_c[-1, :, :], p)
        new_TR, _, _, _, _, _, _ = aggr.revenue(
            new_r_hh, new_w, b_s, nssmat, new_bq, cssmat, new_Y, L, K,
            factor, theta, etr_params_3D, p, 'SS')
    elif p.baseline_spending:
        new_TR = TR
    else:
        new_TR = p.alpha_T[-1] * new_Y

    return euler_errors, bssmat, nssmat, new_r, new_r_gov, new_r_hh, \
        new_w, new_TR, new_Y, new_factor, new_BQ, average_income_model
Ejemplo n.º 10
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
Ejemplo n.º 11
0
def SS_solver(bmat, nmat, r, BQ, TR, factor, Y, p, client,
              fsolve_flag=False):
    '''
    Solves for the steady state distribution of capital, labor, as well
    as w, r, TR and the scaling factor, using functional iteration.

    Args:
        bmat (Numpy array): initial guess at savings, size = SxJ
        nmat (Numpy array): initial guess at labor supply, size = SxJ
        r (scalar): real interest rate
        BQ (array_like): aggregate bequest amount(s)
        TR (scalar): lump sum transfer amount
        factor (scalar): scaling factor converting model units to dollars
        Y (scalar): real GDP
        p (OG-USA Specifications object): model parameters
        client (Dask client object): client

    Returns:
        output (dictionary): dictionary with steady state solution
            results

    '''
    # Rename the inputs
    if not p.budget_balance:
        if not p.baseline_spending:
            Y = TR / p.alpha_T[-1]
    if p.small_open:
        r = p.hh_r[-1]

    dist = 10
    iteration = 0
    dist_vec = np.zeros(p.maxiter)
    maxiter_ss = p.maxiter
    nu_ss = p.nu

    if fsolve_flag:
        maxiter_ss = 1

    while (dist > p.mindist_SS) and (iteration < maxiter_ss):
        # Solve for the steady state levels of b and n, given w, r,
        # Y and factor
        if p.budget_balance:
            outer_loop_vars = (bmat, nmat, r, BQ, TR, factor)
        else:
            outer_loop_vars = (bmat, nmat, r, BQ, Y, TR, factor)

        (euler_errors, new_bmat, new_nmat, new_r, new_r_gov, new_r_hh,
         new_w, new_TR, new_Y, new_factor, new_BQ,
         average_income_model) =\
            inner_loop(outer_loop_vars, p, client)

        r = utils.convex_combo(new_r, r, nu_ss)
        factor = utils.convex_combo(new_factor, factor, nu_ss)
        BQ = utils.convex_combo(new_BQ, BQ, nu_ss)
        # bmat = utils.convex_combo(new_bmat, bmat, nu_ss)
        # nmat = utils.convex_combo(new_nmat, nmat, nu_ss)
        if not p.baseline_spending:
            TR = utils.convex_combo(new_TR, TR, nu_ss)
            dist = np.array([utils.pct_diff_func(new_r, r)] +
                            list(utils.pct_diff_func(new_BQ, BQ)) +
                            [utils.pct_diff_func(new_TR, TR)] +
                            [utils.pct_diff_func(new_factor, factor)]).max()
        else:
            Y = utils.convex_combo(new_Y, Y, nu_ss)
            if Y != 0:
                dist = np.array([utils.pct_diff_func(new_r, r)] +
                                list(utils.pct_diff_func(new_BQ, BQ)) +
                                [utils.pct_diff_func(new_Y, Y)] +
                                [utils.pct_diff_func(new_factor,
                                                     factor)]).max()
            else:
                # If Y is zero (if there is no output), a percent difference
                # will throw NaN's, so we use an absolute difference
                dist = np.array([utils.pct_diff_func(new_r, r)] +
                                list(utils.pct_diff_func(new_BQ, BQ)) +
                                [abs(new_Y - Y)] +
                                [utils.pct_diff_func(new_factor,
                                                     factor)]).max()
        dist_vec[iteration] = dist
        # Similar to TPI: if the distance between iterations increases, then
        # decrease the value of nu to prevent cycling
        if iteration > 10:
            if dist_vec[iteration] - dist_vec[iteration - 1] > 0:
                nu_ss /= 2.0
                print('New value of nu:', nu_ss)
        iteration += 1
        print('Iteration: %02d' % iteration, ' Distance: ', dist)

    # Generate the SS values of variables, including euler errors
    bssmat_s = np.append(np.zeros((1, p.J)), bmat[:-1, :], axis=0)
    bssmat_splus1 = bmat
    nssmat = nmat

    rss = r
    r_gov_ss = fiscal.get_r_gov(rss, p)
    if p.budget_balance:
        r_hh_ss = rss
        Dss = 0.0
    else:
        Dss = p.debt_ratio_ss * Y
    Lss = aggr.get_L(nssmat, p, 'SS')
    Bss = aggr.get_B(bssmat_splus1, p, 'SS', False)
    K_demand_open_ss = firm.get_K(Lss, p.firm_r[-1], p, 'SS')
    D_f_ss = p.zeta_D[-1] * Dss
    D_d_ss = Dss - D_f_ss
    K_d_ss = Bss - D_d_ss
    if not p.small_open:
        K_f_ss = p.zeta_K[-1] * (K_demand_open_ss - Bss + D_d_ss)
        Kss = K_f_ss + K_d_ss
        # Note that implicity in this computation is that immigrants'
        # wealth is all in the form of private capital
        I_d_ss = aggr.get_I(bssmat_splus1, K_d_ss, K_d_ss, p, 'SS')
        Iss = aggr.get_I(bssmat_splus1, Kss, Kss, p, 'SS')
    else:
        K_d_ss = Bss - D_d_ss
        K_f_ss = K_demand_open_ss - Bss + D_d_ss
        Kss = K_f_ss + K_d_ss
        InvestmentPlaceholder = np.zeros(bssmat_splus1.shape)
        Iss = aggr.get_I(InvestmentPlaceholder, Kss, Kss, p, 'SS')
        I_d_ss = aggr.get_I(bssmat_splus1, K_d_ss, K_d_ss, p, 'SS')
    r_hh_ss = aggr.get_r_hh(rss, r_gov_ss, Kss, Dss)
    wss = new_w
    BQss = new_BQ
    factor_ss = factor
    TR_ss = TR
    bqssmat = household.get_bq(BQss, None, p, 'SS')
    trssmat = household.get_tr(TR_ss, None, p, 'SS')

    Yss = firm.get_Y(Kss, Lss, p, 'SS')
    theta = tax.replacement_rate_vals(nssmat, wss, factor_ss, None, p)

    # Compute effective and marginal tax rates for all agents
    etr_params_3D = np.tile(np.reshape(
        p.etr_params[-1, :, :], (p.S, 1, p.etr_params.shape[2])), (1, p.J, 1))
    mtrx_params_3D = np.tile(np.reshape(
        p.mtrx_params[-1, :, :], (p.S, 1, p.mtrx_params.shape[2])),
                             (1, p.J, 1))
    mtry_params_3D = np.tile(np.reshape(
        p.mtry_params[-1, :, :], (p.S, 1, p.mtry_params.shape[2])),
                             (1, p.J, 1))
    mtry_ss = tax.MTR_income(r_hh_ss, wss, bssmat_s, nssmat, factor, True,
                             p.e, etr_params_3D, mtry_params_3D, p)
    mtrx_ss = tax.MTR_income(r_hh_ss, wss, bssmat_s, nssmat, factor, False,
                             p.e, etr_params_3D, mtrx_params_3D, p)
    etr_ss = tax.ETR_income(r_hh_ss, wss, bssmat_s, nssmat, factor, p.e,
                            etr_params_3D, p)

    taxss = tax.total_taxes(r_hh_ss, wss, bssmat_s, nssmat, bqssmat,
                            factor_ss, trssmat, theta, None, None, False,
                            'SS', p.e, etr_params_3D, p)
    cssmat = household.get_cons(r_hh_ss, wss, bssmat_s, bssmat_splus1,
                                nssmat, bqssmat, taxss,
                                p.e, p.tau_c[-1, :, :], p)
    yss_before_tax_mat = r_hh_ss * bssmat_s + wss * p.e * nssmat
    Css = aggr.get_C(cssmat, p, 'SS')

    (total_revenue_ss, T_Iss, T_Pss, T_BQss, T_Wss, T_Css,
     business_revenue) =\
        aggr.revenue(r_hh_ss, wss, bssmat_s, nssmat, bqssmat, cssmat,
                     Yss, Lss, Kss, factor, theta, etr_params_3D, p,
                     'SS')
    debt_service_ss = r_gov_ss * Dss
    new_borrowing = Dss * ((1 + p.g_n_ss) * np.exp(p.g_y) - 1)
    # government spends such that it expands its debt at the same rate as GDP
    if p.budget_balance:
        Gss = 0.0
    else:
        Gss = total_revenue_ss + new_borrowing - (TR_ss + debt_service_ss)
        print('G components = ', new_borrowing, TR_ss, debt_service_ss)

    # Compute total investment (not just domestic)
    Iss_total = ((1 + p.g_n_ss) * np.exp(p.g_y) - 1 + p.delta) * Kss

    # solve resource constraint
    # net foreign borrowing
    print('Foreign debt holdings = ', D_f_ss)
    print('Foreign capital holdings = ', K_f_ss)
    new_borrowing_f = D_f_ss * (np.exp(p.g_y) * (1 + p.g_n_ss) - 1)
    debt_service_f = D_f_ss * r_hh_ss
    RC = aggr.resource_constraint(Yss, Css, Gss, I_d_ss, K_f_ss,
                                  new_borrowing_f, debt_service_f, r_hh_ss,
                                  p)
    print('resource constraint: ', RC)

    if Gss < 0:
        print('Steady state government spending is negative to satisfy'
              + ' budget')

    if ENFORCE_SOLUTION_CHECKS and (np.absolute(RC) >
                                    p.mindist_SS):
        print('Resource Constraint Difference:', RC)
        err = 'Steady state aggregate resource constraint not satisfied'
        raise RuntimeError(err)

    # check constraints
    household.constraint_checker_SS(bssmat_splus1, nssmat, cssmat, p.ltilde)

    euler_savings = euler_errors[:p.S, :]
    euler_labor_leisure = euler_errors[p.S:, :]
    print('Maximum error in labor FOC = ',
          np.absolute(euler_labor_leisure).max())
    print('Maximum error in savings FOC = ',
          np.absolute(euler_savings).max())

    # Return dictionary of SS results
    output = {'Kss': Kss, 'K_f_ss': K_f_ss, 'K_d_ss': K_d_ss,
              'Bss': Bss, 'Lss': Lss, 'Css': Css, 'Iss': Iss,
              'Iss_total': Iss_total, 'I_d_ss': I_d_ss, 'nssmat': nssmat,
              'Yss': Yss, 'Dss': Dss, 'D_f_ss': D_f_ss,
              'D_d_ss': D_d_ss, 'wss': wss, 'rss': rss,
              'r_gov_ss': r_gov_ss, 'r_hh_ss': r_hh_ss, 'theta': theta,
              'BQss': BQss, 'factor_ss': factor_ss, 'bssmat_s': bssmat_s,
              'cssmat': cssmat, 'bssmat_splus1': bssmat_splus1,
              'yss_before_tax_mat': yss_before_tax_mat,
              'bqssmat': bqssmat, 'TR_ss': TR_ss, 'trssmat': trssmat,
              'Gss': Gss, 'total_revenue_ss': total_revenue_ss,
              'business_revenue': business_revenue,
              'IITpayroll_revenue': T_Iss,
              'T_Pss': T_Pss, 'T_BQss': T_BQss, 'T_Wss': T_Wss,
              'T_Css': T_Css, 'euler_savings': euler_savings,
              'debt_service_f': debt_service_f,
              'new_borrowing_f': new_borrowing_f,
              'debt_service_ss': debt_service_ss,
              'new_borrowing': new_borrowing,
              'euler_labor_leisure': euler_labor_leisure,
              'resource_constraint_error': RC,
              'etr_ss': etr_ss, 'mtrx_ss': mtrx_ss, 'mtry_ss': mtry_ss}

    return output
Ejemplo n.º 12
0
def SS_solver(bmat, nmat, r, BQ, T_H, factor, Y, p, client,
              fsolve_flag=False):
    '''
    --------------------------------------------------------------------
    Solves for the steady state distribution of capital, labor, as well
    as w, r, T_H and the scaling factor, using a bisection method
    similar to TPI.
    --------------------------------------------------------------------

    INPUTS:
    b_guess_init = [S,J] array, initial guesses for savings
    n_guess_init = [S,J] array, initial guesses for labor supply
    wguess = scalar, initial guess for SS real wage rate
    rguess = scalar, initial guess for SS real interest rate
    T_Hguess = scalar, initial guess for lump sum transfer
    factorguess = scalar, initial guess for scaling factor to dollars
    chi_b = [J,] vector, chi^b_j, the utility weight on bequests
    chi_n = [S,] vector, chi^n_s utility weight on labor supply
    params = length X tuple, list of parameters
    iterative_params = length X tuple, list of parameters that determine
                       the convergence of the while loop
    tau_bq = [J,] vector, bequest tax rate
    rho = [S,] vector, mortality rates by age
    lambdas = [J,] vector, fraction of population with each ability type
    omega = [S,] vector, stationary population weights
    e =  [S,J] array, effective labor units by age and ability type


    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
    euler_equation_solver()
    aggr.get_K()
    aggr.get_L()
    firm.get_Y()
    firm.get_r()
    firm.get_w()
    aggr.get_BQ()
    tax.replacement_rate_vals()
    aggr.revenue()
    utils.convex_combo()
    utils.pct_diff_func()


    OBJECTS CREATED WITHIN FUNCTION:
    b_guess = [S,] vector, initial guess at household savings
    n_guess = [S,] vector, initial guess at household labor supply
    b_s = [S,] vector, wealth enter period with
    b_splus1 = [S,] vector, household savings
    b_splus2 = [S,] vector, household savings one period ahead
    BQ = scalar, aggregate bequests to lifetime income group
    theta = scalar, replacement rate for social security benenfits
    error1 = [S,] vector, errors from FOC for savings
    error2 = [S,] vector, errors from FOC for labor supply
    tax1 = [S,] vector, total income taxes paid
    cons = [S,] vector, household consumption

    OBJECTS CREATED WITHIN FUNCTION - SMALL OPEN ONLY
    Bss = scalar, aggregate household wealth in the steady state
    BIss = scalar, aggregate household net investment in the steady state

    RETURNS: solutions = steady state values of b, n, w, r, factor,
                    T_H ((2*S*J+4)x1 array)

    OUTPUT: None
    --------------------------------------------------------------------
    '''
    # Rename the inputs
    if not p.budget_balance:
        if not p.baseline_spending:
            Y = T_H / p.alpha_T[-1]
    if p.small_open:
        r = p.hh_r[-1]

    dist = 10
    iteration = 0
    dist_vec = np.zeros(p.maxiter)
    maxiter_ss = p.maxiter
    nu_ss = p.nu

    if fsolve_flag:
        maxiter_ss = 1

    while (dist > p.mindist_SS) and (iteration < maxiter_ss):
        # Solve for the steady state levels of b and n, given w, r,
        # Y and factor
        if p.budget_balance:
            outer_loop_vars = (bmat, nmat, r, BQ, T_H, factor)
        else:
            outer_loop_vars = (bmat, nmat, r, BQ, Y, T_H, factor)

        (euler_errors, new_bmat, new_nmat, new_r, new_r_gov, new_r_hh,
         new_w, new_T_H, new_Y, new_factor, new_BQ,
         average_income_model) =\
            inner_loop(outer_loop_vars, p, client)

        r = utils.convex_combo(new_r, r, nu_ss)
        factor = utils.convex_combo(new_factor, factor, nu_ss)
        BQ = utils.convex_combo(new_BQ, BQ, nu_ss)
        # bmat = utils.convex_combo(new_bmat, bmat, nu_ss)
        # nmat = utils.convex_combo(new_nmat, nmat, nu_ss)
        if p.budget_balance:
            T_H = utils.convex_combo(new_T_H, T_H, nu_ss)
            dist = np.array([utils.pct_diff_func(new_r, r)] +
                            list(utils.pct_diff_func(new_BQ, BQ)) +
                            [utils.pct_diff_func(new_T_H, T_H)] +
                            [utils.pct_diff_func(new_factor, factor)]).max()
        else:
            Y = utils.convex_combo(new_Y, Y, nu_ss)
            if Y != 0:
                dist = np.array([utils.pct_diff_func(new_r, r)] +
                                list(utils.pct_diff_func(new_BQ, BQ)) +
                                [utils.pct_diff_func(new_Y, Y)] +
                                [utils.pct_diff_func(new_factor,
                                                     factor)]).max()
            else:
                # If Y is zero (if there is no output), a percent difference
                # will throw NaN's, so we use an absoluate difference
                dist = np.array([utils.pct_diff_func(new_r, r)] +
                                list(utils.pct_diff_func(new_BQ, BQ)) +
                                [abs(new_Y - Y)] +
                                [utils.pct_diff_func(new_factor,
                                                     factor)]).max()
        dist_vec[iteration] = dist
        # Similar to TPI: if the distance between iterations increases, then
        # decrease the value of nu to prevent cycling
        if iteration > 10:
            if dist_vec[iteration] - dist_vec[iteration - 1] > 0:
                nu_ss /= 2.0
                print('New value of nu:', nu_ss)
        iteration += 1
        print('Iteration: %02d' % iteration, ' Distance: ', dist)

    '''
    ------------------------------------------------------------------------
        Generate the SS values of variables, including euler errors
    ------------------------------------------------------------------------
    '''
    bssmat_s = np.append(np.zeros((1, p.J)), bmat[:-1, :], axis=0)
    bssmat_splus1 = bmat
    nssmat = nmat

    rss = r
    r_gov_ss = fiscal.get_r_gov(rss, p)
    if p.budget_balance:
        r_hh_ss = rss
        debt_ss = 0.0
    else:
        debt_ss = p.debt_ratio_ss * Y
    Lss = aggr.get_L(nssmat, p, 'SS')
    if not p.small_open:
        Bss = aggr.get_K(bssmat_splus1, p, 'SS', False)
        Kss = Bss - debt_ss
        Iss = aggr.get_I(bssmat_splus1, Kss, Kss, p, 'SS')
    else:
        # Compute capital (K) and wealth (B) separately
        Kss = firm.get_K(Lss, p.firm_r[-1], p, 'SS')
        InvestmentPlaceholder = np.zeros(bssmat_splus1.shape)
        Iss = aggr.get_I(InvestmentPlaceholder, Kss, Kss, p, 'SS')
        Bss = aggr.get_K(bssmat_splus1, p, 'SS', False)
        BIss = aggr.get_I(bssmat_splus1, Bss, Bss, p, 'BI_SS')

    if p.budget_balance:
        r_hh_ss = rss
    else:
        r_hh_ss = aggr.get_r_hh(rss, r_gov_ss, Kss, debt_ss)
    if p.small_open:
        r_hh_ss = p.hh_r[-1]
    wss = new_w
    BQss = new_BQ
    factor_ss = factor
    T_Hss = T_H
    bqssmat = household.get_bq(BQss, None, p, 'SS')

    Yss = firm.get_Y(Kss, Lss, p, 'SS')
    theta = tax.replacement_rate_vals(nssmat, wss, factor_ss, None, p)

    # Compute effective and marginal tax rates for all agents
    etr_params_3D = np.tile(np.reshape(
        p.etr_params[-1, :, :], (p.S, 1, p.etr_params.shape[2])), (1, p.J, 1))
    mtrx_params_3D = np.tile(np.reshape(
        p.mtrx_params[-1, :, :], (p.S, 1, p.mtrx_params.shape[2])),
                             (1, p.J, 1))
    mtry_params_3D = np.tile(np.reshape(
        p.mtry_params[-1, :, :], (p.S, 1, p.mtry_params.shape[2])),
                             (1, p.J, 1))
    mtry_ss = tax.MTR_income(r_hh_ss, wss, bssmat_s, nssmat, factor, True,
                             p.e, etr_params_3D, mtry_params_3D, p)
    mtrx_ss = tax.MTR_income(r_hh_ss, wss, bssmat_s, nssmat, factor, False,
                             p.e, etr_params_3D, mtrx_params_3D, p)
    etr_ss = tax.ETR_income(r_hh_ss, wss, bssmat_s, nssmat, factor, p.e,
                            etr_params_3D, p)

    taxss = tax.total_taxes(r_hh_ss, wss, bssmat_s, nssmat, bqssmat,
                            factor_ss, T_Hss, theta, None, None, False,
                            'SS', p.e, etr_params_3D, p)
    cssmat = household.get_cons(r_hh_ss, wss, bssmat_s, bssmat_splus1,
                                nssmat, bqssmat, taxss,
                                p.e, p.tau_c[-1, :, :], p)
    Css = aggr.get_C(cssmat, p, 'SS')

    (total_revenue_ss, T_Iss, T_Pss, T_BQss, T_Wss, T_Css,
     business_revenue) =\
        aggr.revenue(r_hh_ss, wss, bssmat_s, nssmat, bqssmat, cssmat,
                     Yss, Lss, Kss, factor, theta, etr_params_3D, p,
                     'SS')
    debt_service_ss = r_gov_ss * p.debt_ratio_ss * Yss
    new_borrowing = p.debt_ratio_ss * Yss * ((1 + p.g_n_ss) *
                                             np.exp(p.g_y) - 1)
    # government spends such that it expands its debt at the same rate as GDP
    if p.budget_balance:
        Gss = 0.0
    else:
        Gss = total_revenue_ss + new_borrowing - (T_Hss + debt_service_ss)
        print('G components = ', new_borrowing, T_Hss, debt_service_ss)

    # Compute total investment (not just domestic)
    Iss_total = p.delta * Kss

    # solve resource constraint
    if p.small_open:
        # include term for current account
        resource_constraint = (Yss + new_borrowing - (Css + BIss + Gss)
                               + (p.hh_r[-1] * Bss -
                                  (p.delta + p.firm_r[-1]) *
                                  Kss - debt_service_ss))
        print('Yss= ', Yss, '\n', 'Css= ', Css, '\n', 'Bss = ', Bss,
              '\n', 'BIss = ', BIss, '\n', 'Kss = ', Kss, '\n', 'Iss = ',
              Iss, '\n', 'Lss = ', Lss, '\n', 'T_H = ', T_H, '\n',
              'Gss= ', Gss)
        print('D/Y:', debt_ss / Yss, 'T/Y:', T_Hss / Yss, 'G/Y:',
              Gss / Yss, 'Rev/Y:', total_revenue_ss / Yss,
              'Int payments to GDP:', (r_gov_ss * debt_ss) / Yss)
        print('resource constraint: ', resource_constraint)
    else:
        resource_constraint = Yss - (Css + Iss + Gss)
        print('Yss= ', Yss, '\n', 'Gss= ', Gss, '\n', 'Css= ', Css, '\n',
              'Kss = ', Kss, '\n', 'Iss = ', Iss, '\n', 'Lss = ', Lss,
              '\n', 'Debt service = ', debt_service_ss)
        print('D/Y:', debt_ss / Yss, 'T/Y:', T_Hss / Yss, 'G/Y:',
              Gss / Yss, 'Rev/Y:', total_revenue_ss / Yss, 'business rev/Y: ',
              business_revenue / Yss, 'Int payments to GDP:',
              (r_gov_ss * debt_ss) / Yss)
        print('Check SS budget: ', Gss - (np.exp(p.g_y) *
                                          (1 + p.g_n_ss) - 1 - r_gov_ss)
              * debt_ss - total_revenue_ss + T_Hss)
        print('resource constraint: ', resource_constraint)

    if Gss < 0:
        print('Steady state government spending is negative to satisfy'
              + ' budget')

    if ENFORCE_SOLUTION_CHECKS and (np.absolute(resource_constraint) >
                                    p.mindist_SS):
        print('Resource Constraint Difference:', resource_constraint)
        err = 'Steady state aggregate resource constraint not satisfied'
        raise RuntimeError(err)

    # check constraints
    household.constraint_checker_SS(bssmat_splus1, nssmat, cssmat, p.ltilde)

    euler_savings = euler_errors[:p.S, :]
    euler_labor_leisure = euler_errors[p.S:, :]
    print('Maximum error in labor FOC = ',
          np.absolute(euler_labor_leisure).max())
    print('Maximum error in savings FOC = ',
          np.absolute(euler_savings).max())

    '''
    ------------------------------------------------------------------------
        Return dictionary of SS results
    ------------------------------------------------------------------------
    '''
    output = {'Kss': Kss, 'Bss': Bss, 'Lss': Lss, 'Css': Css, 'Iss': Iss,
              'Iss_total': Iss_total, 'nssmat': nssmat, 'Yss': Yss,
              'Dss': debt_ss, 'wss': wss, 'rss': rss,
              'r_gov_ss': r_gov_ss, 'r_hh_ss': r_hh_ss, 'theta': theta,
              'BQss': BQss, 'factor_ss': factor_ss, 'bssmat_s': bssmat_s,
              'cssmat': cssmat, 'bssmat_splus1': bssmat_splus1,
              'bqssmat': bqssmat, 'T_Hss': T_Hss, 'Gss': Gss,
              'total_revenue_ss': total_revenue_ss,
              'business_revenue': business_revenue,
              'IITpayroll_revenue': T_Iss,
              'T_Pss': T_Pss, 'T_BQss': T_BQss, 'T_Wss': T_Wss,
              'T_Css': T_Css, 'euler_savings': euler_savings,
              'euler_labor_leisure': euler_labor_leisure,
              'resource_constraint_error': resource_constraint,
              'etr_ss': etr_ss, 'mtrx_ss': mtrx_ss, 'mtry_ss': mtry_ss}

    return output
Ejemplo n.º 13
0
def inner_loop(outer_loop_vars, p, client):
    '''
    This function solves for the inner loop of
    the SS.  That is, given the guesses of the
    outer loop variables (r, w, Y, factor)
    this function solves the households'
    problems in the SS.

    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
        Y        = [T,] vector, lump sum transfer amount(s)


    Functions called:
        euler_equation_solver()
        aggr.get_K()
        aggr.get_L()
        firm.get_Y()
        firm.get_r()
        firm.get_w()
        aggr.get_BQ()
        tax.replacement_rate_vals()
        aggr.revenue()

    Objects in function:


    Returns: euler_errors, bssmat, nssmat, new_r, new_w
             new_T_H, new_factor, new_BQ

    '''
    # unpack variables to pass to function
    if p.budget_balance:
        bssmat, nssmat, r, BQ, T_H, factor = outer_loop_vars
    else:
        bssmat, nssmat, r, BQ, Y, T_H, factor = outer_loop_vars

    euler_errors = np.zeros((2 * p.S, p.J))

    w = firm.get_w_from_r(r, p, 'SS')
    r_gov = fiscal.get_r_gov(r, p)
    if p.budget_balance:
        r_hh = r
        D = 0
    else:
        D = p.debt_ratio_ss * Y
        K = firm.get_K_from_Y(Y, r, p, 'SS')
        r_hh = aggr.get_r_hh(r, r_gov, K, D)
    if p.small_open:
        r_hh = p.hh_r[-1]
    bq = household.get_bq(BQ, None, p, 'SS')

    lazy_values = []
    for j in range(p.J):
        guesses = np.append(bssmat[:, j], nssmat[:, j])
        euler_params = (r_hh, w, bq[:, j], T_H, factor, j, p)
        lazy_values.append(delayed(opt.fsolve)(euler_equation_solver,
                                               guesses * .9,
                                               args=euler_params,
                                               xtol=MINIMIZER_TOL,
                                               full_output=True))
    results = compute(*lazy_values, scheduler=dask.multiprocessing.get,
                      num_workers=p.num_workers)

    # for j, result in results.items():
    for j, result in enumerate(results):
        [solutions, infodict, ier, message] = result
        euler_errors[:, j] = infodict['fvec']
        bssmat[:, j] = solutions[:p.S]
        nssmat[:, j] = solutions[p.S:]

    L = aggr.get_L(nssmat, p, 'SS')
    if not p.small_open:
        B = aggr.get_K(bssmat, p, 'SS', False)
        if p.budget_balance:
            K = B
        else:
            K = B - D
    else:
        K = firm.get_K(L, r, p, 'SS')
    new_Y = firm.get_Y(K, L, p, 'SS')
    if p.budget_balance:
        Y = new_Y
    if not p.small_open:
        new_r = firm.get_r(Y, K, p, 'SS')
    else:
        new_r = p.firm_r[-1]
    new_w = firm.get_w_from_r(new_r, p, 'SS')
    print('inner factor prices: ', new_r, new_w)

    b_s = np.array(list(np.zeros(p.J).reshape(1, p.J)) +
                   list(bssmat[:-1, :]))
    new_r_gov = fiscal.get_r_gov(new_r, p)
    if p.small_open:
        new_r_hh = p.hh_r[-1]
    else:
        new_r_hh = aggr.get_r_hh(new_r, new_r_gov, K, D)
    average_income_model = ((new_r_hh * b_s + new_w * p.e * nssmat) *
                            p.omega_SS.reshape(p.S, 1) *
                            p.lambdas.reshape(1, p.J)).sum()
    if p.baseline:
        new_factor = p.mean_income_data / average_income_model
    else:
        new_factor = factor
    new_BQ = aggr.get_BQ(new_r_hh, bssmat, None, p, 'SS', False)
    new_bq = household.get_bq(new_BQ, None, p, 'SS')
    theta = tax.replacement_rate_vals(nssmat, new_w, new_factor, None, p)

    if p.budget_balance:
        etr_params_3D = np.tile(np.reshape(
            p.etr_params[-1, :, :], (p.S, 1, p.etr_params.shape[2])),
                                (1, p.J, 1))
        taxss = tax.total_taxes(new_r_hh, new_w, b_s, nssmat, new_bq,
                                factor, T_H, theta, None, None, False,
                                'SS', p.e, etr_params_3D, p)
        cssmat = household.get_cons(new_r_hh, new_w, b_s, bssmat,
                                    nssmat, new_bq, taxss,
                                    p.e, p.tau_c[-1, :, :], p)
        new_T_H, _, _, _, _, _, _ = aggr.revenue(
            new_r_hh, new_w, b_s, nssmat, new_bq, cssmat, new_Y, L, K,
            factor, theta, etr_params_3D, p, 'SS')
    elif p.baseline_spending:
        new_T_H = T_H
    else:
        new_T_H = p.alpha_T[-1] * new_Y

    return euler_errors, bssmat, nssmat, new_r, new_r_gov, new_r_hh, \
        new_w, new_T_H, new_Y, new_factor, new_BQ, average_income_model
Ejemplo n.º 14
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
Ejemplo n.º 15
0
def SS_solver(bmat, nmat, r, BQ, T_H, factor, Y, p, client,
              fsolve_flag=False):
    '''
    --------------------------------------------------------------------
    Solves for the steady state distribution of capital, labor, as well
    as w, r, T_H and the scaling factor, using a bisection method
    similar to TPI.
    --------------------------------------------------------------------

    INPUTS:
    b_guess_init = [S,J] array, initial guesses for savings
    n_guess_init = [S,J] array, initial guesses for labor supply
    wguess = scalar, initial guess for SS real wage rate
    rguess = scalar, initial guess for SS real interest rate
    T_Hguess = scalar, initial guess for lump sum transfer
    factorguess = scalar, initial guess for scaling factor to dollars
    chi_b = [J,] vector, chi^b_j, the utility weight on bequests
    chi_n = [S,] vector, chi^n_s utility weight on labor supply
    params = length X tuple, list of parameters
    iterative_params = length X tuple, list of parameters that determine
                       the convergence of the while loop
    tau_bq = [J,] vector, bequest tax rate
    rho = [S,] vector, mortality rates by age
    lambdas = [J,] vector, fraction of population with each ability type
    omega = [S,] vector, stationary population weights
    e =  [S,J] array, effective labor units by age and ability type


    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
    euler_equation_solver()
    aggr.get_K()
    aggr.get_L()
    firm.get_Y()
    firm.get_r()
    firm.get_w()
    aggr.get_BQ()
    tax.replacement_rate_vals()
    aggr.revenue()
    utils.convex_combo()
    utils.pct_diff_func()


    OBJECTS CREATED WITHIN FUNCTION:
    b_guess = [S,] vector, initial guess at household savings
    n_guess = [S,] vector, initial guess at household labor supply
    b_s = [S,] vector, wealth enter period with
    b_splus1 = [S,] vector, household savings
    b_splus2 = [S,] vector, household savings one period ahead
    BQ = scalar, aggregate bequests to lifetime income group
    theta = scalar, replacement rate for social security benenfits
    error1 = [S,] vector, errors from FOC for savings
    error2 = [S,] vector, errors from FOC for labor supply
    tax1 = [S,] vector, total income taxes paid
    cons = [S,] vector, household consumption

    OBJECTS CREATED WITHIN FUNCTION - SMALL OPEN ONLY
    Bss = scalar, aggregate household wealth in the steady state
    BIss = scalar, aggregate household net investment in the steady state

    RETURNS: solutions = steady state values of b, n, w, r, factor,
                    T_H ((2*S*J+4)x1 array)

    OUTPUT: None
    --------------------------------------------------------------------
    '''
    # Rename the inputs
    if not p.budget_balance:
        if not p.baseline_spending:
            Y = T_H / p.alpha_T[-1]
    if p.small_open:
        r = p.hh_r[-1]

    dist = 10
    iteration = 0
    dist_vec = np.zeros(p.maxiter)
    maxiter_ss = p.maxiter
    nu_ss = p.nu

    if fsolve_flag:
        maxiter_ss = 1

    while (dist > p.mindist_SS) and (iteration < maxiter_ss):
        # Solve for the steady state levels of b and n, given w, r,
        # Y and factor
        if p.budget_balance:
            outer_loop_vars = (bmat, nmat, r, BQ, T_H, factor)
        else:
            outer_loop_vars = (bmat, nmat, r, BQ, Y, T_H, factor)

        (euler_errors, new_bmat, new_nmat, new_r, new_r_gov, new_r_hh,
         new_w, new_T_H, new_Y, new_factor, new_BQ,
         average_income_model) =\
            inner_loop(outer_loop_vars, p, client)

        r = utils.convex_combo(new_r, r, nu_ss)
        factor = utils.convex_combo(new_factor, factor, nu_ss)
        BQ = utils.convex_combo(new_BQ, BQ, nu_ss)
        # bmat = utils.convex_combo(new_bmat, bmat, nu_ss)
        # nmat = utils.convex_combo(new_nmat, nmat, nu_ss)
        if not p.baseline_spending:
            T_H = utils.convex_combo(new_T_H, T_H, nu_ss)
            dist = np.array([utils.pct_diff_func(new_r, r)] +
                            list(utils.pct_diff_func(new_BQ, BQ)) +
                            [utils.pct_diff_func(new_T_H, T_H)] +
                            [utils.pct_diff_func(new_factor, factor)]).max()
        else:
            Y = utils.convex_combo(new_Y, Y, nu_ss)
            if Y != 0:
                dist = np.array([utils.pct_diff_func(new_r, r)] +
                                list(utils.pct_diff_func(new_BQ, BQ)) +
                                [utils.pct_diff_func(new_Y, Y)] +
                                [utils.pct_diff_func(new_factor,
                                                     factor)]).max()
            else:
                # If Y is zero (if there is no output), a percent difference
                # will throw NaN's, so we use an absolute difference
                dist = np.array([utils.pct_diff_func(new_r, r)] +
                                list(utils.pct_diff_func(new_BQ, BQ)) +
                                [abs(new_Y - Y)] +
                                [utils.pct_diff_func(new_factor,
                                                     factor)]).max()
        dist_vec[iteration] = dist
        # Similar to TPI: if the distance between iterations increases, then
        # decrease the value of nu to prevent cycling
        if iteration > 10:
            if dist_vec[iteration] - dist_vec[iteration - 1] > 0:
                nu_ss /= 2.0
                print('New value of nu:', nu_ss)
        iteration += 1
        print('Iteration: %02d' % iteration, ' Distance: ', dist)

    '''
    ------------------------------------------------------------------------
        Generate the SS values of variables, including euler errors
    ------------------------------------------------------------------------
    '''
    bssmat_s = np.append(np.zeros((1, p.J)), bmat[:-1, :], axis=0)
    bssmat_splus1 = bmat
    nssmat = nmat

    rss = r
    r_gov_ss = fiscal.get_r_gov(rss, p)
    if p.budget_balance:
        r_hh_ss = rss
        Dss = 0.0
    else:
        Dss = p.debt_ratio_ss * Y
    Lss = aggr.get_L(nssmat, p, 'SS')
    Bss = aggr.get_K(bssmat_splus1, p, 'SS', False)
    K_demand_open_ss = firm.get_K(Lss, p.firm_r[-1], p, 'SS')
    D_f_ss = p.zeta_D[-1] * Dss
    D_d_ss = Dss - D_f_ss
    K_d_ss = Bss - D_d_ss
    if not p.small_open:
        K_f_ss = p.zeta_K[-1] * (K_demand_open_ss - Bss + D_d_ss)
        Kss = K_f_ss + K_d_ss
        # Note that implicity in this computation is that immigrants'
        # wealth is all in the form of private capital
        I_d_ss = aggr.get_I(bssmat_splus1, K_d_ss, K_d_ss, p, 'SS')
        Iss = aggr.get_I(bssmat_splus1, Kss, Kss, p, 'SS')
    else:
        K_d_ss = Bss - D_d_ss
        K_f_ss = K_demand_open_ss - Bss + D_d_ss
        Kss = K_f_ss + K_d_ss
        InvestmentPlaceholder = np.zeros(bssmat_splus1.shape)
        Iss = aggr.get_I(InvestmentPlaceholder, Kss, Kss, p, 'SS')
        BIss = aggr.get_I(bssmat_splus1, Bss, Bss, p, 'BI_SS')
        I_d_ss = aggr.get_I(bssmat_splus1, K_d_ss, K_d_ss, p, 'SS')
    r_hh_ss = aggr.get_r_hh(rss, r_gov_ss, Kss, Dss)
    wss = new_w
    BQss = new_BQ
    factor_ss = factor
    T_Hss = T_H
    bqssmat = household.get_bq(BQss, None, p, 'SS')

    Yss = firm.get_Y(Kss, Lss, p, 'SS')
    theta = tax.replacement_rate_vals(nssmat, wss, factor_ss, None, p)

    # Compute effective and marginal tax rates for all agents
    etr_params_3D = np.tile(np.reshape(
        p.etr_params[-1, :, :], (p.S, 1, p.etr_params.shape[2])), (1, p.J, 1))
    mtrx_params_3D = np.tile(np.reshape(
        p.mtrx_params[-1, :, :], (p.S, 1, p.mtrx_params.shape[2])),
                             (1, p.J, 1))
    mtry_params_3D = np.tile(np.reshape(
        p.mtry_params[-1, :, :], (p.S, 1, p.mtry_params.shape[2])),
                             (1, p.J, 1))
    mtry_ss = tax.MTR_income(r_hh_ss, wss, bssmat_s, nssmat, factor, True,
                             p.e, etr_params_3D, mtry_params_3D, p)
    mtrx_ss = tax.MTR_income(r_hh_ss, wss, bssmat_s, nssmat, factor, False,
                             p.e, etr_params_3D, mtrx_params_3D, p)
    etr_ss = tax.ETR_income(r_hh_ss, wss, bssmat_s, nssmat, factor, p.e,
                            etr_params_3D, p)

    taxss = tax.total_taxes(r_hh_ss, wss, bssmat_s, nssmat, bqssmat,
                            factor_ss, T_Hss, theta, None, None, False,
                            'SS', p.e, etr_params_3D, p)
    cssmat = household.get_cons(r_hh_ss, wss, bssmat_s, bssmat_splus1,
                                nssmat, bqssmat, taxss,
                                p.e, p.tau_c[-1, :, :], p)
    yss_before_tax_mat = r_hh_ss * bssmat_s + wss * p.e * nssmat
    Css = aggr.get_C(cssmat, p, 'SS')

    (total_revenue_ss, T_Iss, T_Pss, T_BQss, T_Wss, T_Css,
     business_revenue) =\
        aggr.revenue(r_hh_ss, wss, bssmat_s, nssmat, bqssmat, cssmat,
                     Yss, Lss, Kss, factor, theta, etr_params_3D, p,
                     'SS')
    debt_service_ss = r_gov_ss * Dss
    new_borrowing = Dss * ((1 + p.g_n_ss) * np.exp(p.g_y) - 1)
    # government spends such that it expands its debt at the same rate as GDP
    if p.budget_balance:
        Gss = 0.0
    else:
        Gss = total_revenue_ss + new_borrowing - (T_Hss + debt_service_ss)
        print('G components = ', new_borrowing, T_Hss, debt_service_ss)

    # Compute total investment (not just domestic)
    Iss_total = ((1 + p.g_n_ss) * np.exp(p.g_y) - 1 + p.delta) * Kss

    # solve resource constraint
    # net foreign borrowing
    print('Foreign debt holdings = ', D_f_ss)
    print('Foreign capital holdings = ', K_f_ss)
    new_borrowing_f = D_f_ss * (np.exp(p.g_y) * (1 + p.g_n_ss) - 1)
    debt_service_f = D_f_ss * r_hh_ss
    RC = aggr.resource_constraint(Yss, Css, Gss, I_d_ss, K_f_ss,
                                  new_borrowing_f, debt_service_f, r_hh_ss,
                                  p)
    print('resource constraint: ', RC)

    if Gss < 0:
        print('Steady state government spending is negative to satisfy'
              + ' budget')

    if ENFORCE_SOLUTION_CHECKS and (np.absolute(RC) >
                                    p.mindist_SS):
        print('Resource Constraint Difference:', RC)
        err = 'Steady state aggregate resource constraint not satisfied'
        raise RuntimeError(err)

    # check constraints
    household.constraint_checker_SS(bssmat_splus1, nssmat, cssmat, p.ltilde)

    euler_savings = euler_errors[:p.S, :]
    euler_labor_leisure = euler_errors[p.S:, :]
    print('Maximum error in labor FOC = ',
          np.absolute(euler_labor_leisure).max())
    print('Maximum error in savings FOC = ',
          np.absolute(euler_savings).max())

    '''
    ------------------------------------------------------------------------
        Return dictionary of SS results
    ------------------------------------------------------------------------
    '''
    output = {'Kss': Kss, 'K_f_ss': K_f_ss, 'K_d_ss': K_d_ss,
              'Bss': Bss, 'Lss': Lss, 'Css': Css, 'Iss': Iss,
              'Iss_total': Iss_total, 'I_d_ss': I_d_ss, 'nssmat': nssmat,
              'Yss': Yss, 'Dss': Dss, 'D_f_ss': D_f_ss,
              'D_d_ss': D_d_ss, 'wss': wss, 'rss': rss,
              'r_gov_ss': r_gov_ss, 'r_hh_ss': r_hh_ss, 'theta': theta,
              'BQss': BQss, 'factor_ss': factor_ss, 'bssmat_s': bssmat_s,
              'cssmat': cssmat, 'bssmat_splus1': bssmat_splus1,
              'yss_before_tax_mat': yss_before_tax_mat,
              'bqssmat': bqssmat, 'T_Hss': T_Hss, 'Gss': Gss,
              'total_revenue_ss': total_revenue_ss,
              'business_revenue': business_revenue,
              'IITpayroll_revenue': T_Iss,
              'T_Pss': T_Pss, 'T_BQss': T_BQss, 'T_Wss': T_Wss,
              'T_Css': T_Css, 'euler_savings': euler_savings,
              'debt_service_f': debt_service_f,
              'new_borrowing_f': new_borrowing_f,
              'debt_service_ss': debt_service_ss,
              'new_borrowing': new_borrowing,
              'euler_labor_leisure': euler_labor_leisure,
              'resource_constraint_error': RC,
              'etr_ss': etr_ss, 'mtrx_ss': mtrx_ss, 'mtry_ss': mtry_ss}

    return output
Ejemplo n.º 16
0
def test_euler_equation_solver():
    # Test SS.inner_loop function.  Provide inputs to function and
    # ensure that output returned matches what it has been before.
    input_tuple = utils.safe_read_pickle(
        os.path.join(CUR_PATH, 'test_io_data/euler_eqn_solver_inputs.pkl'))
    (guesses, params) = input_tuple
    p = Specifications()
    (r, w, T_H, factor, j, p.J, p.S, p.beta, p.sigma, p.ltilde, p.g_y,
     p.g_n_ss, tau_payroll, retire, p.mean_income_data, h_wealth,
     p_wealth, m_wealth, p.b_ellipse, p.upsilon, j, p.chi_b,
     p.chi_n, tau_bq, p.rho, lambdas, p.omega_SS, p.e,
     p.analytical_mtrs, etr_params, mtrx_params, mtry_params) = params
    p.tau_bq = np.ones(p.T + p.S) * 0.0
    p.tau_payroll = np.ones(p.T + p.S) * tau_payroll
    p.h_wealth = np.ones(p.T + p.S) * h_wealth
    p.p_wealth = np.ones(p.T + p.S) * p_wealth
    p.m_wealth = np.ones(p.T + p.S) * m_wealth
    p.retire = (np.ones(p.T + p.S) * retire).astype(int)
    p.etr_params = np.transpose(etr_params.reshape(
        p.S, 1, etr_params.shape[-1]), (1, 0, 2))
    p.mtrx_params = np.transpose(mtrx_params.reshape(
        p.S, 1, mtrx_params.shape[-1]), (1, 0, 2))
    p.mtry_params = np.transpose(mtry_params.reshape(
        p.S, 1, mtry_params.shape[-1]), (1, 0, 2))
    p.tax_func_type = 'DEP'
    p.lambdas = lambdas.reshape(p.J, 1)
    b_splus1 = np.array(guesses[:p.S]).reshape(p.S, 1) + 0.005
    BQ = aggregates.get_BQ(r, b_splus1, j, p, 'SS', False)
    bq = household.get_bq(BQ, j, p, 'SS')
    args = (r, w, bq, T_H, factor, j, p)
    test_list = SS.euler_equation_solver(guesses, *args)

    expected_list = np.array([
        -3.62741663e+00, -6.30068841e+00, -6.76592886e+00,
        -6.97731223e+00, -7.05777777e+00, -6.57305440e+00,
        -7.11553046e+00, -7.30569622e+00, -7.45808107e+00,
        -7.89984062e+00, -8.11466111e+00, -8.28230086e+00,
        -8.79253862e+00, -8.86994311e+00, -9.31299476e+00,
        -9.80834199e+00, -9.97333771e+00, -1.08349979e+01,
        -1.13199826e+01, -1.22890930e+01, -1.31550471e+01,
        -1.42753713e+01, -1.55721098e+01, -1.73811490e+01,
        -1.88856303e+01, -2.09570569e+01, -2.30559500e+01,
        -2.52127149e+01, -2.76119605e+01, -3.03141128e+01,
        -3.30900203e+01, -3.62799730e+01, -3.91169706e+01,
        -4.24246421e+01, -4.55740527e+01, -4.92914871e+01,
        -5.30682805e+01, -5.70043846e+01, -6.06075991e+01,
        -6.45251018e+01, -6.86128365e+01, -7.35896515e+01,
        -7.92634608e+01, -8.34733231e+01, -9.29802390e+01,
        -1.01179788e+02, -1.10437881e+02, -1.20569527e+02,
        -1.31569973e+02, -1.43633399e+02, -1.57534056e+02,
        -1.73244610e+02, -1.90066728e+02, -2.07980863e+02,
        -2.27589046e+02, -2.50241670e+02, -2.76314755e+02,
        -3.04930986e+02, -3.36196973e+02, -3.70907934e+02,
        -4.10966644e+02, -4.56684022e+02, -5.06945218e+02,
        -5.61838645e+02, -6.22617808e+02, -6.90840503e+02,
        -7.67825713e+02, -8.54436805e+02, -9.51106365e+02,
        -1.05780305e+03, -1.17435473e+03, -1.30045062e+03,
        -1.43571221e+03, -1.57971603e+03, -1.73204264e+03,
        -1.88430524e+03, -2.03403679e+03, -2.17861987e+03,
        -2.31532884e+03, -8.00654731e+03, -5.21487172e-02,
        -2.80234170e-01, 4.93894552e-01, 3.11884938e-01, 6.55799607e-01,
        5.62182419e-01,  3.86074983e-01,  3.43741491e-01,  4.22461089e-01,
        3.63707951e-01,  4.93150010e-01,  4.72813688e-01,  4.07390308e-01,
        4.94974186e-01,  4.69900128e-01,  4.37562389e-01,  5.67370182e-01,
        4.88965362e-01,  6.40728461e-01,  6.14619979e-01,  4.97173823e-01,
        6.19549666e-01,  6.51193557e-01,  4.48906118e-01,  7.93091492e-01,
        6.51249363e-01,  6.56307713e-01,  1.12948552e+00,  9.50018058e-01,
        6.79613030e-01,  9.51359123e-01,  6.31059147e-01,  7.97896887e-01,
        8.44620817e-01,  7.43683837e-01,  1.56693187e+00,  2.75630011e-01,
        5.32956891e-01,  1.57110727e+00,  1.22674610e+00, 4.63932928e-01,
        1.47225464e+00,  1.16948107e+00,  1.07965795e+00, -3.20557791e-01,
        -1.17064127e+00, -7.84880649e-01, -7.60851182e-01, -1.61415945e+00,
        -8.30363975e-01, -1.68459409e+00, -1.49260581e+00, -1.84257084e+00,
        -1.72143079e+00, -1.43131579e+00, -1.63719219e+00, -1.43874851e+00,
        -1.57207905e+00, -1.72909159e+00, -1.98778122e+00, -1.80843826e+00,
        -2.12828312e+00, -2.24768762e+00, -2.36961877e+00, -2.49117258e+00,
        -2.59914065e+00, -2.82309085e+00, -2.93613362e+00, -3.34446991e+00,
        -3.45445086e+00, -3.74962140e+00, -3.78113417e+00, -4.55643800e+00,
        -4.86929016e+00, -5.08657898e+00, -5.22054177e+00, -5.54606515e+00,
        -5.78478304e+00, -5.93652041e+00, -6.11519786e+00])

    assert(np.allclose(np.array(test_list), np.array(expected_list)))
Ejemplo n.º 17
0
def test_euler_equation_solver():
    # Test SS.inner_loop function.  Provide inputs to function and
    # ensure that output returned matches what it has been before.
    input_tuple = utils.safe_read_pickle(
        os.path.join(CUR_PATH, 'test_io_data/euler_eqn_solver_inputs.pkl'))
    (guesses, params) = input_tuple
    p = Specifications()
    (r, w, T_H, factor, j, p.J, p.S, p.beta, p.sigma, p.ltilde, p.g_y,
     p.g_n_ss, tau_payroll, retire, p.mean_income_data, h_wealth,
     p_wealth, m_wealth, p.b_ellipse, p.upsilon, j, p.chi_b,
     p.chi_n, tau_bq, p.rho, lambdas, p.omega_SS, p.e,
     p.analytical_mtrs, etr_params, mtrx_params, mtry_params) = params
    p.tau_bq = np.ones(p.T + p.S) * 0.0
    p.tau_payroll = np.ones(p.T + p.S) * tau_payroll
    p.h_wealth = np.ones(p.T + p.S) * h_wealth
    p.p_wealth = np.ones(p.T + p.S) * p_wealth
    p.m_wealth = np.ones(p.T + p.S) * m_wealth
    p.retire = (np.ones(p.T + p.S) * retire).astype(int)
    p.etr_params = np.transpose(etr_params.reshape(
        p.S, 1, etr_params.shape[-1]), (1, 0, 2))
    p.mtrx_params = np.transpose(mtrx_params.reshape(
        p.S, 1, mtrx_params.shape[-1]), (1, 0, 2))
    p.mtry_params = np.transpose(mtry_params.reshape(
        p.S, 1, mtry_params.shape[-1]), (1, 0, 2))
    p.tax_func_type = 'DEP'
    p.lambdas = lambdas.reshape(p.J, 1)
    b_splus1 = np.array(guesses[:p.S]).reshape(p.S, 1) + 0.005
    BQ = aggregates.get_BQ(r, b_splus1, j, p, 'SS', False)
    bq = household.get_bq(BQ, j, p, 'SS')
    args = (r, w, bq, T_H, factor, j, p)
    test_list = SS.euler_equation_solver(guesses, *args)

    expected_list = np.array([
        -3.62741663e+00, -6.30068841e+00, -6.76592886e+00,
        -6.97731223e+00, -7.05777777e+00, -6.57305440e+00,
        -7.11553046e+00, -7.30569622e+00, -7.45808107e+00,
        -7.89984062e+00, -8.11466111e+00, -8.28230086e+00,
        -8.79253862e+00, -8.86994311e+00, -9.31299476e+00,
        -9.80834199e+00, -9.97333771e+00, -1.08349979e+01,
        -1.13199826e+01, -1.22890930e+01, -1.31550471e+01,
        -1.42753713e+01, -1.55721098e+01, -1.73811490e+01,
        -1.88856303e+01, -2.09570569e+01, -2.30559500e+01,
        -2.52127149e+01, -2.76119605e+01, -3.03141128e+01,
        -3.30900203e+01, -3.62799730e+01, -3.91169706e+01,
        -4.24246421e+01, -4.55740527e+01, -4.92914871e+01,
        -5.30682805e+01, -5.70043846e+01, -6.06075991e+01,
        -6.45251018e+01, -6.86128365e+01, -7.35896515e+01,
        -7.92634608e+01, -8.34733231e+01, -9.29802390e+01,
        -1.01179788e+02, -1.10437881e+02, -1.20569527e+02,
        -1.31569973e+02, -1.43633399e+02, -1.57534056e+02,
        -1.73244610e+02, -1.90066728e+02, -2.07980863e+02,
        -2.27589046e+02, -2.50241670e+02, -2.76314755e+02,
        -3.04930986e+02, -3.36196973e+02, -3.70907934e+02,
        -4.10966644e+02, -4.56684022e+02, -5.06945218e+02,
        -5.61838645e+02, -6.22617808e+02, -6.90840503e+02,
        -7.67825713e+02, -8.54436805e+02, -9.51106365e+02,
        -1.05780305e+03, -1.17435473e+03, -1.30045062e+03,
        -1.43571221e+03, -1.57971603e+03, -1.73204264e+03,
        -1.88430524e+03, -2.03403679e+03, -2.17861987e+03,
        -2.31532884e+03, -8.00654731e+03, -5.21487172e-02,
        -2.80234170e-01, 4.93894552e-01, 3.11884938e-01, 6.55799607e-01,
        5.62182419e-01,  3.86074983e-01,  3.43741491e-01,  4.22461089e-01,
        3.63707951e-01,  4.93150010e-01,  4.72813688e-01,  4.07390308e-01,
        4.94974186e-01,  4.69900128e-01,  4.37562389e-01,  5.67370182e-01,
        4.88965362e-01,  6.40728461e-01,  6.14619979e-01,  4.97173823e-01,
        6.19549666e-01,  6.51193557e-01,  4.48906118e-01,  7.93091492e-01,
        6.51249363e-01,  6.56307713e-01,  1.12948552e+00,  9.50018058e-01,
        6.79613030e-01,  9.51359123e-01,  6.31059147e-01,  7.97896887e-01,
        8.44620817e-01,  7.43683837e-01,  1.56693187e+00,  2.75630011e-01,
        5.32956891e-01,  1.57110727e+00,  1.22674610e+00, 4.63932928e-01,
        1.47225464e+00,  1.16948107e+00,  1.07965795e+00, -3.20557791e-01,
        -1.17064127e+00, -7.84880649e-01, -7.60851182e-01, -1.61415945e+00,
        -8.30363975e-01, -1.68459409e+00, -1.49260581e+00, -1.84257084e+00,
        -1.72143079e+00, -1.43131579e+00, -1.63719219e+00, -1.43874851e+00,
        -1.57207905e+00, -1.72909159e+00, -1.98778122e+00, -1.80843826e+00,
        -2.12828312e+00, -2.24768762e+00, -2.36961877e+00, -2.49117258e+00,
        -2.59914065e+00, -2.82309085e+00, -2.93613362e+00, -3.34446991e+00,
        -3.45445086e+00, -3.74962140e+00, -3.78113417e+00, -4.55643800e+00,
        -4.86929016e+00, -5.08657898e+00, -5.22054177e+00, -5.54606515e+00,
        -5.78478304e+00, -5.93652041e+00, -6.11519786e+00])

    assert(np.allclose(np.array(test_list), np.array(expected_list)))