コード例 #1
0
    def test_Harmenberg_mtd(self):

        example = IndShockConsumerType(**dict_harmenberg, verbose=0)
        example.cycles = 0
        example.track_vars = ['aNrm', 'mNrm', 'cNrm', 'pLvl', 'aLvl']
        example.T_sim = 20000

        example.solve()

        example.neutral_measure = True
        example.update_income_process()

        example.initialize_sim()
        example.simulate()

        Asset_list = []
        Consumption_list = []
        M_list = []

        for i in range(example.T_sim):
            Assetagg = np.mean(example.history['aNrm'][i])
            Asset_list.append(Assetagg)
            ConsAgg = np.mean(example.history['cNrm'][i])
            Consumption_list.append(ConsAgg)
            Magg = np.mean(example.history['mNrm'][i])
            M_list.append(Magg)

        #########################################################

        example2 = IndShockConsumerType(**dict_harmenberg, verbose=0)
        example2.cycles = 0
        example2.track_vars = ['aNrm', 'mNrm', 'cNrm', 'pLvl', 'aLvl']
        example2.T_sim = 20000

        example2.solve()
        example2.initialize_sim()
        example2.simulate()

        Asset_list2 = []
        Consumption_list2 = []
        M_list2 = []

        for i in range(example2.T_sim):
            Assetagg = np.mean(example2.history['aLvl'][i])
            Asset_list2.append(Assetagg)
            ConsAgg = np.mean(example2.history['cNrm'][i] *
                              example2.history['pLvl'][i])
            Consumption_list2.append(ConsAgg)
            Magg = np.mean(example2.history['mNrm'][i] *
                           example2.history['pLvl'][i])
            M_list2.append(Magg)

        c_std2 = np.std(Consumption_list2)
        c_std1 = np.std(Consumption_list)
        c_std_ratio = c_std2 / c_std1

        self.assertAlmostEqual(c_std2, 0.03768819564871894)
        self.assertAlmostEqual(c_std1, 0.004411745897568616)
        self.assertAlmostEqual(c_std_ratio, 8.542694099741672)
コード例 #2
0
def perturbParameterToGetcPlotList(base_dictionary,
                                   param_name,
                                   param_min,
                                   param_max,
                                   N=20,
                                   time_vary=False):
    param_vec = np.linspace(
        param_min, param_max, num=N, endpoint=True
    )  # vector of alternative values of the parameter to examine
    thisConsumer = IndShockConsumerType(
        **my_dictionary)  # create an instance of the consumer type
    thisConsumer.cycles = 0  # Make this type have an infinite horizon
    x = np.linspace(
        mMinVal, mMaxVal, xPoints, endpoint=True
    )  # Define a vector of x values that span the range from the minimum to the maximum values of m

    for j in range(
            N):  # loop from the first to the last values of the parameter
        if time_vary:  # Some parameters are time-varying; others are not
            setattr(thisConsumer, param_name, [param_vec[j]])
        else:
            setattr(thisConsumer, param_name, param_vec[j])
        thisConsumer.update(
        )  # set up the preliminaries required to solve the problem
        thisConsumer.solve()  # solve the problem
        y = thisConsumer.solution[0].cFunc(
            x
        )  # Get the values of the consumption function at the points in the vector of x points
        pylab.plot(
            x, y, label=str(round(param_vec[j], 3))
        )  # plot it and generate a label indicating the rounded value of the parameter
        pylab.legend(loc='upper right')  # put the legend in the upper right
    return pylab  # return the figure
コード例 #3
0
    def test_ConsIndShockSolverBasic(self):
        LifecycleExample = IndShockConsumerType(**init_lifecycle)
        LifecycleExample.cycles = 1
        LifecycleExample.solve()

        solver = ConsIndShockSolverBasic(
            LifecycleExample.solution[1], LifecycleExample.IncomeDstn[0],
            LifecycleExample.LivPrb[0], LifecycleExample.DiscFac,
            LifecycleExample.CRRA, LifecycleExample.Rfree,
            LifecycleExample.PermGroFac[0], LifecycleExample.BoroCnstArt,
            LifecycleExample.aXtraGrid, LifecycleExample.vFuncBool,
            LifecycleExample.CubicBool)

        solver.prepareToSolve()

        self.assertAlmostEqual(solver.DiscFacEff, 0.9503999999999999)
        self.assertAlmostEqual(solver.PermShkMinNext, 0.850430160026919)
        self.assertAlmostEqual(solver.cFuncNowCnst(4).tolist(), 4.0)
        self.assertAlmostEqual(solver.prepareToCalcEndOfPrdvP()[0],
                               -0.2491750859108316)
        self.assertAlmostEqual(solver.prepareToCalcEndOfPrdvP()[-1],
                               19.74982491408914)

        EndOfPrdvP = solver.calcEndOfPrdvP()

        self.assertAlmostEqual(EndOfPrdvP[0], 6622.251864311334)
        self.assertAlmostEqual(EndOfPrdvP[-1], 0.026301061207747087)

        solution = solver.makeBasicSolution(EndOfPrdvP, solver.aNrmNow,
                                            solver.makeLinearcFunc)
        solver.addMPCandHumanWealth(solution)

        self.assertAlmostEqual(solution.cFunc(4).tolist(), 1.7391265696400773)
コード例 #4
0
    def test_cyclical(self):
        CyclicalExample = IndShockConsumerType(**CyclicalDict)
        CyclicalExample.cycles = 0  # Make this consumer type have an infinite horizon
        CyclicalExample.solve()

        self.assertAlmostEqual(CyclicalExample.solution[3].cFunc(3).tolist(),
                               1.5958390056965004)
