This notebook explores the behavior of a consumer identical to the perfect foresight consumer described in Gentle-Intro-To-HARK-PerfForesightCRRA except that now the model incorporates income uncertainty.
# This cell has a bit of initial setup.
# Click the "Run" button immediately above the notebook in order to execute the contents of any cell
# WARNING: Each cell in the notebook relies upon results generated by previous cells
# The most common problem beginners have is to execute a cell before all its predecessors
# If you do this, you can restart the kernel (see the "Kernel" menu above) and start over
import matplotlib.pyplot as plt
import numpy as np
import HARK
from copy import deepcopy
mystr = lambda number : "{:.4f}".format(number)
from HARK.utilities import plot_funcs
Our new type of consumer receives two income shocks at the beginning of each period. Permanent income would grow by a factor $\Gamma$ in the absence of any shock , but its growth is modified by a shock, $\psi_{t+1}$: \begin{align} P_{t+1} & = \Gamma P_{t}\psi_{t+1} \end{align} whose expected (mean) value is $\mathbb{E}_{t}[\psi_{t+1}]=1$. Actual income received $Y$ is equal to permanent income $P$ multiplied by a transitory shock $\theta$: \begin{align} Y_{t+1} & = \Gamma P_{t+1}\theta_{t+1} \end{align} where again $\mathbb{E}_{t}[\theta_{t+1}] = 1$.
As with the perfect foresight problem, this model can be rewritten in terms of normalized variables, e.g. the ratio of 'market resources' $M_{t}$ (wealth plus current income) to permanent income is $m_t \equiv M_t/P_t$. (See here for the theory). In addition, lenders may set a limit on borrowing: The ratio $a_{t}$ of end-of-period assets to permanent income $A_t/P_t$ must be greater than $\underline{a} \leq 0$. (So, if $\underline{a}=-0.3$, the consumer cannot borrow more than 30 percent of their permanent income).
The consumer's (normalized) problem turns out to be: \begin{eqnarray*} v_t(m_t) &=& \max_{c_t} ~~u(c_t) + \beta \mathbb{E} [(\Gamma_{t+1}\psi_{t+1})^{1-\rho} v_{t+1}(m_{t+1}) ], \\ & \text{s.t.} & \\ a_t &=& m_t - c_t, \\ a_t &\geq& \underline{a}, \\ m_{t+1} &=& a_t R/(\Gamma_{t+1} \psi_{t+1}) + \theta_{t+1}. \end{eqnarray*}
For present purposes, we assume that the transitory and permanent shocks are independent. The permanent shock is assumed to be (approximately) lognormal, while the transitory shock has two components: A probability $\wp$ that the consumer is unemployed, in which case $\theta^{u}=\underline{\theta}$, and a probability $(1-\wp)$ of a shock that is a lognormal with a mean chosen so that $\mathbb{E}_{t}[\theta_{t+n}]=1$.
Computers are discrete devices; even if somehow we knew with certainty that the transitory and permanent shocks were, say, continuously lognormally distributed, in order to be represented on a computer those distributions would need to be approximated by a finite set of points. A large literature in numerical computation explores ways to construct such approximations; probably the easiest discretization to understand is the equiprobable approximation, in which the continuous distribution is represented by a set of $N$ outcomes that are equally likely to occur.
In the case of a single variable (say, the permanent shock $\psi$), and when the number of equiprobable points is, say, 5, the procedure is to construct a list: $\psi^{0}$ is the mean value of the continuous $\psi$ given that the draw of $\psi$ is in the bottom 20 percent of the distribution of the continuous $\psi$. $\psi^{1}$ is the mean value of $\psi$ given that the draw is between the 20th and 40th percentiles, and so on. Having constructed these, the approximation to the expectation of some expression $g(\psi)$ can be very quickly calculated by:
$$ \mathbb{E}_{t}[g(\psi)] \equiv \int_{0}^{\infty} g(\psi) dF_{\psi} \approx (1/N) \sum_{i=0}^{N-1} g(\psi^{i}). $$(For a graphical depiction of a particular instance of this, see SolvingMicroDSOPs/#discreteApprox.)
In addition to the parameters required for the perfect foresight model (like the time preference factor $\beta$), under the assumptions above, we need to choose values for the following extra parameters that describe the income shock distribution and the artificial borrowing constraint.
Param | Description | Code | Value |
---|---|---|---|
$\underline{a}$ | Artificial borrowing constraint | $\texttt{BoroCnstArt}$ | 0.0 |
$\sigma_\psi$ | Underlying stdev of permanent income shocks | $\texttt{PermShkStd}$ | 0.1 |
$\sigma_\theta^{e}$ | Underlying stdev of transitory income shocks | $\texttt{TranShkStd}$ | 0.1 |
$N_\psi$ | Number of discrete permanent income shocks | $\texttt{PermShkCount}$ | 7 |
$N_\theta$ | Number of discrete transitory income shocks | $\texttt{TranShkCount}$ | 7 |
$\wp$ | Unemployment probability | $\texttt{UnempPrb}$ | 0.05 |
$\underline{\theta}$ | Transitory shock when unemployed | $\texttt{IncUnemp}$ | 0.3 |
HARK agents with this kind of problem are instances of the class $\texttt{IndShockConsumerType}$, which is constructed by "inheriting" the properties of the $\texttt{PerfForesightConsumerType}$ and then adding only the new information required:
# This cell defines a parameter dictionary for making an instance of IndShockConsumerType.
IndShockDictionary = {
'PermShkStd': [0.1], # ... by specifying the new parameters for constructing the income process.
'PermShkCount': 7,
'TranShkStd': [0.1],
'TranShkCount': 7,
'UnempPrb': 0.05,
'IncUnemp': 0.3, # ... and income for unemployed people (30 percent of "permanent" income)
'BoroCnstArt': 0.0, # ... and specifying the location of the borrowing constraint (0 means no borrowing is allowed)
'cycles': 0 # signifies an infinite horizon solution (see below)
}
You can see all the attributes of an object in Python by using the dir()
command. From the output of that command below, you can see that many of the model variables are now attributes of this object, along with many other attributes that are outside the scope of this tutorial.
from HARK.ConsumptionSaving.ConsIndShockModel import PerfForesightConsumerType
pfc = PerfForesightConsumerType()
dir(pfc)
['AgentCount', 'BoroCnstArt', 'CRRA', 'DiscFac', 'LivPrb', 'MaxKinks', 'PermGroFac', 'PermGroFacAgg', 'RNG', 'Rfree', 'T_age', 'T_cycle', '__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'aNrmInitMean', 'aNrmInitStd', 'addToTimeInv', 'addToTimeVary', 'assignParameters', 'cFunc_terminal_', 'check_AIC', 'check_condition', 'check_conditions', 'checkElementsOfTimeVaryAreLists', 'check_FHWC', 'check_GIC', 'check_RIC', 'checkRestrictions', 'clearHistory', 'cycles', 'delFromTimeInv', 'delFromTimeVary', 'distance', 'distance_criteria', 'getAvg', 'getControls', 'getMortality', 'getPostStates', 'getRfree', 'getShocks', 'getStates', 'history', 'initializeSim', 'makeShockHistory', 'pLvlInitMean', 'pLvlInitStd', 'postSolve', 'poststate_vars', 'poststate_vars_', 'preSolve', 'pseudo_terminal', 'quiet', 'readShocks', 'read_shocks', 'resetRNG', 'seed', 'shock_vars', 'shock_vars_', 'simBirth', 'simDeath', 'simOnePeriod', 'simulate', 'solution_terminal', 'solution_terminal_', 'solve', 'solveOnePeriod', 'time_inv', 'time_inv_', 'time_vary', 'time_vary_', 'tolerance', 'track_vars', 'unpack', 'unpackcFunc', 'updateSolutionTerminal', 'vFunc_terminal_', 'verbose']
In python terminology, IndShockConsumerType
is a superclass of PerfForesightConsumerType
. This means that it builds on the functionality of its parent type (including, for example, the definition of the utility function). You can find the superclasses of a type in Python using the __bases__
attribute:
from HARK.ConsumptionSaving.ConsIndShockModel import IndShockConsumerType
IndShockConsumerType.__bases__
(HARK.ConsumptionSaving.ConsIndShockModel.PerfForesightConsumerType,)
# So, let's create an instance of the IndShockConsumerType
IndShockExample = IndShockConsumerType(**IndShockDictionary)
As before, we need to import the relevant subclass of $\texttt{AgentType}$ into our workspace, then create an instance by passing the dictionary to the class as if the class were a function.
The scatterplot below shows how the discretized probability distribution is represented in HARK: The lognormal distribution is represented by a set of equiprobable point masses.
# Plot values for equiprobable distribution of permanent shocks
plt.scatter(IndShockExample.PermShkDstn[0].X,
IndShockExample.PermShkDstn[0].pmf)
plt.xlabel("Value")
plt.ylabel("Probability Mass")
plt.show()
This distribution was created, using the parameters in the dictionary above, when the IndShockConsumerType
object was initialized.
HARK solves this problem using backwards induction: It will derive a solution for each period ($t$) by finding a mapping between specific values of market resources $\{m[0],m[1],...\}$ and the corresponding optimal consumption $\{c[0],c[1],...\}$. The function that "connects the dots" will be stored in a variable named cFunc
.
Backwards induction requires a "terminal" (last; final) period to work backwards from. IndShockExample
constructed above did not specify a terminal consumption function, and consequently it uses the default terminal function in which all resources are consumed: $c_{T} = m_{t}$.
IndShockExample.solution_terminal
<HARK.ConsumptionSaving.ConsIndShockModel.ConsumerSolution at 0x11d9ae5d0>
The consumption function cFunc
is defined by piecewise linear interpolation.
It is defined by a series of $(m,c)$ points on a grid; the value of the function for any $m$ is the $c$ determined by the line connecting the nearest defined gridpoints.
You can see below that in the terminal period, $c = m$; the agent consumes all available resources.
# Plot terminal consumption function
plt.plot(IndShockExample.solution_terminal.cFunc.x_list,
IndShockExample.solution_terminal.cFunc.y_list,
color='k')
plt.scatter(IndShockExample.solution_terminal.cFunc.x_list,
IndShockExample.solution_terminal.cFunc.y_list)
<matplotlib.collections.PathCollection at 0x11fb197d0>
The solution also has a representation of a value function
, the value v(m)
as a function of available market resources. Because the agent consumes all their resources in the last period, the value function for the terminal solution looks just like the CRRA utility function: $v_{T}(m) = u(m)$.
# Final consumption function c=m
m = np.linspace(0.1,1,100)
plt.plot(m,IndShockExample.solution_terminal.vFunc(m))
[<matplotlib.lines.Line2D at 0x11fb194d0>]
This solution is generated by invoking solve()
which is a method that is an attribute of the IndShockExample
object. Methods in Python are supposed to have documentation that tell you what they do. You can read the documentation for methods and other attributes in HARK with the built-in Python help()
function:
help(IndShockExample.solve)
Help on method solve in module HARK.core: solve(verbose=False) method of HARK.ConsumptionSaving.ConsIndShockModel.IndShockConsumerType instance Solve the model for this instance of an agent type by backward induction. Loops through the sequence of one period problems, passing the solution from period t+1 to the problem for period t. Parameters ---------- verbose : boolean If True, solution progress is printed to screen. Returns ------- none
$\texttt{ConsIndShockType}$ can solve either finite-horizon (e.g., life-cycle) problems, or infinite-horizon problems (where the problem is the same in every period). Elsewhere you can find documentation about the finite horizon solution; here we are interested in the infinite-horizon solution which is obtained (by definition) when iterating one more period yields a solution that is essentially the same. In the dictionary above we signaled to HARK that we want the infinite horizon solution by setting the "cycles" paramter to zero:
IndShockExample.cycles # Infinite horizon solution is computed when cycles = 0
0
# Solve It
IndShockExample.solve(verbose=True) # Verbose prints progress as solution proceeds
GPFRaw = 0.984539 GPFNrm = 0.993777 GPFAggLivPrb = 0.964848 Thorn = APF = 0.994384 PermGroFacAdj = 1.000611 uInvEpShkuInv = 0.990704 VAF = 0.932054 WRPF = 0.213705 DiscFacGPFNrmMax = 0.972061 DiscFacGPFAggLivPrbMax = 1.010600
Finished cycle #1 in 0.0016739368438720703 seconds, solution distance = 100.0 Finished cycle #2 in 0.0020780563354492188 seconds, solution distance = 10.088015890333441 Finished cycle #3 in 0.0017011165618896484 seconds, solution distance = 3.3534114736589693 Finished cycle #4 in 0.001529693603515625 seconds, solution distance = 1.669952961389428 Finished cycle #5 in 0.0019981861114501953 seconds, solution distance = 0.9967360674688486 Finished cycle #6 in 0.0018858909606933594 seconds, solution distance = 0.6602619046109517 Finished cycle #7 in 0.007195234298706055 seconds, solution distance = 0.46809484231437537 Finished cycle #8 in 0.002302885055541992 seconds, solution distance = 0.34807706501006663 Finished cycle #9 in 0.0022499561309814453 seconds, solution distance = 0.2681341538834978 Finished cycle #10 in 0.0018150806427001953 seconds, solution distance = 0.2122324816862755 Finished cycle #11 in 0.0015168190002441406 seconds, solution distance = 0.17162798586899441 Finished cycle #12 in 0.0026161670684814453 seconds, solution distance = 0.14121714401876417 Finished cycle #13 in 0.004358053207397461 seconds, solution distance = 0.11786112023934692 Finished cycle #14 in 0.0019199848175048828 seconds, solution distance = 0.09954374358267426 Finished cycle #15 in 0.002624034881591797 seconds, solution distance = 0.08492077965589928 Finished cycle #16 in 0.0026040077209472656 seconds, solution distance = 0.07306820983636797 Finished cycle #17 in 0.0028498172760009766 seconds, solution distance = 0.06333371450893699 Finished cycle #18 in 0.0033011436462402344 seconds, solution distance = 0.055246317280595036 Finished cycle #19 in 0.00168609619140625 seconds, solution distance = 0.04845886926538867 Finished cycle #20 in 0.0015017986297607422 seconds, solution distance = 0.042711109600137576 Finished cycle #21 in 0.0015749931335449219 seconds, solution distance = 0.037804865822300915 Finished cycle #22 in 0.0015451908111572266 seconds, solution distance = 0.03358704056809714 Finished cycle #23 in 0.0015947818756103516 seconds, solution distance = 0.029937835775703636 Finished cycle #24 in 0.0015821456909179688 seconds, solution distance = 0.02676242583398336 Finished cycle #25 in 0.0017249584197998047 seconds, solution distance = 0.02398495974448922 Finished cycle #26 in 0.0013790130615234375 seconds, solution distance = 0.021544181039296006 Finished cycle #27 in 0.0014410018920898438 seconds, solution distance = 0.019390181762535263 Finished cycle #28 in 0.0017719268798828125 seconds, solution distance = 0.01748196739049135 Finished cycle #29 in 0.0017309188842773438 seconds, solution distance = 0.015785611379662168 Finished cycle #30 in 0.0017249584197998047 seconds, solution distance = 0.014272839895088651 Finished cycle #31 in 0.0014142990112304688 seconds, solution distance = 0.012919936192925086 Finished cycle #32 in 0.001615762710571289 seconds, solution distance = 0.011706884785620986 Finished cycle #33 in 0.0022771358489990234 seconds, solution distance = 0.010616703056517629 Finished cycle #34 in 0.001847982406616211 seconds, solution distance = 0.009634898474986997 Finished cycle #35 in 0.0017590522766113281 seconds, solution distance = 0.00874904442068214 Finished cycle #36 in 0.0013680458068847656 seconds, solution distance = 0.007948413988061898 Finished cycle #37 in 0.0012519359588623047 seconds, solution distance = 0.00722372447082309 Finished cycle #38 in 0.0012059211730957031 seconds, solution distance = 0.006566906564932307 Finished cycle #39 in 0.0013859272003173828 seconds, solution distance = 0.005970916077075117 Finished cycle #40 in 0.0011909008026123047 seconds, solution distance = 0.005429579002497409 Finished cycle #41 in 0.00110626220703125 seconds, solution distance = 0.004937463273915643 Finished cycle #42 in 0.0010828971862792969 seconds, solution distance = 0.004489772052598262 Finished cycle #43 in 0.001149892807006836 seconds, solution distance = 0.004082254546442954 Finished cycle #44 in 0.0011780261993408203 seconds, solution distance = 0.003711131170160087 Finished cycle #45 in 0.0012040138244628906 seconds, solution distance = 0.003373030500466001 Finished cycle #46 in 0.001112222671508789 seconds, solution distance = 0.0030649359736791837 Finished cycle #47 in 0.0012929439544677734 seconds, solution distance = 0.0027841406665807256 Finished cycle #48 in 0.0010399818420410156 seconds, solution distance = 0.0025282088157077 Finished cycle #49 in 0.0010499954223632812 seconds, solution distance = 0.0022949429754119954 Finished cycle #50 in 0.0010769367218017578 seconds, solution distance = 0.0020823559119378388 Finished cycle #51 in 0.0010399818420410156 seconds, solution distance = 0.0018886464739757969 Finished cycle #52 in 0.0017330646514892578 seconds, solution distance = 0.0017121788176539532 Finished cycle #53 in 0.0021021366119384766 seconds, solution distance = 0.0015514644867238303 Finished cycle #54 in 0.0017199516296386719 seconds, solution distance = 0.0014051468883913287 Finished cycle #55 in 0.0011959075927734375 seconds, solution distance = 0.0012719878080478253 Finished cycle #56 in 0.001257181167602539 seconds, solution distance = 0.0011508556554602478 Finished cycle #57 in 0.0015118122100830078 seconds, solution distance = 0.001040715183035168 Finished cycle #58 in 0.0014200210571289062 seconds, solution distance = 0.0009406184572178233 Finished cycle #59 in 0.0014238357543945312 seconds, solution distance = 0.0008496968979514463 Finished cycle #60 in 0.002164125442504883 seconds, solution distance = 0.0007671542298588463 Finished cycle #61 in 0.0020990371704101562 seconds, solution distance = 0.0006922602130656763 Finished cycle #62 in 0.001447916030883789 seconds, solution distance = 0.00062434504219544 Finished cycle #63 in 0.001293182373046875 seconds, solution distance = 0.0005627943195669616 Finished cycle #64 in 0.0014579296112060547 seconds, solution distance = 0.0005070445234869325 Finished cycle #65 in 0.0012559890747070312 seconds, solution distance = 0.00045657890516936916 Finished cycle #66 in 0.0012729167938232422 seconds, solution distance = 0.0004109237583840297 Finished cycle #67 in 0.0014119148254394531 seconds, solution distance = 0.0003696450150627584 Finished cycle #68 in 0.00180816650390625 seconds, solution distance = 0.0003323451276209255 Finished cycle #69 in 0.002145051956176758 seconds, solution distance = 0.0002986602050065734 Finished cycle #70 in 0.0018019676208496094 seconds, solution distance = 0.0002682573749837047 Finished cycle #71 in 0.0016438961029052734 seconds, solution distance = 0.00024083234929284103 Finished cycle #72 in 0.00138092041015625 seconds, solution distance = 0.00021610717220754694 Finished cycle #73 in 0.0019290447235107422 seconds, solution distance = 0.00019382813573720625 Finished cycle #74 in 0.001438140869140625 seconds, solution distance = 0.0001737638473713332 Finished cycle #75 in 0.0015208721160888672 seconds, solution distance = 0.0001557034380539335 Finished cycle #76 in 0.0011610984802246094 seconds, solution distance = 0.00013945489982480908 Finished cycle #77 in 0.0014510154724121094 seconds, solution distance = 0.00012484354371977702 Finished cycle #78 in 0.0015549659729003906 seconds, solution distance = 0.00011171056964087711 Finished cycle #79 in 0.0016109943389892578 seconds, solution distance = 9.991174074253095e-05 Finished cycle #80 in 0.0013659000396728516 seconds, solution distance = 8.931615549911953e-05 Finished cycle #81 in 0.0011630058288574219 seconds, solution distance = 7.98051111954301e-05 Finished cycle #82 in 0.0012030601501464844 seconds, solution distance = 7.127105311699466e-05 Finished cycle #83 in 0.0011370182037353516 seconds, solution distance = 6.361660386744461e-05 Finished cycle #84 in 0.0010991096496582031 seconds, solution distance = 5.675366786039859e-05 Finished cycle #85 in 0.0011119842529296875 seconds, solution distance = 5.060260605649347e-05 Finished cycle #86 in 0.001277923583984375 seconds, solution distance = 4.5091476412739695e-05 Finished cycle #87 in 0.0012450218200683594 seconds, solution distance = 4.0155335675251536e-05 Finished cycle #88 in 0.0011320114135742188 seconds, solution distance = 3.573559836667073e-05 Finished cycle #89 in 0.0011420249938964844 seconds, solution distance = 3.1779449082502964e-05 Finished cycle #90 in 0.001935720443725586 seconds, solution distance = 2.8239304256771902e-05 Finished cycle #91 in 0.0014662742614746094 seconds, solution distance = 2.507231993220671e-05 Finished cycle #92 in 0.0020759105682373047 seconds, solution distance = 2.2239942116808464e-05 Finished cycle #93 in 0.0031790733337402344 seconds, solution distance = 1.970749654489623e-05 Finished cycle #94 in 0.0017740726470947266 seconds, solution distance = 1.7443814824158466e-05 Finished cycle #95 in 0.0015819072723388672 seconds, solution distance = 1.5420894161621845e-05 Finished cycle #96 in 0.0024521350860595703 seconds, solution distance = 1.361358793783296e-05 Finished cycle #97 in 0.002887725830078125 seconds, solution distance = 1.1999324726730265e-05 Finished cycle #98 in 0.0015711784362792969 seconds, solution distance = 1.0557853297399333e-05 Finished cycle #99 in 0.0014679431915283203 seconds, solution distance = 9.271011537581586e-06 Finished cycle #100 in 0.0019409656524658203 seconds, solution distance = 8.122517190400913e-06 Finished cycle #101 in 0.0013899803161621094 seconds, solution distance = 7.097778525810838e-06 Finished cycle #102 in 0.001196146011352539 seconds, solution distance = 6.183723240127392e-06 Finished cycle #103 in 0.0012407302856445312 seconds, solution distance = 5.368643900993675e-06 Finished cycle #104 in 0.0011181831359863281 seconds, solution distance = 4.6420585193551744e-06 Finished cycle #105 in 0.0012371540069580078 seconds, solution distance = 3.994584801603196e-06 Finished cycle #106 in 0.001432657241821289 seconds, solution distance = 3.4178268535356437e-06 Finished cycle #107 in 0.0011641979217529297 seconds, solution distance = 2.9042732037076746e-06 Finished cycle #108 in 0.0011570453643798828 seconds, solution distance = 2.4472050093038433e-06 Finished cycle #109 in 0.0012590885162353516 seconds, solution distance = 2.0406135354811283e-06 Finished cycle #110 in 0.0011327266693115234 seconds, solution distance = 1.6791260115667228e-06 Finished cycle #111 in 0.0011620521545410156 seconds, solution distance = 1.3579390065743269e-06 Finished cycle #112 in 0.001386880874633789 seconds, solution distance = 1.0727586690073565e-06 Finished cycle #113 in 0.0012333393096923828 seconds, solution distance = 8.197470720006095e-07
# plot_funcs([list],min,max) takes a [list] of functions and plots their values over a range from min to max
plot_funcs([IndShockExample.solution[0].cFunc,IndShockExample.solution_terminal.cFunc],0.,10.)
In the parameter dictionary above, we chose values for HARK to use when constructing its numerical representation of $F_t$, the joint distribution of permanent and transitory income shocks. When $\texttt{IndShockExample}$ was created, those parameters ($\texttt{TranShkStd}$, etc) were used by the constructor or initialization method of $\texttt{IndShockConsumerType}$ to construct an attribute called $\texttt{IncomeDstn}$.
Suppose you were interested in changing (say) the amount of permanent income risk. From the section above, you might think that you could simply change the attribute $\texttt{TranShkStd}$, solve the model again, and it would work.
That's almost true-- there's one extra step. $\texttt{TranShkStd}$ is a primitive input, but it's not the thing you actually want to change. Changing $\texttt{TranShkStd}$ doesn't actually update the income distribution... unless you tell it to (just like changing an agent's preferences does not change the consumption function that was stored for the old set of parameters -- until you invoke the $\texttt{solve}$ method again). In the cell below, we invoke the method $\texttt{updateIncomeProcess}$ so HARK knows to reconstruct the attribute $\texttt{IncomeDstn}$.
OtherExample = deepcopy(IndShockExample) # Make a copy so we can compare consumption functions
OtherExample.PermShkStd = [0.2] # Double permanent income risk (note that it's a one element list)
OtherExample.updateIncomeProcess() # Call the method to reconstruct the representation of F_t
OtherExample.solve()
GPFRaw = 0.984539 GPFNrm = 1.021965 GPFAggLivPrb = 0.964848 Thorn = APF = 0.994384 PermGroFacAdj = 0.973012 uInvEpShkuInv = 0.963379 VAF = 0.906347 WRPF = 0.213705 DiscFacGPFNrmMax = 0.919178 DiscFacGPFAggLivPrbMax = 1.010600
In the cell below, use your blossoming HARK skills to plot the consumption function for $\texttt{IndShockExample}$ and $\texttt{OtherExample}$ on the same figure.
# Use the remainder of this cell to plot the IndShockExample and OtherExample consumption functions against each other
There are some combinations of parameter values under which problems of the kind specified above have "degenerate" solutions; for example, if consumers are so patient that they always prefer deferring consumption to the future, the limiting consumption rule can be $c(m)=0$.
The toolkit has built-in tests for a number of parametric conditions that can be shown to result in various characteristics in the optimal solution.
Perhaps the most interesting such condition is the "Growth Impatience Condition": If this condition is satisfied, the consumer's optimal behavior is to aim to achieve a "target" value of $m$, to serve as a precautionary buffer against income shocks.
The tests can be invoked using the check_conditions()
method:
IndShockExample.check_conditions(verbose=True)
GPFRaw = 0.984539 GPFNrm = 0.993777 GPFAggLivPrb = 0.964848 Thorn = APF = 0.994384 PermGroFacAdj = 1.000611 uInvEpShkuInv = 0.990704 VAF = 0.932054 WRPF = 0.213705 DiscFacGPFNrmMax = 0.972061 DiscFacGPFAggLivPrbMax = 1.010600