예제 #1
0
def euler_sys(guesses, *args):
    '''
    --------------------------------------------------------------------
    Specify the system of Euler Equations characterizing the household
    problem.
    --------------------------------------------------------------------
    INPUTS:
    guesses = (2S-1,) vector, guess at labor supply and savings decisions
    args = length 14 tuple, (r, w, beta, sigma, l_tilde, chi_n_vec,
            b_ellip, upsilon, diff, S, SS_tol)

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        hh.get_n_errors()
        hh.get_n_errors()
        hh.get_cons()

    OBJECTS CREATED WITHIN FUNCTION:
    r    = scalar > 0, guess at steady-state interest rate
    w    = scalar > 0, guess at steady-state wage
    beta       = scalar in (0,1), discount factor
    sigma      = scalar >= 1, coefficient of relative risk aversion
    l_tilde    = scalar > 0, per-period time endowment for every agent
    chi_n_vec  = (S,) vector, values for chi^n_s
    b_ellip    = scalar > 0, fitted value of b for elliptical disutility
                 of labor
    upsilon    = scalar > 1, fitted value of upsilon for elliptical
                 disutility of labor
    A          = scalar > 0, total factor productivity parameter in
                 firms' production function
    diff    = boolean, =True if simple difference Euler errors,
                 otherwise percent deviation Euler errors
    S          = integer >= 3, number of periods in individual lifetime
    SS_tol     = scalar > 0, tolerance level for steady-state fsolve
    nvec       = (S,) vector, lifetime labor supply (n1, n2, ...nS)
    bvec       = (S,) vector, lifetime savings (b1, b2, ...bS) with b1=0
    cvec       = (S,) vector, lifetime consumption (c1, c2, ...cS)
    b_sp1      = = (S,) vector, lifetime savings (b1, b2, ...bS) with bS=0
    n_errors   = (S,) vector, labor supply Euler errors
    b_errors   = (S-1,) vector, savings Euler errors

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: array of n_errors and b_errors
    --------------------------------------------------------------------
    '''
    (r, w, beta, sigma, l_tilde, chi_n_vec, b_ellip, upsilon, diff, S) = args
    nvec = guesses[:S]
    bvec1 = guesses[S:]

    b_s = np.append(0.0, bvec1)
    b_sp1 = np.append(bvec1, 0.0)
    cvec = hh.get_cons(r, w, b_s, b_sp1, nvec)
    n_args = (w, sigma, l_tilde, chi_n_vec, b_ellip, upsilon, diff, cvec)
    n_errors = hh.get_n_errors(nvec, *n_args)
    b_args = (r, beta, sigma, diff)
    b_errors = hh.get_b_errors(cvec, *b_args)

    errors = np.append(n_errors, b_errors)

    return errors
예제 #2
0
파일: SS.py 프로젝트: snowdj/WB-India
def SS_EulErrs(bvec, *args):
    '''
    --------------------------------------------------------------------
    --------------------------------------------------------------------
    INPUTS:
    bvec = (S-1,) vector, lifetime savings
    args = length 7 tuple, (nvec, beta, sigma, A, alpha, delta, EulDiff)

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

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

    FILES CREATED BY THIS FUNCTION: None

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

    return errors
예제 #3
0
파일: TPI.py 프로젝트: snowdj/WB-India
def LfEulerSys(bvec, *args):
    '''
    --------------------------------------------------------------------
    Generates vector of all Euler errors for a given bvec, which errors
    characterize all optimal lifetime decisions, where p is an integer
    in [2, S] representing the remaining periods of life
    --------------------------------------------------------------------
    INPUTS:
    bvec       = (p-1,) vector, remaining lifetime savings decisions
                 where p is the number of remaining periods
    args       = length 7 tuple, (beta, sigma, beg_wealth, nvec, rpath,
                 wpath, EulDiff)
    beta       = scalar in [0,1), discount factor
    sigma      = scalar > 0, coefficient of relative risk aversion
    beg_wealth = scalar, wealth at the beginning of first age
    nvec       = (p,) vector, remaining exogenous labor supply
    rpath      = (p,) vector, interest rates over remaining life
    wpath      = (p,) vector, wages rates over remaining life
    EulDiff    = Boolean, =True if want difference version of Euler
                 errors beta*(1+r)*u'(c2) - u'(c1), =False if want ratio
                 version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        c6ssf.get_cvec()
        c6ssf.get_b_errors()

    OBJECTS CREATED WITHIN FUNCTION:
    bvec2        = (p,) vector, remaining savings including initial
                   savings
    cvec         = (p,) vector, remaining lifetime consumption
                   levels implied by bvec2
    c_cnstr      = (p,) Boolean vector, =True if c_{s,t}<=0
    b_err_params = length 2 tuple, (beta, sigma)
    b_err_vec    = (p-1,) vector, Euler errors from lifetime
                   consumption vector

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: b_err_vec
    --------------------------------------------------------------------
    '''
    beta, sigma, beg_wealth, nvec, rpath, wpath, EulDiff = args
    c_args = (nvec, rpath, wpath)
    cvec = hh.get_cons(bvec, beg_wealth, c_args)
    b_args = (beta, sigma, rpath[1:], EulDiff)
    b_err_vec = hh.get_b_errors(cvec, b_args)

    return b_err_vec
예제 #4
0
파일: TPI.py 프로젝트: LeiliPR/OG-JRC
def firstdoughnutring(guesses, args):
    '''
    Solves the first entries of the upper triangle of the twist doughnut.  This is
    separate from the main TPI function because the the values of b and n are scalars,
    so it is easier to just have a separate function for these cases.
    Inputs:
        guesses = guess for b and n (2x1 list)
        winit = initial wage rate (scalar)
        rinit = initial rental rate (scalar)
        BQinit = initial aggregate bequest (scalar)
        T_H_init = initial lump sum tax (scalar)
        initial_b = initial distribution of capital (SxJ array)
        factor = steady state scaling factor (scalar)
        j = which ability type is being solved for (scalar)
        parameters = list of parameters (list)
        theta = replacement rates (Jx1 array)
        tau_bq = bequest tax rates (Jx1 array)
    Output:
        euler errors (2x1 list)
    '''

    # unpack tuples of parameters
    r, w, S, T2, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec,\
        initial_b, diff = args

    b_splus1 = 0.0  # leave zero savings in last period of life
    n = float(guesses[1])
    b_s = float(initial_b[-1])

    # Euler equations
    cons = hh.get_cons(r, w, b_s, b_splus1, n)
    b_params = (beta, sigma)
    error1 = 0.0  #hh.get_b_errors(b_params, r, cons, diff)

    n_args = (w, cons, sigma, l_tilde, chi_n_vec, b_ellip, upsilon, diff)
    error2 = hh.get_n_errors(n, n_args)

    if n <= 0 or n >= 1:
        error2 += 1e14
    if cons <= 0:
        error1 += 1e14
    return [error1] + [error2]
예제 #5
0
파일: TPI.py 프로젝트: LeiliPR/OG-JRC
def get_TPI(params, bvec1, graphs):
    '''
    --------------------------------------------------------------------
    Solves for transition path equilibrium using time path iteration
    (TPI)
    --------------------------------------------------------------------
    INPUTS:
    params = length 21 tuple, (S, T1, T2, beta, sigma, l_tilde, b_ellip,
             upsilon, chi_n_vec, A, alpha, delta, K_ss, L_ss, C_ss,
             maxiter, mindist, TPI_tol, xi, diff, hh_fsolve)
    bvec1  = (S,) vector, initial period savings distribution
    graphs = Boolean, =True if want graphs of TPI objects

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

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

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

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

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

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

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

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

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

    tpi_time = time.clock() - start_time

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

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

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

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

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

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

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

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

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

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

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

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

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

    return tpi_output