コード例 #5
0
    def setUp(self):
        """
        Prepare to compare the models by initializing and solving them
        """
        # Set up and solve infinite type

        # Define a test dictionary that should have the same solution in the
        # perfect foresight and idiosyncratic shocks models.
        test_dictionary = deepcopy(init_idiosyncratic_shocks)
        test_dictionary["LivPrb"] = [1.0]
        test_dictionary["DiscFac"] = 0.955
        test_dictionary["PermGroFac"] = [1.0]
        test_dictionary["PermShkStd"] = [0.0]
        test_dictionary["TranShkStd"] = [0.0]
        test_dictionary["UnempPrb"] = 0.0
        test_dictionary["T_cycle"] = 1
        test_dictionary["T_retire"] = 0
        test_dictionary["BoroCnstArt"] = None

        InfiniteType = IndShockConsumerType(**test_dictionary)
        InfiniteType.cycles = 0

        InfiniteType.update_income_process()
        InfiniteType.solve()
        InfiniteType.unpack("cFunc")

        # Make and solve a perfect foresight consumer type with the same parameters
        PerfectForesightType = PerfForesightConsumerType(**test_dictionary)
        PerfectForesightType.cycles = 0

        PerfectForesightType.solve()
        PerfectForesightType.unpack("cFunc")

        self.InfiniteType = InfiniteType
        self.PerfectForesightType = PerfectForesightType
コード例 #6
0
def makeConvergencePlot(DiscFac, CRRA, Rfree, PermShkStd):
    # Construct finite horizon agent with baseline parameters
    baseAgent_Fin = IndShockConsumerType(verbose=0, **base_params)
    baseAgent_Fin.DiscFac = DiscFac
    baseAgent_Fin.CRRA = CRRA
    baseAgent_Fin.Rfree = Rfree
    baseAgent_Fin.PermShkStd = [PermShkStd]
    baseAgent_Fin.cycles = 100
    baseAgent_Fin.updateIncomeProcess()
    baseAgent_Fin.solve()
    baseAgent_Fin.unpack('cFunc')

    # figure limits
    mMax = 6  # 11
    mMin = 0
    cMin = 0
    cMax = 4  # 7

    mPlotMin = 0
    mLocCLabels = 5.6  # 9.6 # Defines horizontal limit of figure
    mPlotTop = 3.5  # 6.5    # Defines maximum m value where functions are plotted
    mPts = 1000  # Number of points at which functions are evaluated

    plt.figure(figsize=(12, 8))
    plt.ylim([cMin, cMax])
    plt.xlim([mMin, mMax])

    mBelwLabels = np.linspace(mPlotMin, mLocCLabels - 0.1,
                              mPts)  # Range of m below loc of labels
    m_FullRange = np.linspace(mPlotMin, mPlotTop, mPts)  # Full plot range
    c_Tm0 = m_FullRange  # c_Tm0  defines the last period consumption rule (c=m)
    c_Tm1 = baseAgent_Fin.cFunc[-2](
        mBelwLabels
    )  # c_Tm1 defines the second-to-last period consumption rule
    c_Tm5 = baseAgent_Fin.cFunc[-6](
        mBelwLabels)  # c_Tm5 defines the T-5 period consumption rule
    c_Tm10 = baseAgent_Fin.cFunc[-11](
        mBelwLabels)  # c_Tm10 defines the T-10 period consumption rule
    c_Limt = baseAgent_Fin.cFunc[0](
        mBelwLabels
    )  # c_Limt defines limiting infinite-horizon consumption rule

    plt.plot(mBelwLabels, c_Limt, label="$c(m)$")
    plt.plot(mBelwLabels, c_Tm1, label="$c_{T-1}(m)$")
    plt.plot(mBelwLabels, c_Tm5, label="$c_{T-5}(m)$")
    plt.plot(mBelwLabels, c_Tm10, label="$c_{T-10}(m)$")
    plt.plot(m_FullRange, c_Tm0, label="$c_{T}(m) = 45$ degree line")
    plt.legend(fontsize='x-large')
    plt.tick_params(
        labelbottom=False,
        labelleft=False,
        left="off",
        right="off",
        bottom="off",
        top="off",
    )

    plt.show()
    return None
コード例 #7
0
    def test_ConsIndShockSolverBasic(self):
        LifecycleExample = IndShockConsumerType(**init_lifecycle)
        LifecycleExample.cycles = 1
        LifecycleExample.solve()

        # test the solution_terminal
        self.assertAlmostEqual(LifecycleExample.solution[-1].cFunc(2).tolist(),
                               2)

        self.assertAlmostEqual(LifecycleExample.solution[9].cFunc(1),
                               0.79429538)
        self.assertAlmostEqual(LifecycleExample.solution[8].cFunc(1),
                               0.79391692)
        self.assertAlmostEqual(LifecycleExample.solution[7].cFunc(1),
                               0.79253095)

        self.assertAlmostEqual(LifecycleExample.solution[0].cFunc(1).tolist(),
                               0.7506184692092213)
        self.assertAlmostEqual(LifecycleExample.solution[1].cFunc(1).tolist(),
                               0.7586358637239385)
        self.assertAlmostEqual(LifecycleExample.solution[2].cFunc(1).tolist(),
                               0.7681247572911291)

        solver = ConsIndShockSolverBasic(
            LifecycleExample.solution[1],
            LifecycleExample.IncShkDstn[0],
            LifecycleExample.LivPrb[0],
            LifecycleExample.DiscFac,
            LifecycleExample.CRRA,
            LifecycleExample.Rfree,
            LifecycleExample.PermGroFac[0],
            LifecycleExample.BoroCnstArt,
            LifecycleExample.aXtraGrid,
            LifecycleExample.vFuncBool,
            LifecycleExample.CubicBool,
        )

        solver.prepare_to_solve()

        self.assertAlmostEqual(solver.DiscFacEff, 0.9586233599999999)
        self.assertAlmostEqual(solver.PermShkMinNext, 0.6554858756904397)
        self.assertAlmostEqual(solver.cFuncNowCnst(4).tolist(), 4.0)
        self.assertAlmostEqual(solver.prepare_to_calc_EndOfPrdvP()[0],
                               -0.19792871012285213)
        self.assertAlmostEqual(solver.prepare_to_calc_EndOfPrdvP()[-1],
                               19.801071289877118)

        EndOfPrdvP = solver.calc_EndOfPrdvP()

        self.assertAlmostEqual(EndOfPrdvP[0], 6657.839372100613)
        self.assertAlmostEqual(EndOfPrdvP[-1], 0.2606075215645896)

        solution = solver.make_basic_solution(EndOfPrdvP, solver.aNrmNow,
                                              solver.make_linear_cFunc)
        solver.add_MPC_and_human_wealth(solution)

        self.assertAlmostEqual(solution.cFunc(4).tolist(), 1.0028005137373956)
