diff --git a/.gitmodules b/.gitmodules
index b2bc1c87d..e69de29bb 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "Documentation/submodules/DemARK"]
- path = Documentation/submodules/DemARK
- url = https://github.com/econ-ark/DemARK
diff --git a/Documentation/example_notebooks/ConsPortfolioModelDoc.ipynb b/Documentation/example_notebooks/ConsPortfolioModelDoc.ipynb
new file mode 120000
index 000000000..148cec20a
--- /dev/null
+++ b/Documentation/example_notebooks/ConsPortfolioModelDoc.ipynb
@@ -0,0 +1 @@
+../../examples/ConsPortfolioModelDoc/ConsPortfolioModelDoc.ipynb
\ No newline at end of file
diff --git a/Documentation/example_notebooks/GenIncProcessModel.ipynb b/Documentation/example_notebooks/GenIncProcessModel.ipynb
new file mode 120000
index 000000000..95382b26a
--- /dev/null
+++ b/Documentation/example_notebooks/GenIncProcessModel.ipynb
@@ -0,0 +1 @@
+../../examples/GenIncProcessModel/GenIncProcessModel.ipynb
\ No newline at end of file
diff --git a/Documentation/example_notebooks/Gentle-Intro-To-HARK.ipynb b/Documentation/example_notebooks/Gentle-Intro-To-HARK.ipynb
new file mode 120000
index 000000000..85e84e64c
--- /dev/null
+++ b/Documentation/example_notebooks/Gentle-Intro-To-HARK.ipynb
@@ -0,0 +1 @@
+../../examples/Gentle-Intro/Gentle-Intro-To-HARK.ipynb
\ No newline at end of file
diff --git a/Documentation/example_notebooks/IndShockConsumerType.ipynb b/Documentation/example_notebooks/IndShockConsumerType.ipynb
new file mode 120000
index 000000000..2bc279db3
--- /dev/null
+++ b/Documentation/example_notebooks/IndShockConsumerType.ipynb
@@ -0,0 +1 @@
+../../examples/ConsIndShockModel/IndShockConsumerType.ipynb
\ No newline at end of file
diff --git a/Documentation/example_notebooks/KinkedRconsumerType.ipynb b/Documentation/example_notebooks/KinkedRconsumerType.ipynb
new file mode 120000
index 000000000..fd9844aa1
--- /dev/null
+++ b/Documentation/example_notebooks/KinkedRconsumerType.ipynb
@@ -0,0 +1 @@
+../../examples/ConsIndShockModel/KinkedRconsumerType.ipynb
\ No newline at end of file
diff --git a/Documentation/example_notebooks/LifecycleModelExample.ipynb b/Documentation/example_notebooks/LifecycleModelExample.ipynb
new file mode 120000
index 000000000..564f6c0d2
--- /dev/null
+++ b/Documentation/example_notebooks/LifecycleModelExample.ipynb
@@ -0,0 +1 @@
+../../examples/LifecycleModel/LifecycleModelExample.ipynb
\ No newline at end of file
diff --git a/Documentation/example_notebooks/PerfForesightConsumerType.ipynb b/Documentation/example_notebooks/PerfForesightConsumerType.ipynb
new file mode 120000
index 000000000..23345c01c
--- /dev/null
+++ b/Documentation/example_notebooks/PerfForesightConsumerType.ipynb
@@ -0,0 +1 @@
+../../examples/ConsIndShockModel/PerfForesightConsumerType.ipynb
\ No newline at end of file
diff --git a/Documentation/example_notebooks/README.md b/Documentation/example_notebooks/README.md
new file mode 100644
index 000000000..bef0ac27f
--- /dev/null
+++ b/Documentation/example_notebooks/README.md
@@ -0,0 +1,5 @@
+This directory contains symlinks to the notebooks in the top level `examples/` directory.
+
+These symlinks are referenced in the sphinx documentation, e.g. in `index.rst`.
+
+`nbsphinx`, the sphinx notebook extension, sees the `.ipynb` extension, and resolves the link, properly converting the notebook into Sphinx themed HTML.
\ No newline at end of file
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 9ca2810b6..b7ae1edc3 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -28,8 +28,13 @@ you might want to look at the `DemARK
:maxdepth: 2
:caption: Notebooks
- submodules/DemARK/notebooks/Gentle-Intro-To-HARK
- submodules/DemARK/notebooks/KinkedRconsumerType
+ example_notebooks/Gentle-Intro-To-HARK.ipynb
+ example_notebooks/PerfForesightConsumerType.ipynb
+ example_notebooks/IndShockConsumerType.ipynb
+ example_notebooks/KinkedRconsumerType.ipynb
+ example_notebooks/ConsPortfolioModelDoc.ipynb
+ example_notebooks/GenIncProcessModel.ipynb
+ example_notebooks/LifecycleModelExample.ipynb
.. toctree::
:maxdepth: 2
diff --git a/Documentation/submodules/DemARK b/Documentation/submodules/DemARK
deleted file mode 160000
index ad40b284e..000000000
--- a/Documentation/submodules/DemARK
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit ad40b284e3b9320daac0e4b5d75a3335072b4f12
diff --git a/Documentation/submodules/README.rst b/Documentation/submodules/README.rst
deleted file mode 100644
index ef4e4f86d..000000000
--- a/Documentation/submodules/README.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Adding a submodule
-------------------
-
-This directory contains submodules that are used for generating docs.
-
-You can add a new one like this::
-
- git submodule add https://github.com/econ-ark/DemARK
-
-Then when building on Read the Docs,
-it should automatically be cloned and included in the build.
diff --git a/examples/ConsIndShockModel/IndShockConsumerType.ipynb b/examples/ConsIndShockModel/IndShockConsumerType.ipynb
new file mode 100644
index 000000000..868c9f5b4
--- /dev/null
+++ b/examples/ConsIndShockModel/IndShockConsumerType.ipynb
@@ -0,0 +1,696 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# IndShockConsumerType Documentation\n",
+ "## Consumption-Saving model with Idiosyncratic Income Shocks"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "code_folding": [
+ 0
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "# Initial imports and notebook setup, click arrow to show\n",
+ "from HARK.ConsumptionSaving.ConsIndShockModel import IndShockConsumerType\n",
+ "from HARK.utilities import plotFuncsDer, plotFuncs\n",
+ "from time import clock\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "mystr = lambda number : \"{:.4f}\".format(number)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The module $\\texttt{HARK.ConsumptionSaving.ConsIndShockModel}$ concerns consumption-saving models with idiosyncratic shocks to (non-capital) income. All of the models assume CRRA utility with geometric discounting, no bequest motive, and income shocks are fully transitory or fully permanent.\n",
+ "\n",
+ "$\\texttt{ConsIndShockModel}$ includes:\n",
+ "1. A very basic \"perfect foresight\" model with no uncertainty.\n",
+ "2. A model with risk over transitory and permanent income shocks.\n",
+ "3. The model described in (2), with an interest rate for debt that differs from the interest rate for savings.\n",
+ "\n",
+ "This notebook provides documentation for the second of these models.\n",
+ "$\\newcommand{\\CRRA}{\\rho}$\n",
+ "$\\newcommand{\\DiePrb}{\\mathsf{D}}$\n",
+ "$\\newcommand{\\PermGroFac}{\\Gamma}$\n",
+ "$\\newcommand{\\Rfree}{\\mathsf{R}}$\n",
+ "$\\newcommand{\\DiscFac}{\\beta}$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Statement of idiosyncratic income shocks model\n",
+ "\n",
+ "Suppose we want to solve a model like the one analyzed in [BufferStockTheory](http://econ.jhu.edu/people/ccarroll/papers/BufferStockTheory/), with all the same features as the perfect foresight consumer, plus idiosyncratic shocks to income each period. Agents with this kind of model are represented by the class $\\texttt{IndShockConsumerType}$.\n",
+ "\n",
+ "Specifically, this type of consumer receives two income shocks at the beginning of each period: a completely transitory shock $\\newcommand{\\tShkEmp}{\\theta}{\\tShkEmp_t}$ and a completely permanent shock $\\newcommand{\\pShk}{\\psi}{\\pShk_t}$. Moreover, lenders will not let the agent borrow money such that his ratio of end-of-period assets $A_t$ to permanent income $P_t$ is less than $\\underline{a}$. As with the perfect foresight problem, this model can be framed in terms of *normalized* variables, dividing all real variables by $P_t$:\n",
+ "\n",
+ "\\begin{eqnarray*}\n",
+ "v_t(m_t) &=& \\max_{c_t} {~} u(c_t) + \\DiscFac (1-\\DiePrb_{t+1}) \\mathbb{E}_{t} \\left[ (\\PermGroFac_{t+1}\\psi_{t+1})^{1-\\CRRA} v_{t+1}(m_{t+1}) \\right], \\\\\n",
+ "a_t &=& m_t - c_t, \\\\\n",
+ "a_t &\\geq& \\underline{a}, \\\\\n",
+ "m_{t+1} &=& \\Rfree/(\\PermGroFac_{t+1} \\psi_{t+1}) a_t + \\theta_{t+1}, \\\\\n",
+ "(\\psi_{t+1},\\theta_{t+1}) &\\sim& F_{t+1}, \\\\\n",
+ "\\mathbb{E}[\\psi]=\\mathbb{E}[\\theta] &=& 1, \\\\\n",
+ "u(c) &=& \\frac{c^{1-\\rho}}{1-\\rho}.\n",
+ "\\end{eqnarray*}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Solution method for IndShockConsumerType\n",
+ "\n",
+ "With the introduction of (non-trivial) risk, the idiosyncratic income shocks model has no closed form solution and must be solved numerically. The function $\\texttt{solveConsIndShock}$ solves the one period problem for the $\\texttt{IndShockConsumerType}$ class. To do so, HARK uses the original version of the endogenous grid method (EGM) first described [here](http://www.econ2.jhu.edu/people/ccarroll/EndogenousGridpoints.pdf) ; see also the [SolvingMicroDSOPs](http://www.econ2.jhu.edu/people/ccarroll/SolvingMicroDSOPs/) lecture notes. \n",
+ "\n",
+ "Briefly, the transition equation for $m_{t+1}$ can be substituted into the problem definition; the second term of the reformulated maximand represents \"end of period value of assets\" $\\mathfrak{v}_t(a_t)$ (\"Gothic v\"):\n",
+ "\n",
+ "\\begin{eqnarray*}\n",
+ "v_t(m_t) &=& \\max_{c_t} {~} U(c_t) + \\underbrace{\\DiscFac (1-\\DiePrb_{t+1}) \\mathbb{E}_{t} \\left[ (\\PermGroFac_{t+1}\\psi_{t+1})^{1-\\CRRA} v_{t+1}(\\Rfree/(\\PermGroFac_{t+1} \\psi_{t+1}) a_t + \\theta_{t+1}) \\right]}_{\\equiv \\mathfrak{v}_t(a_t)}.\n",
+ "\\end{eqnarray*}\n",
+ "\n",
+ "The first order condition with respect to $c_t$ is thus simply:\n",
+ "\n",
+ "\\begin{eqnarray*}\n",
+ "U'(c_t) - \\mathfrak{v}'_t(a_t) = 0 \\Longrightarrow c_t^{-\\CRRA} = \\mathfrak{v}'_t(a_t) \\Longrightarrow c_t = \\mathfrak{v}'_t(a_t)^{-1/\\CRRA}.\n",
+ "\\end{eqnarray*}\n",
+ "\n",
+ "Where the marginal value of end-of-period assets can be computed as:\n",
+ "\n",
+ "\\begin{eqnarray*}\n",
+ "\\mathfrak{v}'_t(a_t) = \\DiscFac (1-\\DiePrb_{t+1}) \\mathbb{E}_{t} \\left[ \\Rfree (\\PermGroFac_{t+1}\\psi_{t+1})^{-\\CRRA} v'_{t+1}(\\Rfree/(\\PermGroFac_{t+1} \\psi_{t+1}) a_t + \\theta_{t+1}) \\right].\n",
+ "\\end{eqnarray*}\n",
+ "\n",
+ "To solve the model, we choose an exogenous grid of $a_t$ values that spans the range of values that could plausibly be achieved, compute $\\mathfrak{v}'_t(a_t)$ at each of these points, calculate the value of consumption $c_t$ whose marginal utility is consistent with the marginal value of assets, then find the endogenous $m_t$ gridpoint as $m_t = a_t + c_t$. The set of $(m_t,c_t)$ gridpoints is then interpolated to construct the consumption function."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Example parameter values to construct an instance of IndShockConsumerType\n",
+ "\n",
+ "In order to create an instance of $\\texttt{IndShockConsumerType}$, the user must specify parameters that characterize the (age-varying) distribution of income shocks $F_{t+1}$, the artificial borrowing constraint $\\underline{a}$, and the exogenous grid of end-of-period assets-above-minimum for use by EGM, along with all of the parameters for the perfect foresight model. The table below presents the complete list of parameter values required to instantiate an $\\texttt{IndShockConsumerType}$, along with example values.\n",
+ "\n",
+ "| Parameter | Description | Code | Example value | Time-varying? |\n",
+ "| :---: | --- | --- | --- | --- |\n",
+ "| $\\DiscFac$ |Intertemporal discount factor | $\\texttt{DiscFac}$ | $0.96$ | |\n",
+ "| $\\CRRA $ |Coefficient of relative risk aversion | $\\texttt{CRRA}$ | $2.0$ | |\n",
+ "| $\\Rfree$ | Risk free interest factor | $\\texttt{Rfree}$ | $1.03$ | |\n",
+ "| $1 - \\DiePrb_{t+1}$ |Survival probability | $\\texttt{LivPrb}$ | $[0.98]$ | $\\surd$ |\n",
+ "|$\\PermGroFac_{t+1}$|Permanent income growth factor|$\\texttt{PermGroFac}$| $[1.01]$ | $\\surd$ |\n",
+ "| $\\sigma_\\psi $ | Standard deviation of log permanent income shocks | $\\texttt{PermShkStd}$ | $[0.1]$ |$\\surd$ |\n",
+ "| $N_\\psi $ | Number of discrete permanent income shocks | $\\texttt{PermShkCount}$ | $7$ | |\n",
+ "| $\\sigma_\\theta $ | Standard deviation of log transitory income shocks | $\\texttt{TranShkStd}$ | $[0.2]$ | $\\surd$ |\n",
+ "| $N_\\theta $ | Number of discrete transitory income shocks | $\\texttt{TranShkCount}$ | $7$ | |\n",
+ "| $\\mho$ | Probability of being unemployed and getting $\\theta=\\underline{\\theta}$ | $\\texttt{UnempPrb}$ | $0.05$ | |\n",
+ "| $\\underline{\\theta} $ | Transitory shock when unemployed | $\\texttt{IncUnemp}$ | $0.3$ | |\n",
+ "| $\\mho^{Ret}$ | Probability of being \"unemployed\" when retired | $\\texttt{UnempPrb}$ | $0.0005$ | |\n",
+ "| $\\underline{\\theta}^{Ret} $ | Transitory shock when \"unemployed\" and retired | $\\texttt{IncUnemp}$ | $0.0$ | |\n",
+ "| $(none)$ | Period of the lifecycle model when retirement begins | $\\texttt{T_retire}$ | $0$ | |\n",
+ "| $(none)$ | Minimum value in assets-above-minimum grid | $\\texttt{aXtraMin}$ | $0.001$ | |\n",
+ "| $(none)$ | Maximum value in assets-above-minimum grid | $\\texttt{aXtraMax}$ | $20.0$ | |\n",
+ "| $(none)$ | Number of points in base assets-above-minimum grid | $\\texttt{aXtraCount}$ | $48$ | |\n",
+ "| $(none)$ | Exponential nesting factor for base assets-above-minimum grid | $\\texttt{aXtraNestFac}$ | $3$ | |\n",
+ "| $(none)$ | Additional values to add to assets-above-minimum grid | $\\texttt{aXtraExtra}$ | $None$ | |\n",
+ "| $\\underline{a} $ | Artificial borrowing constraint (normalized) | $\\texttt{BoroCnstArt}$ | $0.0$ | |\n",
+ "| $(none) $ |Indicator for whether $\\texttt{vFunc}$ should be computed | $\\texttt{vFuncBool}$ | $True$ | |\n",
+ "| $(none)$ |Indicator for whether $\\texttt{cFunc}$ should use cubic splines | $\\texttt{CubicBool}$ | $False$ | |\n",
+ "|$T$| Number of periods in this type's \"cycle\" |$\\texttt{T_cycle}$| $1$ | |\n",
+ "|(none)| Number of times the \"cycle\" occurs |$\\texttt{cycles}$| $0$ | |"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "code_folding": [
+ 0
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "IdiosyncDict={\n",
+ " # Parameters shared with the perfect foresight model\n",
+ " \"CRRA\": 2.0, # Coefficient of relative risk aversion\n",
+ " \"Rfree\": 1.03, # Interest factor on assets\n",
+ " \"DiscFac\": 0.96, # Intertemporal discount factor\n",
+ " \"LivPrb\" : [0.98], # Survival probability\n",
+ " \"PermGroFac\" :[1.01], # Permanent income growth factor\n",
+ " \n",
+ " # Parameters that specify the income distribution over the lifecycle\n",
+ " \"PermShkStd\" : [0.1], # Standard deviation of log permanent shocks to income\n",
+ " \"PermShkCount\" : 7, # Number of points in discrete approximation to permanent income shocks\n",
+ " \"TranShkStd\" : [0.2], # Standard deviation of log transitory shocks to income\n",
+ " \"TranShkCount\" : 7, # Number of points in discrete approximation to transitory income shocks\n",
+ " \"UnempPrb\" : 0.05, # Probability of unemployment while working\n",
+ " \"IncUnemp\" : 0.3, # Unemployment benefits replacement rate\n",
+ " \"UnempPrbRet\" : 0.0005, # Probability of \"unemployment\" while retired\n",
+ " \"IncUnempRet\" : 0.0, # \"Unemployment\" benefits when retired\n",
+ " \"T_retire\" : 0, # Period of retirement (0 --> no retirement)\n",
+ " \"tax_rate\" : 0.0, # Flat income tax rate (legacy parameter, will be removed in future)\n",
+ " \n",
+ " # Parameters for constructing the \"assets above minimum\" grid\n",
+ " \"aXtraMin\" : 0.001, # Minimum end-of-period \"assets above minimum\" value\n",
+ " \"aXtraMax\" : 20, # Maximum end-of-period \"assets above minimum\" value\n",
+ " \"aXtraCount\" : 48, # Number of points in the base grid of \"assets above minimum\"\n",
+ " \"aXtraNestFac\" : 3, # Exponential nesting factor when constructing \"assets above minimum\" grid\n",
+ " \"aXtraExtra\" : [None], # Additional values to add to aXtraGrid\n",
+ " \n",
+ " # A few other paramaters\n",
+ " \"BoroCnstArt\" : 0.0, # Artificial borrowing constraint; imposed minimum level of end-of period assets\n",
+ " \"vFuncBool\" : True, # Whether to calculate the value function during solution \n",
+ " \"CubicBool\" : False, # Preference shocks currently only compatible with linear cFunc\n",
+ " \"T_cycle\" : 1, # Number of periods in the cycle for this agent type \n",
+ " \n",
+ " # Parameters only used in simulation\n",
+ " \"AgentCount\" : 10000, # Number of agents of this type\n",
+ " \"T_sim\" : 120, # Number of periods to simulate\n",
+ " \"aNrmInitMean\" : -6.0, # Mean of log initial assets\n",
+ " \"aNrmInitStd\" : 1.0, # Standard deviation of log initial assets\n",
+ " \"pLvlInitMean\" : 0.0, # Mean of log initial permanent income\n",
+ " \"pLvlInitStd\" : 0.0, # Standard deviation of log initial permanent income\n",
+ " \"PermGroFacAgg\" : 1.0, # Aggregate permanent income growth factor\n",
+ " \"T_age\" : None, # Age after which simulated agents are automatically killed\n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The distribution of permanent income shocks is specified as mean one lognormal, with an age-varying (underlying) standard deviation. The distribution of transitory income shocks is also mean one lognormal, but with an additional point mass representing unemployment; the transitory shocks are adjusted so that the distribution is still mean one. The continuous distributions are discretized with an equiprobable distribution.\n",
+ "\n",
+ "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.\n",
+ "\n",
+ "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$.\n",
+ "\n",
+ "The artificial borrowing constraint $\\texttt{BoroCnstArt}$ can be set to $\\texttt{None}$ to turn it off.\n",
+ "\n",
+ "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}$."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "heading_collapsed": true
+ },
+ "source": [
+ "## Solving and examining the solution of the idiosyncratic income shocks model\n",
+ "\n",
+ "The cell below creates an infinite horizon instance of $\\texttt{IndShockConsumerType}$ and solves its model by calling its $\\texttt{solve}$ method."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "hidden": true,
+ "lines_to_next_cell": 2
+ },
+ "outputs": [],
+ "source": [
+ "IndShockExample = IndShockConsumerType(**IdiosyncDict)\n",
+ "IndShockExample.cycles = 0 # Make this type have an infinite horizon\n",
+ "IndShockExample.solve()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "hidden": true
+ },
+ "source": [
+ "After solving the model, we can examine an element of this type's $\\texttt{solution}$:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "hidden": true
+ },
+ "outputs": [],
+ "source": [
+ "print(vars(IndShockExample.solution[0]))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "hidden": true
+ },
+ "source": [
+ "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.\n",
+ "\n",
+ "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.\n",
+ "\n",
+ "Let's take a look at the consumption function by plotting it, along with its derivative (the MPC):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "hidden": true
+ },
+ "outputs": [],
+ "source": [
+ "print('Consumption function for an idiosyncratic shocks consumer type:')\n",
+ "plotFuncs(IndShockExample.solution[0].cFunc,IndShockExample.solution[0].mNrmMin,5)\n",
+ "print('Marginal propensity to consume for an idiosyncratic shocks consumer type:')\n",
+ "plotFuncsDer(IndShockExample.solution[0].cFunc,IndShockExample.solution[0].mNrmMin,5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "hidden": true
+ },
+ "source": [
+ "The lower part of the consumption function is linear with a slope of 1, representing the *constrained* part of the consumption function where the consumer *would like* to consume more by borrowing-- his marginal utility of consumption exceeds the marginal value of assets-- but he is prevented from doing so by the artificial borrowing constraint.\n",
+ "\n",
+ "The MPC is a step function, as the $\\texttt{cFunc}$ itself is a piecewise linear function; note the large jump in the MPC where the borrowing constraint begins to bind.\n",
+ "\n",
+ "If you want to look at the interpolation nodes for the consumption function, these can be found by \"digging into\" attributes of $\\texttt{cFunc}$:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "hidden": true
+ },
+ "outputs": [],
+ "source": [
+ "print('mNrmGrid for unconstrained cFunc is ',IndShockExample.solution[0].cFunc.functions[0].x_list)\n",
+ "print('cNrmGrid for unconstrained cFunc is ',IndShockExample.solution[0].cFunc.functions[0].y_list)\n",
+ "print('mNrmGrid for borrowing constrained cFunc is ',IndShockExample.solution[0].cFunc.functions[1].x_list)\n",
+ "print('cNrmGrid for borrowing constrained cFunc is ',IndShockExample.solution[0].cFunc.functions[1].y_list)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "hidden": true
+ },
+ "source": [
+ "The consumption function in this model is an instance of $\\texttt{LowerEnvelope1D}$, a class that takes an arbitrary number of 1D interpolants as arguments to its initialization method. When called, a $\\texttt{LowerEnvelope1D}$ evaluates each of its component functions and returns the lowest value. Here, the two component functions are the *unconstrained* consumption function-- how the agent would consume if the artificial borrowing constraint did not exist for *just this period*-- and the *borrowing constrained* consumption function-- how much he would consume if the artificial borrowing constraint is binding. \n",
+ "\n",
+ "The *actual* consumption function is the lower of these two functions, pointwise. We can see this by plotting the component functions on the same figure:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "hidden": true
+ },
+ "outputs": [],
+ "source": [
+ "plotFuncs(IndShockExample.solution[0].cFunc.functions,-0.25,5.)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Simulating the idiosyncratic income shocks model\n",
+ "\n",
+ "In order to generate simulated data, an instance of $\\texttt{IndShockConsumerType}$ needs to know how many agents there are that share these particular parameters (and are thus *ex ante* homogeneous), the distribution of states for newly \"born\" agents, and how many periods to simulated. These simulation parameters are described in the table below, along with example values.\n",
+ "\n",
+ "| Description | Code | Example value |\n",
+ "| :---: | --- | --- |\n",
+ "| Number of consumers of this type | $\\texttt{AgentCount}$ | $10000$ |\n",
+ "| Number of periods to simulate | $\\texttt{T_sim}$ | $120$ |\n",
+ "| Mean of initial log (normalized) assets | $\\texttt{aNrmInitMean}$ | $-6.0$ |\n",
+ "| Stdev of initial log (normalized) assets | $\\texttt{aNrmInitStd}$ | $1.0$ |\n",
+ "| Mean of initial log permanent income | $\\texttt{pLvlInitMean}$ | $0.0$ |\n",
+ "| Stdev of initial log permanent income | $\\texttt{pLvlInitStd}$ | $0.0$ |\n",
+ "| Aggregrate productivity growth factor | $\\texttt{PermGroFacAgg}$ | $1.0$ |\n",
+ "| Age after which consumers are automatically killed | $\\texttt{T_age}$ | $None$ |\n",
+ "\n",
+ "Here, we will simulate 10,000 consumers for 120 periods. All newly born agents will start with permanent income of exactly $P_t = 1.0 = \\exp(\\texttt{pLvlInitMean})$, as $\\texttt{pLvlInitStd}$ has been set to zero; they will have essentially zero assets at birth, as $\\texttt{aNrmInitMean}$ is $-6.0$; assets will be less than $1\\%$ of permanent income at birth.\n",
+ "\n",
+ "These example parameter values were already passed as part of the parameter dictionary that we used to create $\\texttt{IndShockExample}$, so it is ready to simulate. We need to set the $\\texttt{track_vars}$ attribute to indicate the variables for which we want to record a *history*."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "IndShockExample.track_vars = ['aNrmNow','mNrmNow','cNrmNow','pLvlNow']\n",
+ "IndShockExample.initializeSim()\n",
+ "IndShockExample.simulate()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can now look at the simulated data in aggregate or at the individual consumer level. Like in the perfect foresight model, we can plot average (normalized) market resources over time, as well as average consumption:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "plt.plot(np.mean(IndShockExample.mNrmNow_hist,axis=1))\n",
+ "plt.xlabel('Time')\n",
+ "plt.ylabel('Mean market resources')\n",
+ "plt.show()\n",
+ "\n",
+ "plt.plot(np.mean(IndShockExample.cNrmNow_hist,axis=1))\n",
+ "plt.xlabel('Time')\n",
+ "plt.ylabel('Mean consumption')\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We could also plot individual consumption paths for some of the consumers-- say, the first five:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "plt.plot(IndShockExample.cNrmNow_hist[:,0:5])\n",
+ "plt.xlabel('Time')\n",
+ "plt.ylabel('Individual consumption paths')\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Other example specifications of idiosyncratic income shocks consumers\n",
+ "\n",
+ "$\\texttt{IndShockConsumerType}$-- and $\\texttt{HARK}$ in general-- can also represent models that are not infinite horizon. \n",
+ "\n",
+ "### Lifecycle example\n",
+ "\n",
+ "Suppose we wanted to represent consumers with a *lifecycle*-- parameter values that differ by age, with a finite end point beyond which the individual cannot surive. This can be done very easily by simply specifying the time-varying attributes $\\texttt{PermGroFac}$, $\\texttt{LivPrb}$, $\\texttt{PermShkStd}$, and $\\texttt{TranShkStd}$ as Python *lists* specifying the sequence of periods these agents will experience, from beginning to end.\n",
+ "\n",
+ "In the cell below, we define a parameter dictionary for a rather short ten period lifecycle, with arbitrarily chosen parameters. For a more realistically calibrated (and much longer) lifecycle model, see the [SolvingMicroDSOPs REMARK](https://github.com/econ-ark/REMARK/blob/master/REMARKs/SolvingMicroDSOPs.md)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "code_folding": [
+ 0
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "LifecycleDict={ # Click arrow to expand this fairly large parameter dictionary\n",
+ " # Parameters shared with the perfect foresight model\n",
+ " \"CRRA\": 2.0, # Coefficient of relative risk aversion\n",
+ " \"Rfree\": 1.03, # Interest factor on assets\n",
+ " \"DiscFac\": 0.96, # Intertemporal discount factor\n",
+ " \"LivPrb\" : [0.99,0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1],\n",
+ " \"PermGroFac\" : [1.01,1.01,1.01,1.02,1.02,1.02,0.7,1.0,1.0,1.0],\n",
+ " \n",
+ " # Parameters that specify the income distribution over the lifecycle\n",
+ " \"PermShkStd\" : [0.1,0.2,0.1,0.2,0.1,0.2,0.1,0,0,0],\n",
+ " \"PermShkCount\" : 7, # Number of points in discrete approximation to permanent income shocks\n",
+ " \"TranShkStd\" : [0.3,0.2,0.1,0.3,0.2,0.1,0.3,0,0,0],\n",
+ " \"TranShkCount\" : 7, # Number of points in discrete approximation to transitory income shocks\n",
+ " \"UnempPrb\" : 0.05, # Probability of unemployment while working\n",
+ " \"IncUnemp\" : 0.3, # Unemployment benefits replacement rate\n",
+ " \"UnempPrbRet\" : 0.0005, # Probability of \"unemployment\" while retired\n",
+ " \"IncUnempRet\" : 0.0, # \"Unemployment\" benefits when retired\n",
+ " \"T_retire\" : 7, # Period of retirement (0 --> no retirement)\n",
+ " \"tax_rate\" : 0.0, # Flat income tax rate (legacy parameter, will be removed in future)\n",
+ " \n",
+ " # Parameters for constructing the \"assets above minimum\" grid\n",
+ " \"aXtraMin\" : 0.001, # Minimum end-of-period \"assets above minimum\" value\n",
+ " \"aXtraMax\" : 20, # Maximum end-of-period \"assets above minimum\" value\n",
+ " \"aXtraCount\" : 48, # Number of points in the base grid of \"assets above minimum\"\n",
+ " \"aXtraNestFac\" : 3, # Exponential nesting factor when constructing \"assets above minimum\" grid\n",
+ " \"aXtraExtra\" : [None], # Additional values to add to aXtraGrid\n",
+ " \n",
+ " # A few other paramaters\n",
+ " \"BoroCnstArt\" : 0.0, # Artificial borrowing constraint; imposed minimum level of end-of period assets\n",
+ " \"vFuncBool\" : True, # Whether to calculate the value function during solution \n",
+ " \"CubicBool\" : False, # Preference shocks currently only compatible with linear cFunc\n",
+ " \"T_cycle\" : 10, # Number of periods in the cycle for this agent type \n",
+ " \n",
+ " # Parameters only used in simulation\n",
+ " \"AgentCount\" : 10000, # Number of agents of this type\n",
+ " \"T_sim\" : 120, # Number of periods to simulate\n",
+ " \"aNrmInitMean\" : -6.0, # Mean of log initial assets\n",
+ " \"aNrmInitStd\" : 1.0, # Standard deviation of log initial assets\n",
+ " \"pLvlInitMean\" : 0.0, # Mean of log initial permanent income\n",
+ " \"pLvlInitStd\" : 0.0, # Standard deviation of log initial permanent income\n",
+ " \"PermGroFacAgg\" : 1.0, # Aggregate permanent income growth factor\n",
+ " \"T_age\" : 11, # Age after which simulated agents are automatically killed \n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "In this case, we have specified a ten period model in which retirement happens in period $t=7$. Agents in this model are more likely to die as they age, and their permanent income drops by 30\\% at retirement. Let's make and solve this lifecycle example, then look at the $\\texttt{solution}$ attribute."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "LifecycleExample = IndShockConsumerType(**LifecycleDict)\n",
+ "LifecycleExample.cycles = 1 # Make this consumer live a sequence of periods -- a lifetime -- exactly once\n",
+ "LifecycleExample.solve()\n",
+ "print('First element of solution is',LifecycleExample.solution[0])\n",
+ "print('Solution has', len(LifecycleExample.solution),'elements.')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This was supposed to be a *ten* period lifecycle model-- why does our consumer type have *eleven* elements in its $\\texttt{solution}$? It would be more precise to say that this specification has ten *non-terminal* periods. The solution to the 11th and final period in the model would be the same for every set of parameters: consume $c_t = m_t$, because there is no future. In a lifecycle model, the terminal period is assumed to exist; the $\\texttt{LivPrb}$ parameter does not need to end with a $0.0$ in order to guarantee that survivors die.\n",
+ "\n",
+ "We can quickly plot the consumption functions in each period of the model:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print('Consumption functions across the lifecycle:')\n",
+ "mMin = np.min([LifecycleExample.solution[t].mNrmMin for t in range(LifecycleExample.T_cycle)])\n",
+ "LifecycleExample.unpackcFunc() # This makes all of the cFuncs accessible in the attribute cFunc\n",
+ "plotFuncs(LifecycleExample.cFunc,mMin,5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### \"Cyclical\" example\n",
+ "\n",
+ "We can also model consumers who face an infinite horizon, but who do *not* face the same problem in every period. Consider someone who works as a ski instructor: they make most of their income for the year in the winter, and make very little money in the other three seasons.\n",
+ "\n",
+ "We can represent this type of individual as a four period, infinite horizon model in which expected \"permanent\" income growth varies greatly across seasons."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "code_folding": [
+ 0
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "CyclicalDict = { # Click the arrow to expand this parameter dictionary\n",
+ " # Parameters shared with the perfect foresight model\n",
+ " \"CRRA\": 2.0, # Coefficient of relative risk aversion\n",
+ " \"Rfree\": 1.03, # Interest factor on assets\n",
+ " \"DiscFac\": 0.96, # Intertemporal discount factor\n",
+ " \"LivPrb\" : 4*[0.98], # Survival probability\n",
+ " \"PermGroFac\" : [1.082251, 2.8, 0.3, 1.1],\n",
+ " \n",
+ " # Parameters that specify the income distribution over the lifecycle\n",
+ " \"PermShkStd\" : [0.1,0.1,0.1,0.1],\n",
+ " \"PermShkCount\" : 7, # Number of points in discrete approximation to permanent income shocks\n",
+ " \"TranShkStd\" : [0.2,0.2,0.2,0.2],\n",
+ " \"TranShkCount\" : 7, # Number of points in discrete approximation to transitory income shocks\n",
+ " \"UnempPrb\" : 0.05, # Probability of unemployment while working\n",
+ " \"IncUnemp\" : 0.3, # Unemployment benefits replacement rate\n",
+ " \"UnempPrbRet\" : 0.0005, # Probability of \"unemployment\" while retired\n",
+ " \"IncUnempRet\" : 0.0, # \"Unemployment\" benefits when retired\n",
+ " \"T_retire\" : 0, # Period of retirement (0 --> no retirement)\n",
+ " \"tax_rate\" : 0.0, # Flat income tax rate (legacy parameter, will be removed in future)\n",
+ " \n",
+ " # Parameters for constructing the \"assets above minimum\" grid\n",
+ " \"aXtraMin\" : 0.001, # Minimum end-of-period \"assets above minimum\" value\n",
+ " \"aXtraMax\" : 20, # Maximum end-of-period \"assets above minimum\" value\n",
+ " \"aXtraCount\" : 48, # Number of points in the base grid of \"assets above minimum\"\n",
+ " \"aXtraNestFac\" : 3, # Exponential nesting factor when constructing \"assets above minimum\" grid\n",
+ " \"aXtraExtra\" : [None], # Additional values to add to aXtraGrid\n",
+ " \n",
+ " # A few other paramaters\n",
+ " \"BoroCnstArt\" : 0.0, # Artificial borrowing constraint; imposed minimum level of end-of period assets\n",
+ " \"vFuncBool\" : True, # Whether to calculate the value function during solution \n",
+ " \"CubicBool\" : False, # Preference shocks currently only compatible with linear cFunc\n",
+ " \"T_cycle\" : 4, # Number of periods in the cycle for this agent type \n",
+ " \n",
+ " # Parameters only used in simulation\n",
+ " \"AgentCount\" : 10000, # Number of agents of this type\n",
+ " \"T_sim\" : 120, # Number of periods to simulate\n",
+ " \"aNrmInitMean\" : -6.0, # Mean of log initial assets\n",
+ " \"aNrmInitStd\" : 1.0, # Standard deviation of log initial assets\n",
+ " \"pLvlInitMean\" : 0.0, # Mean of log initial permanent income\n",
+ " \"pLvlInitStd\" : 0.0, # Standard deviation of log initial permanent income\n",
+ " \"PermGroFacAgg\" : 1.0, # Aggregate permanent income growth factor\n",
+ " \"T_age\" : None, # Age after which simulated agents are automatically killed \n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This consumer type's parameter dictionary is nearly identical to the original infinite horizon type we made, except that each of the time-varying parameters now have *four* values, rather than just one. Most of these have the same value in each period *except* for $\\texttt{PermGroFac}$, which varies greatly over the four seasons. Note that the product of the four \"permanent\" income growth factors is almost exactly 1.0-- this type's income does not grow on average in the long run!\n",
+ "\n",
+ "Let's make and solve this consumer type, then plot his quarterly consumption functions:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "CyclicalExample = IndShockConsumerType(**CyclicalDict)\n",
+ "CyclicalExample.cycles = 0 # Make this consumer type have an infinite horizon\n",
+ "CyclicalExample.solve()\n",
+ "\n",
+ "CyclicalExample.unpackcFunc()\n",
+ "print('Quarterly consumption functions:')\n",
+ "mMin = min([X.mNrmMin for X in CyclicalExample.solution])\n",
+ "plotFuncs(CyclicalExample.cFunc,mMin,5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The very low green consumption function corresponds to the quarter in which the ski instructors make most of their income. They know that they are about to experience a 70% drop in \"permanent\" income, so they do not consume much *relative to their income this quarter*. In the other three quarters, *normalized* consumption is much higher, as current \"permanent\" income is low relative to future expectations. In *level*, the consumption chosen in each quarter is much more similar"
+ ]
+ }
+ ],
+ "metadata": {
+ "@webio": {
+ "lastCommId": "779f6c5616b04b58baaaa0f6c348270c",
+ "lastKernelId": "a944b08f-0ae0-4c26-883f-9fab53a82ac3"
+ },
+ "cite2c": {
+ "citations": {
+ "6202365/HQ6H9JEI": {
+ "DOI": "10.1016/j.econlet.2005.09.013",
+ "URL": "http://econ.jhu.edu/people/ccarroll/EndogenousArchive.zip",
+ "author": [
+ {
+ "family": "Carroll",
+ "given": "Christopher D."
+ }
+ ],
+ "container-title": "Economics Letters",
+ "id": "6202365/HQ6H9JEI",
+ "issued": {
+ "month": 9,
+ "year": 2006
+ },
+ "page": "312–320",
+ "page-first": "312",
+ "title": "The Method of Endogenous Gridpoints for Solving Dynamic Stochastic Optimization Problems",
+ "type": "article-journal"
+ }
+ }
+ },
+ "jupytext": {
+ "cell_metadata_filter": "collapsed,code_folding",
+ "formats": "ipynb,py:percent"
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.7"
+ },
+ "varInspector": {
+ "cols": {
+ "lenName": 16,
+ "lenType": 16,
+ "lenVar": 40
+ },
+ "kernels_config": {
+ "python": {
+ "delete_cmd_postfix": "",
+ "delete_cmd_prefix": "del ",
+ "library": "var_list.py",
+ "varRefreshCmd": "print(var_dic_list())"
+ },
+ "r": {
+ "delete_cmd_postfix": ") ",
+ "delete_cmd_prefix": "rm(",
+ "library": "var_list.r",
+ "varRefreshCmd": "cat(var_dic_list()) "
+ }
+ },
+ "types_to_exclude": [
+ "module",
+ "function",
+ "builtin_function_or_method",
+ "instance",
+ "_Feature"
+ ],
+ "window_display": false
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/examples/ConsIndShockModel/IndShockConsumerType.py b/examples/ConsIndShockModel/IndShockConsumerType.py
new file mode 100644
index 000000000..39965b594
--- /dev/null
+++ b/examples/ConsIndShockModel/IndShockConsumerType.py
@@ -0,0 +1,419 @@
+# ---
+# jupyter:
+# jupytext:
+# cell_metadata_filter: collapsed,code_folding
+# formats: ipynb,py:percent
+# text_representation:
+# extension: .py
+# format_name: percent
+# format_version: '1.2'
+# jupytext_version: 1.1.3
+# kernelspec:
+# display_name: Python 3
+# language: python
+# name: python3
+# ---
+
+# %% [markdown]
+# # IndShockConsumerType Documentation
+# ## Consumption-Saving model with Idiosyncratic Income Shocks
+
+# %% {"code_folding": [0]}
+# Initial imports and notebook setup, click arrow to show
+from HARK.ConsumptionSaving.ConsIndShockModel import IndShockConsumerType
+from HARK.utilities import plotFuncsDer, plotFuncs
+from time import clock
+import matplotlib.pyplot as plt
+import numpy as np
+mystr = lambda number : "{:.4f}".format(number)
+
+# %% [markdown]
+# The module $\texttt{HARK.ConsumptionSaving.ConsIndShockModel}$ concerns consumption-saving models with idiosyncratic shocks to (non-capital) income. All of the models assume CRRA utility with geometric discounting, no bequest motive, and income shocks are fully transitory or fully permanent.
+#
+# $\texttt{ConsIndShockModel}$ includes:
+# 1. A very basic "perfect foresight" model with no uncertainty.
+# 2. A model with risk over transitory and permanent income shocks.
+# 3. The model described in (2), with an interest rate for debt that differs from the interest rate for savings.
+#
+# This notebook provides documentation for the second of these models.
+# $\newcommand{\CRRA}{\rho}$
+# $\newcommand{\DiePrb}{\mathsf{D}}$
+# $\newcommand{\PermGroFac}{\Gamma}$
+# $\newcommand{\Rfree}{\mathsf{R}}$
+# $\newcommand{\DiscFac}{\beta}$
+
+# %% [markdown]
+# ## Statement of idiosyncratic income shocks model
+#
+# Suppose we want to solve a model like the one analyzed in [BufferStockTheory](http://econ.jhu.edu/people/ccarroll/papers/BufferStockTheory/), with all the same features as the perfect foresight consumer, plus idiosyncratic shocks to income each period. Agents with this kind of model are represented by the class $\texttt{IndShockConsumerType}$.
+#
+# Specifically, this type of consumer receives two income shocks at the beginning of each period: a completely transitory shock $\newcommand{\tShkEmp}{\theta}{\tShkEmp_t}$ and a completely permanent shock $\newcommand{\pShk}{\psi}{\pShk_t}$. Moreover, lenders will not let the agent borrow money such that his ratio of end-of-period assets $A_t$ to permanent income $P_t$ is less than $\underline{a}$. As with the perfect foresight problem, this model can be framed in terms of *normalized* variables, dividing all real variables by $P_t$:
+#
+# \begin{eqnarray*}
+# v_t(m_t) &=& \max_{c_t} {~} u(c_t) + \DiscFac (1-\DiePrb_{t+1}) \mathbb{E}_{t} \left[ (\PermGroFac_{t+1}\psi_{t+1})^{1-\CRRA} v_{t+1}(m_{t+1}) \right], \\
+# a_t &=& m_t - c_t, \\
+# a_t &\geq& \underline{a}, \\
+# m_{t+1} &=& \Rfree/(\PermGroFac_{t+1} \psi_{t+1}) a_t + \theta_{t+1}, \\
+# (\psi_{t+1},\theta_{t+1}) &\sim& F_{t+1}, \\
+# \mathbb{E}[\psi]=\mathbb{E}[\theta] &=& 1, \\
+# u(c) &=& \frac{c^{1-\rho}}{1-\rho}.
+# \end{eqnarray*}
+
+# %% [markdown]
+# ## Solution method for IndShockConsumerType
+#
+# With the introduction of (non-trivial) risk, the idiosyncratic income shocks model has no closed form solution and must be solved numerically. The function $\texttt{solveConsIndShock}$ solves the one period problem for the $\texttt{IndShockConsumerType}$ class. To do so, HARK uses the original version of the endogenous grid method (EGM) first described [here](http://www.econ2.jhu.edu/people/ccarroll/EndogenousGridpoints.pdf) ; see also the [SolvingMicroDSOPs](http://www.econ2.jhu.edu/people/ccarroll/SolvingMicroDSOPs/) lecture notes.
+#
+# Briefly, the transition equation for $m_{t+1}$ can be substituted into the problem definition; the second term of the reformulated maximand represents "end of period value of assets" $\mathfrak{v}_t(a_t)$ ("Gothic v"):
+#
+# \begin{eqnarray*}
+# v_t(m_t) &=& \max_{c_t} {~} U(c_t) + \underbrace{\DiscFac (1-\DiePrb_{t+1}) \mathbb{E}_{t} \left[ (\PermGroFac_{t+1}\psi_{t+1})^{1-\CRRA} v_{t+1}(\Rfree/(\PermGroFac_{t+1} \psi_{t+1}) a_t + \theta_{t+1}) \right]}_{\equiv \mathfrak{v}_t(a_t)}.
+# \end{eqnarray*}
+#
+# The first order condition with respect to $c_t$ is thus simply:
+#
+# \begin{eqnarray*}
+# U'(c_t) - \mathfrak{v}'_t(a_t) = 0 \Longrightarrow c_t^{-\CRRA} = \mathfrak{v}'_t(a_t) \Longrightarrow c_t = \mathfrak{v}'_t(a_t)^{-1/\CRRA}.
+# \end{eqnarray*}
+#
+# Where the marginal value of end-of-period assets can be computed as:
+#
+# \begin{eqnarray*}
+# \mathfrak{v}'_t(a_t) = \DiscFac (1-\DiePrb_{t+1}) \mathbb{E}_{t} \left[ \Rfree (\PermGroFac_{t+1}\psi_{t+1})^{-\CRRA} v'_{t+1}(\Rfree/(\PermGroFac_{t+1} \psi_{t+1}) a_t + \theta_{t+1}) \right].
+# \end{eqnarray*}
+#
+# To solve the model, we choose an exogenous grid of $a_t$ values that spans the range of values that could plausibly be achieved, compute $\mathfrak{v}'_t(a_t)$ at each of these points, calculate the value of consumption $c_t$ whose marginal utility is consistent with the marginal value of assets, then find the endogenous $m_t$ gridpoint as $m_t = a_t + c_t$. The set of $(m_t,c_t)$ gridpoints is then interpolated to construct the consumption function.
+
+# %% [markdown]
+# ## Example parameter values to construct an instance of IndShockConsumerType
+#
+# In order to create an instance of $\texttt{IndShockConsumerType}$, the user must specify parameters that characterize the (age-varying) distribution of income shocks $F_{t+1}$, the artificial borrowing constraint $\underline{a}$, and the exogenous grid of end-of-period assets-above-minimum for use by EGM, along with all of the parameters for the perfect foresight model. The table below presents the complete list of parameter values required to instantiate an $\texttt{IndShockConsumerType}$, along with example values.
+#
+# | Parameter | Description | Code | Example value | Time-varying? |
+# | :---: | --- | --- | --- | --- |
+# | $\DiscFac$ |Intertemporal discount factor | $\texttt{DiscFac}$ | $0.96$ | |
+# | $\CRRA $ |Coefficient of relative risk aversion | $\texttt{CRRA}$ | $2.0$ | |
+# | $\Rfree$ | Risk free interest factor | $\texttt{Rfree}$ | $1.03$ | |
+# | $1 - \DiePrb_{t+1}$ |Survival probability | $\texttt{LivPrb}$ | $[0.98]$ | $\surd$ |
+# |$\PermGroFac_{t+1}$|Permanent income growth factor|$\texttt{PermGroFac}$| $[1.01]$ | $\surd$ |
+# | $\sigma_\psi $ | Standard deviation of log permanent income shocks | $\texttt{PermShkStd}$ | $[0.1]$ |$\surd$ |
+# | $N_\psi $ | Number of discrete permanent income shocks | $\texttt{PermShkCount}$ | $7$ | |
+# | $\sigma_\theta $ | Standard deviation of log transitory income shocks | $\texttt{TranShkStd}$ | $[0.2]$ | $\surd$ |
+# | $N_\theta $ | Number of discrete transitory income shocks | $\texttt{TranShkCount}$ | $7$ | |
+# | $\mho$ | Probability of being unemployed and getting $\theta=\underline{\theta}$ | $\texttt{UnempPrb}$ | $0.05$ | |
+# | $\underline{\theta} $ | Transitory shock when unemployed | $\texttt{IncUnemp}$ | $0.3$ | |
+# | $\mho^{Ret}$ | Probability of being "unemployed" when retired | $\texttt{UnempPrb}$ | $0.0005$ | |
+# | $\underline{\theta}^{Ret} $ | Transitory shock when "unemployed" and retired | $\texttt{IncUnemp}$ | $0.0$ | |
+# | $(none)$ | Period of the lifecycle model when retirement begins | $\texttt{T_retire}$ | $0$ | |
+# | $(none)$ | Minimum value in assets-above-minimum grid | $\texttt{aXtraMin}$ | $0.001$ | |
+# | $(none)$ | Maximum value in assets-above-minimum grid | $\texttt{aXtraMax}$ | $20.0$ | |
+# | $(none)$ | Number of points in base assets-above-minimum grid | $\texttt{aXtraCount}$ | $48$ | |
+# | $(none)$ | Exponential nesting factor for base assets-above-minimum grid | $\texttt{aXtraNestFac}$ | $3$ | |
+# | $(none)$ | Additional values to add to assets-above-minimum grid | $\texttt{aXtraExtra}$ | $None$ | |
+# | $\underline{a} $ | Artificial borrowing constraint (normalized) | $\texttt{BoroCnstArt}$ | $0.0$ | |
+# | $(none) $ |Indicator for whether $\texttt{vFunc}$ should be computed | $\texttt{vFuncBool}$ | $True$ | |
+# | $(none)$ |Indicator for whether $\texttt{cFunc}$ should use cubic splines | $\texttt{CubicBool}$ | $False$ | |
+# |$T$| Number of periods in this type's "cycle" |$\texttt{T_cycle}$| $1$ | |
+# |(none)| Number of times the "cycle" occurs |$\texttt{cycles}$| $0$ | |
+
+# %% {"code_folding": [0]}
+IdiosyncDict={
+ # Parameters shared with the perfect foresight model
+ "CRRA": 2.0, # Coefficient of relative risk aversion
+ "Rfree": 1.03, # Interest factor on assets
+ "DiscFac": 0.96, # Intertemporal discount factor
+ "LivPrb" : [0.98], # Survival probability
+ "PermGroFac" :[1.01], # Permanent income growth factor
+
+ # Parameters that specify the income distribution over the lifecycle
+ "PermShkStd" : [0.1], # Standard deviation of log permanent shocks to income
+ "PermShkCount" : 7, # Number of points in discrete approximation to permanent income shocks
+ "TranShkStd" : [0.2], # Standard deviation of log transitory shocks to income
+ "TranShkCount" : 7, # Number of points in discrete approximation to transitory income shocks
+ "UnempPrb" : 0.05, # Probability of unemployment while working
+ "IncUnemp" : 0.3, # Unemployment benefits replacement rate
+ "UnempPrbRet" : 0.0005, # Probability of "unemployment" while retired
+ "IncUnempRet" : 0.0, # "Unemployment" benefits when retired
+ "T_retire" : 0, # Period of retirement (0 --> no retirement)
+ "tax_rate" : 0.0, # Flat income tax rate (legacy parameter, will be removed in future)
+
+ # Parameters for constructing the "assets above minimum" grid
+ "aXtraMin" : 0.001, # Minimum end-of-period "assets above minimum" value
+ "aXtraMax" : 20, # Maximum end-of-period "assets above minimum" value
+ "aXtraCount" : 48, # Number of points in the base grid of "assets above minimum"
+ "aXtraNestFac" : 3, # Exponential nesting factor when constructing "assets above minimum" grid
+ "aXtraExtra" : [None], # Additional values to add to aXtraGrid
+
+ # A few other paramaters
+ "BoroCnstArt" : 0.0, # Artificial borrowing constraint; imposed minimum level of end-of period assets
+ "vFuncBool" : True, # Whether to calculate the value function during solution
+ "CubicBool" : False, # Preference shocks currently only compatible with linear cFunc
+ "T_cycle" : 1, # Number of periods in the cycle for this agent type
+
+ # Parameters only used in simulation
+ "AgentCount" : 10000, # Number of agents of this type
+ "T_sim" : 120, # 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
+}
+
+# %% [markdown]
+# The distribution of permanent income shocks is specified as mean one lognormal, with an age-varying (underlying) standard deviation. The distribution of transitory income shocks is also mean one lognormal, but with an additional point mass representing unemployment; the transitory shocks are adjusted so that the distribution is still mean one. The continuous distributions are discretized with an equiprobable distribution.
+#
+# 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):
+
+# %% {"hidden": true}
+print('Consumption function for an idiosyncratic shocks consumer type:')
+plotFuncs(IndShockExample.solution[0].cFunc,IndShockExample.solution[0].mNrmMin,5)
+print('Marginal propensity to consume for an idiosyncratic shocks consumer type:')
+plotFuncsDer(IndShockExample.solution[0].cFunc,IndShockExample.solution[0].mNrmMin,5)
+
+# %% [markdown] {"hidden": true}
+# The lower part of the consumption function is linear with a slope of 1, representing the *constrained* part of the consumption function where the consumer *would like* to consume more by borrowing-- his marginal utility of consumption exceeds the marginal value of assets-- but he is prevented from doing so by the artificial borrowing constraint.
+#
+# The MPC is a step function, as the $\texttt{cFunc}$ itself is a piecewise linear function; note the large jump in the MPC where the borrowing constraint begins to bind.
+#
+# If you want to look at the interpolation nodes for the consumption function, these can be found by "digging into" attributes of $\texttt{cFunc}$:
+
+# %% {"hidden": true}
+print('mNrmGrid for unconstrained cFunc is ',IndShockExample.solution[0].cFunc.functions[0].x_list)
+print('cNrmGrid for unconstrained cFunc is ',IndShockExample.solution[0].cFunc.functions[0].y_list)
+print('mNrmGrid for borrowing constrained cFunc is ',IndShockExample.solution[0].cFunc.functions[1].x_list)
+print('cNrmGrid for borrowing constrained cFunc is ',IndShockExample.solution[0].cFunc.functions[1].y_list)
+
+# %% [markdown] {"hidden": true}
+# The consumption function in this model is an instance of $\texttt{LowerEnvelope1D}$, a class that takes an arbitrary number of 1D interpolants as arguments to its initialization method. When called, a $\texttt{LowerEnvelope1D}$ evaluates each of its component functions and returns the lowest value. Here, the two component functions are the *unconstrained* consumption function-- how the agent would consume if the artificial borrowing constraint did not exist for *just this period*-- and the *borrowing constrained* consumption function-- how much he would consume if the artificial borrowing constraint is binding.
+#
+# The *actual* consumption function is the lower of these two functions, pointwise. We can see this by plotting the component functions on the same figure:
+
+# %% {"hidden": true}
+plotFuncs(IndShockExample.solution[0].cFunc.functions,-0.25,5.)
+
+# %% [markdown]
+# ## Simulating the idiosyncratic income shocks model
+#
+# In order to generate simulated data, an instance of $\texttt{IndShockConsumerType}$ needs to know how many agents there are that share these particular parameters (and are thus *ex ante* homogeneous), the distribution of states for newly "born" agents, and how many periods to simulated. These simulation parameters are described in the table below, along with example values.
+#
+# | Description | Code | Example value |
+# | :---: | --- | --- |
+# | Number of consumers of this type | $\texttt{AgentCount}$ | $10000$ |
+# | Number of periods to simulate | $\texttt{T_sim}$ | $120$ |
+# | Mean of initial log (normalized) assets | $\texttt{aNrmInitMean}$ | $-6.0$ |
+# | Stdev of initial log (normalized) assets | $\texttt{aNrmInitStd}$ | $1.0$ |
+# | Mean of initial log permanent income | $\texttt{pLvlInitMean}$ | $0.0$ |
+# | Stdev of initial log permanent income | $\texttt{pLvlInitStd}$ | $0.0$ |
+# | Aggregrate productivity growth factor | $\texttt{PermGroFacAgg}$ | $1.0$ |
+# | Age after which consumers are automatically killed | $\texttt{T_age}$ | $None$ |
+#
+# Here, we will simulate 10,000 consumers for 120 periods. All newly born agents will start with permanent income of exactly $P_t = 1.0 = \exp(\texttt{pLvlInitMean})$, as $\texttt{pLvlInitStd}$ has been set to zero; they will have essentially zero assets at birth, as $\texttt{aNrmInitMean}$ is $-6.0$; assets will be less than $1\%$ of permanent income at birth.
+#
+# These example parameter values were already passed as part of the parameter dictionary that we used to create $\texttt{IndShockExample}$, so it is ready to simulate. We need to set the $\texttt{track_vars}$ attribute to indicate the variables for which we want to record a *history*.
+
+# %%
+IndShockExample.track_vars = ['aNrmNow','mNrmNow','cNrmNow','pLvlNow']
+IndShockExample.initializeSim()
+IndShockExample.simulate()
+
+# %% [markdown]
+# We can now look at the simulated data in aggregate or at the individual consumer level. Like in the perfect foresight model, we can plot average (normalized) market resources over time, as well as average consumption:
+
+# %%
+plt.plot(np.mean(IndShockExample.mNrmNow_hist,axis=1))
+plt.xlabel('Time')
+plt.ylabel('Mean market resources')
+plt.show()
+
+plt.plot(np.mean(IndShockExample.cNrmNow_hist,axis=1))
+plt.xlabel('Time')
+plt.ylabel('Mean consumption')
+plt.show()
+
+# %% [markdown]
+# We could also plot individual consumption paths for some of the consumers-- say, the first five:
+
+# %%
+plt.plot(IndShockExample.cNrmNow_hist[:,0:5])
+plt.xlabel('Time')
+plt.ylabel('Individual consumption paths')
+plt.show()
+
+# %% [markdown]
+# ## Other example specifications of idiosyncratic income shocks consumers
+#
+# $\texttt{IndShockConsumerType}$-- and $\texttt{HARK}$ in general-- can also represent models that are not infinite horizon.
+#
+# ### Lifecycle example
+#
+# Suppose we wanted to represent consumers with a *lifecycle*-- parameter values that differ by age, with a finite end point beyond which the individual cannot surive. This can be done very easily by simply specifying the time-varying attributes $\texttt{PermGroFac}$, $\texttt{LivPrb}$, $\texttt{PermShkStd}$, and $\texttt{TranShkStd}$ as Python *lists* specifying the sequence of periods these agents will experience, from beginning to end.
+#
+# In the cell below, we define a parameter dictionary for a rather short ten period lifecycle, with arbitrarily chosen parameters. For a more realistically calibrated (and much longer) lifecycle model, see the [SolvingMicroDSOPs REMARK](https://github.com/econ-ark/REMARK/blob/master/REMARKs/SolvingMicroDSOPs.md).
+
+# %% {"code_folding": [0]}
+LifecycleDict={ # Click arrow to expand this fairly large parameter dictionary
+ # Parameters shared with the perfect foresight model
+ "CRRA": 2.0, # Coefficient of relative risk aversion
+ "Rfree": 1.03, # Interest factor on assets
+ "DiscFac": 0.96, # Intertemporal discount factor
+ "LivPrb" : [0.99,0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1],
+ "PermGroFac" : [1.01,1.01,1.01,1.02,1.02,1.02,0.7,1.0,1.0,1.0],
+
+ # Parameters that specify the income distribution over the lifecycle
+ "PermShkStd" : [0.1,0.2,0.1,0.2,0.1,0.2,0.1,0,0,0],
+ "PermShkCount" : 7, # Number of points in discrete approximation to permanent income shocks
+ "TranShkStd" : [0.3,0.2,0.1,0.3,0.2,0.1,0.3,0,0,0],
+ "TranShkCount" : 7, # Number of points in discrete approximation to transitory income shocks
+ "UnempPrb" : 0.05, # Probability of unemployment while working
+ "IncUnemp" : 0.3, # Unemployment benefits replacement rate
+ "UnempPrbRet" : 0.0005, # Probability of "unemployment" while retired
+ "IncUnempRet" : 0.0, # "Unemployment" benefits when retired
+ "T_retire" : 7, # Period of retirement (0 --> no retirement)
+ "tax_rate" : 0.0, # Flat income tax rate (legacy parameter, will be removed in future)
+
+ # Parameters for constructing the "assets above minimum" grid
+ "aXtraMin" : 0.001, # Minimum end-of-period "assets above minimum" value
+ "aXtraMax" : 20, # Maximum end-of-period "assets above minimum" value
+ "aXtraCount" : 48, # Number of points in the base grid of "assets above minimum"
+ "aXtraNestFac" : 3, # Exponential nesting factor when constructing "assets above minimum" grid
+ "aXtraExtra" : [None], # Additional values to add to aXtraGrid
+
+ # A few other paramaters
+ "BoroCnstArt" : 0.0, # Artificial borrowing constraint; imposed minimum level of end-of period assets
+ "vFuncBool" : True, # Whether to calculate the value function during solution
+ "CubicBool" : False, # Preference shocks currently only compatible with linear cFunc
+ "T_cycle" : 10, # Number of periods in the cycle for this agent type
+
+ # Parameters only used in simulation
+ "AgentCount" : 10000, # Number of agents of this type
+ "T_sim" : 120, # 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" : 11, # Age after which simulated agents are automatically killed
+}
+
+# %% [markdown]
+# In this case, we have specified a ten period model in which retirement happens in period $t=7$. Agents in this model are more likely to die as they age, and their permanent income drops by 30\% at retirement. Let's make and solve this lifecycle example, then look at the $\texttt{solution}$ attribute.
+
+# %%
+LifecycleExample = IndShockConsumerType(**LifecycleDict)
+LifecycleExample.cycles = 1 # Make this consumer live a sequence of periods -- a lifetime -- exactly once
+LifecycleExample.solve()
+print('First element of solution is',LifecycleExample.solution[0])
+print('Solution has', len(LifecycleExample.solution),'elements.')
+
+# %% [markdown]
+# This was supposed to be a *ten* period lifecycle model-- why does our consumer type have *eleven* elements in its $\texttt{solution}$? It would be more precise to say that this specification has ten *non-terminal* periods. The solution to the 11th and final period in the model would be the same for every set of parameters: consume $c_t = m_t$, because there is no future. In a lifecycle model, the terminal period is assumed to exist; the $\texttt{LivPrb}$ parameter does not need to end with a $0.0$ in order to guarantee that survivors die.
+#
+# We can quickly plot the consumption functions in each period of the model:
+
+# %%
+print('Consumption functions across the lifecycle:')
+mMin = np.min([LifecycleExample.solution[t].mNrmMin for t in range(LifecycleExample.T_cycle)])
+LifecycleExample.unpackcFunc() # This makes all of the cFuncs accessible in the attribute cFunc
+plotFuncs(LifecycleExample.cFunc,mMin,5)
+
+# %% [markdown]
+# ### "Cyclical" example
+#
+# We can also model consumers who face an infinite horizon, but who do *not* face the same problem in every period. Consider someone who works as a ski instructor: they make most of their income for the year in the winter, and make very little money in the other three seasons.
+#
+# We can represent this type of individual as a four period, infinite horizon model in which expected "permanent" income growth varies greatly across seasons.
+
+# %% {"code_folding": [0]}
+CyclicalDict = { # Click the arrow to expand this parameter dictionary
+ # Parameters shared with the perfect foresight model
+ "CRRA": 2.0, # Coefficient of relative risk aversion
+ "Rfree": 1.03, # Interest factor on assets
+ "DiscFac": 0.96, # Intertemporal discount factor
+ "LivPrb" : 4*[0.98], # Survival probability
+ "PermGroFac" : [1.082251, 2.8, 0.3, 1.1],
+
+ # Parameters that specify the income distribution over the lifecycle
+ "PermShkStd" : [0.1,0.1,0.1,0.1],
+ "PermShkCount" : 7, # Number of points in discrete approximation to permanent income shocks
+ "TranShkStd" : [0.2,0.2,0.2,0.2],
+ "TranShkCount" : 7, # Number of points in discrete approximation to transitory income shocks
+ "UnempPrb" : 0.05, # Probability of unemployment while working
+ "IncUnemp" : 0.3, # Unemployment benefits replacement rate
+ "UnempPrbRet" : 0.0005, # Probability of "unemployment" while retired
+ "IncUnempRet" : 0.0, # "Unemployment" benefits when retired
+ "T_retire" : 0, # Period of retirement (0 --> no retirement)
+ "tax_rate" : 0.0, # Flat income tax rate (legacy parameter, will be removed in future)
+
+ # Parameters for constructing the "assets above minimum" grid
+ "aXtraMin" : 0.001, # Minimum end-of-period "assets above minimum" value
+ "aXtraMax" : 20, # Maximum end-of-period "assets above minimum" value
+ "aXtraCount" : 48, # Number of points in the base grid of "assets above minimum"
+ "aXtraNestFac" : 3, # Exponential nesting factor when constructing "assets above minimum" grid
+ "aXtraExtra" : [None], # Additional values to add to aXtraGrid
+
+ # A few other paramaters
+ "BoroCnstArt" : 0.0, # Artificial borrowing constraint; imposed minimum level of end-of period assets
+ "vFuncBool" : True, # Whether to calculate the value function during solution
+ "CubicBool" : False, # Preference shocks currently only compatible with linear cFunc
+ "T_cycle" : 4, # Number of periods in the cycle for this agent type
+
+ # Parameters only used in simulation
+ "AgentCount" : 10000, # Number of agents of this type
+ "T_sim" : 120, # 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
+}
+
+# %% [markdown]
+# This consumer type's parameter dictionary is nearly identical to the original infinite horizon type we made, except that each of the time-varying parameters now have *four* values, rather than just one. Most of these have the same value in each period *except* for $\texttt{PermGroFac}$, which varies greatly over the four seasons. Note that the product of the four "permanent" income growth factors is almost exactly 1.0-- this type's income does not grow on average in the long run!
+#
+# Let's make and solve this consumer type, then plot his quarterly consumption functions:
+
+# %%
+CyclicalExample = IndShockConsumerType(**CyclicalDict)
+CyclicalExample.cycles = 0 # Make this consumer type have an infinite horizon
+CyclicalExample.solve()
+
+CyclicalExample.unpackcFunc()
+print('Quarterly consumption functions:')
+mMin = min([X.mNrmMin for X in CyclicalExample.solution])
+plotFuncs(CyclicalExample.cFunc,mMin,5)
+
+# %% [markdown]
+# The very low green consumption function corresponds to the quarter in which the ski instructors make most of their income. They know that they are about to experience a 70% drop in "permanent" income, so they do not consume much *relative to their income this quarter*. In the other three quarters, *normalized* consumption is much higher, as current "permanent" income is low relative to future expectations. In *level*, the consumption chosen in each quarter is much more similar
diff --git a/examples/ConsIndShockModel/KinkedRconsumerType.ipynb b/examples/ConsIndShockModel/KinkedRconsumerType.ipynb
new file mode 100644
index 000000000..cc57b6c4a
--- /dev/null
+++ b/examples/ConsIndShockModel/KinkedRconsumerType.ipynb
@@ -0,0 +1,369 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# KinkedRconsumerType: Consumption-saving model with idiosyncratic income shocks and different interest rates on borrowing and saving"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "code_folding": [
+ 0
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "# Initial imports and notebook setup, click arrow to show\n",
+ "from HARK.ConsumptionSaving.ConsIndShockModel import KinkedRconsumerType\n",
+ "from HARK.utilities import plotFuncsDer, plotFuncs\n",
+ "from time import clock\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "mystr = lambda number : \"{:.4f}\".format(number)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The module $\\texttt{HARK.ConsumptionSaving.ConsIndShockModel}$ concerns consumption-saving models with idiosyncratic shocks to (non-capital) income. All of the models assume CRRA utility with geometric discounting, no bequest motive, and income shocks are fully transitory or fully permanent.\n",
+ "\n",
+ "$\\texttt{ConsIndShockModel}$ currently includes three models:\n",
+ "1. A very basic \"perfect foresight\" model with no uncertainty.\n",
+ "2. A model with risk over transitory and permanent income shocks.\n",
+ "3. The model described in (2), with an interest rate for debt that differs from the interest rate for savings.\n",
+ "\n",
+ "This notebook provides documentation for the third of these models.\n",
+ "$\\newcommand{\\CRRA}{\\rho}$\n",
+ "$\\newcommand{\\DiePrb}{\\mathsf{D}}$\n",
+ "$\\newcommand{\\PermGroFac}{\\Gamma}$\n",
+ "$\\newcommand{\\Rfree}{\\mathsf{R}}$\n",
+ "$\\newcommand{\\DiscFac}{\\beta}$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Statement of \"kinked R\" model\n",
+ "\n",
+ "Consider a small extension to the model faced by $\\texttt{IndShockConsumerType}$s: that the interest rate on borrowing $a_t < 0$ is greater than the interest rate on saving $a_t > 0$. Consumers who face this kind of problem are represented by the $\\texttt{KinkedRconsumerType}$ class.\n",
+ "\n",
+ "For a full theoretical treatment, this model analyzed in [A Theory of the Consumption Function, With\n",
+ "and Without Liquidity Constraints](http://www.econ2.jhu.edu/people/ccarroll/ATheoryv3JEP.pdf)\n",
+ "and its [expanded edition](http://www.econ2.jhu.edu/people/ccarroll/ATheoryv3NBER.pdf).\n",
+ "\n",
+ "Continuing to work with *normalized* variables (e.g. $m_t$ represents the level of market resources divided by permanent income), the \"kinked R\" model can be stated as:\n",
+ "\n",
+ "\\begin{eqnarray*}\n",
+ "v_t(m_t) &=& \\max_{c_t} {~} U(c_t) + \\DiscFac (1-\\DiePrb_{t+1}) \\mathbb{E}_{t} \\left[ (\\PermGroFac_{t+1}\\psi_{t+1})^{1-\\CRRA} v_{t+1}(m_{t+1}) \\right], \\\\\n",
+ "a_t &=& m_t - c_t, \\\\\n",
+ "a_t &\\geq& \\underline{a}, \\\\\n",
+ "m_{t+1} &=& \\Rfree_t/(\\PermGroFac_{t+1} \\psi_{t+1}) a_t + \\theta_{t+1}, \\\\\n",
+ "\\Rfree_t &=& \\cases{\\Rfree_{boro} \\texttt{ if } a_t < 0 \\\\\n",
+ " \\Rfree_{save} \\texttt{ if } a_t \\geq 0},\\\\\n",
+ "\\Rfree_{boro} &>& \\Rfree_{save}, \\\\\n",
+ "(\\psi_{t+1},\\theta_{t+1}) &\\sim& F_{t+1}, \\\\\n",
+ "\\mathbb{E}[\\psi]=\\mathbb{E}[\\theta] &=& 1.\n",
+ "\\end{eqnarray*}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Solving the \"kinked R\" model\n",
+ "\n",
+ "The solution method for the \"kinked R\" model is nearly identical to that of the $\\texttt{IndShockConsumerType}$ on which it is based, using the endogenous grid method; see the notebook for that model for more information. The only significant difference is that the interest factor varies by $a_t$ across the exogenously chosen grid of end-of-period assets, with a discontinuity in $\\Rfree$ at $a_t=0$.\n",
+ "\n",
+ "To correctly handle this, the $\\texttt{solveConsKinkedR}$ function inserts *two* instances of $a_t=0$ into the grid of $a_t$ values: the first corresponding to $\\Rfree_{boro}$ ($a_t = -0$) and the other corresponding to $\\Rfree_{save}$ ($a_t = +0$). The two consumption levels (and corresponding endogenous $m_t$ gridpoints) represent points at which the agent's first order condition is satisfied at *exactly* $a_t=0$ at the two different interest factors. In between these two points, the first order condition *does not hold with equality*: the consumer will end the period with exactly $a_t=0$, consuming $c_t=m_t$, but his marginal utility of consumption exceeds the marginal value of saving and is less than the marginal value of borrowing. This generates a consumption function with *two* kinks: two concave portions (for borrowing and saving) with a linear segment of slope 1 in between."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Example parameter values to construct an instance of KinkedRconsumerType\n",
+ "\n",
+ "The parameters required to create an instance of $\\texttt{KinkedRconsumerType}$ are nearly identical to those for $\\texttt{IndShockConsumerType}$. The only difference is that the parameter $\\texttt{Rfree}$ is replaced with $\\texttt{Rboro}$ and $\\texttt{Rsave}$.\n",
+ "\n",
+ "While the parameter $\\texttt{CubicBool}$ is required to create a valid $\\texttt{KinkedRconsumerType}$ instance, it must be set to $\\texttt{False}$; cubic spline interpolation has not yet been implemented for this model. In the future, this restriction will be lifted.\n",
+ "\n",
+ "| Parameter | Description | Code | Example value | Time-varying? |\n",
+ "| :---: | --- | --- | --- | --- |\n",
+ "| $\\DiscFac$ |Intertemporal discount factor | $\\texttt{DiscFac}$ | $0.96$ | |\n",
+ "| $\\CRRA $ |Coefficient of relative risk aversion | $\\texttt{CRRA}$ | $2.0$ | |\n",
+ "| $\\Rfree_{boro}$ | Risk free interest factor for borrowing | $\\texttt{Rboro}$ | $1.20$ | |\n",
+ "| $\\Rfree_{save}$ | Risk free interest factor for saving | $\\texttt{Rsave}$ | $1.01$ | |\n",
+ "| $1 - \\DiePrb_{t+1}$ |Survival probability | $\\texttt{LivPrb}$ | $[0.98]$ | $\\surd$ |\n",
+ "|$\\PermGroFac_{t+1}$|Permanent income growth factor|$\\texttt{PermGroFac}$| $[1.01]$ | $\\surd$ |\n",
+ "| $\\sigma_\\psi $ | Standard deviation of log permanent income shocks | $\\texttt{PermShkStd}$ | $[0.1]$ |$\\surd$ |\n",
+ "| $N_\\psi $ | Number of discrete permanent income shocks | $\\texttt{PermShkCount}$ | $7$ | |\n",
+ "| $\\sigma_\\theta $ | Standard deviation of log transitory income shocks | $\\texttt{TranShkStd}$ | $[0.2]$ | $\\surd$ |\n",
+ "| $N_\\theta $ | Number of discrete transitory income shocks | $\\texttt{TranShkCount}$ | $7$ | |\n",
+ "| $\\mho$ | Probability of being unemployed and getting $\\theta=\\underline{\\theta}$ | $\\texttt{UnempPrb}$ | $0.05$ | |\n",
+ "| $\\underline{\\theta} $ | Transitory shock when unemployed | $\\texttt{IncUnemp}$ | $0.3$ | |\n",
+ "| $\\mho^{Ret}$ | Probability of being \"unemployed\" when retired | $\\texttt{UnempPrb}$ | $0.0005$ | |\n",
+ "| $\\underline{\\theta}^{Ret} $ | Transitory shock when \"unemployed\" and retired | $\\texttt{IncUnemp}$ | $0.0$ | |\n",
+ "| $(none)$ | Period of the lifecycle model when retirement begins | $\\texttt{T_retire}$ | $0$ | |\n",
+ "| $(none)$ | Minimum value in assets-above-minimum grid | $\\texttt{aXtraMin}$ | $0.001$ | |\n",
+ "| $(none)$ | Maximum value in assets-above-minimum grid | $\\texttt{aXtraMax}$ | $20.0$ | |\n",
+ "| $(none)$ | Number of points in base assets-above-minimum grid | $\\texttt{aXtraCount}$ | $48$ | |\n",
+ "| $(none)$ | Exponential nesting factor for base assets-above-minimum grid | $\\texttt{aXtraNestFac}$ | $3$ | |\n",
+ "| $(none)$ | Additional values to add to assets-above-minimum grid | $\\texttt{aXtraExtra}$ | $None$ | |\n",
+ "| $\\underline{a} $ | Artificial borrowing constraint (normalized) | $\\texttt{BoroCnstArt}$ | $None$ | |\n",
+ "| $(none) $ |Indicator for whether $\\texttt{vFunc}$ should be computed | $\\texttt{vFuncBool}$ | $True$ | |\n",
+ "| $(none)$ |Indicator for whether $\\texttt{cFunc}$ should use cubic splines | $\\texttt{CubicBool}$ | $False$ | |\n",
+ "|$T$| Number of periods in this type's \"cycle\" |$\\texttt{T_cycle}$| $1$ | |\n",
+ "|(none)| Number of times the \"cycle\" occurs |$\\texttt{cycles}$| $0$ | |\n",
+ "\n",
+ "These example parameters are almostidentical to those used for $\\texttt{IndShockExample}$ in the prior notebook, except that the interest rate on borrowing is 20% (like a credit card), and the interest rate on saving is 1%. Moreover, the artificial borrowing constraint has been set to $\\texttt{None}$. The cell below defines a parameter dictionary with these example values."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "code_folding": [
+ 0
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "KinkedRdict={ # Click the arrow to expand this parameter dictionary\n",
+ " # Parameters shared with the perfect foresight model\n",
+ " \"CRRA\" : 2.0, # Coefficient of relative risk aversion\n",
+ " \"DiscFac\": 0.96, # Intertemporal discount factor\n",
+ " \"LivPrb\" : [0.98], # Survival probability\n",
+ " \"PermGroFac\" :[1.01], # Permanent income growth factor\n",
+ " \n",
+ " # New parameters unique to the \"kinked R\" model\n",
+ " \"Rboro\" : 1.20, # Interest factor on borrowing (a < 0)\n",
+ " \"Rsave\" : 1.01, # Interest factor on saving (a > 0)\n",
+ " \n",
+ " # Parameters that specify the income distribution over the lifecycle\n",
+ " \"PermShkStd\" : [0.1], # Standard deviation of log permanent shocks to income\n",
+ " \"PermShkCount\" : 7, # Number of points in discrete approximation to permanent income shocks\n",
+ " \"TranShkStd\" : [0.2], # Standard deviation of log transitory shocks to income\n",
+ " \"TranShkCount\" : 7, # Number of points in discrete approximation to transitory income shocks\n",
+ " \"UnempPrb\" : 0.05, # Probability of unemployment while working\n",
+ " \"IncUnemp\" : 0.3, # Unemployment benefits replacement rate\n",
+ " \"UnempPrbRet\" : 0.0005, # Probability of \"unemployment\" while retired\n",
+ " \"IncUnempRet\" : 0.0, # \"Unemployment\" benefits when retired\n",
+ " \"T_retire\" : 0, # Period of retirement (0 --> no retirement)\n",
+ " \"tax_rate\" : 0.0, # Flat income tax rate (legacy parameter, will be removed in future)\n",
+ " \n",
+ " # Parameters for constructing the \"assets above minimum\" grid\n",
+ " \"aXtraMin\" : 0.001, # Minimum end-of-period \"assets above minimum\" value\n",
+ " \"aXtraMax\" : 20, # Maximum end-of-period \"assets above minimum\" value\n",
+ " \"aXtraCount\" : 48, # Number of points in the base grid of \"assets above minimum\"\n",
+ " \"aXtraNestFac\" : 3, # Exponential nesting factor when constructing \"assets above minimum\" grid\n",
+ " \"aXtraExtra\" : [None], # Additional values to add to aXtraGrid\n",
+ " \n",
+ " # A few other paramaters\n",
+ " \"BoroCnstArt\" : None, # Artificial borrowing constraint; imposed minimum level of end-of period assets\n",
+ " \"vFuncBool\" : True, # Whether to calculate the value function during solution \n",
+ " \"CubicBool\" : False, # Preference shocks currently only compatible with linear cFunc\n",
+ " \"T_cycle\" : 1, # Number of periods in the cycle for this agent type \n",
+ " \n",
+ " # Parameters only used in simulation\n",
+ " \"AgentCount\" : 10000, # Number of agents of this type\n",
+ " \"T_sim\" : 500, # Number of periods to simulate\n",
+ " \"aNrmInitMean\" : -6.0, # Mean of log initial assets\n",
+ " \"aNrmInitStd\" : 1.0, # Standard deviation of log initial assets\n",
+ " \"pLvlInitMean\" : 0.0, # Mean of log initial permanent income\n",
+ " \"pLvlInitStd\" : 0.0, # Standard deviation of log initial permanent income\n",
+ " \"PermGroFacAgg\" : 1.0, # Aggregate permanent income growth factor\n",
+ " \"T_age\" : None, # Age after which simulated agents are automatically killed\n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Solving and examining the solution of the \"kinked R\" model\n",
+ "\n",
+ "The cell below creates an infinite horizon instance of $\\texttt{KinkedRconsumerType}$ and solves its model by calling its $\\texttt{solve}$ method."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "KinkyExample = KinkedRconsumerType(**KinkedRdict)\n",
+ "KinkyExample.cycles = 0 # Make the example infinite horizon\n",
+ "KinkyExample.solve()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "An element of a $\\texttt{KinkedRconsumerType}$'s solution will have all the same attributes as that of a $\\texttt{IndShockConsumerType}$; see that notebook for details.\n",
+ "\n",
+ "We can plot the consumption function of our \"kinked R\" example, as well as the MPC:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print('Kinked R consumption function:')\n",
+ "plotFuncs(KinkyExample.solution[0].cFunc,KinkyExample.solution[0].mNrmMin,5)\n",
+ "\n",
+ "print('Kinked R marginal propensity to consume:')\n",
+ "plotFuncsDer(KinkyExample.solution[0].cFunc,KinkyExample.solution[0].mNrmMin,5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Simulating the \"kinked R\" model\n",
+ "\n",
+ "In order to generate simulated data, an instance of $\\texttt{KinkedRconsumerType}$ needs to know how many agents there are that share these particular parameters (and are thus *ex ante* homogeneous), the distribution of states for newly \"born\" agents, and how many periods to simulated. These simulation parameters are described in the table below, along with example values.\n",
+ "\n",
+ "| Description | Code | Example value |\n",
+ "| :---: | --- | --- |\n",
+ "| Number of consumers of this type | $\\texttt{AgentCount}$ | $10000$ |\n",
+ "| Number of periods to simulate | $\\texttt{T_sim}$ | $500$ |\n",
+ "| Mean of initial log (normalized) assets | $\\texttt{aNrmInitMean}$ | $-6.0$ |\n",
+ "| Stdev of initial log (normalized) assets | $\\texttt{aNrmInitStd}$ | $1.0$ |\n",
+ "| Mean of initial log permanent income | $\\texttt{pLvlInitMean}$ | $0.0$ |\n",
+ "| Stdev of initial log permanent income | $\\texttt{pLvlInitStd}$ | $0.0$ |\n",
+ "| Aggregrate productivity growth factor | $\\texttt{PermGroFacAgg}$ | $1.0$ |\n",
+ "| Age after which consumers are automatically killed | $\\texttt{T_age}$ | $None$ |\n",
+ "\n",
+ "Here, we will simulate 10,000 consumers for 500 periods. All newly born agents will start with permanent income of exactly $P_t = 1.0 = \\exp(\\texttt{pLvlInitMean})$, as $\\texttt{pLvlInitStd}$ has been set to zero; they will have essentially zero assets at birth, as $\\texttt{aNrmInitMean}$ is $-6.0$; assets will be less than $1\\%$ of permanent income at birth.\n",
+ "\n",
+ "These example parameter values were already passed as part of the parameter dictionary that we used to create $\\texttt{KinkyExample}$, so it is ready to simulate. We need to set the $\\texttt{track_vars}$ attribute to indicate the variables for which we want to record a *history*."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "KinkyExample.track_vars = ['mNrmNow','cNrmNow','pLvlNow']\n",
+ "KinkyExample.initializeSim()\n",
+ "KinkyExample.simulate()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can plot the average (normalized) market resources in each simulated period:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "plt.plot(np.mean(KinkyExample.mNrmNow_hist,axis=1))\n",
+ "plt.xlabel('Time')\n",
+ "plt.ylabel('Mean market resources')\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Now let's plot the distribution of (normalized) assets $a_t$ for the current population, after simulating for $500$ periods; this should be fairly close to the long run distribution:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "plt.plot(np.sort(KinkyExample.aNrmNow),np.linspace(0.,1.,KinkyExample.AgentCount))\n",
+ "plt.xlabel('End-of-period assets')\n",
+ "plt.ylabel('Cumulative distribution')\n",
+ "plt.ylim(-0.01,1.01)\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see there's a significant point mass of consumers with *exactly* $a_t=0$; these are consumers who do not find it worthwhile to give up a bit of consumption to begin saving (because $\\Rfree_{save}$ is too low), and also are not willing to finance additional consumption by borrowing (because $\\Rfree_{boro}$ is too high).\n",
+ "\n",
+ "The smaller point masses in this distribution are due to $\\texttt{HARK}$ drawing simulated income shocks from the discretized distribution, rather than the \"true\" lognormal distributions of shocks. For consumers who ended $t-1$ with $a_{t-1}=0$ in assets, there are only 8 values the transitory shock $\\theta_{t}$ can take on, and thus only 8 values of $m_t$ thus $a_t$ they can achieve; the value of $\\psi_t$ is immaterial to $m_t$ when $a_{t-1}=0$. You can verify this by changing $\\texttt{TranShkCount}$ to some higher value, like 25, in the dictionary above, then running the subsequent cells; the smaller point masses will not be visible to the naked eye."
+ ]
+ }
+ ],
+ "metadata": {
+ "@webio": {
+ "lastCommId": "779f6c5616b04b58baaaa0f6c348270c",
+ "lastKernelId": "a944b08f-0ae0-4c26-883f-9fab53a82ac3"
+ },
+ "jupytext": {
+ "cell_metadata_filter": "collapsed,code_folding",
+ "formats": "ipynb,py:percent"
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.7.3"
+ },
+ "varInspector": {
+ "cols": {
+ "lenName": 16,
+ "lenType": 16,
+ "lenVar": 40
+ },
+ "kernels_config": {
+ "python": {
+ "delete_cmd_postfix": "",
+ "delete_cmd_prefix": "del ",
+ "library": "var_list.py",
+ "varRefreshCmd": "print(var_dic_list())"
+ },
+ "r": {
+ "delete_cmd_postfix": ") ",
+ "delete_cmd_prefix": "rm(",
+ "library": "var_list.r",
+ "varRefreshCmd": "cat(var_dic_list()) "
+ }
+ },
+ "types_to_exclude": [
+ "module",
+ "function",
+ "builtin_function_or_method",
+ "instance",
+ "_Feature"
+ ],
+ "window_display": false
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/examples/ConsIndShockModel/PerfForesightConsumerType.ipynb b/examples/ConsIndShockModel/PerfForesightConsumerType.ipynb
new file mode 100644
index 000000000..25bfddfa5
--- /dev/null
+++ b/examples/ConsIndShockModel/PerfForesightConsumerType.ipynb
@@ -0,0 +1,676 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# PerfForesightConsumerType"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "code_folding": [
+ 0
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "# Initial imports and notebook setup, click arrow to show\n",
+ "from HARK.ConsumptionSaving.ConsIndShockModel import PerfForesightConsumerType\n",
+ "from HARK.utilities import plotFuncs\n",
+ "from time import clock\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "mystr = lambda number : \"{:.4f}\".format(number)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The module $\\texttt{HARK.ConsumptionSaving.ConsIndShockModel}$ concerns consumption-saving models with idiosyncratic shocks to (non-capital) income. All of the models assume CRRA utility with geometric discounting, no bequest motive, and income shocks that are either fully transitory or fully permanent.\n",
+ "\n",
+ "$\\texttt{ConsIndShockModel}$ currently includes three models:\n",
+ "1. A very basic \"perfect foresight\" model with no uncertainty (shocks are zero).\n",
+ "2. A model with risk over transitory and permanent income shocks.\n",
+ "3. The model described in (2), with an interest rate for debt that differs from the interest rate for savings.\n",
+ "\n",
+ "This notebook provides documentation for the first of these three models.\n",
+ "$\\newcommand{\\CRRA}{\\rho}$\n",
+ "$\\newcommand{\\DiePrb}{\\mathsf{D}}$\n",
+ "$\\newcommand{\\PermGroFac}{\\Gamma}$\n",
+ "$\\newcommand{\\Rfree}{\\mathsf{R}}$\n",
+ "$\\newcommand{\\DiscFac}{\\beta}$"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Statement of the model\n",
+ "\n",
+ "The $\\texttt{PerfForesightConsumerType}$ class solves the problem of a consumer with Constant Relative Risk Aversion utility \n",
+ "${\\CRRA}$\n",
+ "\\begin{equation}\n",
+ "U(C) = \\frac{C^{1-\\CRRA}}{1-\\rho},\n",
+ "\\end{equation}\n",
+ "who has perfect foresight about everything except whether he will die between the end of period $t$ and the beginning of period $t+1$. Permanent labor income $P_t$ grows from period $t$ to period $t+1$ by factor $\\PermGroFac_{t+1}$. The consumer faces no artificial borrowing constraint: He is able to borrow against his entire future stream of income.\n",
+ "\n",
+ "At the beginning of period $t$, the consumer has market resources $M_t$ (which includes both market wealth and currrent income) and must choose how much to consume $C_t$ and how much to retain in a riskless asset $A_t$, which will earn return factor $\\Rfree$. The agent's flow of future utility $U(C_{t+n})$ from consumption is geometrically discounted by factor $\\DiscFac$ per period. The consumer only experiences future value if he survives, which occurs with probability $1-\\DiePrb_{t+1}$.\n",
+ "\n",
+ "For parallelism with the treatment of more complicated problems, we write the problem rather elaborately in Bellman form as:\n",
+ "\n",
+ "\\begin{eqnarray*}\n",
+ "V_t(M_t,P_t) &=& \\max_{C_t}~U(C_t) ~+ \\DiscFac (1 - \\DiePrb_{t+1}) V_{t+1}(M_{t+1},P_{t+1}), \\\\\n",
+ "& s.t. & \\\\\n",
+ "A_t &=& M_t - C_t, \\\\\n",
+ "M_{t+1} &=& \\Rfree A_t + Y_{t+1}, \\\\\n",
+ "Y_{t+1} &=& P_{t+1}, \\\\ \n",
+ "P_{t+1} &=& \\PermGroFac_{t+1} P_t.\n",
+ "\\end{eqnarray*}\n",
+ "\n",
+ "The parameters of the consumer's problem are the coefficient of relative risk aversion $\\CRRA$, the intertemporal discount factor $\\DiscFac$, an interest factor $\\Rfree$, and age-varying sequences of the permanent income growth factor $\\PermGroFac_t$ and survival probability $(1 - \\DiePrb_t)$. [These lecture notes](http://econ.jhu.edu/people/ccarroll/public/lecturenotes/consumption/PerfForesightCRRA) show that under these assumptions the problem can be transformed into an equivalent problem stated in terms of *normalized* variables (represented in lower case); all real variables are divided by permanent income $P_t$ and value is divided by $P_t^{1-\\CRRA}$. The Bellman form of the normalized model (see the lecture notes for details) is:\n",
+ "\n",
+ "\\begin{eqnarray*}\n",
+ "v_t(m_t) &=& \\max_{c_t}~U(c_t) ~+ \\DiscFac (1 - \\DiePrb_{t+1}) \\PermGroFac_{t+1}^{1-\\CRRA} v_{t+1}(m_{t+1}), \\\\\n",
+ "& s.t. & \\\\\n",
+ "a_t &=& m_t - c_t, \\\\\n",
+ "m_{t+1} &=& a_t (\\Rfree/\\PermGroFac_{t+1} )+ 1.\n",
+ "\\end{eqnarray*}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Solution method for PerfForesightConsumerType\n",
+ "\n",
+ "Because of the assumptions of CRRA utility, no risk other than mortality, and no artificial borrowing constraint, the problem has a closed form solution in which consumption is a linear function of resources, and the utility-inverse of the value function is also linear (that is, $u^{-1}(v)$ is linear in $m$). Details of the mathematical solution of this model can be found in the lecture notes [PerfForesightCRRA](http://econ.jhu.edu/people/ccarroll/public/lecturenotes/consumption/PerfForesightCRRA). \n",
+ "\n",
+ "The one period problem for this model is solved by the function $\\texttt{solveConsPerfForesight}$, which creates an instance of the class $\\texttt{ConsPerfForesightSolver}$. To construct an instance of the class $\\texttt{PerfForesightConsumerType}$, several parameters must be passed to this constructor. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Example parameter values\n",
+ "\n",
+ "| Parameter | Description | Code | Example value | Time-varying? |\n",
+ "| :---: | --- | --- | --- | --- |\n",
+ "| $\\DiscFac$ |Intertemporal discount factor | $\\texttt{DiscFac}$ | $0.96$ | |\n",
+ "| $\\CRRA $ |Coefficient of relative risk aversion | $\\texttt{CRRA}$ | $2.0$ | |\n",
+ "| $\\Rfree$ | Risk free interest factor | $\\texttt{Rfree}$ | $1.03$ | |\n",
+ "| $1 - \\DiePrb_{t+1}$ |Survival probability | $\\texttt{LivPrb}$ | $[0.98]$ | $\\surd$ |\n",
+ "|$\\PermGroFac_{t+1}$|Permanent income growth factor|$\\texttt{PermGroFac}$| $[1.01]$ | $\\surd$ |\n",
+ "|$T$| Number of periods in this type's \"cycle\" |$\\texttt{T_cycle}$| $1$ | |\n",
+ "|(none)| Number of times the \"cycle\" occurs |$\\texttt{cycles}$| $0$ | |\n",
+ "\n",
+ "Note that the survival probability and income growth factor have time subscripts; likewise, the example values for these parameters are *lists* rather than simply single floats. This is because those parameters are in principle *time-varying*: their values can depend on which period of the problem the agent is in (for example, mortality probability depends on age). All time-varying parameters *must* be specified as lists, even when the model is being solved for an infinite horizon case where in practice the parameter takes the same value in every period.\n",
+ "\n",
+ "The last two parameters in the table specify the \"nature of time\" for this type: the number of (non-terminal) periods in this type's \"cycle\", and the number of times that the \"cycle\" occurs. *Every* subclass of $\\texttt{AgentType}$ uses these two code parameters to define the nature of time. Here, $\\texttt{T_cycle}$ has the value $1$, indicating that there is exactly one period in the cycle, while $\\texttt{cycles}$ is $0$, indicating that the cycle is repeated in *infinite* number of times-- it is an infinite horizon model, with the same \"kind\" of period repeated over and over.\n",
+ "\n",
+ "In contrast, we could instead specify a life-cycle model by setting $\\texttt{T_cycle}$ to $1$, and specifying age-varying sequences of income growth and survival probability. In all cases, the number of elements in each time-varying parameter should exactly equal $\\texttt{T_cycle}$.\n",
+ "\n",
+ "The parameter $\\texttt{AgentCount}$ specifies how many consumers there are of this *type*-- how many individuals have these exact parameter values and are *ex ante* homogeneous. This information is not relevant for solving the model, but is needed in order to simulate a population of agents, introducing *ex post* heterogeneity through idiosyncratic shocks. Of course, simulating a perfect foresight model is quite boring, as there are *no* idiosyncratic shocks other than death!\n",
+ "\n",
+ "The cell below defines a dictionary that can be passed to the constructor method for $\\texttt{PerfForesightConsumerType}$, with the values from the table here."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "code_folding": [
+ 0
+ ]
+ },
+ "outputs": [],
+ "source": [
+ "PerfForesightDict = {\n",
+ " # Parameters actually used in the solution method\n",
+ " \"CRRA\" : 2.0, # Coefficient of relative risk aversion\n",
+ " \"Rfree\" : 1.03, # Interest factor on assets\n",
+ " \"DiscFac\" : 0.96, # Default intertemporal discount factor\n",
+ " \"LivPrb\" : [0.98], # Survival probability\n",
+ " \"PermGroFac\" :[1.01], # Permanent income growth factor\n",
+ " \n",
+ " # Parameters that characterize the nature of time\n",
+ " \"T_cycle\" : 1, # Number of periods in the cycle for this agent type\n",
+ " \"cycles\" : 0 # Number of times the cycle occurs (0 --> infinitely repeated)\n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Inspecting the solution\n",
+ "\n",
+ "With the dictionary we have just defined, we can create an instance of $\\texttt{PerfForesightConsumerType}$ by passing the dictionary to the class (as if the class were a function). This instance can then be solved by invoking its $\\texttt{solve}$ method."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "PFexample = PerfForesightConsumerType(**PerfForesightDict)\n",
+ "PFexample.cycles = 0\n",
+ "PFexample.solve()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The $\\texttt{solve}$ method fills in the instance's attribute $\\texttt{solution}$ as a time-varying list of solutions to each period of the consumer's problem. In this case, $\\texttt{solution}$ will be a list with exactly one instance of the class $\\texttt{ConsumerSolution}$, representing the solution to the infinite horizon model we specified."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[]\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(PFexample.solution)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Each element of $\\texttt{solution}$ has a few attributes. To see all of them, we can use the $\\texttt{vars}$ built in function: the consumption functions are instantiated in the attribute $\\texttt{cFunc}$ of each element of $\\texttt{ConsumerType.solution}$. This method creates a (time varying) attribute $\\texttt{cFunc}$ that contains a list of consumption functions by age."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'cFunc': , 'vFunc': , 'vPfunc': , 'vPPfunc': , 'mNrmMin': -50.49994992551661, 'hNrm': 50.49994992551661, 'MPCmin': 0.04428139169919579, 'MPCmax': 0.04428139169919579}\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(vars(PFexample.solution[0]))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The two most important attributes of a single period solution are the (normalized) consumption function $\\texttt{cFunc}$ and the (normalized) value function $\\texttt{vFunc}$; the marginal value function $\\texttt{vPfunc}$ is also constructed. Let's plot those functions near the lower bound of the permissible state space (the attribute $\\texttt{mNrmMin}$ tells us the lower bound of $m_t$ where the consumption function is defined)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Linear perfect foresight consumption function:\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nO3deXxU9b3/8deXhAAJEJYQlkBIgEASQEBCoC5FFNkXbW1F3Jcfba/WXnu1trZChKKIVkXFrbjfeqn1tjXsgqCiuACuTBYICWRhDyRAQraZ7++PoObGAEPI5GQm7+fj4eORM3OYeT++hncOJ3M+x1hrERER/9fC6QAiItIwVOgiIgFChS4iEiBU6CIiAUKFLiISIIKdeuOIiAgbExPj1NuLiPilrVu3HrLWdqnrOccKPSYmhi1btjj19iIifskYs/tUz+mUi4hIgFChi4gECBW6iEiAUKGLiAQIFbqISIBQoYuIBAgVuohIgHDsc+giIuI9t8fyP5/lnnYfFbqISBO3ZddhZr/tIm3v0dPup1MuIiJN1IGjZdz19y+56rmPOVJawdMzh512fx2hi4g0MRVVHl7+KIcn391Bpdtyx5h+/MeYvoSGnL6yVegiIk3I+9sP8sAyF9kHSxibEMn9UxLp3TnMqz+rQhcRaQLyDpcyd3kaa9P2ExsRxss3j2DMgMizeg0VuoiIg05UuHn2/Z089/5OglsY7p0Qzy0XxdAqOOisX0uFLiLiAGstq7ft488r0ikoOsG0IT24b1IC3cJb1/s1VegiIo1sx/5jpCxz8VFWIfHd2vH3WaMY2afzOb+uCl1EpJEcK6tk0bodvLJpF6EhQcydPpCZydEEBzXMJ8hV6CIiPubxWP75RQELVmVQWFLOjBHR3DN+AJ3CQhr0fVToIiI+9E1+MbNTt/FFbhHDojvw8k0jGNwz3CfvpUIXEfGBwyUVPLImg6Wb8+gc1opHfzaEnwyLokUL47P3VKGLiDSgKreHNz7L5dE1mZRWuLn1wljuHBtH+9Ytff7eKnQRkQbyaXYhc1JdZOw7xkX9IkiZlki/yHaN9v4qdBGRc7SvuIwHV6aT+tUeojq04dlrz2fCoG4Y47vTK3VRoYuI1FN5lZsXP8zh6fVZVHksd14Wx69G96VNyNlf5dkQvCp0Y8wEYBEQBCyx1i44xX5XAf8ARlhrtzRYShGRJmZDxgHmLk8j51AJ4xK7cv+URHp1CnU00xkL3RgTBCwGLgfygc3GmFRrbVqt/doBdwKf+iKoiEhTsLuwhHnL01iXfoA+XcJ47ZZkfty/i9OxAO+O0JOBLGttNoAxZikwHUirtd88YCFwd4MmFBFpAkorqnhmw05e2JhNyxaG+ybFc9MFsYQEN537BHlT6FFAXo3tfGBkzR2MMcOAXtba5caYUxa6MWYWMAsgOjr67NOKiDQyay0rvtnLgyvS2VNcxpXDovj9xHi6tq//EC1f8abQ6/o1rf3uSWNaAI8DN53phay1LwAvACQlJdkz7C4i4qjMfcdISXXxcXYhid3b8+Q1w0iK6eR0rFPyptDzgV41tnsCe2pstwMGAe+d/IhONyDVGDNNvxgVEX9UfKKSJ9Zt57WPd9OudTB/vmIQ1yRHE+TDqzwbgjeFvhmIM8bEAgXADGDmt09aa4uBiG+3jTHvAXerzEXE33g8lre25vPw6gwOl1YwMzmau8cNoGMDD9HylTMWurW2yhhzB7CG6o8tvmStdRlj5gJbrLWpvg4pIuJrX+YVMSfVxVd5RST17sir05IZFOWbIVq+4tXn0K21K4GVtR6bfYp9Lzn3WCIijePQ8XIWrs7gzS35RLZrxeNXD+GKoVGNfpVnQ9CVoiLSLFW5Pbz+yW4eW7udExVufvHjPvz6sjjatvLfWvTf5CIi9fTxzkJSUl1k7j/GxXERzJk6kH6RbZ2Odc5U6CLSbOwpOsH8lems+HovPTu24fnrhzMusatfnl6piwpdRAJeWaWbJRuzWbxhJx5ruWtsf34xug+tWzozRMtXVOgiEtDeTd/P3OVp7C4sZeKgbvxxcgI9Ozo7RMtXVOgiEpByDpUwd5mLDZkH6RfZlv++dSQXxUWc+Q/6MRW6iASUkvIqnt6QxYsbcwgJbsGfJidw4wUxtAxqOkO0fEWFLiIBwVrLsq+rh2jtO1rGT8/vyb0TBxDZrukN0fIVFbqI+L30vUdJSXXxac5hBkeFs/ja8xneu6PTsRqdCl1E/FZxaSWPrc3k9U92E96mJQ9eOZirR/Rq8kO0fEWFLiJ+x+2xvLklj0fWZFJUWsF1o3rz28v70yHUP4Zo+YoKXUT8yue5R5jztotvCopJjulEyrSBJPZo73SsJkGFLiJ+4eCxch5encFbW/Pp2r4Vi2YMZdqQHgFzlWdDUKGLSJNW6fbw6qZdLFq3g7IqN78c3ZdfX9qPMD8eouUrWhERabI+yjpESqqLHQeOc8mALsyekkifLv4/RMtXVOgi0uQUFJ1g/oo0Vn6zj+hOoSy5IYnLEiJ1euUMVOgi0mSUVbp54YNsnnkvC4C7x/XntosDb4iWr6jQRcRx1lrWpu1n3oo08g6fYPLg7tw3OYGoDm2cjuZXVOgi4qidB4/zwLI0Pth+kP5d2/LGbSO5oF9gD9HyFRW6iDjieHkVT63fwUsf5tA6OIjZUxK5/ke9m8UQLV9RoYtIo7LW8vaXe3hwZToHjpXz86Se/G5CPBFtWzkdze+p0EWk0bj2FJOS6mLzriMM6RnO89cPZ1h08xui5SsqdBHxuaLSCh59J5M3Ps2lY2gID/90MD8b3osWzXSIlq+o0EXEZ9wey/98lsuj72RyrKyKG34Uw12X9ye8TUunowUkFbqI+MTW3YeZ/bYL156jjOpTPUQrvpuGaPmSCl1EGtSBo2UsWJXBP78ooHt4a566ZhhTzuuuqzwbgQpdRBpERZWHVzbl8OS7WVRUebh9TF9uH9OP0BDVTGPRSovIOftg+0FSlrnIPljCZfGR3D8lkZiIMKdjNTsqdBGpt7zDpfx5RRprXPuJ6RzKyzeNYEx8pNOxmi0VuoictbJKN8++t5Pn3t9JC2P43YQB3HpRLK2CNUTLSSp0EfGatZY1rn3MW55OQdEJpg7pwX2T4ukeriFaTYEKXUS8knXgOA8sc7FxxyHiu7Vj6axRjOrT2elYUoMKXURO61hZJU++u4OXP9pFaEgQKVMTuW5Ub4I1RKvJUaGLSJ08Hsu/vihgweoMDh0v5+qkXtwzfgCdNUSryVKhi8gPbCsoZvbb2/g8t4ihvTqw5IYkhvTq4HQsOQMVuoh853BJBY+syWTp5lw6h4XwyFXn8dPze2qIlp/wqtCNMROARUAQsMRau6DW878EbgfcwHFglrU2rYGzioiPuD2WNz7dzaPvbOd4eRW3XBjLb8bG0b61hmj5kzMWujEmCFgMXA7kA5uNMam1CvsNa+1zJ/efBjwGTPBBXhFpYJ/lHGZOqov0vUe5oG9nUqYNpH/Xdk7Hknrw5gg9Gciy1mYDGGOWAtOB7wrdWnu0xv5hgG3IkCLS8PYVl/HQqnTe/nIPPcJb88y15zNxUDcN0fJj3hR6FJBXYzsfGFl7J2PM7cBvgRDg0rpeyBgzC5gFEB0dfbZZRaQBVFR5eOmjHJ58dwdVHsudl/bjV5f0o02IrvL0d94Uel0/rn9wBG6tXQwsNsbMBP4E3FjHPi8ALwAkJSXpKF6kkb2XeYC5y9LIPlTC5YlduX9yItGdQ52OJQ3Em0LPB3rV2O4J7DnN/kuBZ88llIg0rNzCUuYuT2Nd+n76RITxys0juGSAhmgFGm8KfTMQZ4yJBQqAGcDMmjsYY+KstTtObk4GdiAijjtR4eaZ97J4/oNsWrYw/H5iPLdcGEtIsK7yDERnLHRrbZUx5g5gDdUfW3zJWusyxswFtlhrU4E7jDFjgUrgCHWcbhGRxmOtZeU3+5i/Io09xWVcMbQHf5iUQNf2rZ2OJj7k1efQrbUrgZW1Hptd4+vfNHAuEamn7fuPkZLqYtPOQhK6t+eJGcNIju3kdCxpBLpSVCRAHC2r5Im1O3j14120bRXMvOkDmTmyN0G6yrPZUKGL+DmPx/LW5/ksXJ1BYUkF1yRHc/e4AXQKC3E6mjQyFbqIH/sqr4g5qS6+zCtieO+OvHJzMoOiwp2OJQ5RoYv4ocLj5SxcncmbW/PoHNaKx34+hCuHRekqz2ZOhS7iR6rcHv77k908tnY7pRVubrsoljsvi6OdhmgJKnQRv/FJdiEpqS4y9h3j4rgI5kxNpF+khmjJ91ToIk3c3uITzF+RzvKv9xLVoQ3PXTec8QO76vSK/IAKXaSJKq9ys2RjDk+vz8JjLf85No5fju5L65YaoiV1U6GLNEHrM/Yzd1kauwpLGT+wK3+anEivThqiJaenQhdpQnYdKmHu8jTWZxygb5cwXr81mYvjujgdS/yECl2kCSitqOLp9Vks2ZhDSHAL/jgpgRsviNEQLTkrKnQRB1lrWf71Xh5cmc7e4jJ+MiyK30+MJ1JDtKQeVOgiDsnYd5SUVBefZB9mYI/2PD1zGMN7a4iW1J8KXaSRFZdW8vi67bz+yW7atQ5m/pWDmDEiWkO05Jyp0EUaicdjeXNLHgvXZFJUWsG1I3vzX+P60yFUQ7SkYajQRRrBF7lHSEl18VV+MSNiOpIyLZmBPTRESxqWCl3Ehw4eK2fh6gz+sTWfyHateOLqoUwf2kNXeYpPqNBFfKDS7eG1j3fzxNrtlFW5+cXoPvz60jjattJfOfEdfXeJNLBNWYdIWeZi+/7jjO7fhdlTE+nbpa3TsaQZUKGLNJCCohM8uCKdFd/spVenNvz1hiTGJkTq9Io0GhW6yDkqq3Tz1w+yWfxeFgC/vbw/s37cR0O0pNGp0EXqyVrLuvQDzFueRu7hUiYN7sZ9kxLo2VFDtMQZKnSResg+eJwHlqXx/vaDxEW25W+3jeTCfhFOx5JmToUuchZKyqt4an0WL36YTevgIP40uXqIVssgDdES56nQRbxgrSX1qz08uDKd/UfLuWp4T+6dEE+Xdq2cjibyHRW6yBmk7akeovXZrsOc1zOcZ68bzvnRHZ2OJfIDKnSRUygqreAv72znb5/upkNoCAt+MpifJ/WihYZoSROlQhepxe2x/H1zHo+syaD4RCU3/CiGu8b2Jzy0pdPRRE5LhS5Sw9bdR5iTuo1tBUdJju3EA9MGktC9vdOxRLyiQhcBDhwrY8GqDP75eQHd2rfmyWuGMfW87rrKU/yKCl2atUq3h1c+2sWid3dQUeXhPy7py+1j+hGmIVrih/RdK83Wxh0HSUl1sfNgCZfGR3L/lERiI8KcjiVSbyp0aXbyDpcyf0U6q1376N05lBdvTOKyhK5OxxI5Zyp0aTbKKt089/5Onn1vJy2M4Z7xA7j1olgN0ZKAoUKXgGetZY1rP39ekUb+kRNMOa87901KoEeHNk5HE2lQXhW6MWYCsAgIApZYaxfUev63wG1AFXAQuMVau7uBs4qctawDx3lgmYuNOw4xoGs73vh/I7mgr4ZoSWA6Y6EbY4KAxcDlQD6w2RiTaq1Nq7HbF0CStbbUGPMrYCFwtS8Ci3jjWFklT63P4qUPc2gTEsScqYlcP6o3wRqiJQHMmyP0ZCDLWpsNYIxZCkwHvit0a+2GGvt/AlzXkCFFvGWt5V9fFPDQqgwOHS/n58N7cc+EAUS01RAtCXzeFHoUkFdjOx8YeZr9bwVWnUsokfrYVlDMnFQXW3cfYUivDiy5IYkhvTo4HUuk0XhT6HVdKmfr3NGY64AkYPQpnp8FzAKIjo72MqLI6R0pqeDRdzJ547NcOoWGsPCq87jq/J4aoiXNjjeFng/0qrHdE9hTeydjzFjgj8Boa215XS9krX0BeAEgKSmpzh8KIt5yeyxvfJbLX97J5FhZFTddEMN/ju1PeBsN0ZLmyZtC3wzEGWNigQJgBjCz5g7GmGHA88AEa+2BBk8pUsvmXYeZ87aLtL1H+VGfzqRMG8iAbu2cjiXiqDMWurW2yhhzB7CG6o8tvmStdRlj5gJbrLWpwCNAW+AfJ4cZ5Vprp/kwtzRT+4+W8dDKdP795R66h7fm6ZnDmDxYQ7REwMvPoVtrVwIraz02u8bXYxs4l8j/UVHl4eWPcnjy3R1Uui13jOnHf4zpS2iIro0T+Zb+NkiT9/72gzywzEX2wRLGJlQP0erdWUO0RGpToUuTlXe4lLnL01ibtp/YiDBevnkEYwZEOh1LpMlSoUuTc6LCzbPvZfHcB9kEtzDcOyGeWy6KoVWwhmiJnI4KXZoMay2rtu1j/op0CopOMG1ID+6blEC38NZORxPxCyp0aRJ27D9GyjIXH2UVEt+tHX+fNYqRfTo7HUvEr6jQxVFHyypZtG4Hr27aRWhIEHOnD2RmcrSGaInUgwpdHOHxWP75RQELVmVQWFLOjBHR3DN+AJ3CQpyOJuK3VOjS6L7JL2Z26ja+yC1iWHQHXr5pBIN7hjsdS8TvqdCl0RQeL+fRdzJZujmPzmGtePRnQ/jJsCgN0RJpICp08bkqt4e/fVo9RKu0ws2tF8Zy59g42rfWEC2RhqRCF5/6NLuQOakuMvYd48J+nUmZOpC4rhqiJeILKnTxiX3FZTy4Mp3Ur/YQ1aENz157PhMGddMQLREfUqFLgyqvcvPihzk8vT6LKo/lzsvi+NXovrQJ0VWeIr6mQpcGsyHjAHOXp5FzqIRxiV25f0oivTqFOh1LpNlQocs5211YwtxlabybcYA+EWG8eksyo/t3cTqWSLOjQpd6K62oYvGGLP76QQ4tgwx/mBjPzRfGEhKsqzxFnKBCl7NmrWXFN3uZvyKdvcVlXDksit9PjKdrew3REnGSCl3OSua+Y6Skuvg4u5DE7u156pphJMV0cjqWiKBCFy8Vn6jk8bXbef2T3bRrHcyfrxjENcnRBOkqT5EmQ4Uup+XxWN7ams/DqzM4XFrBzORo7h43gI4aoiXS5KjQ5ZS+zCtiTqqLr/KKSOrdkVenJTMoSkO0RJoqFbr8wKHj5SxcncGbW/Lp0q4Vj189hCuGRukqT5EmToUu36lye3jt4908vm47JyrczPpxH359aT/aaYiWiF9QoQsAm3YeIiXVxfb9x7k4LoI5UwfSL7Kt07FE5Cyo0Ju5PUUnmL8ynRVf76VnxzY8f/1wxiV21ekVET+kQm+myirdLNmYzeINO/FYy11j+/OL0X1o3VJDtET8lQq9GXo3fT8PLEsj93ApEwd144+TE+jZUUO0RPydCr0ZyTlUwtxlLjZkHqRfZFv++9aRXBQX4XQsEWkgKvRmoKS8iqc3ZPHixhxCglvwp8kJ3HhBDC2DNERLJJCo0AOYtZbUr/bw0MoM9h0t46fn9+TeiQOIbKchWiKBSIUeoNL3HmVOqovPcg4zOCqcxdeez/DeHZ2OJSI+pEIPMMWllTy2NpPXP9lNeJuWPHjlYK4e0UtDtESaARV6gHB7LG9uyeORNZkUlVZw3aje/Pby/nQI1RAtkeZChR4APs89wpy3XXxTUExyTCdSpg0ksUd7p2OJSCNTofuxA8fKeHhVJv/7eT5d27di0YyhTBvSQ1d5ijRTKnQ/VOn28OqmXSxat4OyKje/HN2XX1/aj7BW+t8p0px51QDGmAnAIiAIWGKtXVDr+R8DTwDnATOstW81dFCp9lHWIeakusg6cJxLBnRh9pRE+nTREC0R8aLQjTFBwGLgciAf2GyMSbXWptXYLRe4CbjbFyEF8o+UMn9FOqu27SO6UyhLbkjisoRInV4Rke94c4SeDGRZa7MBjDFLgenAd4Vurd118jmPDzI2a2WVbp5/P5tn388C4O5x/bntYg3REpEf8qbQo4C8Gtv5wMj6vJkxZhYwCyA6Oro+L9FsWGtZm7afeSvSyDt8gsmDu3Pf5ASiOrRxOpqINFHeFHpd/6a39Xkza+0LwAsASUlJ9XqN5mDnweM8sCyND7YfpH/Xtrxx20gu6KchWiJyet4Uej7Qq8Z2T2CPb+I0b8fLq3jq3R289FEOrYODmD0lket/1FtDtETEK94U+mYgzhgTCxQAM4CZPk3VzFhr+feXBTy0MoMDx8r5eVJPfjchnoi2rZyOJiJ+5IyFbq2tMsbcAayh+mOLL1lrXcaYucAWa22qMWYE8C+gIzDVGPOAtXagT5MHCNeeYua87WLL7iMM6RnO89cPZ1i0hmiJyNnz6nPo1tqVwMpaj82u8fVmqk/FiJeOlFTwl7WZvPFpLh1DQ3j4p4P52fBetNAQLRGpJ11a2MjcHsv/fJbLo+9kcqysiht+FMNdl/cnvE1Lp6OJiJ9ToTeiLbsOMyfVhWvPUUb1qR6iFd9NQ7REpGGo0BvBgaNlPLQqg399UUD38NY8dc0wppzXXVd5ikiDUqH7UEWVh1c25bBo3Q4q3Zbbx/Tl9jH9CA3RsotIw1Oz+MgH2w+SssxF9sESLouP5P4picREhDkdS0QCmAq9geUdLmXe8jTeSdtPTOdQXropiUvjuzodS0SaARV6AzlR4ebZ93fy/Ps7aWEM94wfwG0Xx9IqWEO0RKRxqNDPkbWWNa59zFueTkHRCaYO6cF9k+LpHq4hWiLSuFTo5yDrwDFSUtP4MOsQ8d3asXTWKEb16ex0LBFpplTo9XCsrJJF63bwyqZdhIYEkTI1ketG9SZYQ7RExEEq9LPg8Vj++UUBC1ZlUFhSztVJvbhn/AA6a4iWiDQBKnQvbSsoZvbb2/g8t4ihvTrw4o1JDOnVwelYIiLfUaGfweGSCh5Zk8nSzbl0DgvhkavO46fn99QQLRFpclTop1Dl9vDGZ7n85Z3tHC+v4pYLY/nN2Djat9YQLRFpmlTodfgsp3qIVvreo1zQtzMp0wbSv2s7p2OJiJyWCr2GfcVlPLQqnbe/3EOP8NY8c+35TBzUTUO0RMQvqNCB8io3L324i6fW76DKY7nz0n786pJ+tAnRVZ4i4j+afaFvyDzA3GVp5BwqYWxCV2ZPSSS6c6jTsUREzlqzLfTdhSXMW57GuvQD9IkI45WbR3DJgEinY4mI1FuzK/QTFW6eeS+L5z/IpmULw+8nxnPLhbGEBOsqTxHxb82m0K21rPxmH/NXpLGnuIwrhvbgD5MS6Nq+tdPRREQaRLMo9O37j5GS6mLTzkISurfniRnDSI7t5HQsEZEGFdCFXnyikifWbee1j3fTtlUw86YPZObI3gTpKk8RCUABWegej+Wtz/NZuDqDwpIKrkmO5u5xA+gUFuJ0NBERnwm4Qv8qr4g5qS6+zCtieO+OvHJzMoOiwp2OJSLicwFT6IXHy1m4OpM3t+bROawVj/18CFcOi9JVniLSbPh9oVe5Pbz+yW4eW7udExVubrsoljsvi6OdhmiJSDPj14X+8c5CUlJdZO4/xsVxEcyZmki/SA3REpHmyS8LfW/xCeavSGf513uJ6tCG564bzviBXXV6RUSaNb8q9PIqN0s25vD0+iw81vKby+L41SV9ad1SQ7RERPym0Ndn7OeBZWnsLixl/MCu/GlyIr06aYiWiMi3mnyh7zpUwtzlaazPOEDfLmG8fmsyF8d1cTqWiEiT02QLvaS8isUbsliyMYeQ4Bb8cVICN14QoyFaIiKn0OQK3VrLsq/38uCKdPYdLeMnw6L4/cR4IjVES0TktJpUoafvPUpKqotPcw4zsEd7Fl87jOG9NURLRMQbTaLQi0sreXzddl77eBft27Rk/pWDmDEiWkO0RETOgleFboyZACwCgoAl1toFtZ5vBbwGDAcKgauttbvO9Loej+XNLXksXJNJUWkF147szX+N60+HUA3REhE5W2csdGNMELAYuBzIBzYbY1KttWk1drsVOGKt7WeMmQE8DFx9utctrXBzxTMf8XV+MSNiOpIyLZmBPTRES0Skvrw5Qk8Gsqy12QDGmKXAdKBmoU8HUk5+/RbwtDHGWGvtqV5058HjtC0u44mrhzJ9aA9d5Skico68KfQoIK/Gdj4w8lT7WGurjDHFQGfgUM2djDGzgFkAHaNiWX/3JbRt1SRO44uI+D1vPtRd16Fz7SNvb/bBWvuCtTbJWpvUp1snlbmISAPyptDzgV41tnsCe061jzEmGAgHDjdEQBER8Y43hb4ZiDPGxBpjQoAZQGqtfVKBG09+fRWw/nTnz0VEpOGd8ZzHyXPidwBrqP7Y4kvWWpcxZi6wxVqbCrwIvG6MyaL6yHyGL0OLiMgPeXUS21q7ElhZ67HZNb4uA37WsNFERORsaNKViEiAUKGLiAQIFbqISIBQoYuIBAjj1KcLjTEHgd3n+DIR1LoatRnTWnxPa/E9rcX3AmUteltr67xtm2OF3hCMMVustUlO52gKtBbf01p8T2vxveawFjrlIiISIFToIiIBwt8L/QWnAzQhWovvaS2+p7X4XsCvhV+fQxcRke/5+xG6iIicpEIXEQkQflfoxpgUY0yBMebLk/9NqvHcH4wxWcaYTGPMeCdzNiZjzN3GGGuMiTi5HW6MWWaM+coY4zLG3Ox0xsZSey1OPnbJye8VlzHmfSfzNaa61uLk4yOMMW5jzFVOZWtsdfwdudYY8/XJ/zYZY4Y4nbEh+Ostgx631j5a8wFjTCLVY3sHAj2AdcaY/tZatxMBG4sxphfVN/DOrfHw7UCatXaqMaYLkGmM+Zu1tsKRkI2krrUwxnQAngEmWGtzjTGRTuVrTKf4vvj2pu8PUz0Ou1k4xVrkAKOttUeMMROp/oVp7Vtr+h2/O0I/jenAUmttubU2B8ii+gbXge5x4Hf831v+WaCdqb7zdluqZ9RXOZCtsdW1FjOBf1prcwGstQecCOaAutYC4NfA/wLNZR2gjrWw1m6y1h45ufkJ1Xdi83v+Wuh3nPyn0kvGmI4nH6vrZtZRjR+t8RhjpgEF1tqvaj31NJBA9a0CvwF+Y631NHa+xnSategPdDTGvGeM2WqMucGBeI3qVGthjIkCrgSecySYA07zfVHTrcCqRorkU03ylIsxZh3QrY6n/gg8C8yj+qftPOAvwC14eaNqf3OGtbgPGFfHc+OBL4FLgb7AWmPMRmvtUZ8FbQT1XBGpSxAAAAGhSURBVItgYDhwGdAG+NgY84m1drvPgjaCeq7FE8C91lp39T/eAkM91+LbPzuG6kK/yDfpGleTLHRr7Vhv9jPG/BVYfnLTm5tZ+51TrYUxZjAQC3x18i9nT+BzY0wycDOw4OR9XbOMMTlAPPBZ46T2jXquRT5wyFpbApQYYz4AhgB+Xej1XIskYOnJxyOAScaYKmvtvxsntW/UZy2stfuMMecBS4CJ1trCRgvsQ353YZExpru1du/Jr+8CRlprZxhjBgJvUH3evAfwLhAX6L8U/ZYxZheQZK09ZIx5FthvrU0xxnQFPgeGWGsDYdLcGdVaiwSqT0GNB0Ko/qE2w1q7zcGIjabmWtR6/BVgubX2LSdyOaHW90U0sB64wVq7ydlkDadJHqGfwUJjzFCqT6fsAn4BcPLG1W8CaVT/AvD25lLmdZgHvGKM+YbqU1H3Npcyr81am26MWQ18DXiAJc2lzOW0ZgOdgWdOHr1XBcIkRr87QhcRkbr566dcRESkFhW6iEiAUKGLiAQIFbqISIBQoYuIBAgVuohIgFChi4gEiP8PyZkLqx5khicAAAAASUVORK5CYII=\n",
+ "text/plain": [
+ "