예제 #6
0
파일: TPI.py 프로젝트: LeiliPR/OG-JRC
def twist_doughnut(guesses, td_args):
    '''
    Parameters:
        guesses = distribution of capital and labor (various length list)
        w   = wage rate ((T+S)x1 array)
        r   = rental rate ((T+S)x1 array)
        BQ = aggregate bequests ((T+S)x1 array)
        T_H = lump sum tax over time ((T+S)x1 array)
        factor = scaling factor (scalar)
        j = which ability type is being solved for (scalar)
        s = which upper triangle loop is being solved for (scalar)
        t = which diagonal is being solved for (scalar)
        params = list of parameters (list)
        theta = replacement rates (Jx1 array)
        tau_bq = bequest tax rate (Jx1 array)
        rho = mortalit rate (Sx1 array)
        lambdas = ability weights (Jx1 array)
        e = ability type (SxJ array)
        initial_b = capital stock distribution in period 0 (SxJ array)
        chi_b = chi^b_j (Jx1 array)
        chi_n = chi^n_s (Sx1 array)
    Output:
        Value of Euler error (various length list)
    '''
    rpath, wpath, s, t, S, T2, beta, sigma, l_tilde, b_ellip, upsilon, \
                chi_n_vec, initial_b, diff = td_args

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

    b_guess[-1] = 0.0  # save nothing in last period

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

    w = wpath[t:t + length]
    r = rpath[t:t + length]

    # Euler equations
    cons = hh.get_cons(r, w, b_s, b_guess, n_guess)

    b_params = (beta, sigma)
    euler_errors = hh.get_b_errors(b_params, r[1:], cons, diff)
    error1 = np.append(euler_errors, 0.0)

    n_args = (w, cons, sigma, l_tilde, chi_n_vec[-length:], b_ellip, upsilon,
              diff)
    error2 = hh.get_n_errors(n_guess, n_args)

    # Check and punish constraint violations
    mask1 = n_guess < 0
    error2[mask1] += 1e14
    mask2 = n_guess > l_tilde
    error2[mask2] += 1e14
    mask3 = cons < 0
    error2[mask3] += 1e14

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

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

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

    FILES CREATED BY THIS FUNCTION: None

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

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

    return (K, L, cmat, nmat, bmat, b_Sp1_vec, r_new, w_new, n_err_mat,
            b_err_mat)
예제 #8
0
def inner_loop(rpath, wpath, args):
    '''
    --------------------------------------------------------------------
    Given time paths for interest rates and wages, this function
    generates matrices for the time path of the distribution of
    individual consumption, labor supply, savings, the corresponding
    Euler errors for the labor supply decision and the savings decision,
    and the residual error of end-of-life savings associated with
    solving each lifetime decision.
    --------------------------------------------------------------------
    INPUTS:
    rpath = (T2+S-1,) vector, equilibrium time path of interest rate
    wpath = (T2+S-1,) vector, equilibrium time path of the real wage
    args  = length 12 tuple, (S, T2, beta, sigma, l_tilde, b_ellip,
            upsilon, chi_n_vec, bvec1, n_ss, In_Tol, diff)
    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        hh.get_n_errors()
        hh.get_b_errors()
    OBJECTS CREATED WITHIN FUNCTION:
    S             = integer in [3,80], number of periods an individual
                    lives
    T2            = integer > S, number of periods until steady state
    beta          = scalar in (0,1), discount factor
    sigma         = scalar > 0, coefficient of relative risk aversion
    l_tilde       = scalar > 0, time endowment for each agent each
                    period
    b_ellip       = scalar > 0, fitted value of b for elliptical
                    disutility of labor
    upsilon       = scalar > 1, fitted value of upsilon for elliptical
                    disutility of labor
    chi_n_vec     = (S,) vector, values for chi^n_s
    bvec1         = (S,) vector, initial period savings distribution
    In _tol       = scalar > 0, tolerance level for fsolve's in TPI
    diff          = boolean, =True if want difference version of Euler
                    errors beta*(1+r)*u'(c2) - u'(c1), =False if want
                    ratio version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1
    cpath         = (S, T2+S-1) matrix, time path of the distribution of
                    consumption
    npath         = (S, T2+S-1) matrix, time path of the distribution of
                    labor supply
    bpath         = (S, T2+S-1) matrix, time path of the distribution of
                    savings
    n_err_path    = (S, T2+S-1) matrix, time path of distribution of
                    labor supply Euler errors
    b_err_path    = (S, T2+S-1) matrix, time path of distribution of
                    savings Euler errors
    bSp1_err_path = (S, T2) matrix, residual last period savings, which
                    should be close to zero in equilibrium. Nonzero
                    elements of matrix should only be in first column
                    and first row
    b_err_params  = length 2 tuple, args to pass into
                    hh.get_b_errors()
    p             = integer in [1, S-1], index representing number of
                    periods remaining in a lifetime, used to solve
                    incomplete lifetimes
    cvec          = (p,) vector, individual lifetime consumption
                    decisions
    nvec          = (p,) vector, individual lifetime labor supply
                    decisions
    bvec          = (p,) vector, individual lifetime savings decisions
    b_Sp1         = scalar, savings in last period for next period.
                    Should be zero in equilibrium
    DiagMaskc     = (p, p) boolean identity matrix
    DiagMaskb     = (p-1, p-1) boolean identity matrix
    n_err_params  = length 5 tuple, args to pass into hh.get_n_errors()
    n_err_vec     = (p,) vector, individual lifetime labor supply Euler
                    errors
    b_err_vec     = (p-1,) vector, individual lifetime savings Euler
                    errors
    t             = integer in [0,T2-1], index of time period (minus 1)
    FILES CREATED BY THIS FUNCTION: None
    RETURNS: cpath, npath, bpath, n_err_path, b_err_path, bSp1_err_path
    --------------------------------------------------------------------
    '''
    (S, T2, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec, bvec1, n_ss,
     In_Tol, diff) = args
    cpath = np.zeros((S, T2 + S - 1))
    npath = np.zeros((S, T2 + S - 1))
    bpath = np.append(bvec1.reshape((S, 1)), np.zeros((S, T2 + S - 2)), axis=1)
    n_err_path = np.zeros((S, T2 + S - 1))
    b_err_path = np.zeros((S, T2 + S - 1))
    b_err_args = (beta, sigma, diff)

    # Solve the incomplete remaining lifetime decisions of agents alive
    # in period t=1 but not born in period t=1
    for p in range(1, S):

        if p == 1:
            # p=1 individual only has an s=S labor supply decision n_S
            n_S1_init = n_ss[-1]
            nS1_args = (wpath[0], sigma, l_tilde, chi_n_vec[-1], b_ellip,
                        upsilon, diff, rpath[0], bvec1[-1], 0.0)
            results_nS1 = opt.root(hh.get_n_errors,
                                   n_S1_init,
                                   args=(nS1_args),
                                   method='lm',
                                   tol=In_Tol)
            n_S1 = results_nS1.x
            npath[-1, 0] = n_S1
            n_err_path[-1, 0] = results_nS1.fun
            cpath[-1, 0] = hh.get_cons(rpath[0], wpath[0], bvec1[-1], 0.0,
                                       n_S1)

        else:
            # 1<p<S chooses b_{s+1} and n_s and has incomplete lives
            DiagMaskb = np.eye(p - 1, dtype=bool)
            DiagMaskn = np.eye(p, dtype=bool)
            b_sp1_init = np.diag(bpath[S - p + 1:, :p - 1])
            n_s_init = np.hstack(
                (n_ss[S - p], np.diag(npath[S - p + 1:, :p - 1])))
            bn_init = np.hstack((b_sp1_init, n_s_init))
            bn_args = (rpath[:p], wpath[:p], bvec1[-p], p, beta, sigma,
                       l_tilde, chi_n_vec[-p:], b_ellip, upsilon, diff)
            results_bn = opt.root(hh.bn_errors,
                                  bn_init,
                                  args=(bn_args),
                                  tol=In_Tol)
            bvec = results_bn.x[:p - 1]
            nvec = results_bn.x[p - 1:]
            b_s_vec = np.append(bvec1[-p], bvec)
            b_sp1_vec = np.append(bvec, 0.0)
            cvec = hh.get_cons(rpath[:p], wpath[:p], b_s_vec, b_sp1_vec, nvec)
            npath[S - p:, :p] = DiagMaskn * nvec + npath[S - p:, :p]
            bpath[S - p + 1:,
                  1:p] = (DiagMaskb * bvec + bpath[S - p + 1:, 1:p])
            cpath[S - p:, :p] = DiagMaskn * cvec + cpath[S - p:, :p]
            n_args = (wpath[:p], sigma, l_tilde, chi_n_vec[-p:], b_ellip,
                      upsilon, diff, cvec)
            n_errors = hh.get_n_errors(nvec, *n_args)
            n_err_path[S - p:, :p] = (DiagMaskn * n_errors +
                                      n_err_path[S - p:, :p])
            b_errors = hh.get_b_errors(cvec, rpath[1:p], *b_err_args)
            b_err_path[S - p + 1:, 1:p] = (DiagMaskb * b_errors +
                                           b_err_path[S - p + 1:, 1:p])

    # Solve the complete remaining lifetime decisions of agents born
    # between period t=1 and t=T2
    for t in range(T2):
        DiagMaskb = np.eye(S - 1, dtype=bool)
        DiagMaskn = np.eye(S, dtype=bool)
        b_sp1_init = np.diag(bpath[1:, t:t + S - 1])
        if t == 0:
            n_s_init = np.hstack((n_ss[0], np.diag(npath[1:, t:t + S - 1])))
        else:
            n_s_init = np.diag(npath[:, t - 1:t + S - 1])
        bn_init = np.hstack((b_sp1_init, n_s_init))
        bn_args = (rpath[t:t + S], wpath[t:t + S], 0.0, S, beta, sigma,
                   l_tilde, chi_n_vec, b_ellip, upsilon, diff)
        results_bn = opt.root(hh.bn_errors,
                              bn_init,
                              args=(bn_args),
                              tol=In_Tol)
        bvec = results_bn.x[:S - 1]
        nvec = results_bn.x[S - 1:]
        b_s_vec = np.append(0.0, bvec)
        b_sp1_vec = np.append(bvec, 0.0)
        cvec = hh.get_cons(rpath[t:t + S], wpath[t:t + S], b_s_vec, b_sp1_vec,
                           nvec)
        npath[:, t:t + S] = DiagMaskn * nvec + npath[:, t:t + S]
        bpath[1:, t + 1:t + S] = (DiagMaskb * bvec + bpath[1:, t + 1:t + S])
        cpath[:, t:t + S] = DiagMaskn * cvec + cpath[:, t:t + S]
        n_args = (wpath[t:t + S], sigma, l_tilde, chi_n_vec, b_ellip, upsilon,
                  diff, cvec)
        n_errors = hh.get_n_errors(nvec, *n_args)
        n_err_path[:,
                   t:t + S] = (DiagMaskn * n_errors + n_err_path[:, t:t + S])
        b_errors = hh.get_b_errors(cvec, rpath[t + 1:t + S], *b_err_args)
        b_err_path[1:, t + 1:t + S] = (DiagMaskb * b_errors +
                                       b_err_path[1:, t + 1:t + S])

    return cpath, npath, bpath, n_err_path, b_err_path