コード例 #8
0
    def test_lifecyle(self):
        LifecycleExample = IndShockConsumerType(**LifecycleDict)
        LifecycleExample.cycles = 1
        LifecycleExample.solve()

        self.assertEquals(len(LifecycleExample.solution), 11)

        mMin = np.min([LifecycleExample.solution[t].mNrmMin for t in
                       range(LifecycleExample.T_cycle)])

        self.assertAlmostEqual(LifecycleExample.solution[5].cFunc(3).tolist(),
                               2.129983771775666)
コード例 #9
0
def create_agents(CRRA, TranShkStd):

    # Copy base dictionaries
    un_dict = copy(IdiosyncDict)
    pf_dict = copy(PFDict)

    # Update CRRA
    un_dict['CRRA'] = CRRA
    pf_dict['CRRA'] = CRRA

    # Update transitory shock sd
    un_dict["TranShkStd"] = [TranShkStd]

    IndShockConsumer = IndShockConsumerType(**un_dict)
    IndShockConsumer.cycles = 2  # Make this type have a two-period horizon
    IndShockConsumer.solve()

    PFConsumer = IndShockConsumerType(**pf_dict)
    PFConsumer.cycles = 2
    PFConsumer.solve()

    return ((IndShockConsumer, PFConsumer))
コード例 #10
0
    def test_cyclical(self):
        CyclicalExample = IndShockConsumerType(**CyclicalDict)
        CyclicalExample.cycles = 0  # Make this consumer type have an infinite horizon
        CyclicalExample.solve()

        self.assertAlmostEqual(CyclicalExample.solution[3].cFunc(3).tolist(),
                               1.5958390056965004)

        CyclicalExample.initialize_sim()
        CyclicalExample.simulate()

        self.assertAlmostEqual(CyclicalExample.state_now['aLvl'][1],
                               0.41839957)
コード例 #11
0
    def test_infinite_horizon(self):
        IndShockExample = IndShockConsumerType(**IdiosyncDict)
        IndShockExample.cycles = 0 # Make this type have an infinite horizon
        IndShockExample.solve()

        self.assertAlmostEqual(IndShockExample.solution[0].mNrmSS,
                               1.5488165705077026)
        self.assertAlmostEqual(IndShockExample.solution[0].cFunc.functions[0].x_list[0],
                               -0.25017509)

        IndShockExample.track_vars = ['aNrmNow','mNrmNow','cNrmNow','pLvlNow']
        IndShockExample.initializeSim()
        IndShockExample.simulate()

        self.assertAlmostEqual(IndShockExample.mNrmNow_hist[0][0],
                               1.0170176090252379)
コード例 #12
0
    def test_baseEx(self):
        baseEx = IndShockConsumerType(**self.base_params)
        baseEx.cycles = 100  # Make this type have a finite horizon (Set T = 100)

        baseEx.solve()
        baseEx.unpack("cFunc")

        m = np.linspace(0, 9.5, 1000)

        c_m = baseEx.cFunc[0](m)
        c_t1 = baseEx.cFunc[-2](m)
        c_t5 = baseEx.cFunc[-6](m)
        c_t10 = baseEx.cFunc[-11](m)

        self.assertAlmostEqual(c_m[500], 1.4008090582203356)
        self.assertAlmostEqual(c_t1[500], 2.9227437159255216)
        self.assertAlmostEqual(c_t5[500], 1.7350607327187664)
        self.assertAlmostEqual(c_t10[500], 1.4991390649979213)
        self.assertAlmostEqual(c_t10[600], 1.6101476268581576)
        self.assertAlmostEqual(c_t10[700], 1.7196531041366991)
コード例 #13
0
    def setUp(self):
        """
        Prepare to compare the models by initializing and solving them
        """
        # Set up and solve infinite type
        import HARK.ConsumptionSaving.ConsumerParameters as Params

        # Define a test dictionary that should have the same solution in the
        # perfect foresight and idiosyncratic shocks models.
        test_dictionary = deepcopy(Params.init_idiosyncratic_shocks)
        test_dictionary['LivPrb'] = [1.]
        test_dictionary['DiscFac'] = 0.955
        test_dictionary['PermGroFac'] = [1.]
        test_dictionary['PermShkStd'] = [0.]
        test_dictionary['TranShkStd'] = [0.]
        test_dictionary['UnempPrb'] = 0.
        test_dictionary['T_cycle'] = 1
        test_dictionary['T_retire'] = 0
        test_dictionary['BoroCnstArt'] = None

        InfiniteType = IndShockConsumerType(**test_dictionary)
        InfiniteType.cycles = 0

        InfiniteType.updateIncomeProcess()
        InfiniteType.solve()
        InfiniteType.timeFwd()
        InfiniteType.unpackcFunc()

        # Make and solve a perfect foresight consumer type with the same parameters
        PerfectForesightType = PerfForesightConsumerType(**test_dictionary)
        PerfectForesightType.cycles = 0

        PerfectForesightType.solve()
        PerfectForesightType.unpackcFunc()
        PerfectForesightType.timeFwd()

        self.InfiniteType = InfiniteType
        self.PerfectForesightType = PerfectForesightType
