Beispiel #1
0
def feasible(f_params, bvec_guess):
    b_cnstr=np.zeros(bvec_guess.shape,dtype=bool)
    nvec, A, alpha, delta, bq_distr, beta=f_params
    K,K_cnstr=utils.get_K(bvec_guess)
    L=utils.get_L(nvec)
    r=utils.get_r(K,L,(A, alpha, delta))
    w=utils.get_w(K,L,(A, alpha))
    c_vec,c_cnstr=utils.get_cvec_ss(r, w, bvec_guess, nvec, bq_distr)
    b_cnstr[0]=c_cnstr[0]
    b_cnstr[-1]=c_cnstr[-1]
    for k in range(1,len(c_cnstr)-1):
        b_cnstr[k]=c_cnstr[k]
        b_cnstr[k-1]=b_cnstr[k]
    return b_cnstr, c_cnstr, K_cnstr
Beispiel #2
0
def get_SS(params, bvec_guess, SS_graphs):
    start_time = time.clock()
    beta, sigma, nvec, L, A, alpha, delta, SS_tol, bq_distr, chi = params
    f_params = (nvec, A, alpha, delta, bq_distr, beta)
    b1_cnstr, c1_cnstr, K1_cnstr = feasible(f_params, bvec_guess)
    try:
        if b1_cnstr.max() or c1_cnstr.max() or K1_cnstr.max():
            raise cstError
            
        else:
            # errors=zero_func(bvec_guess,beta, sigma, nvec, L, A, alpha, delta)
            b = opt.root(utils.EulerSys_ss, bvec_guess, args=(beta, sigma, nvec, A, alpha, delta, bq_distr,chi), tol=SS_tol)
    except cstError:
        print ('Did not pass the feasible test')
    if b.success:
        b_ss = b.x
        # iterations=b.nit

    K_ss, K_cnstr = utils.get_K(b_ss)
    L=utils.get_L(nvec)
    w_ss = utils.get_w(K_ss,L, (A, alpha))
    r_ss = utils.get_r(K_ss, L, (A, alpha, delta))
    Y_ss = utils.get_Y(K_ss, L, (A, alpha))
    c_ss, c_cnstr = utils.get_cvec_ss(r_ss, w_ss, b_ss, nvec, bq_distr)
    EulErr_ss = utils.EulerSys_ss(b_ss, beta, sigma, nvec, A, alpha, delta, bq_distr, chi)
    C_ss=utils.get_C(c_ss)
    RCerr_ss = Y_ss - C_ss - delta * K_ss
    BQ_ss = b_ss[-1]

    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,
               'EulErr_ss': EulErr_ss, 'RCerr_ss': RCerr_ss, 'BQ_ss': BQ_ss, 'ss_time': ss_time}

    # print('\n Savings: \t\t\t {} \n Capital and Labor: \t\t {} \n Wage and Interest rate: \t {} \n Consumption: \t\t\t {}'.format(
    #         b_ss, np.array([K_ss, L]), np.array([w_ss, r_ss]), c_ss))
    #
    # print('Euler errors: ', EulErr_ss)
    # print('Resource Constraint error: ', RCerr_ss)
    # print('Time needed: ', ss_time)
    # print ('It took {iterations} iterations to get the solution.')
    if SS_graphs:
        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)

        age = np.arange(21, 101)
        fig, ax = plt.subplots()
        plt.plot(age, c_ss, marker='D', label='Consumption')
        plt.plot(age, b_ss, marker='D', label='Savings')
        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')
        plt.xlabel('Age')
        plt.ylabel('Consumption units')
        plt.legend()
        output_path = os.path.join(output_dir, 'ss_bc')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

    return ss_output