예제 #9
0
파일: TPI.py 프로젝트: snowdj/WB-India
def paths_life(params, beg_age, beg_wealth, nvec, rpath, wpath,
               b_init):
    '''
    --------------------------------------------------------------------
    Solve for the remaining lifetime savings decisions of an individual
    who enters the model at age beg_age, with corresponding initial
    wealth beg_wealth. Variable p is an integer in [2, S] representing
    the remaining periods of life.
    --------------------------------------------------------------------
    INPUTS:
    params     = length 5 tuple, (S, beta, sigma, TPI_tol, EulDiff)
    S          = integer in [3,80], number of periods an individual
                 lives
    beta       = scalar in (0,1), discount factor for each model
                 period
    sigma      = scalar > 0, coefficient of relative risk aversion
    TPI_tol    = scalar > 0, tolerance level for fsolve's in TPI
    EulDiff    = Boolean, =True if want difference version of Euler
                 errors beta*(1+r)*u'(c2) - u'(c1), =False if want
                 ratio version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1
    beg_age    = integer in [1,S-1], beginning age of remaining life
    beg_wealth = scalar, beginning wealth at beginning age
    nvec       = (p,) vector, remaining exogenous labor supplies
    rpath      = (p,) vector, remaining lifetime interest rates
    wpath      = (p,) vector, remaining lifetime wages
    b_init     = (p-1,) vector, initial guess for remaining lifetime
                 savings

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        LfEulerSys()
        c6ssf.get_cvec()
        c6ssf.get_b_errors()

    OBJECTS CREATED WITHIN FUNCTION:
    p            = integer in [2,S], remaining periods in life
    b_guess      = (p-1,) vector, initial guess for lifetime savings
                   decisions
    eullf_objs   = length 7 tuple, (beta, sigma, beg_wealth, nvec,
                   rpath, wpath, EulDiff)
    bpath        = (p-1,) vector, optimal remaining lifetime savings
                   decisions
    cpath        = (p,) vector, optimal remaining lifetime
                   consumption decisions
    c_cnstr      = (p,) boolean vector, =True if c_p <= 0,
    b_err_params = length 2 tuple, (beta, sigma)
    b_err_vec    = (p-1,) vector, Euler errors associated with
                   optimal savings decisions

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: bpath, cpath, b_err_vec
    --------------------------------------------------------------------
    '''
    S, beta, sigma, TPI_tol, EulDiff = params
    p = int(S - beg_age + 1)
    if beg_age == 1 and beg_wealth != 0:
        sys.exit("Beginning wealth is nonzero for age s=1.")
    if len(rpath) != p:
        sys.exit("Beginning age and length of rpath do not match.")
    if len(wpath) != p:
        sys.exit("Beginning age and length of wpath do not match.")
    if len(nvec) != p:
        sys.exit("Beginning age and length of nvec do not match.")
    b_guess = 1.01 * b_init
    eullf_objs = (beta, sigma, beg_wealth, nvec, rpath, wpath, EulDiff)
    results_bp = opt.root(LfEulerSys, b_guess, args=(eullf_objs),
                          tol=TPI_tol)
    bpath = results_bp.x
    c_args = (nvec, rpath, wpath)
    cpath = hh.get_cons(bpath, beg_wealth, c_args)
    b_err_vec = results_bp.fun

    return bpath, cpath, b_err_vec