コード例 #14
0
# Under the given parameter values, [the paper's first figure](https://econ-ark.github.io/BufferStockTheory/#Convergence-of-the-Consumption-Rules) depicts the successive consumption rules that apply in the last period of life $(c_{T}(m))$, the second-to-last period, and earlier periods $(c_{T-n})$.  The consumption function to which these converge is $c(m)$:
#
# $$
# c(m) = \lim_{n \uparrow \infty} c_{T-n}(m) \notag
# $$
#

# %%
# Create a buffer stock consumer instance by invoking the IndShockConsumerType class

# %% {"jupyter": {"source_hidden": true}, "tags": []}
# with the built-in parameter dictionary "base_params"

# Construct finite horizon agent with baseline parameters
baseAgent_Fin = IndShockConsumerType(**base_params)
baseAgent_Fin.cycles = 100   # Set finite horizon (T = 100)

baseAgent_Fin.solve(verbose=0)        # Solve the model
baseAgent_Fin.unpack('cFunc')  # Make the consumption function easily accessible


# %%
# Plot the different consumption rules for the different periods

# %% {"jupyter": {"source_hidden": true, "outputs_hidden": true}, "tags": []}

mPlotMin = 0
mLocCLabels = 9.6  # Defines horizontal limit of figure
mPlotTop = 6.5    # Defines maximum m value where functions are plotted
mPts = 1000      # Number of points at which functions are evaluated
コード例 #15
0
# Optionally, the user can specify the period when the individual retires and escapes essentially all income risk as $\texttt{T_retire}$; this can be turned off by setting the parameter to $0$.  In retirement, all permanent income shocks are turned off, and the only transitory shock is an "unemployment" shock, likely with small probability; this prevents the retired problem from degenerating into a perfect foresight model.
#
# The grid of assets above minimum $\texttt{aXtraGrid}$ is specified by its minimum and maximum level, the number of gridpoints, and the extent of exponential nesting.  The greater the (integer) value of $\texttt{aXtraNestFac}$, the more dense the gridpoints will be at the bottom of the grid (and more sparse near the top); setting $\texttt{aXtraNestFac}$ to $0$ will generate an evenly spaced grid of $a_t$.
#
# The artificial borrowing constraint $\texttt{BoroCnstArt}$ can be set to $\texttt{None}$ to turn it off.
#
# It is not necessary to compute the value function in this model, and it is not computationally free to do so.  You can choose whether the value function should be calculated and returned as part of the solution of the model with $\texttt{vFuncBool}$.  The consumption function will be constructed as a piecewise linear interpolation when $\texttt{CubicBool}$ is \texttt{False}, and will be a piecewise cubic spline interpolator if $\texttt{True}$.

# %% [markdown] {"heading_collapsed": true}
# ## Solving and examining the solution of the idiosyncratic income shocks model
#
# The cell below creates an infinite horizon instance of $\texttt{IndShockConsumerType}$ and solves its model by calling its $\texttt{solve}$ method.

# %% {"hidden": true}
IndShockExample = IndShockConsumerType(**IdiosyncDict)
IndShockExample.cycles = 0 # Make this type have an infinite horizon
IndShockExample.solve()


# %% [markdown] {"hidden": true}
# After solving the model, we can examine an element of this type's $\texttt{solution}$:

# %% {"hidden": true}
print(vars(IndShockExample.solution[0]))

# %% [markdown] {"hidden": true}
# The single-period solution to an idiosyncratic shocks consumer's problem has all of the same attributes as in the perfect foresight model, with a couple additions.  The solution can include the marginal marginal value of market resources function $\texttt{vPPfunc}$, but this is only constructed if $\texttt{CubicBool}$ is $\texttt{True}$, so that the MPC can be accurately computed; when it is $\texttt{False}$, then $\texttt{vPPfunc}$ merely returns $\texttt{NaN}$ everywhere.
#
# The $\texttt{solveConsIndShock}$ function calculates steady state market resources and stores it in the attribute $\texttt{mNrmSS}$.  This represents the steady state level of $m_t$ if *this period* were to occur indefinitely, but with income shocks turned off.  This is relevant in a "one period infinite horizon" model like we've specified here, but is less useful in a lifecycle model.
#
# Let's take a look at the consumption function by plotting it, along with its derivative (the MPC):
コード例 #16
0
from HARK.ConsumptionSaving.ConsIndShockModel import \
    IndShockConsumerType, ConsIndShockSolverBasic
import HARK.ConsumptionSaving.ConsumerParameters as Params

LifecycleExample = IndShockConsumerType(**Params.init_lifecycle)
LifecycleExample.cycles = 1
LifecycleExample.solve()

# test the solution_terminal
assert (LifecycleExample.solution[10].cFunc(2).tolist() == 2)

print(LifecycleExample.solution[9].cFunc(1))
assert (LifecycleExample.solution[9].cFunc(1) == 0.97769632)
self.assertAlmostEqual(LifecycleExample.solution[8].cFunc(1), 0.96624445)
self.assertAlmostEqual(LifecycleExample.solution[7].cFunc(1), 0.95691449)

self.assertAlmostEqual(LifecycleExample.solution[0].cFunc(1).tolist(),
                       0.87362789)
self.assertAlmostEqual(LifecycleExample.solution[1].cFunc(1).tolist(),
                       0.9081621)
self.assertAlmostEqual(LifecycleExample.solution[2].cFunc(1).tolist(),
                       0.9563899)