Beispiel #3
0
def get_TPI(b1vec, c1_guess, ss_params, params):
    t1=time.time()

    # r_guess: guess of interest rate path from period 1 to T1
    beta, sigma, S, l_ub, b, upsilon, chi, A, alpha, delta, tpi_max_iter, tpi_tol, xi_tpi, T1, T2 = params
    r_ss, w_ss, c_ss, n_ss, b_ss, K_ss, L_ss = ss_params
    abs_tpi = 1
    tpi_iter = 0
    rpath_old = np.zeros(T2 + S - 1)
    rpath_old[:T1] = get_path(r_ss, r_ss, T1, 'quadratic')
    rpath_old[T1:] = r_ss
    while abs_tpi > tpi_tol and tpi_iter < tpi_max_iter:
        tpi_iter += 1
        wpath_old = utils.get_w(rpath_old, (A, alpha, delta))
        bmat = np.zeros((S, T2 + S - 1))
        bmat[:, 0] = b1vec
        bmat[:, T2:] = numpy.matlib.repmat(b_ss, S - 1, 1).T
        nmat = np.zeros((S, T2 + S - 1))
        nmat[:, T2:] = numpy.matlib.repmat(n_ss, S - 1, 1).T
        cmat = np.zeros((S, T2 + S - 1))
        cmat[:, T2:] = numpy.matlib.repmat(c_ss, S-1, 1).T
        # Solve the incomplete remaining lifetime decisions of agents alive
        # in period t=1 but not born in period t=1
        for p in range(S): # p is remaining periods of life
            c1_args = (rpath_old[:p + 1], wpath_old[:p + 1], beta, sigma, l_ub, b, upsilon, p + 1, b1vec[S - p - 1], chi[S-p-1:])
            result_c1 = opt.root(utils.get_b_last, c1_guess, args = (c1_args))
            if result_c1.success:
                c1 = result_c1.x
            else:
                raise ValueError("failed to find an appropriate initial consumption")
            # Calculate aggregate supplies for capital and labor
            cvec = utils.get_c(c1, rpath_old[:p + 1], beta, sigma, p + 1)
            # print (np.shape(cvec))
            nvec = utils.get_n(cvec, sigma, l_ub, b, upsilon, wpath_old[:p + 1], p + 1,chi[S-p-1:])
            bvec = utils.get_b(cvec, nvec, rpath_old[:p + 1], wpath_old[:p + 1], p + 1, bs = b1vec[S - p - 1])[1:]
            # Insert the vector lifetime solutions diagonally (twist donut)
            DiagMaskbp = np.eye(p)
            bp_path = DiagMaskbp * bvec
            bmat[S - p:, 1:p + 1] += bp_path

            DiagMasknp = np.eye(p + 1)
            np_path = DiagMasknp * nvec
            nmat[S - p - 1:, :p + 1] += np_path

            DiagMasknp = np.eye(p + 1)
            c_path = DiagMasknp * cvec
            cmat[S - p - 1:, :p + 1] += c_path

        # Solve for complete lifetime decisions of agents born in periods
        # 1 to T2 and insert the vector lifetime solutions diagonally (twist
        # donut) into the cpath, bpath, and EulErrPath matrices
        for t in range(1, T2):
            c1_args = (rpath_old[t: S + t], wpath_old[t: S + t], beta, sigma, l_ub, b, upsilon, S, 0.0, chi)
            result_c1 = opt.root(utils.get_b_last, c1_guess, args = (c1_args))
            if result_c1.success:
                c1 = result_c1.x
            else:
                raise ValueError("failed to find an appropriate initial consumption")
            # Calculate aggregate supplies for capital and labor
            cvec = utils.get_c(c1, rpath_old[t : S + t], beta, sigma, S)
            nvec = utils.get_n(cvec, sigma, l_ub, b, upsilon, wpath_old[t: S + t], S, chi)
            bvec = utils.get_b(cvec, nvec, rpath_old[t: S + t], wpath_old[t: S + t], S)
            # print ("nvec,cvec,bvec: {}".format(np.shape(nvec),np.shape(cvec),np.shape(bvec)))
            DiagMaskbt = np.eye(S)
            bt_path = DiagMaskbt * bvec
            bmat[:, t: t + S] += bt_path

            DiagMasknp = np.eye(S)
            np_path = DiagMasknp * nvec
            nmat[:, t: t + S] += np_path

            DiagMasknp = np.eye(S)
            c_path = DiagMasknp * cvec
            cmat[:, t: t + S] += c_path

        bmat[:, T2:] = np.matlib.repmat(b_ss, S - 1, 1).T
        nmat[:, T2:] = np.matlib.repmat(n_ss, S - 1, 1).T
        cmat[:, T2:] = np.matlib.repmat(c_ss, S - 1, 1).T

        K = utils.get_K(bmat)[0]
        L = utils.get_L(nmat)[0]
        Y = utils.get_Y(K, L, (A, alpha))
        C = utils.get_C(cmat)

        rpath_new = utils.get_r(K, L, (A, alpha, delta))

        # Calculate the implied capital stock from conjecture and the error
        abs_tpi = ((rpath_old[:T2] - rpath_new[:T2]) ** 2).sum()
        # Update guess
        rpath_old[:T2] = xi_tpi * rpath_new[:T2] + (1 - xi_tpi) * rpath_old[:T2]

        print('iteration:', tpi_iter, ' squared distance: ', abs_tpi)
    b_last = abs(bmat[S - 1, :]).max()
    b_err = abs(utils.get_b_errors(cmat[:, :T2 + S - 1], rpath_old[:T2 + S - 1], beta, sigma)).max()
    n_err = abs(utils.get_n_errors(nmat[:, :T2 + S - 1], cmat[:, :T2 + S - 1], sigma, l_ub, b,
                                   upsilon, wpath_old[:T2 + S - 1], chi[0] * np.ones(T2 + S - 1))).max()
    cnt_err = abs(Y[:-1] - C[:-1] - K[1:] + (1 - delta) * K[:-1]).max()
    t2=time.time()
    t=t2-t1
    print (f'It took {t} seconds to solve TPI.')

    k_first = [k for k in K if abs(k - K_ss) < 0.0001][0]
    T_1 = np.where(K == k_first)[0][0]

    return rpath_old, wpath_old, K, L, bmat, nmat, cmat, b_last, b_err, n_err, cnt_err, T_1