예제 #10
0
파일: SS.py 프로젝트: rickecon/OG-JRC
def inner_loop(r, w, Y, x, params):
    '''
    --------------------------------------------------------------------
    Given values for r and w, solve for equilibrium errors from the two
    first order conditions of the firm
    --------------------------------------------------------------------
    INPUTS:
    r      = scalar > 0, guess at steady-state interest rate
    w      = scalar > 0, guess at steady-state wage
    Y      = scalar > 0, guess steady-state output
    x      = scalar > 0, guess as steady-state transfers per household
    params = length 16 tuple, (c1_init, S, beta, sigma, l_tilde, b_ellip,
                               upsilon, chi_n_vec, A, alpha, delta, tax_params,
                               fiscal_params, diff, hh_fsolve, SS_tol)


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

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


    FILES CREATED BY THIS FUNCTION: None

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

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

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

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


    return B, K, L, Y_new, debt, cvec, nvec, b_s_vec, b_splus1_vec, \
                b_Sp1, x_new, r_new, w_new
예제 #11
0
def get_cnbpath(rpath, wpath, args):
    '''
    --------------------------------------------------------------------
    Given time paths for interest rates and wages, this function
    generates matrices for the time path of the distribution of
    individual consumption, labor supply, savings, the corresponding
    Euler errors for the labor supply decision and the savings decision,
    and the residual error of end-of-life savings associated with
    solving each lifetime decision.
    --------------------------------------------------------------------
    INPUTS:
    rpath = (T2+S-1,) vector, equilibrium time path of interest rate
    wpath = (T2+S-1,) vector, equilibrium time path of the real wage
    args  = length 13 tuple, (J, S, T2, emat, beta, sigma, l_tilde,
            b_ellip, upsilon, chi_n_vec, bmat1, n_ss, In_Tol)

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        hh.c1_bSp1err()
        hh.get_cnb_vecs()
        hh.get_n_errors()
        hh.get_b_errors()

    OBJECTS CREATED WITHIN FUNCTION:
    J             =
    S             = integer in [3,80], number of periods an individual
                    lives
    T2            = integer > S, number of periods until steady state
    emat          = (S, J) matrix
    beta          = scalar in (0,1), discount factor
    sigma         = scalar > 0, coefficient of relative risk aversion
    l_tilde       = scalar > 0, time endowment for each agent each
                    period
    b_ellip       = scalar > 0, fitted value of b for elliptical
                    disutility of labor
    upsilon       = scalar > 1, fitted value of upsilon for elliptical
                    disutility of labor
    chi_n_vec     = (S,) vector, values for chi^n_s
    bmat1         = (S, J) matrix, initial period household savings
                    distribution
    In_Tol        = scalar > 0, tolerance level for TPI inner-loop root
                    finders
    cpath         = (S, J, T2+S-1) array, time path of the distribution
                    of household consumption
    npath         = (S, J, T2+S-1) array, time path of the distribution
                    of household labor supply
    bpath         = (S, J, T2+S-1) array, time path of the distribution
                    of household savings
    n_err_path    = (S, J, T2+S-1) matrix, time path of household labor
                    supply Euler errors
    b_err_path    = (S, J, T2+S-1) matrix, time path of household
                    savings Euler errors
    per_rmn       = integer in [1, S-1], index representing number of
                    periods remaining in a lifetime, used to solve
                    incomplete lifetimes
    j_ind         = integer in [0, J-1], index representing ability type
    n_S1_init     = scalar in (0, l_tilde), initial guess for n_{j,S,1}
    nS1_args      = length 10 tuple, args to pass in to
                    hh.get_n_errors()
    results_nS1   = results object, results from
                    opt.root(hh.get_n_errors,...)
    DiagMaskb     = (per_rmn-1, per_rmn-1) boolean identity matrix
    DiagMaskn     = (per_rmn, per_rmn) boolean identity matrix
    b_sp1_init    = (per_rmn-1,) vector, initial guess for remaining
                    lifetime savings for household j in period t
    n_s_init      = (per_rmn,) vector, initial guess for remaining
                    lifetime labor supply for household j in period t
    bn_init       = (2*per_rmn - 1,) vector, initial guess for remaining
                    lifetime savings and labor supply for household j in
                    period t
    bn_args       = length 11 tuple, arguments to pass into
                    opt.root(hh.bn_errors,...)
    results_bn    = results object, results from opt.root(hh.bn_errors,)
    bvec          = (per_rmn-1,) vector, optimal savings given rpath and
                    wpath
    nvec          = (per_rmn,) vector, optimal labor supply given rpath
                    and wpath
    b_errors      = (per_rmn-1,) vector, savings Euler errors
    n_errors      = (per_rmn,) vector, labor supply Euler errors
    b_s_vec       = (per_rmn,) vector, remaining lifetime beginning of
                    period wealth for household j in period t
    b_sp1_vec     = (per_rmn,) vector, remaining lifetime savings for
                    household j in period t
    cvec          = (per_rmn,) vector, remaining lifetime consumption
                    for household j in period t
    t             = integer in [0, T2-1], index of time period

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: cpath, npath, bpath, n_err_path, b_err_path, bSp1_err_path
    --------------------------------------------------------------------
    '''
    (J, S, T2, lambdas, emat, zeta_mat, omega_path, mort_rates, chi_n_vec,
     chi_b_vec, beta, sigma, l_tilde, b_ellip, upsilon, g_y, bmat1, n_ss,
     In_Tol) = args
    cpath = np.zeros((S, J, T2 + S - 1))
    npath = np.zeros((S, J, T2 + S - 1))
    bpath = np.zeros((S, J, T2 + S - 1))
    bpath[:, :, 0] = bmat1
    n_err_path = np.zeros((S, J, T2 + S - 1))
    b_err_path = np.zeros((S, J, T2 + S - 1))

    # Solve the incomplete remaining lifetime decisions of agents alive
    # in period t=1 but not born in period t=1
    for per_rmn in range(1, S):

        for j_ind in range(J):

            if per_rmn == 1:
                # per_rmn=1 individual only has an s=S labor supply
                # decision n_S
                n_S1_init = n_ss[-1, j_ind]
                nS1_args = (wpath[0], emat[-1, j_ind], sigma, l_tilde,
                            chi_n_vec[-1], b_ellip, upsilon, rpath[0],
                            bmat1[-1, j_ind], 0.0)
                results_nS1 = opt.root(hh.get_n_errors,
                                       n_S1_init,
                                       args=(nS1_args),
                                       method='lm',
                                       tol=In_Tol)
                n_S1 = results_nS1.x
                npath[-1, j_ind, 0] = n_S1
                n_err_path[-1, j_ind, 0] = results_nS1.fun
                cpath[-1, j_ind, 0] = \
                    hh.get_cons(rpath[0], wpath[0], emat[-1, j_ind],
                                bmat1[-1, j_ind], 0.0, n_S1)

            else:
                # 1<p<S chooses b_{s+1} and n_s and has incomplete lives
                DiagMaskb = np.eye(per_rmn - 1, dtype=bool)
                DiagMaskn = np.eye(per_rmn, dtype=bool)
                b_sp1_init = np.diag(bpath[S - per_rmn + 1:,
                                           j_ind, :per_rmn - 1])
                n_s_init = \
                    np.hstack((n_ss[S - per_rmn, j_ind],
                               np.diag(npath[S - per_rmn + 1:, j_ind,
                                             :per_rmn - 1])))
                bn_init = np.hstack((b_sp1_init, n_s_init))
                bn_args = (rpath[:per_rmn], wpath[:per_rmn], bmat1[-per_rmn,
                                                                   j_ind],
                           emat[-per_rmn:, j_ind], per_rmn, beta, sigma,
                           l_tilde, chi_n_vec[-per_rmn:], b_ellip, upsilon)
                results_bn = opt.root(hh.bn_errors,
                                      bn_init,
                                      args=(bn_args),
                                      tol=In_Tol)
                bvec = results_bn.x[:per_rmn - 1]
                nvec = results_bn.x[per_rmn - 1:]
                b_errors = results_bn.fun[:per_rmn - 1]
                n_errors = results_bn.fun[per_rmn - 1:]
                b_s_vec = np.append(bmat1[-per_rmn, j_ind], bvec)
                b_sp1_vec = np.append(bvec, 0.0)
                cvec = hh.get_cons(rpath[:per_rmn], wpath[:per_rmn],
                                   emat[-per_rmn:,
                                        j_ind], b_s_vec, b_sp1_vec, nvec)
                npath[S - per_rmn:, j_ind, :per_rmn] = \
                    DiagMaskn * nvec + npath[S - per_rmn:, j_ind,
                                             :per_rmn]
                bpath[S - per_rmn + 1:, j_ind, 1:per_rmn] = \
                    (DiagMaskb * bvec + bpath[S - per_rmn + 1:, j_ind,
                                              1:per_rmn])
                cpath[S - per_rmn:, j_ind, :per_rmn] = \
                    DiagMaskn * cvec + cpath[S - per_rmn:, j_ind,
                                             :per_rmn]
                n_err_path[S - per_rmn:, j_ind, :per_rmn] = \
                    (DiagMaskn * n_errors + n_err_path[S - per_rmn:,
                                                       j_ind, :per_rmn])
                b_err_path[S - per_rmn + 1:, j_ind, 1:per_rmn] = \
                    (DiagMaskb * b_errors + b_err_path[S - per_rmn + 1:,
                                                       j_ind,
                                                       1:per_rmn])

    # Solve the complete remaining lifetime decisions of agents born
    # between period t=1 and t=T2
    for t in range(T2):

        for j_ind in range(J):

            DiagMaskb = np.eye(S - 1, dtype=bool)
            DiagMaskn = np.eye(S, dtype=bool)
            b_sp1_init = np.diag(bpath[1:, j_ind, t:t + S - 1])
            if t == 0:
                n_s_init = np.hstack(
                    (n_ss[0, j_ind], np.diag(npath[1:, j_ind, t:t + S - 1])))
            else:
                n_s_init = np.diag(npath[:, j_ind, t - 1:t + S - 1])
            bn_init = np.hstack((b_sp1_init, n_s_init))
            bn_args = (rpath[t:t + S], wpath[t:t + S], 0.0, emat[:, j_ind], S,
                       beta, sigma, l_tilde, chi_n_vec, b_ellip, upsilon)
            results_bn = opt.root(hh.bn_errors,
                                  bn_init,
                                  args=(bn_args),
                                  tol=In_Tol)
            bvec = results_bn.x[:S - 1]
            nvec = results_bn.x[S - 1:]
            b_errors = results_bn.fun[:S - 1]
            n_errors = results_bn.fun[S - 1:]
            b_s_vec = np.append(0.0, bvec)
            b_sp1_vec = np.append(bvec, 0.0)
            cvec = hh.get_cons(rpath[t:t + S], wpath[t:t + S], emat[:, j_ind],
                               b_s_vec, b_sp1_vec, nvec)
            npath[:, j_ind,
                  t:t + S] = (DiagMaskn * nvec + npath[:, j_ind, t:t + S])
            bpath[1:, j_ind, t + 1:t + S] = \
                DiagMaskb * bvec + bpath[1:, j_ind, t + 1:t + S]
            cpath[:, j_ind,
                  t:t + S] = (DiagMaskn * cvec + cpath[:, j_ind, t:t + S])
            n_err_path[:, j_ind, t:t + S] = \
                DiagMaskn * n_errors + n_err_path[:, j_ind, t:t + S]
            b_err_path[1:, j_ind, t + 1:t + S] = \
                DiagMaskb * b_errors + b_err_path[1:, j_ind,
                                                  t + 1:t + S]

    return cpath, npath, bpath, n_err_path, b_err_path
예제 #12
0
파일: SS.py 프로젝트: rickecon/OG-JRC
def get_SS(init_vals, args, graphs=False):
    '''
    --------------------------------------------------------------------
    Solve for the steady-state solution of the S-period-lived agent OG
    model with endogenous labor supply and a small open economy.
    --------------------------------------------------------------------
    INPUTS:
    init_vals = length 5 tuple,
                (Kss_init, Lss_init, rss_init, wss_init,c1_init)
    args      = length 14 tuple, (S, beta, sigma, l_tilde, b_ellip,
                upsilon, chi_n_vec, A, alpha, delta, SS_tol, EulDiff,
                hh_fsolve, KL_outer)
    graphs    = boolean, =True if output steady-state graphs

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

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

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

    RETURNS: ss_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    c1_init = init_vals
    (S, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec, A, alpha, delta,
     r_star, SS_tol, EulDiff, hh_fsolve) = args
    c1_options = {'maxiter': 500}
    cnb_args = (0.0, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec,
                EulDiff)
    w_params = (A, alpha, delta)
    K_params = (A, alpha, delta)
    r_ss = r_star
    w_ss = firms.get_w(r_ss, w_params)

    if hh_fsolve:
        b_init = np.ones((S - 1, 1)) * 0.05
        n_init = np.ones((S, 1)) * 0.4
        guesses = np.append(b_init, n_init)
        bn_params = (r_ss, w_ss, S, beta, sigma, l_tilde, b_ellip, upsilon,
                     chi_n_vec, EulDiff)
        [solutions, infodict, ier, message] = \
            opt.fsolve(hh.bn_solve, guesses, args=bn_params,
                       xtol=SS_tol, full_output=True)
        euler_errors = infodict['fvec']
        print('Max Euler errors: ', np.absolute(euler_errors).max())
        b_splus1_ss = np.append(solutions[:S - 1], 0.0)
        n_ss = solutions[S - 1:]
        b_Sp1_ss = 0.0
        b_s_ss = np.append(0.0, b_splus1_ss[:-1])
        c_ss = hh.get_cons(r_ss, w_ss, b_s_ss, b_splus1_ss, n_ss)
    else:
        rpath = r_ss * np.ones(S)
        wpath = w_ss * np.ones(S)
        c1_args = (0.0, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec,
                   rpath, wpath, EulDiff)
        c1_options = {'maxiter': 500}
        results_c1 = \
            opt.root(hh.c1_bSp1err, c1_new, args=(c1_args),
                     method='lm', tol=SS_tol, options=(c1_options))
        c1_ss = results_c1.x
        cnb_args = (0.0, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec,
                    EulDiff)
        c_ss, n_ss, b_s_ss, b_Sp1_ss = hh.get_cnb_vecs(c1_ss, rpath, wpath,
                                                       cnb_args)
        b_splus1_ss = np.append(b_s_ss[1:], b_Sp1_ss)

    L_ss = aggr.get_L_s(n_ss)
    K_s_ss, K_cnstr = aggr.get_K_s(b_s_ss)
    K_d_ss = firms.get_K_d(r_ss, L_ss, K_params)
    Y_params = (A, alpha)
    Y_ss = aggr.get_Y(Y_params, K_d_ss, L_ss)
    C_ss = aggr.get_C(c_ss)
    n_err_args = (w_ss, c_ss, sigma, l_tilde, chi_n_vec, b_ellip, upsilon,
                  EulDiff)
    n_err_ss = hh.get_n_errors(n_ss, n_err_args)
    b_err_params = (beta, sigma)
    b_err_ss = hh.get_b_errors(b_err_params, r_ss, c_ss, EulDiff)
    NX_ss = Y_ss - C_ss - delta * K_s_ss
    RCerr_ss = Y_ss - C_ss - delta * K_s_ss - NX_ss

    ss_time = time.clock() - start_time

    ss_output = {
        'n_ss': n_ss,
        'b_s_ss': b_s_ss,
        'b_splus1_ss': b_splus1_ss,
        'c_ss': c_ss,
        'b_Sp1_ss': b_Sp1_ss,
        'w_ss': w_ss,
        'r_ss': r_ss,
        'K_s_ss': K_s_ss,
        'K_d_ss': K_d_ss,
        'L_ss': L_ss,
        'Y_ss': Y_ss,
        'C_ss': C_ss,
        'n_err_ss': n_err_ss,
        'b_err_ss': b_err_ss,
        'RCerr_ss': RCerr_ss,
        'ss_time': ss_time
    }
    print('n_ss is: ', n_ss)
    print('b_splus1_ss is: ', b_splus1_ss)
    print('K_s_ss=', K_s_ss, 'K_d_ss=', K_d_ss, ', L_ss=', L_ss)
    print('r_ss=', r_ss, ', w_ss=', w_ss)
    print('Maximum abs. labor supply Euler error is: ',
          np.absolute(n_err_ss).max())
    print('Maximum abs. savings Euler error is: ', np.absolute(b_err_ss).max())
    print('Resource constraint error is: ', RCerr_ss)
    print('Net Exports = ', NX_ss)
    print('Output and consumption: ', Y_ss, C_ss)
    print('Steady-state residual savings b_Sp1 is: ', b_Sp1_ss)

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

    if graphs:
        '''
        ----------------------------------------------------------------
        cur_path    = string, path name of current directory
        output_fldr = string, folder in current path to save files
        output_dir  = string, total path of images folder
        output_path = string, path of file name of figure to be saved
        age_pers    = (S,) vector, ages from 1 to S
        ----------------------------------------------------------------
        '''
        # Create directory if images directory does not already exist
        cur_path = os.path.split(os.path.abspath(__file__))[0]
        output_fldr = 'images'
        output_dir = os.path.join(cur_path, output_fldr)
        if not os.access(output_dir, os.F_OK):
            os.makedirs(output_dir)

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

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

    return ss_output