コード例 #17
0
## There is one more parameter value we need to change.  This one is more complicated than the rest.
## We could solve the problem for a consumer with an infinite horizon of periods that (ex-ante)
## are all identical.  We could also solve the problem for a consumer with a fininite lifecycle,
## or for a consumer who faces an infinite horizon of periods that cycle (e.g., a ski instructor
## facing an infinite series of winters, with lots of income, and summers, with very little income.)
## The way to differentiate is through the "cycles" attribute, which indicates how often the
## sequence of periods needs to be solved.  The default value is 1, for a consumer with a finite
## lifecycle that is only experienced 1 time.  A consumer who lived that life twice in a row, and
## then died, would have cycles = 2.  But neither is what we want.  Here, we need to set cycles = 0,
## to tell HARK that we are solving the model for an infinite horizon consumer.


## Note that another complication with the cycles attribute is that it does not come from
## Params.init_idiosyncratic_shocks.  Instead it is a keyword argument to the  __init__() method of
## IndShockConsumerType.
BaselineExample.cycles      = 0

# + {"cell_marker": "\"\"\"", "cell_type": "markdown"}
# Now, create another consumer to compare the BaselineExample to.
# + {}
# The easiest way to begin creating the comparison example is to just copy the baseline example.
# We can change the parameters we want to change later.
from copy import deepcopy
XtraCreditExample = deepcopy(BaselineExample)

# Now, change whatever parameters we want.
# Here, we want to see what happens if we give the consumer access to more credit.
# Remember, parameters are stored as attributes of the consumer they are used for.
# So, to give the consumer more credit, we just need to relax their borrowing constraint a tiny bit.

# Declare how much we want to increase credit by
コード例 #18
0
    "AgentCount": 4000000,  # Number of agents of this type
    "T_sim": 2000,  # Number of periods to simulate
    "aNrmInitMean": np.log(1.25) - (.5**2) / 2,  # Mean of log initial assets
    "aNrmInitStd": .5,  # Standard deviation of log initial assets
    "pLvlInitMean": 0,  # Mean of log initial permanent income
    "pLvlInitStd": 0,  # Standard deviation of log initial permanent income
    "PermGroFacAgg": 1.0,  # Aggregate permanent income growth factor
    "T_age": None,  # Age after which simulated agents are automatically killed
}

# %% [markdown]
# # Solve

# %% collapsed=true jupyter={"outputs_hidden": true, "source_hidden": true}
fast = IndShockConsumerType(**Harmenberg_Dict, verbose=1)
fast.cycles = 0
fast.Rfree = 1.2**.25
fast.PermGroFac = [1.02]
fast.tolerance = fast.tolerance / 100

fast.track_vars = ['cNrm', 'pLvl']
fast.solve(verbose=False)

# %% [markdown]
# # Calculate Patience Conditions

# %% collapsed=true jupyter={"outputs_hidden": true}
fast.check_conditions(verbose=True)

# %% jupyter={"source_hidden": true}
# Simulate a population
コード例 #19
0
# #### Add MPC and human wealth `addMPCandHumanWealth`
# Add values calculated in `defBoroCnst` now that we have a solution object to put them in.
#
# #### Special to the non-Basic solver
# We are now done, but in the `ConsIndShockSolver` (non-`Basic`!) solver there are a few extra steps. We add steady state m, and depending on the values of `vFuncBool` and `CubicBool` we also add the value function and the marginal marginal value function.

# %% [markdown]
# # Let's try it in action!
# First, we define a standard lifecycle model, solve it and then

# %%
from HARK.ConsumptionSaving.ConsIndShockModel import IndShockConsumerType, init_lifecycle
import numpy as np
import matplotlib.pyplot as plt
LifecycleExample = IndShockConsumerType(init_lifecycle)
LifecycleExample.cycles = 1 # Make this consumer live a sequence of periods exactly once
LifecycleExample.solve()

# %% [markdown]
# Let's have a look at the solution in time period second period. We should then be able to

# %%
from HARK.utilities import plotFuncs
plotFuncs([LifecycleExample.solution[0].cFunc],LifecycleExample.solution[0].mNrmMin,10)

# %% [markdown]
# Let us then create a solver for the first period.