Beispiel #4
0
def get_TPI(params, b1vec, graphs):

    start_time = time.clock()
    S, T, beta, sigma, nvec, L, A, alpha, delta, b_ss, K_ss, C_ss, BQ_ss, \
    maxiter_TPI, mindist_TPI, xi, TPI_tol, bq_distr, chi = params

    K1 = utils.get_K(b1vec)[0]
    # K: s=1 ~ S, sum of b: s=2 ~ S+1
    Kpath_old = np.zeros(T + S)
    # print (f'K1: {K1}, K_ss: {K_ss}')
    Kpath_old[:T] = np.linspace(K1, K_ss, T)  # Until reaching steady state
    Kpath_old[T:] = K_ss
    r = utils.get_r(Kpath_old[0], utils.get_L(nvec), (A, alpha, delta))
    BQ1 = (1 + r) * b1vec[-1]
    BQpath_old = np.zeros(T + S)
    BQpath_old[:T] = np.linspace(BQ1, BQ_ss, T)  # Until reaching steady state
    BQpath_old[T:] = BQ_ss
    L = np.sum(nvec)

    iter_TPI = int(0)
    abs2 = 10.
    Kpath_new = Kpath_old.copy()
    r_params = (A, alpha, delta)
    w_params = (A, alpha)
    # cbe_params = (S, T, beta, sigma, nvec, b_ss, TPI_tol, A, alpha, delta, bq_distr, chi)

    while (iter_TPI < maxiter_TPI) and (abs2 >= mindist_TPI):
        iter_TPI += 1
        # Kpath_init = xi * Kpath_new + (1 - xi) * Kpath_old
        rpath = utils.get_r(Kpath_old, L, r_params)
        wpath = utils.get_w(Kpath_old, L, w_params)
        # cpath, bpath, EulErrPath = get_cbepath(cbe_params, rpath, wpath, b1vec)
        # b: 2~S+1
        bpath = np.append(b1vec.reshape(S, 1),
                          np.zeros((S, T + S - 2)),
                          axis=1)
        cpath = np.zeros((S, T + S - 1))
        EulErrPath = np.zeros((S, T + S - 1))
        cpath[S - 1,
              0] = ((1 + rpath[0]) * b1vec[S - 2] + wpath[0] * nvec[S - 1])
        for p in range(1, S):
            bvec_guess = np.diagonal(bpath[S - p:, :p])
            beg_wealth = bpath[S - p - 1, 0]
            #beg_wealth, nvec, beta, sigma, wpath, rpath, BQpath, chi, bq_distr
            args_sol = (beg_wealth, nvec[-p:], beta, sigma, wpath[:p],
                        rpath[:p], BQpath_old[:p], chi[-p:], bq_distr[-p:])
            b_sol = opt.root(utils.EulerSys_tpi, bvec_guess, args=(args_sol)).x
            #rpath, wpath, bvec, nvec, bq, bq_distr
            cp, c_cnstr_p = utils.get_cvec_tpi(rpath[:p], wpath[:p],
                                               np.append(beg_wealth,
                                                         b_sol), nvec[-p:],
                                               BQpath_old[:p], bq_distr[-p:])
            # rpath, wpath, bvec, nvec, bq, bq_distr
            b_err_p = utils.EulerSys_tpi(b_sol, beg_wealth, nvec[-p:], beta,
                                         sigma, wpath[:p], rpath[:p],
                                         BQpath_old[:p], chi[-p:],
                                         bq_distr[-p:])

            # Insert the vector lifetime solutions diagonally (twist donut)
            bp_path = np.eye(p) * b_sol
            cp_path = np.eye(p) * cp
            ep_path = np.eye(p) * b_err_p
            bpath[S - p:, 1:p + 1] += bp_path
            cpath[S - p:, 1:p + 1] += cp_path
            EulErrPath[S - p:, 1:p + 1] += ep_path

        for t in range(1, T):
            bvec_guess_t = np.diagonal(bpath[:, t - 1:S + t - 1])
            args_bt = (0, nvec, beta, sigma, wpath[t - 1:S + t - 1],
                       rpath[t - 1:S + t - 1], BQpath_old[t - 1:S + t - 1],
                       chi, bq_distr)
            bt = opt.root(utils.EulerSys_tpi, bvec_guess_t, args=(args_bt)).x
            # print (f'bt.shape: {bt.shape}, ')
            #np.append(nvec,[0.2])
            # rpath, wpath, bvec, nvec, bq, bq_distr
            ct, c_cnstr_t = utils.get_cvec_tpi(rpath[t - 1:S + t - 1],
                                               wpath[t - 1:S + t - 1],
                                               np.append([0], bt), nvec,
                                               BQpath_old[t - 1:S + t - 1],
                                               bq_distr)
            b_err_t = utils.EulerSys_tpi(bt, 0, nvec, beta, sigma,
                                         wpath[t - 1:S + t - 1],
                                         rpath[t - 1:S + t - 1],
                                         BQpath_old[t - 1:S + t - 1], chi,
                                         bq_distr)

            # DiagMask = np.eye(S)

            bt_path = np.eye(p + 1) * bt
            # print(f'bt: {bt.shape}, btpath:{bt_path.shape}, t:{t}, bpath:{bpath.shape}')
            ct_path = np.eye(p + 1) * ct
            et_path = np.eye(p + 1) * b_err_t
            bpath[:, t:S + t] += bt_path
            cpath[:, t:S + t] += ct_path
            EulErrPath[:, t:S + t] += et_path

        Kpath_new = np.zeros(T + S)
        Kpath_new[:T], Kpath_cnstr = utils.get_K(bpath[:, :T])
        Kpath_new[T:] = K_ss * np.ones(S)
        Kpath_cnstr = np.append(Kpath_cnstr, np.zeros(S, dtype=bool))
        Kpath_new[Kpath_cnstr] = 0.1

        BQpath_new = np.zeros(T + S)
        # print (f'Here: bpath {bpath[S, :T].shape}')
        #, BQ:{BQpath_new.shape}, rpath:{rpath[:T].shape}
        BQpath_new[:T] = (1 + rpath[:T]) * bpath[-1, :T]
        BQpath_new[T:] = BQ_ss * np.ones(S)

        abs2 = (((Kpath_old[:T] - Kpath_new[:T]) / Kpath_old[:T] * 100) ** 2).sum() + \
               (((BQpath_old[:T] - BQpath_new[:T]) / BQpath_old[:T] * 100) ** 2).sum()

        Kpath_old[:T] = xi * Kpath_new[:T] + (1 - xi) * Kpath_old[:T]
        BQpath_old[:T] = xi * BQpath_new[:T] + (1 - xi) * BQpath_old[:T]
        print('iter: ', iter_TPI, ', squared pct deviation sum: ', abs2,
              ',max Eul err: ',
              np.absolute(EulErrPath).max())

    BQ_path = BQpath_old
    Kpath = Kpath_old
    Ypath = utils.get_Y(Kpath, L, (A, alpha))
    Cpath = np.zeros(Kpath.shape)
    Cpath[:T - 1] = utils.get_C(cpath[:, :T - 1])
    Cpath[T - 1:] = C_ss * np.ones(S + 1)
    RCerrPath = (Ypath[:-1] - Cpath[:-1] - Kpath[1:] +
                 (1 - delta) * Kpath[:-1])
    tpi_time = time.clock() - start_time

    tpi_output = {
        'bpath': bpath,
        'cpath': cpath,
        'wpath': wpath,
        'rpath': rpath,
        'Kpath': Kpath_new,
        'Ypath': Ypath,
        'Cpath': Cpath,
        'EulErrPath': EulErrPath,
        'RCerrPath': RCerrPath,
        'tpi_time': tpi_time,
        'BQ_path': BQ_path
    }

    # Print TPI computation time
    print(f'It took {tpi_time} seconds to run.')
    if graphs:
        '''
        ----------------------------------------------------------------
        cur_path    = string, path name of current directory
        output_fldr = string, folder in current path to save files
        output_dir  = string, total path of images folder
        output_path = string, path of file name of figure to be saved
        tvec        = (T+S-2,) vector, time period vector
        tgridTm1    = (T-1,) vector, time period vector to T-1
        tgridT      = (T,) vector, time period vector to T-1
        sgrid       = (S,) vector, all ages from 1 to S
        sgrid2      = (S-1,) vector, all ages from 2 to S
        tmatb       = (2, 18) matrix, time periods for all savings
                      decisions ages (S-1) and time periods (T)
        smatb       = (2, 18) matrix, ages for all savings decision ages
                      (S-1) and time periods (T)
        tmatc       = (3, 17) matrix, time periods for all consumption
                      decisions ages (S) and time periods (T-1)
        smatc       = (3, 17) matrix, ages for all consumption decisions
                      ages (S) and time periods (T-1)
        ----------------------------------------------------------------
        '''
        # Create directory if images directory does not already exist
        cur_path = os.path.split(os.path.abspath(__file__))[0]
        output_fldr = "images"
        output_dir = os.path.join(cur_path, output_fldr)
        if not os.access(output_dir, os.F_OK):
            os.makedirs(output_dir)

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

        # Plot time path of aggregate capital stock
        tvec = np.linspace(1, T + 5, T + 5)
        minorLocator = MultipleLocator(1)
        fig, ax = plt.subplots()
        plt.plot(tvec, BQ_path[:T + 5], 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 bequest BQ')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'Bequest $BQ$')
        output_path = os.path.join(output_dir, "BQpath")
        plt.savefig(output_path)
        # plt.show()

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

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

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

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

        # Plot time path of real wage
        fig, ax = plt.subplots()
        plt.plot(tvec, bpath[24, :T + 5], 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 savings by 25-year-olds $b_{25}$')
        plt.xlabel(r'Period $t$')
        plt.ylabel(r'$b_{25}$')
        output_path = os.path.join(output_dir, "b25path")
        plt.savefig(output_path)
        # plt.show()

    return tpi_output
Beispiel #5
0
def get_SS(params, bvec_guess, SS_graphs):
    start_time = time.clock()
    beta, sigma, nvec, A, alpha, delta, SS_tol, fert_rates, mort_rates, imm_rates, omega_SS, gn_SS, g_y = params
    b = opt.root(utils.EulerSys_ss,
                 bvec_guess,
                 args=(beta, sigma, nvec, A, alpha, delta, gn_SS, g_y,
                       omega_SS, mort_rates, imm_rates),
                 tol=SS_tol)
    if b.success:
        b_ss = b.x
        # iterations=b.nit

    K_ss = utils.get_K(b_ss, omega_SS, gn_SS, imm_rates)
    L = utils.get_L(nvec, omega_SS)
    w_ss = utils.get_w(K_ss, L, alpha, A)
    r_ss = utils.get_r(K_ss, L, alpha, delta, A)
    Y_ss = utils.get_Y(K_ss, L, (A, alpha))
    c_ss, c_cnstr = utils.get_cvec_ss(r_ss, w_ss, b_ss, nvec, gn_SS, g_y,
                                      omega_SS, mort_rates)
    EulErr_ss = utils.EulerSys_ss(b_ss, beta, sigma, nvec, A, alpha, delta,
                                  gn_SS, g_y, omega_SS, mort_rates, imm_rates)
    C_ss = utils.get_C(c_ss, omega_SS)
    RCerr_ss = Y_ss - C_ss - (
        (1 + gn_SS) * np.exp(g_y) - 1 + delta) * K_ss + np.exp(g_y) * (
            imm_rates * omega_SS * np.append(b_ss, [0]))
    BQ_ss = utils.get_BQ(b_ss, r_ss, gn_SS, omega_SS, mort_rates)

    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,
        'EulErr_ss': EulErr_ss,
        'RCerr_ss': RCerr_ss,
        'BQ_ss': BQ_ss,
        'ss_time': ss_time
    }

    # print('\n Savings: \t\t\t {} \n Capital and Labor: \t\t {} \n Wage and Interest rate: \t {} \n Consumption: \t\t\t {}'.format(
    #         b_ss, np.array([K_ss, L]), np.array([w_ss, r_ss]), c_ss))
    #
    # print('Euler errors: ', EulErr_ss)
    # print('Resource Constraint error: ', RCerr_ss)
    # print('Time needed: ', ss_time)
    # print ('It took {iterations} iterations to get the solution.')
    if SS_graphs:
        cur_path = os.path.split(os.path.abspath(__file__))[0]
        output_fldr = "images_ss_tpi"
        output_dir = os.path.join(cur_path, output_fldr)
        if not os.access(output_dir, os.F_OK):
            os.makedirs(output_dir)

        age = np.arange(21, 101)
        fig, ax = plt.subplots()
        plt.plot(age, c_ss, marker='D', label='Consumption')
        plt.plot(age, np.append([0], b_ss), marker='D', label='Savings')
        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')
        plt.xlabel('Age')
        plt.ylabel('Consumption units')
        plt.legend()
        output_path = os.path.join(output_dir, 'ss_bc')
        plt.savefig(output_path)
        # plt.show()
        plt.close()

    return ss_output