예제 #13
0
파일: SS.py 프로젝트: snowdj/WB-India
def feasible(bvec, params):
    '''
    --------------------------------------------------------------------
    Check whether a vector of steady-state savings is feasible in that
    it satisfies the nonnegativity constraints on consumption in every
    period c_s > 0 and that the aggregate capital stock is strictly
    positive K > 0
    --------------------------------------------------------------------
    INPUTS:
    bvec   = (S-1,) vector, household savings b_{s+1}
    params = length 4 tuple, (nvec, A, alpha, delta)

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

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

    FILES CREATED BY THIS FUNCTION: None

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

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

    return c_cstr, K_cstr, b_cstr
예제 #14
0
파일: SS.py 프로젝트: snowdj/WB-India
def get_SS(bss_guess, args, graphs=False):
    '''
    --------------------------------------------------------------------
    Solve for the steady-state solution of the S-period-lived agent OG
    model with exogenous labor supply using one root finder in bvec
    --------------------------------------------------------------------
    INPUTS:
    bss_guess = (S-1,) vector, initial guess for b_ss
    args      = length 8 tuple,
                (nvec, beta, sigma, A, alpha, delta, SS_tol, SS_EulDiff)
    graphs    = boolean, =True if output steady-state graphs

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

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

    FILES CREATED BY THIS FUNCTION: None

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

    ss_time = time.clock() - start_time

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

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

    if graphs:
        get_ss_graphs(c_ss, b_ss)

    return ss_output