# %%
from HARK.ConsumptionSaving.ConsIndShockModel import ConsIndShockSolverBasic
solver = ConsIndShockSolverBasic(LifecycleExample.solution[1],
コード例 #20
0
# ## Convergence of the Consumption Rules
#
# Under the given parameter values, [the paper's first figure](https://econ-ark.github.io/BufferStockTheory/#Convergence-of-the-Consumption-Rules) depicts the successive consumption rules that apply in the last period of life $(c_{T}(m))$, the second-to-last period, and earlier periods $(c_{T-n})$.  The consumption function to which these converge is $c(m)$:
#
# $$
# c(m) = \lim_{n \uparrow \infty} c_{T-n}(m) \notag
# $$
#

# %%
# Create a buffer stock consumer instance by invoking the IndShockConsumerType class
# with the built-in parameter dictionary "base_params"

# Construct finite horizon agent with baseline parameters
baseAgent_Fin = IndShockConsumerType(**base_params)
baseAgent_Fin.cycles = 100   # Set finite horizon (T = 100)

baseAgent_Fin.solve()        # Solve the model
baseAgent_Fin.unpack('cFunc')  # Make the consumption function easily accessible


# %%
# Plot the different consumption rules for the different periods

mPlotMin  = 0
mLocCLabels = 9.6 # Defines horizontal limit of figure
mPlotTop = 6.5    # Defines maximum m value where functions are plotted
mPts  = 1000      # Number of points at which functions are evaluated

mBelwLabels    = np.linspace(mPlotMin,mLocCLabels-0.1,mPts) # Range of m below loc of labels
m_FullRange    = np.linspace(mPlotMin,mPlotTop,mPts)        # Full plot range 
コード例 #21
0
base_params['T_cycle']      = 1       # No 'seasonal' cycles
base_params['BoroCnstArt']  = None    # No artificial borrowing constraint
# %% [markdown] {"hidden": true}
# ## Convergence of the Consumption Rules
#
# Under the given parameter values, [the paper's first figure](http://econ.jhu.edu/people/ccarroll/papers/BufferStockTheory/#Convergence-of-the-Consumption-Rules) depicts the successive consumption rules that apply in the last period of life $(c_{T}(m))$, the second-to-last period, and earlier periods $(c_{T-n})$.  $c(m)$ is the consumption function to which these converge as 
#
# \[
# c(m) = \lim_{n \uparrow \infty} c_{T-n}(m)
# \]
#

# %% {"hidden": true}
# Create a buffer stock consumer instance by passing the dictionary to the class.
baseEx = IndShockConsumerType(**base_params)
baseEx.cycles = 100   # Make this type have a finite horizon (Set T = 100)

baseEx.solve()        # Solve the model
baseEx.unpackcFunc()  # Make the consumption function easily accessible


# %% {"hidden": true}
# Plot the different periods' consumption rules.

m1 = np.linspace(0,9.5,1000) # Set the plot range of m
m2 = np.linspace(0,6.5,500)
c_m  = baseEx.cFunc[0](m1)   # c_m can be used to define the limiting infinite-horizon consumption rule here
c_t1 = baseEx.cFunc[-2](m1) # c_t1 defines the second-to-last period consumption rule
c_t5 = baseEx.cFunc[-6](m1) # c_t5 defines the T-5 period consumption rule
c_t10 = baseEx.cFunc[-11](m1)  # c_t10 defines the T-10 period consumption rule
c_t0 = m2                            # c_t0 defines the last period consumption rule
コード例 #22
0
    1,  # Standard deviation of log initial assets (only for simulation),not used here
    'pLvlInitMean':
    0,  # Mean of log initial permanent income (only matters for simulation), not used here
    'pLvlInitStd':
    0,  # Standard deviation of log initial permanent income (only matters for simulation), not used here
    'PermGroFacAgg':
    1,  # Aggregate permanent income growth factor (only matters for simulation), not used here
    'T_age': None,  # Age after which simulated agents are automatically killed
    'T_cycle': 1  # Number of periods in the cycle for this agent type
}

# In[ ]:

# Create the baseline instance by passing the dictionary to the class.
BaselineExample = IndShockConsumerType(**baseline_bufferstock_dictionary)
BaselineExample.cycles = 100  # Make this type have an finite horizon (Set T = 100)

start_time = clock()
BaselineExample.solve()
end_time = clock()
print('Solving a baseline buffer stock saving model (100 periods) took ' +
      mystr(end_time - start_time) + ' seconds.')
BaselineExample.unpackcFunc()
BaselineExample.timeFwd()

# In[ ]:

# Now we start plotting the different periods' consumption rules.

m1 = np.linspace(0, 9.5, 1000)  # Set the plot range of m
m2 = np.linspace(0, 6.5, 500)
コード例 #23
0
# Plot the perfect foresight consumption function
print("Perfect foresight consumption function:")
mMin = PFexample.solution[0].mNrmMin
plotFuncs(PFexample.cFunc[0], mMin, mMin + 10)

# %%
if do_simulation:
    PFexample.T_sim = 120  # Set number of simulation periods
    PFexample.track_vars = ["mNrmNow"]
    PFexample.initializeSim()
    PFexample.simulate()

# %%
# Make and solve an example consumer with idiosyncratic income shocks
IndShockExample = IndShockConsumerType()
IndShockExample.cycles = 0  # Make this type have an infinite horizon

# %%
start_time = time()
IndShockExample.solve()
end_time = time()
print("Solving a consumer with idiosyncratic shocks took " +
      mystr(end_time - start_time) + " seconds.")
IndShockExample.unpackcFunc()
IndShockExample.timeFwd()