예제 #15
0
def get_cnbpath(rpath, wpath, BQpath, args):
    '''
    --------------------------------------------------------------------
    Given time paths for interest rates and wages, this function
    generates matrices for the time path of the distribution of
    individual consumption, labor supply, savings, the corresponding
    Euler errors for the labor supply decision and the savings decision,
    and the residual error of end-of-life savings associated with
    solving each lifetime decision.
    --------------------------------------------------------------------
    INPUTS:
    rpath = (T2+S-1,) vector, equilibrium time path of interest rate
    wpath = (T2+S-1,) vector, equilibrium time path of the real wage
    args  = length 13 tuple, (J, S, T2, emat, beta, sigma, l_tilde,
            b_ellip, upsilon, chi_n_vec, bmat1, n_ss, In_Tol)

    OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION:
        hh.c1_bSp1err()
        hh.get_cnb_vecs()
        hh.get_n_errors()
        hh.get_b_errors()

    OBJECTS CREATED WITHIN FUNCTION:
    J             =
    S             = integer in [3,80], number of periods an individual
                    lives
    T2            = integer > S, number of periods until steady state
    emat          = (S, J) matrix
    beta          = scalar in (0,1), discount factor
    sigma         = scalar > 0, coefficient of relative risk aversion
    l_tilde       = scalar > 0, time endowment for each agent each
                    period
    b_ellip       = scalar > 0, fitted value of b for elliptical
                    disutility of labor
    upsilon       = scalar > 1, fitted value of upsilon for elliptical
                    disutility of labor
    chi_n_vec     = (S,) vector, values for chi^n_s
    bmat1         = (S, J) matrix, initial period household savings
                    distribution
    In_Tol        = scalar > 0, tolerance level for TPI inner-loop root
                    finders
    cpath         = (S, J, T2+S-1) array, time path of the distribution
                    of household consumption
    npath         = (S, J, T2+S-1) array, time path of the distribution
                    of household labor supply
    bpath         = (S, J, T2+S-1) array, time path of the distribution
                    of household savings
    n_err_path    = (S, J, T2+S-1) matrix, time path of household labor
                    supply Euler errors
    b_err_path    = (S, J, T2+S-1) matrix, time path of household
                    savings Euler errors
    per_rmn       = integer in [1, S-1], index representing number of
                    periods remaining in a lifetime, used to solve
                    incomplete lifetimes
    j_ind         = integer in [0, J-1], index representing ability type
    n_S1_init     = scalar in (0, l_tilde), initial guess for n_{j,S,1}
    nS1_args      = length 10 tuple, args to pass in to
                    hh.get_n_errors()
    results_nS1   = results object, results from
                    opt.root(hh.get_n_errors,...)
    DiagMaskb     = (per_rmn-1, per_rmn-1) boolean identity matrix
    DiagMaskn     = (per_rmn, per_rmn) boolean identity matrix
    b_sp1_init    = (per_rmn-1,) vector, initial guess for remaining
                    lifetime savings for household j in period t
    n_s_init      = (per_rmn,) vector, initial guess for remaining
                    lifetime labor supply for household j in period t
    bn_init       = (2*per_rmn - 1,) vector, initial guess for remaining
                    lifetime savings and labor supply for household j in
                    period t
    bn_args       = length 11 tuple, arguments to pass into
                    opt.root(hh.bn_errors,...)
    results_bn    = results object, results from opt.root(hh.bn_errors,)
    bvec          = (per_rmn-1,) vector, optimal savings given rpath and
                    wpath
    nvec          = (per_rmn,) vector, optimal labor supply given rpath
                    and wpath
    b_errors      = (per_rmn-1,) vector, savings Euler errors
    n_errors      = (per_rmn,) vector, labor supply Euler errors
    b_s_vec       = (per_rmn,) vector, remaining lifetime beginning of
                    period wealth for household j in period t
    b_sp1_vec     = (per_rmn,) vector, remaining lifetime savings for
                    household j in period t
    cvec          = (per_rmn,) vector, remaining lifetime consumption
                    for household j in period t
    t             = integer in [0, T2-1], index of time period

    FILES CREATED BY THIS FUNCTION: None

    RETURNS: cpath, npath, bpath, n_err_path, b_err_path, bSp1_err_path
    --------------------------------------------------------------------
    '''
    (J, S, T2, lambdas, emat, zeta_mat, omega_path, mort_rates,
        chi_n_vec, chi_b_vec, beta, sigma, l_tilde, b_ellip, upsilon,
        g_y, bmat1, n_ss, In_Tol) = args
    cpath = np.zeros((S, J, T2 + S - 1))
    npath = np.zeros((S, J, T2 + S - 1))
    bpath = np.zeros((S, J, T2 + S))
    bpath[:, :, 0] = bmat1
    n_err_path = np.zeros((S, J, T2 + S - 1))
    b_err_path = np.zeros((S, J, T2 + S))

    # Solve the incomplete remaining lifetime decisions of agents alive
    # in period t=1 but not born in period t=1
    for per_rmn in range(1, S):

        for j_ind in range(J):

            if per_rmn == 1:
                # per_rmn=1 individual only has an s=S labor supply
                # decision n_S
                bn_S1_init = np.array([bmat1[-1, j_ind],
                                       n_ss[-1, j_ind]])
                bnS1_args = \
                    (rpath[0], wpath[0], BQpath[0], bmat1[-2, j_ind],
                     lambdas[j_ind], emat[-1, j_ind],
                     zeta_mat[-1, j_ind], omega_path[0, -1],
                     mort_rates[-1], per_rmn, beta, sigma, l_tilde,
                     chi_n_vec[-1], chi_b_vec[j_ind], b_ellip, upsilon,
                     g_y)
                results_bnS1 = opt.root(hh.bn_errors, bn_S1_init,
                                        args=(bnS1_args), method='lm',
                                        tol=In_Tol)
                b_S1, n_S1 = results_bnS1.x
                npath[-1, j_ind, 0] = n_S1
                bpath[-1, j_ind, 1] = b_S1
                b_err_path[-1, j_ind, 1], n_err_path[-1, j_ind, 0] = \
                    results_bnS1.fun
                c_args = (emat[-1, j_ind], zeta_mat[-1, j_ind],
                          lambdas[j_ind], omega_path[0, -1], g_y)
                cpath[-1, j_ind, 0] = \
                    hh.get_cons(rpath[0], wpath[0], bmat1[-2, j_ind],
                                b_S1, n_S1, BQpath[0], c_args)
                # print('per_rmn=', per_rmn, 'j=', j_ind,
                #       ', Max Err=', "%10.4e" %
                #       np.absolute(results_bnS1.fun).max())
                # if np.absolute(results_bnS1.fun).max() > 1e-10:
                #     print(results_bnS1.success)
            else:
                # 1<p<S chooses b_{s+1} and n_s and has incomplete lives
                DiagMaskbn = np.eye(per_rmn, dtype=bool)
                b_sp1_init = np.diag(bpath[-per_rmn:, j_ind, :per_rmn])
                n_s_init = \
                    np.hstack((n_ss[S - per_rmn, j_ind],
                               np.diag(npath[S - per_rmn + 1:, j_ind,
                                             :per_rmn - 1])))
                bn_init = np.hstack((b_sp1_init, n_s_init))
                bn_args = \
                    (rpath[:per_rmn], wpath[:per_rmn], BQpath[:per_rmn],
                     bmat1[-(per_rmn + 1), j_ind], lambdas[j_ind],
                     emat[-per_rmn:, j_ind], zeta_mat[-per_rmn, j_ind],
                     np.diag(omega_path[:per_rmn, -per_rmn:]),
                     mort_rates[-per_rmn:], per_rmn, beta, sigma,
                     l_tilde, chi_n_vec[-per_rmn:], chi_b_vec[j_ind],
                     b_ellip, upsilon, g_y)
                results_bn = opt.root(hh.bn_errors, bn_init,
                                      args=(bn_args), method='lm',
                                      tol=In_Tol)
                bvec = results_bn.x[:per_rmn]
                nvec = results_bn.x[per_rmn:]
                b_errors = results_bn.fun[:per_rmn]
                n_errors = results_bn.fun[per_rmn:]
                b_s_vec = np.append(bmat1[-(per_rmn + 1), j_ind],
                                    bvec[:-1])
                b_sp1_vec = bvec.copy()
                c_args = (emat[-per_rmn:, j_ind],
                          zeta_mat[-per_rmn:, j_ind], lambdas[j_ind],
                          np.diag(omega_path[:per_rmn, -per_rmn:]), g_y)
                cvec = hh.get_cons(rpath[:per_rmn], wpath[:per_rmn],
                                   b_s_vec, b_sp1_vec, nvec,
                                   BQpath[:per_rmn], c_args)
                npath[-per_rmn:, j_ind, :per_rmn] = \
                    DiagMaskbn * nvec + npath[-per_rmn:, j_ind,
                                              :per_rmn]
                bpath[-per_rmn:, j_ind, 1:per_rmn + 1] = \
                    (DiagMaskbn * bvec + bpath[-per_rmn:, j_ind,
                                               1:per_rmn + 1])
                cpath[-per_rmn:, j_ind, :per_rmn] = \
                    DiagMaskbn * cvec + cpath[-per_rmn:, j_ind,
                                              :per_rmn]
                n_err_path[-per_rmn:, j_ind, :per_rmn] = \
                    (DiagMaskbn * n_errors +
                     n_err_path[-per_rmn:, j_ind, :per_rmn])
                b_err_path[-per_rmn:, j_ind, 1:per_rmn + 1] = \
                    (DiagMaskbn * b_errors +
                     b_err_path[-per_rmn:, j_ind, 1:per_rmn + 1])
                # print('per_rmn=', per_rmn, 'j=', j_ind,
                #       ', Max Err=', "%10.4e" %
                #       results_bn.fun.max())
                # if np.absolute(results_bn.fun).max() > 1e-10:
                #     print(results_bn.success)

    # Solve the complete remaining lifetime decisions of agents born
    # between period t=1 and t=T2
    DiagMaskbn = np.eye(S, dtype=bool)
    # print('bpath, j_ind==0', bpath[:5, 0, :5])
    # print('bpath, j_ind==2', bpath[:5, 2, :5])
    # print('bpath, j_ind==4', bpath[:5, 4, :5])
    # print('npath, j_ind==0', npath[:5, 0, :5])
    # print('npath, j_ind==2', npath[:5, 2, :5])
    # print('npath, j_ind==4', npath[:5, 4, :5])
    # print('n_ss[0, 2], j_ind=2', n_ss[0, 2])

    for t in range(T2):

        for j_ind in range(J):

            if t == 0:
                # In period t=0, make initial guess vectors a little
                # more feasible by decreasing bvec by 10% and increasing
                # nvec by 15%
                b_sp1_init = 0.9 * np.diag(bpath[:, j_ind, t:t + S])
                n1_init = np.diag(npath[1:, j_ind, t:t + S - 1])[0]
                n2_init = np.diag(npath[1:, j_ind, t:t + S - 1])[1]
                n_s_init = 1.1 * np.append(2 * n1_init - n2_init,
                                           np.diag(npath[1:, j_ind,
                                                         t:t + S - 1]))
                # if j_ind == 2:
                #     print('bpath, j_ind=1', np.diag(bpath[:, 1, :S]))
                #     print('npath, j_ind=1', np.diag(bpath[:, 1, 1:S + 1]))
                #     print('t=', t, ', j=', j_ind, 'n_s_init=', n_s_init)
                #     print('t=', t, ', j=', j_ind, 'b_sp1_init=', b_sp1_init)
                # n_s_init = np.append(n_ss[0, j_ind],
                #                      np.diag(npath[1:, j_ind,
                #                                    t:t + S - 1]))
            else:
                b_sp1_init = np.diag(bpath[:, j_ind, t:t + S])
                n_s_init = np.diag(npath[:, j_ind, t - 1:t + S - 1])
            bn_init = np.hstack((b_sp1_init, n_s_init))
            bn_args = (rpath[t:t + S], wpath[t:t + S], BQpath[t:t + S],
                       0.0, lambdas[j_ind], emat[:, j_ind],
                       zeta_mat[:, j_ind],
                       np.diag(omega_path[t:t + S, :]), mort_rates, S,
                       beta, sigma, l_tilde, chi_n_vec,
                       chi_b_vec[j_ind], b_ellip, upsilon, g_y)

            results_bn = opt.root(hh.bn_errors, bn_init, args=(bn_args),
                                  method='lm', tol=In_Tol)
            bvec = results_bn.x[:S]
            nvec = results_bn.x[S:]
            b_errors = results_bn.fun[:S]
            n_errors = results_bn.fun[S:]
            b_s_vec = np.append(0.0, bvec[:-1])
            b_sp1_vec = bvec.copy()
            c_args = (emat[:, j_ind], zeta_mat[:, j_ind],
                      lambdas[j_ind], np.diag(omega_path[t:t + S, :]),
                      g_y)
            cvec = hh.get_cons(rpath[t:t + S], wpath[t:t + S], b_s_vec,
                               b_sp1_vec, nvec, BQpath[t:t + S], c_args)
            # if t == 0 and j_ind == 2:
            #     print('bvec=', bvec)
            #     print('nvec=', nvec)
            #     print('cvec=', cvec)
            #     print('b_errors=', b_errors)
            #     print('n_errors=', n_errors)
            npath[:, j_ind, t:t + S] = (DiagMaskbn * nvec +
                                        npath[:, j_ind, t:t + S])
            bpath[:, j_ind, t + 1:t + S + 1] = \
                DiagMaskbn * bvec + bpath[:, j_ind, t + 1:t + S + 1]
            cpath[:, j_ind, t:t + S] = (DiagMaskbn * cvec +
                                        cpath[:, j_ind, t:t + S])
            n_err_path[:, j_ind, t:t + S] = \
                DiagMaskbn * n_errors + n_err_path[:, j_ind, t:t + S]
            b_err_path[:, j_ind, t + 1:t + S + 1] = \
                (DiagMaskbn * b_errors +
                 b_err_path[:, j_ind, t + 1:t + S + 1])
            # print('t=', t, 'j=', j_ind, ', Max Err=', "%10.4e" %
            #       results_bn.fun.max())
            # if np.absolute(results_bn.fun).max() > 1e-10:
            #     print(results_bn.success)
            #     print('b=', bvec, ', n=', nvec, ', b_err=', b_errors,
            #           ', n_err=', n_errors, ', c=', cvec)

    return cpath, npath, bpath, n_err_path, b_err_path
예제 #16
0
def get_SS(r_init, args, graphs=False):
    '''
    --------------------------------------------------------------------
    Solve for the steady-state solution of the S-period-lived agent OG
    model with endogenous labor supply using the bisection method in K
    and L for the outer loop
    --------------------------------------------------------------------
    INPUTS:
    init_vals = length 2 tuple, (rss_init, c1_init)
    args      = length 15 tuple, (S, beta, sigma, l_tilde, b_ellip,
                upsilon, chi_n_vec, A, alpha, delta, Bsct_Tol, Eul_Tol,
                EulDiff, xi, maxiter)
    graphs    = boolean, =True if output steady-state graphs

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

    OBJECTS CREATED WITHIN FUNCTION:
    start_time = scalar > 0, clock time at beginning of program
    r_init     = scalar > -delta, initial guess for steady-state
                 interest rate
    c1_init    = scalar > 0, initial guess for first period consumpt'n
    S          = integer in [3, 80], number of periods an individual
                 lives
    beta       = scalar in (0,1), discount factor for each model per
    sigma      = scalar > 0, coefficient of relative risk aversion
    l_tilde    = scalar > 0, time endowment for each agent each period
    b_ellip    = scalar > 0, fitted value of b for elliptical disutility
                 of labor
    upsilon    = scalar > 1, fitted value of upsilon for elliptical
                 disutility of labor
    chi_n_vec  = (S,) vector, values for chi^n_s
    A          = scalar > 0, total factor productivity parameter in
                 firms' production function
    alpha      = scalar in (0,1), capital share of income
    delta      = scalar in [0,1], model-period depreciation rate of
                 capital
    Bsct_Tol   = scalar > 0, tolderance level for outer-loop bisection
                 method
    Eul_Tol    = scalar > 0, tolerance level for inner-loop root finder
    EulDiff    = Boolean, =True if want difference version of Euler
                 errors beta*(1+r)*u'(c2) - u'(c1), =False if want
                 ratio version [beta*(1+r)*u'(c2)]/[u'(c1)] - 1
    xi         = scalar in (0, 1], SS updating parameter in outer-loop
                 bisection method
    maxiter    = integer >= 1, maximum number of iterations in outer
                 loop bisection method
    iter_SS    = integer >= 0, index of iteration number
    dist       = scalar > 0, distance metric for current iteration
    rw_params  = length 3 tuple, (A, alpha, delta) args to pass into
                 firms.get_r() and firms.get_w()
    w_init     = scalar, initial value for wage
    inner_args = length 14 tuple, args to pass into inner_loop()
    K_new      = scalar > 0, updated K given r_init, w_init, and bvec
    L_new      = scalar > 0, updated L given r_init, w_init, and nvec
    cvec       = (S,) vector, updated values for lifetime consumption
    nvec       = (S,) vector, updated values for lifetime labor supply
    bvec       = (S,) vector, updated values for lifetime savings
                 (b1, b2,...bS)
    b_Sp1      = scalar, updated value for savings in last period,
                 should be arbitrarily close to zero
    r_new      = scalar > 0, updated interest rate given bvec and nvec
    w_new      = scalar > 0, updated wage given bvec and nvec
    n_errors   = (S,) vector, labor supply Euler errors given r_init
                 and w_init
    b_errors   = (S-1,) vector, savings Euler errors given r_init and
                 w_init
    all_errors = (2S,) vector, (n_errors, b_errors, b_Sp1)
    c_ss       = (S,) vector, steady-state lifetime consumption
    n_ss       = (S,) vector, steady-state lifetime labor supply
    b_ss       = (S,) vector, steady-state wealth enter period with
                 (b1, b2, ...bS)
    b_Sp1_ss   = scalar, steady-state savings for period after last
                 period of life. b_Sp1_ss approx. 0 in equilibrium
    n_err_ss   = (S,) vector, lifetime labor supply Euler errors
    b_err_ss   = (S-1) vector, lifetime savings Euler errors
    r_ss       = scalar > 0, steady-state interest rate
    w_ss       = scalar > 0, steady-state wage
    K_ss       = scalar > 0, steady-state aggregate capital stock
    L_ss       = scalar > 0, steady-state aggregate labor
    Y_params   = length 2 tuple, (A, alpha)
    Y_ss       = scalar > 0, steady-state aggregate output (GDP)
    C_ss       = scalar > 0, steady-state aggregate consumption
    RCerr_ss   = scalar, resource constraint error
    ss_time    = scalar, seconds elapsed for steady-state computation
    ss_output  = length 14 dict, steady-state objects {n_ss, b_ss,
                 c_ss, b_Sp1_ss, w_ss, r_ss, K_ss, L_ss, Y_ss, C_ss,
                 n_err_ss, b_err_ss, RCerr_ss, ss_time}

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

    RETURNS: ss_output
    --------------------------------------------------------------------
    '''
    start_time = time.clock()
    (S, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec, A, alpha, delta,
     SS_Tol, Eul_Tol, EulDiff, xi, maxiter) = args
    ns_guess = 0.4 * l_tilde * np.ones(S)
    bsp1_guess = 0.1 * np.ones(S - 1)
    nb_guess = np.append(ns_guess, bsp1_guess)
    r_args = (nb_guess, S, beta, sigma, l_tilde, b_ellip, upsilon, chi_n_vec,
              A, alpha, delta, Eul_Tol, EulDiff)
    results_r = opt.root(get_r_error, r_init, args=r_args, tol=SS_Tol)
    if results_r.success:
        print('SS SUCCESS: Steady-state outer loop for r converged.')
    r_ss = results_r.x
    r_err_ss = results_r.fun
    # Solve for steady-state w as a function of steady-state r
    w_args = (A, alpha, delta)
    w_ss = firms.get_w(r_ss, w_args)
    # Solve for steady-state n_s and b_s given steady-state r and w
    euler_args = (r_ss, w_ss, beta, sigma, l_tilde, chi_n_vec, b_ellip,
                  upsilon, EulDiff, S)
    results_nb = opt.root(euler_sys,
                          nb_guess,
                          args=euler_args,
                          method='lm',
                          tol=Eul_Tol)
    n_ss = results_nb.x[:S]
    bsp1_ss = results_nb.x[S:]
    n_err_ss = results_nb.fun[:S]
    b_err_ss = results_nb.fun[S:]
    b_ss = np.append(0.0, bsp1_ss)
    c_ss = hh.get_cons(r_ss, w_ss, b_ss, np.append(bsp1_ss, 0.0), n_ss)
    K_ss = bsp1_ss.sum()
    L_ss = n_ss.sum()
    I_ss = delta * K_ss
    Y_params = (A, alpha)
    Y_ss = aggr.get_Y(K_ss, L_ss, Y_params)
    C_ss = aggr.get_C(c_ss)
    RCerr_ss = Y_ss - C_ss - I_ss

    ss_time = time.clock() - start_time

    ss_output = {
        'c_ss': c_ss,
        'n_ss': n_ss,
        'b_ss': b_ss,
        'w_ss': w_ss,
        'r_ss': r_ss,
        'K_ss': K_ss,
        'L_ss': L_ss,
        'Y_ss': Y_ss,
        'I_ss': I_ss,
        'C_ss': C_ss,
        'n_err_ss': n_err_ss,
        'b_err_ss': b_err_ss,
        'r_err_ss': r_err_ss,
        'RCerr_ss': RCerr_ss,
        'ss_time': ss_time
    }
    print('n_ss is: ', n_ss)
    print('b_ss is: ', b_ss)
    print('K_ss=', K_ss, ', L_ss=', L_ss)
    print('Y_ss=', Y_ss, ', I_ss=', I_ss, ', C_ss=', C_ss)
    print('r_ss=', r_ss, ', w_ss=', w_ss)
    print('Maximum abs. labor supply Euler error is: ',
          np.absolute(n_err_ss).max())
    print('Maximum abs. savings Euler error is: ', np.absolute(b_err_ss).max())
    print('Interest rate FOC error is: ', r_err_ss)
    print('Resource constraint error is: ', RCerr_ss)

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

    if graphs:
        create_graphs(c_ss, b_ss, n_ss)

    return ss_output