# %%
# Plot the consumption function and MPC for the infinite horizon consumer
print("Concave consumption function:")
plotFuncs(IndShockExample.cFunc[0], IndShockExample.solution[0].mNrmMin, 5)
print("Marginal consumption function:")
コード例 #24
0
def make_cons_func(in_BoroCnstArt, in_TranShkStd):
    """
    This figure illustrates how the effect of risk is greater if there already exists a constraint.

    Initialize four types: unconstrained perfect foresight, unconstrained with risk, constrained perfect foresight, and constrained with risk.
    """

    WwCR_unconstr = IndShockConsumerType(**init_lifecycle)
    WwCR_unconstr.delFromTimeInv("BoroCnstArt")
    WwCR_unconstr.addToTimeVary("BoroCnstArt")
    WwCR_unconstr.solve()
    WwCR_unconstr.unpack("cFunc")

    init_lifecycle_risk2["TranShkStd"] = [0, in_TranShkStd, 0, 0, 0, 0, 0, 0, 0, 0, 0]

    WwCR_risk = IndShockConsumerType(**init_lifecycle_risk2)
    WwCR_risk.delFromTimeInv("BoroCnstArt")
    WwCR_risk.addToTimeVary("BoroCnstArt")
    WwCR_risk.solve()
    WwCR_risk.unpack("cFunc")

    WwCR_constr = IndShockConsumerType(**init_lifecycle)
    WwCR_constr.cycles = 1  # Make this consumer live a sequence of periods exactly once
    WwCR_constr.delFromTimeInv("BoroCnstArt")
    WwCR_constr.addToTimeVary("BoroCnstArt")
    WwCR_constr.BoroCnstArt = [
        None,
        None,
        in_BoroCnstArt,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
    ]
    WwCR_constr.solve()
    WwCR_constr.unpack("cFunc")

    WwCR_constr_risk = IndShockConsumerType(**init_lifecycle_risk2)
    WwCR_constr_risk.delFromTimeInv("BoroCnstArt")
    WwCR_constr_risk.addToTimeVary("BoroCnstArt")
    WwCR_constr_risk.BoroCnstArt = [
        None,
        None,
        in_BoroCnstArt,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
    ]
    WwCR_constr_risk.solve()
    WwCR_constr_risk.unpack("cFunc")

    x = np.linspace(-8, -4, 1000, endpoint=True)
    y = WwCR_unconstr.cFunc[1](x)
    y2 = WwCR_risk.cFunc[1](x)
    y3 = WwCR_constr.cFunc[1](x)
    y4 = WwCR_constr_risk.cFunc[1](x)

    where_close = np.isclose(y, y3, atol=1e-05)
    where_close_risk = np.isclose(y2, y4, atol=1e-05)
    x0 = x[where_close][0]
    x1 = x[where_close_risk][0]
    y0 = y[where_close][0]
    y1 = y2[where_close_risk][0]

    # Display the figure
    # print('Figure 3: Consumption Functions With and Without a Constraint and a Risk')

    f = plt.figure()
    plt.plot(x, y, color="black", linewidth=3, label="${c}_{t,0}$")
    plt.plot(
        x, y2, color="black", linestyle="--", linewidth=3, label=r"$\tilde{c}_{t,0}$"
    )
    plt.plot(x, y3, color="red", label="${c}_{t,1}$")
    plt.plot(x, y4, color="red", linestyle="--", label=r"$\tilde{c}_{t,1}$")
    plt.xlim(left=-8, right=-4.5)
    plt.ylim(0, 0.30)
    plt.text(-8.15, 0.305, "$c$", fontsize=14)
    plt.text(-4.5, -0.02, "$w$", fontsize=14)

    # plt.plot([-6.15,-6.15],[0,0.05],color="black",linestyle=":")
    plt.plot([x0, x0], [0, y0], color="black", linestyle=":")
    plt.plot([x1, x1], [0, y1], color="black", linestyle=":")

    # plt.text(-6.2,-0.02,r"$\underline{w}_{t,1}$",fontsize=14)
    plt.text(x0, -0.02, r"${w}_{t,1}$", fontsize=14)
    plt.text(x1, -0.02, r"$\bar{w}_{t,1}$", fontsize=14)

    plt.tick_params(
        labelbottom=False,
        labelleft=False,
        left="off",
        right="off",
        bottom="off",
        top="off",
    )
    plt.legend()
    plt.show()
    return None
コード例 #25
0

# %% [markdown]
# We now configure and solve a buffer-stock agent with a default parametrization.

# %% Create and simulate agent tags=[]
# Create and solve agent

popn = IndShockConsumerType(**init_idiosyncratic_shocks)

# Modify default parameters
popn.T_sim = max(sample_periods_lvl) + 1
popn.AgentCount = max_agents
popn.track_vars = ['mNrm', 'cNrm', 'pLvl']
popn.LivPrb = [1.0]
popn.cycles = 0

# Solve (but do not yet simulate)
popn.solve()

# %% [markdown]
# Under the basic simulation strategy, we have to de-normalize market resources and consumption multiplying them by permanent income. Only then we construct our statistics of interest.
#
# Note that our time-sampling strategy requires that, after enough time has passed, the economy settles on a stable distribution of its agents across states. How can we know this will be the case? [Szeidl (2013)](http://www.personal.ceu.hu/staff/Adam_Szeidl/papers/invariant.pdf) and [Harmenberg (2021)](https://www.sciencedirect.com/science/article/pii/S0165188921001202?via%3Dihub) provide conditions that can give us some reassurance.$\newcommand{\Rfree}{\mathsf{R}}$
#
# 1. [Szeidl (2013)](http://www.personal.ceu.hu/staff/Adam_Szeidl/papers/invariant.pdf) shows that if $$\log \left[\frac{(\Rfree\beta)^{1/\rho}}{\PermGroFac}
# \right] < \Ex[\log \PermShk],$$ then there is a stable invariant distribution of normalized market resources $\mNrm$.
# 2. [Harmenberg (2021)](https://www.sciencedirect.com/science/article/pii/S0165188921001202?via%3Dihub) repurposes the Szeidl proof to argue that if the same condition is satisfied when the expectation is taken with respect to the permanent-income-neutral measure ($\pShkNeutDstn$), then there is a stable invariant permanent-income-weighted distribution ($\mWgtDstnMarg$)
#
# We now check both conditions with our parametrization.
コード例 #26
0
    # Parameters only used in simulation
    "AgentCount": 1,  # Number of agents of this type
    "T_sim": 5000,  # Number of periods to simulate
    "aNrmInitMean": -6.0,  # Mean of log initial assets
    "aNrmInitStd": 1.0,  # Standard deviation of log initial assets
    "pLvlInitMean": 0.0,  # Mean of log initial permanent income
    "pLvlInitStd": 0.0,  # Standard deviation of log initial permanent income
    "PermGroFacAgg": 1.0,  # Aggregate permanent income growth factor
    "T_age": None,  # Age after which simulated agents are automatically killed
}

# %% slideshow={"slide_type": "slide"}
from HARK.ConsumptionSaving.ConsIndShockModel import IndShockConsumerType

IndShockSimExample = IndShockConsumerType(**IdiosyncDict)
IndShockSimExample.cycles = 0  # Make this type have an infinite horizon
IndShockSimExample.solve()

plot_funcs(IndShockSimExample.solution[0].cFunc,
           IndShockSimExample.solution[0].mNrmMin, 5)

# simulation
IndShockSimExample.track_vars = ['aNrm', 'mNrm', 'cNrm', 'pLvl']
IndShockSimExample.initialize_sim()
IndShockSimExample.simulate()

# %% slideshow={"slide_type": "slide"}
# distribution of cash on hand
density = np.histogram(IndShockSimExample.history['mNrm'],
                       density=True)  #print(density)
n, bins, patches = plt.hist(IndShockSimExample.history['mNrm'], density=True)
コード例 #27
0
WwCR_unconstr = IndShockConsumerType(**init_lifecycle)
WwCR_unconstr.delFromTimeInv('BoroCnstArt')
WwCR_unconstr.addToTimeVary('BoroCnstArt')
WwCR_unconstr.solve()
WwCR_unconstr.unpackcFunc()
WwCR_unconstr.timeFwd()

WwCR_risk = IndShockConsumerType(**init_lifecycle_risk2)
WwCR_risk.delFromTimeInv('BoroCnstArt')
WwCR_risk.addToTimeVary('BoroCnstArt')
WwCR_risk.solve()
WwCR_risk.unpackcFunc()
WwCR_risk.timeFwd()

WwCR_constr = IndShockConsumerType(**init_lifecycle)
WwCR_constr.cycles = 1  # Make this consumer live a sequence of periods exactly once
WwCR_constr.delFromTimeInv('BoroCnstArt')
WwCR_constr.addToTimeVary('BoroCnstArt')
WwCR_constr(
    BoroCnstArt=[None, None, -6, None, None, None, None, None, None, None])
WwCR_constr.solve()
WwCR_constr.unpackcFunc()
WwCR_constr.timeFwd()

WwCR_constr_risk = IndShockConsumerType(**init_lifecycle_risk2)
WwCR_constr_risk.delFromTimeInv('BoroCnstArt')
WwCR_constr_risk.addToTimeVary('BoroCnstArt')
WwCR_constr_risk(
    BoroCnstArt=[None, None, -6, None, None, None, None, None, None, None])
WwCR_constr_risk.solve()
WwCR_constr_risk.unpackcFunc()
コード例 #28
0
# For transitory shocks, to illustrate the problem, we want two possible
# values: a good and a bad one. This is most easily achieved by setting
# a large standard deviation (3) and telling HARK to approximate the
# distribution using only two points.
IdiosyncDict["TranShkStd"] = [3]
IdiosyncDict["TranShkCount"] = 2

# Create a copy with income uncertainty turned off, for comparison
PFDict = copy(IdiosyncDict)
PFDict["TranShkStd"] = [0]
PFDict["TranShkCount"] = 1

# %% {"code_folding": []}
# Create and solve problems for the two consumers
IndShockConsumer = IndShockConsumerType(**IdiosyncDict)
IndShockConsumer.cycles = 2  # Make this type have a two-period horizon
IndShockConsumer.solve()

PFConsumer = IndShockConsumerType(**PFDict)
PFConsumer.cycles = 2
PFConsumer.solve()

# %% [markdown]
# ## Figure 1: Marginal Utility of Assets and Consumption

# %% [markdown]
# Consider an agent facing the following dynamic problem expressed in recursive form:
#
# \begin{equation}
# \begin{split}
# v_t(m_t) =& \max_{c_t} u(c_t) + \beta \mathbb{E}_t[v_{t+1}(R a_t + \tilde{y}_{t+1})] \\
コード例 #29
0
# Optionally, the user can specify the period when the individual retires and escapes essentially all income risk as $\texttt{T_retire}$; this can be turned off by setting the parameter to $0$.  In retirement, all permanent income shocks are turned off, and the only transitory shock is an "unemployment" shock, likely with small probability; this prevents the retired problem from degenerating into a perfect foresight model.
#
# The grid of assets above minimum $\texttt{aXtraGrid}$ is specified by its minimum and maximum level, the number of gridpoints, and the extent of exponential nesting.  The greater the (integer) value of $\texttt{aXtraNestFac}$, the more dense the gridpoints will be at the bottom of the grid (and more sparse near the top); setting $\texttt{aXtraNestFac}$ to $0$ will generate an evenly spaced grid of $a_t$.
#
# The artificial borrowing constraint $\texttt{BoroCnstArt}$ can be set to $\texttt{None}$ to turn it off.
#
# It is not necessary to compute the value function in this model, and it is not computationally free to do so.  You can choose whether the value function should be calculated and returned as part of the solution of the model with $\texttt{vFuncBool}$.  The consumption function will be constructed as a piecewise linear interpolation when $\texttt{CubicBool}$ is \texttt{False}, and will be a piecewise cubic spline interpolator if $\texttt{True}$.

# %% [markdown]
# ## Solving and examining the solution of the idiosyncratic income shocks model
#
# The cell below creates an infinite horizon instance of $\texttt{IndShockConsumerType}$ and solves its model by calling its $\texttt{solve}$ method.

# %%
IndShockExample = IndShockConsumerType(**IdiosyncDict)
IndShockExample.cycles = 0  # Make this type have an infinite horizon
IndShockExample.solve()

# %% [markdown]
# After solving the model, we can examine an element of this type's $\texttt{solution}$:

# %%
print(vars(IndShockExample.solution[0]))

# %% [markdown]
# The single-period solution to an idiosyncratic shocks consumer's problem has all of the same attributes as in the perfect foresight model, with a couple additions.  The solution can include the marginal marginal value of market resources function $\texttt{vPPfunc}$, but this is only constructed if $\texttt{CubicBool}$ is $\texttt{True}$, so that the MPC can be accurately computed; when it is $\texttt{False}$, then $\texttt{vPPfunc}$ merely returns $\texttt{NaN}$ everywhere.
#
# The $\texttt{solveConsIndShock}$ function calculates steady state market resources and stores it in the attribute $\texttt{mNrmSS}$.  This represents the steady state level of $m_t$ if *this period* were to occur indefinitely, but with income shocks turned off.  This is relevant in a "one period infinite horizon" model like we've specified here, but is less useful in a lifecycle model.
#
# Let's take a look at the consumption function by plotting it, along with its derivative (the MPC):