diff --git a/Documentation/ConsumptionSavingModels.tex b/Documentation/ConsumptionSavingModels.tex deleted file mode 100644 index 9004407bf..000000000 --- a/Documentation/ConsumptionSavingModels.tex +++ /dev/null @@ -1,370 +0,0 @@ -% !TeX spellcheck = en_GB - -\documentclass[12pt,titlepage,letterpaper]{econtex} -\usepackage{econtexSetup}\usepackage{econtexShortcuts} -\usepackage{graphicx} -\usepackage{hyperref} -\newcommand{\E}{\mathbb{E}} -%\newcommand{\pd}[2]{\frac{\partial#1}{\partial#2}} - -\begin{document} -\section{ConsIndShockModel.py} - -Defines consumption-saving models whose agents have CRRA utility over a unitary consumption good, geometric discounting, and who face idiosyncratic shocks to income. - -\subsection{Perfect Foresight} - -Consider an agent with CRRA utility over consumption, who discounts future utility at a constant rate per period and has no bequest motive. His problem can be written as: -\begin{eqnarray*} -V_t(M_t) &=& \max_{C_t} \utilFunc(C_t) + \beta \PLives_{t+1} \E [V_{t+1}(M_{t+1}) ], \\ -A_t &=& M_t - C_t, \\ -M_{t+1} &=& \Rfree A_t + Y_{t+1}, \\ -Y_{t+1} &=& \Gamma_{t+1} Y_t, \\ -\utilFunc(C) &=& \frac{C^{1-\CRRA}}{1-\CRRA}. -\end{eqnarray*} -The model can be normalized by current income (which is also permanent income in this model) by defining lower case variables as their upper case version divided by $Y_t$: -\begin{eqnarray*} -\vFunc_t(m_t) &=& \max_{c_t} \utilFunc(c_t) + \beta \PLives_{t+1} \E [\vFunc_{t+1}(m_{t+1}) ], \\ -a_t &=& m_t - c_t, \\ -m_{t+1} &=& (\Rfree/\Gamma_{t+1}) a_t + 1, \\ -\utilFunc(c) &=& \frac{c^{1-\CRRA}}{1-\CRRA}. -\end{eqnarray*} -An individual agent's model is thus characterized by values of $\CRRA$, $\beta$, and $\Rfree$ along with sequences $\{\Gamma_t\}_{t=1}^T$ and $\{\PLives_t\}_{t=1}^T$, with $T = \infty$ possible. - -The one period problem for this model is solved by the function \texttt{solveConsPerfForesight}, which creates an instance of the class \texttt{ConsPerfForesightSolver}. The class \texttt{PerfForesightConsumerType} extends \texttt{AgentType} to represent agents in this model. The concordance between model variables and their code equivalents is as follows. - -\begin{table}[h!] -\centering -\begin{tabular}{c c c} -Var & Description & Code \\ -\hline -$\CRRA$ & Coefficient of relative risk aversion & \texttt{CRRA} \\ -$\beta$ & Intertemporal discount factor & \texttt{DiscFac} \\ -$\Rfree$ & Risk free interest factor & \texttt{Rfree} \\ -$\PLives$ & Survival probability & \texttt{LivPrb} \\ -$\Gamma$ & Permanent income growth factor & \texttt{PermGroFac} \\ -(none) & Number of agents of this type & \texttt{Nagents} -\end{tabular} -\end{table} - -These are the only six parameters that an instance of \texttt{PerfForesightConsumerType} must have in order to create an instance and its \texttt{solve} method.\footnote{The attribute \texttt{Nagents} is not needed to \texttt{solve} this type, but is instead used during simulation. However, this attribute is used by the constructor method for this class (to set the attributes \texttt{a\_init} and \texttt{p\_init}), so it must be passed when a new instance is created.} Note that \texttt{LivPrb} and \texttt{PermGroFac} are assumed to be time-varying, so they should be input as a list. Each element of the \texttt{solution} attribute will be an instance of \texttt{ConsumerSolution} with the following attributes: - -\begin{table}[h!] -\centering -\begin{tabular}{c c c} -Var & Description & Code \\ -\hline -$\cFunc(\cdot)$ & Noramlized consumption function & \texttt{cFunc} \\ -$\vFunc(\cdot)$ & Normalized value function & \texttt{vFunc} \\ -$\vFunc'(\cdot)$ & Normalized marginal value function & \texttt{vPfunc} \\ -$\underline{m}$ & Mininum normalized market resources & \texttt{mNrmMin} \\ -$h$ & Normalized human wealth & \texttt{hNrm} \\ -$\overline{\kappa}$ & Maximum marginal propensity to consume & \texttt{MPCmax} \\ -$\underline{\kappa}$ & Minimum marginal propensity to consume & \texttt{MPCmin} \\ -\end{tabular} -\end{table} -In the perfect foresight model, the consumption function is linear, so the maximum and minimum MPC are equal. Each of the functions takes normalized market resources $m$ as an argument, and they only defined on the domain $m \geq \underline{m} = -h$. - - -\subsection{Permanent and Transitory Idiosyncratic Shocks} - -Consider an agent with CRRA utility over consumption, who discounts future utility at a constant rate per period and has no bequest motive. He foresees that he will experience shocks to his income that are fully transitory or fully permanent. Using the normalization above, his problem can be written as: - -\begin{eqnarray*} -\vFunc_t(m_t) &=& \max_{c_t} \utilFunc(c_t) + \beta \PLives_{t+1} \E [\vFunc_{t+1}(m_{t+1}) ], \\ -a_t &=& m_t - c_t, \\ -a_t &\geq& \underline{a}, \\ -m_{t+1} &=& \Rfree/(\Gamma_{t+1} \psi_{t+1}) a_t + \theta_{t+1}, \\ -\theta_t \sim F_{\theta t}, &\qquad& \psi_t \sim F_{\psi t}, \hspace{0.25cm} \E[F_{\psi t}] = 1, \\ -\utilFunc(c) &=& \frac{c^{1-\CRRA}}{1-\CRRA}. -\end{eqnarray*} -That is, this agent is identical to the perfect foresight agent except that his income is subject to permanent ($\psi$) and transitory ($\theta$) shocks to income, and he might have an artificial borrowing constraint $\underline{a}$. - -The one period problem for this model is solved by the function \texttt{solveConsIndShock}, which creates an instance of the class \texttt{ConsIndShockSolver}. The class \texttt{IndShockConsumerType} extends \texttt{PerfForesightConsumerType} to represent agents in this model. To construct an instance of this class, several additional parameters must be passed to the constructor. Note that most of these parameters are \textit{indirect} inputs to the consumer's model: they are used to construct direct inputs to the one period problem. The concordance between the model and code is as follows: - -\begin{table}[h!] -\centering -\begin{tabular}{c c c} -Var & Description & Code \\ -\hline -(none) & Minimum of ``assets above minimum'' grid & \texttt{aXtraMin} \\ -(none) & Maximum of ``assets above minimum'' grid & \texttt{aXtraMax} \\ -(none) & Number of points in ``assets above minimum'' grid & \texttt{aXtraCount} \\ -(none) & Additional values for the ``assets above minimum'' grid & \texttt{aXtraExtra} \\ -(none) & Degree of exponential nesting for assets grid & \texttt{exp\_nest} \\ -$N_{\theta}$ & Number of discrete values in transitory shock distribution & \texttt{TranShkCount} \\ -$N_{\psi}$ & Number of discrete values in permanent shock distribution & \texttt{PermShkCount} \\ -$\sigma_\theta$ & Standard deviation of log transitory shocks & \texttt{TranShkStd} \\ -$\sigma_\psi$ & Standard deviation of log permanent shocks & \texttt{PermShkStd} \\ -$\mho$ & Unemployment probability in working period & \texttt{UnempPrb} \\ -$\mho_{ret}$ & ``Unemployment'' probability in retirement period & \texttt{UnempPrbRet} \\ -$\underline{\theta}$ & Transitory income when unemployed in working period & \texttt{IncUnemp} \\ -$\underline{\theta}_{ret}$ & Transitory income when ``unemployed'' in retired period & \texttt{IncUnempRet} \\ -$\tau$ & Marginal income tax rate & \texttt{tax\_rate} \\ -$T_{ret}$ & Period of retirement; number of working periods & \texttt{T\_retire} \\ -$\underline{a}$ & Artificial borrowing constraint & \texttt{BoroCnstArt} \\ -(none) & Indicator for whether \texttt{cFunc} should use cubic splines & \texttt{CubicBool} \\ -(none) & Indicator for whether \texttt{vFunc} should be computed & \texttt{vFuncBool} \\ -$T$ & Total number of (non-terminal) periods in sequence & \texttt{T\_total} \\ -(none) & Number of agents of this type & \texttt{Nagents} -\end{tabular} -\end{table} - -The first five attributes in the table above are used to construct the ``assets above minimum'' grid \texttt{aXtraGrid}, an input for \texttt{solveConsIndShock}.\footnote{In the current configuration, the grid is multi-exponentially spaced given minimum, maximum, number of gridpoints, and degree of exponential nesting (with additional values to force into the grid with \texttt{aXtraExtra}). It is simple to replace this grid with another by changing the function \texttt{makeAssetsGrid}.} The next ten attributes specify an assumed form for the income distribution $(F_{\psi t}, F_{\theta t})$. Both permanent and transitory shocks are lognormally distributed, and with a point mass in the transitory distribution representing unemployment. Further, the sequence of periods is broken into two parts, ``working'' and ``retired'' to allow for a different income process in retirement.\footnote{Permanent and transitory shocks are turned off during retirement, other than the possibility of ``unemployment'', representing (say) a temporary failure of the retirement benefit system.} The attributes \texttt{PermShkStd} and \texttt{TranShkStd} are thus lists of the (log) standard deviation of shocks period-by-period. - -Like the assets grid, the specification of the income process can be changed with little difficulty. No matter what form is used, the relevant direct input to \texttt{solveConsIndShock} is \texttt{IncomeDstn}, a finite discrete approximation to the true income process. This attribute is specified as a list with three elements: an array of probabilities (that sum to 1), an array of permanent income shocks, and an array of transitory income shocks. - -The artificial borrowing constraint imposes a restriction on assets at the end of the period; it can be set to \texttt{None} to turn off the constraint (i.e.\ only the ``natural'' borrowing constraint will be used). The attributes \texttt{CubicBool} and \texttt{vFuncBool} should be set to \texttt{True} or \texttt{False}, as their name implies. The solver can construct a linear or cubic spline interpolation of the consumption function; cubic interpolation is slower but more accurate at any number of gridpoints. The value function is not strictly necessary to compute during solution and carries a computational burden, so it can be turned off with \texttt{vFuncBool=False}. The number of agents of this type \texttt{Nagents} is irrelevant during solution and is only used during simulation (when \textit{ex-post} heterogeneity emerges within the \textit{ex-ante} homogeneous type). - -The \texttt{solve} method of \texttt{IndShockConsumerType} will populate the \texttt{solution} attribute with a list containing instances of \texttt{ConsumerSolution}. Each of these instances has all the elements listed above in the perfect foresight section plus the attribute \texttt{vPPfunc} (representing $\vFunc''(m)$) if \texttt{CubicBool=True}.\footnote{\texttt{vFunc} will be a placeholder function of the class \texttt{NullFunc} if \texttt{vFuncBool=False}.} The problem is solved using the method of endogenous gridpoints, which is explained for this model in section 5.8 of \href{http://www.econ2.jhu.edu/people/ccarroll/SolvingMicroDSOPs/}{this set of lecture notes}. - - -\subsection{Different Interest Rate on Borrowing vs Saving} - -Consider an agent identical to the ``idiosyncratic shocks'' model above, except that his interest factor differs depending on whether he borrows or saves on net. His problem is the same as the one above, with a simple addition: -\begin{equation*} -\Rfree = \begin{cases} -\Rfree_{boro} & \text{if } a_t < 0 \\ -\Rfree_{save} & \text{if } a_t > 0 -\end{cases}, \qquad \Rfree_{boro} \geq \Rfree_{save}. -\end{equation*} - -The one period problem for this model is solved by \texttt{solveConsKinkedR}, which creates an instance of \texttt{ConsKinkedRsolver}. The class \texttt{KinkedRconsumerType} extends \texttt{IndShockConsumerType} to represent agents in this model. The attributes required to specify an instance of \texttt{KinkedRconsumerType} are the same as \texttt{IndShockConsumerType} except that \texttt{Rfree} \textit{should not} be included, instead replaced by values of \texttt{Rboro} and \texttt{Rsave}. The ``kinked R'' solver is not yet compatible with cubic spline interpolation for \texttt{cFunc}; if the \texttt{solve} method is run with \texttt{CubicBool=True}, it will throw an exception.\footnote{This is an item that is ripe for development by an outside contributor.} - -The \texttt{solve} method of \texttt{KinkedRconsumerType} populates the \texttt{solution} attribute with a list of \texttt{ConsumerSolution} instances, in the same format as the idiosyncratic shocks model. The problem is solved using the method of endogenous gridpoints with \textit{two} copies of $a_t = 0$ in the grid of end-of-period states-- one for $\Rfree_{boro}$ and the other for $\Rfree_{save}$. This generates the ``kinked'' portion of the resulting consumption function, where the consumer is unwilling to borrow and insufficiently motivated to save, so he consumes at $c_t = m_t$. - -\section{ConsPrefShockModel.py} - -Defines consumption-saving models whose agents have CRRA utility over a unitary consumption good, geometric discounting, who face idiosyncratic shocks to income and to their utility or preferences. - -\subsection{Multiplicative Shocks to Utility} - -Consider an agent with a very similar problem to that of the ``idiosyncratic shocks'' model in the preceding section, except that he receives an iid multiplicative shock to his utility at the beginning of each period, before making the consumption decision. This model can be written in Bellman form as: - -\begin{eqnarray*} -\vFunc_t(m_t,\eta_t) &=& \max_{c_t} \eta \cdot \utilFunc(c_t) + \beta \PLives_{t+1} \E [\vFunc_{t+1}(m_{t+1},\eta_{t+1}) ], \\ -a_t &=& m_t - c_t, \\ -a_t &\geq& \underline{a}, \\ -m_{t+1} &=& \Rfree/(\Gamma_{t+1} \psi_{t+1}) a_t + \theta_{t+1}, \\ -\theta_t \sim F_{\theta t}, &\qquad& \psi_t \sim F_{\psi t}, \hspace{0.25cm} \E[F_{\psi t}] = 1, \\ -\utilFunc(c) &=& \frac{c^{1-\CRRA}}{1-\CRRA}, \qquad \eta_t \sim F_{\eta t}. -\end{eqnarray*} - -The one period problem for this model is solved by the function \texttt{solveConsPrefShock}, which creates an instance of \texttt{ConsPrefShockSolver}. The class \texttt{PrefShockConsumerType} is used to represent agents in this model. The attributes required to construct an instance of this class are the same as for \texttt{IndShockConsumerType} above, but with three additions: -\begin{table}[h!] -\centering -\begin{tabular}{c c c} -Var & Description & Code \\ -\hline -$N_\eta$ & Number of discrete points in ``body'' of preference shock distribution & \texttt{PrefShkCount} \\ -$N_\eta^{tail}$ & Number of discrete points in ``tails'' of preference shock distribution & \texttt{PrefShk\_tail\_N} \\ -$\sigma_\eta$ & Log standard deviation of multiplicative utility shocks & \texttt{PrefShkStd} -\end{tabular} -\end{table} - -These attributes are indirect inputs to the problem, used during instantiation to construct the \texttt{PrefShkDstn}, an input to \texttt{solveConsPrefShock}. The tails of the preference shock distribution matter a great deal for the accuracy of the solution and are underrepresented by the default equiprobable discrete approximation (unless a very large number of points are used). To fix this issue, the attribute \texttt{PrefShk\_tail\_N} specifies the number of points in each ``augmented tail'' section of the preference shock discrete approximation.\footnote{See documentation for \texttt{HARK.utilities.approxLognormal} for more details.} The standard deviation of preference shocks might vary by period, so \texttt{PrefShkStd} should be input as a list. The ``preference shock'' solver is not yet compatible with cubic spline interpolation for the consumption function and will throw an exception if \texttt{CubicBool=True}. - -The \texttt{solve} method of \texttt{PrefShockConsumerType} populates the \texttt{solution} attribute with a list of \texttt{ConsumerSolution} instaces. These single-period-solution objects have the same attributes as the ``idiosyncratic shocks'' models above, but the attribute \texttt{cFunc} is defined over the space of $(m_t,\eta_t)$ rather than just $m_t$. The value function \texttt{vFunc} and marginal value \texttt{vPfunc}, however, are defined \textit{only} over $m_t$, as they represent expected (marginal) value \textit{just before} the preference shock $\eta_t$ is realized:\footnote{Particularly in the case of \texttt{vPfunc}, this is the object of interest for solving the preceding period.} -\begin{eqnarray*} -\overline{\vFunc}_t(m_t) &=& \int_0^\infty \vFunc(m_t,\eta)dF_{\eta t}(\eta), \\ -\overline{\vFunc}_t'(m_t) &=& \int_0^\infty \vFunc'(m_t,\eta)dF_{\eta t}(\eta). -\end{eqnarray*} - - -\subsection{Utility Shocks and Different Interest Rates} - -Consider an agent with idiosyncratic shocks to permanent and transitory income and multiplicative shocks to utility \textit{and} faces a different interest rate on borrowing vs saving. This agent's model is identical to that of the ``preference shock'' consumer in section 2.1, with the addition of the interest rate rule from the ``kinked R'' consumer in section 1.3. - -The one period problem of this combination model is solved by the function \texttt{solveConsKinkyPref}, which creates an instance of \texttt{ConsKinkyPrefSolver}. The class \texttt{KinkyPrefConsumerType} represents agents in this model. As you will see in \texttt{ConsPrefShockModel.py}, there is \textit{very} little new code required to program this model: the solver and consumer classes each inherit from both \texttt{KinkedR} and \texttt{PrefShock} and only need a trivial constructor function to rectify the differences between the two. This is a good demonstration of the benefit of HARK's object-oriented approach to solution methods: it is sometimes trivial to combine two models to make a new one. - -The attributes required to properly construct an instance of \texttt{KinkyPrefConsumerType} are the same as for \texttt{PrefShockConsumerType} except that (like the ``kinked R'' parent model) \texttt{Rfree} should not be replaced with \texttt{Rboro} and \texttt{Rsave}. Like both of its parents, \texttt{KinkyPref} is not yet compatible with cubic spline interpolation of the consumption function. - -\newpage - -\section{ConsMarkovModel.py} - -Defines consumption-saving models with a discrete state that evolves according to an exogenous Markov process. - -\subsection{Markov States and Idiosyncratic Shocks} - -Consider an agent with CRRA utility over consumption who geometrically discounts future utility flows and expects to experience transitory and permanent shocks to his income. Moreover, in any given period he finds himself in exactly one of several discrete states; this state evolves from period to period according to a Markov process. The individual's income distribution, permanent income growth rate, and interest factor might vary across states. This agent's problem can be written in Bellman form as: -\begin{eqnarray*} -\vFunc_t(m_t,s_t) &=& \max_{c_t} \utilFunc(c_t) + \beta \PLives_{t+1} \E [\vFunc_{t+1}(m_{t+1},s_{t+1}) ], \\ -a_t &=& m_t - c_t, \\ -a_t &\geq& \underline{a}, \\ -m_{t+1} &=& \frac{\Rfree(s_{t+1})}{\Gamma_{t+1}(s_{t+1})\psi_{t+1}} \cdot a_t + \theta_{t+1}, \\ -\theta_t \sim F_{\theta t}(s_{t}), &\qquad& \psi_t \sim F_{\psi t}(s_{t}), \hspace{0.25cm} \E[F_{\psi t}(s_{t})] = 1, \\ -\text{Prob}[s_{t+1}=j | s_t=i] &=& \Delta_{ij}, \\ -\utilFunc(c) &=& \frac{c^{1-\CRRA}}{1-\CRRA}. -\end{eqnarray*} -The Markov matrix is $\Delta$, giving transition probabilities from current state $i$ to future state $j$. This model is the same as the ``idiosyncratic shocks'' model of section 2.1 but for the presence of the Markov state $s_t$, so that the interest factor $\Rfree$, income distribution $(F_{\psi t},F_{\theta t})$, and permanent income growth factor $\Gamma_{t+1}$ are all functions of the Markov state, having a value for each state. - -The function \texttt{solveConsMarkov} solves the one period problem of this model, creating an instance of \texttt{ConsMarkovSolver}. The class \texttt{MarkovConsumerType} is used to represent agents in this model, extending \texttt{IndShockConsumerType}. The attributes required to specify an instance of this class are the same as for \texttt{IndShockConsumerType} but for one addition: - -\begin{table}[h!] -\centering -\begin{tabular}{c c c} -Var & Description & Code \\ -\hline -$\Delta$ & Discrete state transition probability matrix & \texttt{MrkvArray} -\end{tabular} -\end{table} - -The attribute \texttt{MrkvArray} is a \texttt{numpy.array} of size $(N_s,N_s)$ corresponding to the number of discrete states.\footnote{As is, \texttt{MrkvArray} is an element of \texttt{time\_inv}, so the same transition probabilities are used for each period. However, it can be moved to \texttt{time\_vary} and specified as a list of \texttt{array}s instead.} The attributes \texttt{Rfree}, \texttt{PermGroFac}, and \texttt{IncomeDstn} should be specified as lists\footnote{\texttt{PermGroFac} and \texttt{Rfree} can be arrays or lists.} with $N_s$ elements for each period. Note that \texttt{MarkovConsumerType} currently has no method to automatically construct a valid \texttt{IncomeDstn}; as seen in the examples in \texttt{ConsMarkovModel.py}, the \texttt{IncomeDstn} is manually constructed in each case.\footnote{Writing a method to supersede \texttt{IndShockConsumerType.updateIncomeProcess} for the ``Markov model'' would be a welcome contribution.} All other attributes are specified the same as in the ``idiosyncratic shocks'' model. - -When the \texttt{solve} method of a \texttt{MarkovConsumerType} is invoked, the \texttt{solution} attribute is populated with a list of \texttt{ConsumerSolution} objects, which each have the same attributes as the ``idiosyncratic shocks'' model. However, each attribute is now a list (or array) whose elements are \textit{state-conditional} values of that object. For example, in a model with four discrete states, each the \texttt{cFunc} attribute of each element of \texttt{solution} is a length-4 list whose elements are state-conditional consumption functions (e.g. \texttt{cFunc[2]} is the consumption function when $s_t=2$). The ``Markov model'' is compatible with cubic spline interpolation for the consumption functions, so \texttt{CubicBool=True} will not generate an exception. The problem is solved using the method of endogenous gridpoints, which is moderately more complicated than in the basic ``idiosyncratic shocks'' model. - -\section{ConsAggShockModel.py} - -Defines consumption-saving models with idiosyncratic and aggregate shocks to income. - -\subsection{Idiosyncratic and Aggregate Shocks to Income} - -Consider an agent with CRRA preferences over consumption who discounts future utility flows and expects to experience permanent and transitory shocks to his income. He also believes that the market to which he supplies (a fixed amount of) labor will experience \textit{aggregate} permanent and transitory shocks to the effective productivity of labor. The wage rate in the market is the marginal product of labor in the aggregate production function, and the interest factor is one plus the (net) marginal product of capital; assume that the ratio of aggregate capital-to-labor is a sufficient statistic for these marginal products. Further, the agent believes that the capital-to-labor ratio evolves as a function of its current value. This model can be written in Bellman form as: - -\begin{eqnarray*} -\vFunc_t(m_t,k_t) &=& \max_{c_t} \utilFunc(c_t) + \beta \PLives_{t+1} \E [\vFunc_{t+1}(m_{t+1},k_{t+1}) ], \\ -a_t &=& m_t - c_t, \\ -a_t &\geq& 0, \\ -m_{t+1} &=& \frac{\Rfree_{t+1}}{\Gamma_{t+1}\psi_{t+1} \Psi_{t+1}} \cdot a_t + W_{t+1} \theta_{t+1}, \\ -\Rfree_{t+1} = \textbf{R}(k_{t+1}/\Theta_{t+1}), & & W_{t+1} = \textbf{W}(k_{t+1}/\Theta_{t+1}), \\ -k_{t+1} &=& \textbf{k}(k_t), \\ -\theta_t \sim F_{\theta t}, &\qquad& \psi_t \sim F_{\psi t}, \hspace{0.25cm} \E[F_{\psi t}] = 1, \\ -\Theta_t \sim F_{\Theta}, &\qquad& \Psi_t \sim F_{\Psi}, \hspace{0.25cm} \E[F_{\Psi}] = \E[F_{\Theta}] = 1, \\ -\utilFunc(c) &=& \frac{c^{1-\CRRA}}{1-\CRRA}. -\end{eqnarray*} - -The objects $\textbf{R}(\cdot)$ and $\textbf{W}(\cdot)$, are functions of the (effective) capital-to-labor ratio that yield the (net) interest factor and wage rate respectively. As noted above, these are determined by the aggregate production function and the degree of capital depreciation. The $\texttt{k}(\cdot)$ function represents the agent's beliefs about the evolution of the capital-to-labor ratio $k_t$. As with idiosyncratic shocks, there is an aggregate shock process $(F_{\Theta},F_{\Psi})$. - -The one period problem of this model is solved by the function \texttt{solveConsAggShock}, the default value of \texttt{solve_one_period} for \texttt{AggShockConsumerType}. The attributes required to specify an instance of this class are listed in the concordance below. - -\begin{table}[h!] -\centering -\begin{tabular}{c c c} -Var & Description & Code \\ -\hline -$\CRRA$ & Coefficient of relative risk aversion & \texttt{CRRA} \\ -$\beta$ & Intertemporal discount factor & \texttt{DiscFac} \\ -$\PLives$ & Survival probability & \texttt{LivPrb} \\ -$\Gamma$ & Permanent income growth factor & \texttt{PermGroFac} \\ -(none) & Minimum of ``assets above minimum'' grid & \texttt{aXtraMin} \\ -(none) & Maximum of ``assets above minimum'' grid & \texttt{aXtraMax} \\ -(none) & Number of points in ``assets above minimum'' grid & \texttt{aXtraCount} \\ -(none) & Additional values for the ``assets above minimum'' grid & \texttt{aXtraExtra} \\ -(none) & Degree of exponential nesting for assets grid & \texttt{exp\_nest} \\ -$\{\hat{k}\}$ & Array of scaling factors for capital ratio (around SS) & \texttt{kGridBase} \\ -$N_{\theta}$ & Number of discrete values in transitory shock distribution & \texttt{TranShkCount} \\ -$N_{\psi}$ & Number of discrete values in permanent shock distribution & \texttt{PermShkCount} \\ -$\sigma_\theta$ & Standard deviation of log transitory shocks & \texttt{TranShkStd} \\ -$\sigma_\psi$ & Standard deviation of log permanent shocks & \texttt{PermShkStd} \\ -$\mho$ & Unemployment probability in working period & \texttt{UnempPrb} \\ -$\mho_{ret}$ & ``Unemployment'' probability in retirement period & \texttt{UnempPrbRet} \\ -$\underline{\theta}$ & Transitory income when unemployed in working period & \texttt{IncUnemp} \\ -$\underline{\theta}_{ret}$ & Transitory income when ``unemployed'' in retired period & \texttt{IncUnempRet} \\ -$\tau$ & Marginal income tax rate & \texttt{tax\_rate} \\ -$T_{ret}$ & Period of retirement; number of working periods & \texttt{T\_retire} \\ -$T$ & Total number of (non-terminal) periods in sequence & \texttt{T\_total} \\ -(none) & Number of agents of this type & \texttt{Nagents} -\end{tabular} -\end{table} - -This list is very similar to the one for \texttt{IndShockConsumerType}, but several attributes have been removed: \texttt{Rfree} is endogenous here, while \texttt{CubicBool}, \texttt{vFuncBool}, and \texttt{BoroCnstArt} are not yet supported in the ``aggregate shocks'' model. The only new attribute is \texttt{kGridBase}, an array of scaling factors for the (perfect foresight equivalent) steady state capital ratio; it is used to construct \texttt{kGrid}, a direct input for \texttt{solveConsAggShock}. - -A new \texttt{AggShockConsumerType} with these attributes is not yet ready to solve its micro model, as it lacks several features. After creating a valid \texttt{CobbDouglasEconomy} instance (see section 4.2), the agent type must get ``macro'' level objects from this by invoking its \texttt{getEconomyData} method with the \texttt{CobbDouglasEconomy} as the input. This gives the agent type its interest, wage, and next-capital-ratio functions as the attributes \texttt{Rfunc}, \texttt{Wfunc}, and \texttt{kNextFunc}, its capital ratio grid \texttt{kGrid}, and reformats the \texttt{IncomeDstn} attribute as a discrete joint distribution across all four types of shocks.\footnote{As of the beta release, this method is only compatible with one period infinite horizon micro models, but this can be fixed with minimal difficulty.} - -After obtaining ``macro''-level inputs to its model, an \texttt{AggShockConsumerType}'s \texttt{solve} method will populate the \texttt{solution} attribute with a list of \texttt{ConsumerSolution} instances. Unlike the models with only idiosyncratic shocks, the one-period-solution objects have only two attributes, \texttt{cFunc} and \texttt{vPfunc}; both of these functions are defined over the space of $(m_t,k_t)$. The model is solved using the method of endogenous gridpoints, following Kiichi Tokuoka's Mathematica code for the \href{http://www.econ2.jhu.edu/people/ccarroll/papers/cstwMPC/}{``cstwMPC'' project}. - -\subsection{Cobb-Douglas Economy} - -A model with ``aggregate shocks'' only makes sense if there is some market-level object that experiences these shocks. The \texttt{CobbDouglasEconomy} class extends \texttt{Market} to represent an economy with a Cobb-Douglas production function over aggregate capital and aggregate labor\footnote{As the microeconomic model in section 4.1 assumes a fixed per capita labor supply, aggregate labor for this class is assumed constant and disappears into the background. The HARK team welcomes contributions that extend both the micro and macro models to account for endogenous labor supply.} and permanent and transitory shocks to labor productivity. The basic model for the Cobb-Douglas economy is: - -\begin{eqnarray*} -Y &=& K^\alpha L^{1-\alpha}, \qquad k \equiv K/L,\\ -W = \pd{Y}{L} &=& (1-\alpha) K^{\alpha} L^{-\alpha} = (1-\alpha) k^\alpha, \\ -\rfree = \pd{Y}{K} &=& \alpha K^{\alpha-1} L^{1-\alpha} = \alpha k^{\alpha-1}, \\ -\Rfree &=& 1 + \rfree - \delta. -\end{eqnarray*} - -A new instance of \texttt{CobbDouglasEconomy} must have attributes listed in the table below. The constructor for the class uses these attributes to calculate the perfect foresight steady state of the capital-to-labor ratio\footnote{If the economy were populated with perfect foresight agents with preferences given by $\beta^{PF}$ and $\CRRA^{PF}$, the steady state level of capital is where $k_{t+1} = k_t$ (when aggregate shocks are turned off as well).}, wage rate, and interest rate; the interest and wage functions; a discretization of the aggregate shock process, and an initial guess of the next-capital-ratio function. Following Krusell and Smith (1998), we assume that the log of next period's capital ratio is a linear function of the log of this period's capital ratio. - -\begin{table}[h!] -\centering -\begin{tabular}{c c c} -Var & Description & Code \\ -\hline -$\alpha$ & Capital's share of output & \texttt{CapShare} \\ -$\delta$ & Capital depreciation rate & \texttt{DeprFac} \\ -$\sigma_\Psi$ & Standard deviation of log permanent aggregate shocks & \texttt{PermShkAggStd} \\ -$\sigma_\Theta$ & Standard deviation of log transitory aggregate shocks & \texttt{TranShkAggStd} \\ -$N_\Psi$ & Number of discrete values in permanent agg shock distribution & \texttt{PermShkAggCount} \\ -$N_\Theta$ & Number of discrete values in transitory agg shock distribution & \texttt{TranShkAggCount} \\ -$\CRRA^{PF}$ & Perfect foresight coefficient of relative risk aversion & \texttt{CRRAPF} \\ -$\beta^{PF}$ & Perfect foresight intertemporal discount factor & \texttt{DiscFacPF} \\ -\end{tabular} -\end{table} - -After a well-formed \texttt{CobbDouglasEconomy} has been created, its \texttt{agents} attribute can be populated with one or more instances of \texttt{AggShockConsumerType} (who have taken ``macro'' level information from the \texttt{CobbDouglasEconomy}). A history of aggregate shocks can be created by invoking the \texttt{makeAggShkHist} method. If each element of \texttt{AggShockConsumerType} has run its \texttt{makeIncShkHist} method to create a history of idiosyncratic income shocks (for many agents in each type), then the \texttt{CobbDouglasEconomy} can invoke its \texttt{solve} method. This will search for a general equilibrium of the model, defined as a ``dynamic rule'' for the capital ratio $\textbf{k}(k_t)$ that is \textit{consistent}: when agents believe this $\textbf{k}(k_t)$ in their microeconomic problem, and the model is simulated for many periods, the resulting history of the capital ratio is consistent with that same dynamic rule. - -In the \texttt{Market} framework, the \texttt{mill_rule} for \texttt{CobbDouglasEconomy} gathers each agent's end-of-period normalized assets $a_t$ and permanent income $p_t$. It aggregates wealth across all consumers into total capital, which it transforms into the capital-to-labor ratio. It then uses the next aggregate shock values to calculate $\Rfree_t$ and $W_t$, which are distributed back to the consumers along with the aggregate shocks and new capital ratio, so that they can simulated another period. - -After generating a history of several thousand periods, the \texttt{CobbDouglasEconomy} can calculate a new dynamic rule for the capital ratio with its \texttt{calc_dynamics} method. The dynamics calculator simply throws out the first 200 periods of the history and runs a one-period-lag autoregression on the log capital ratio. This generates a new function for \texttt{kNextFunc}, which is distributed to the consumer types in \texttt{agents} to re-solve their micro models. This process continues until successive \texttt{kNextFunc}s are sufficiently close to consider the process converged (as determined by the \texttt{tolerance} attribute). - - -\newpage -\section{TractableBufferStockModel.py} - -Defines the ``tractable buffer stock'' model from Chris Carroll's \href{http://www.econ2.jhu.edu/people/ccarroll/public/LectureNotes/Consumption/TractableBufferStock.pdf}{lecture notes}. - -\subsection{Tractable Buffer Stock} - -Consider a consumer with CRRA utility who faces only a single, very specific risk: that he will become permanently unemployed and receive no income until the end of time. Otherwise, he faces an infinite horizon problem with a steady stream of income that grows by a fixed factor each period, and earns a constant rate of return on assets retained betweed periods. His model when still employed can be written in Bellman form as:\footnote{For technical / teaching reasons, permanent income growth while employed is ``risk compensated'' so that human wealth does not vary with the unemployment probability.} -\begin{eqnarray*} -\vFunc^e(m_t) &=& \max_{c_t} \utilFunc(c_t) + \beta \left( (1-\mho)\vFunc^e(m^e_{t+1}) + \mho \vFunc^u(m^u_{t+1}) \right) \\ -a_t &=& m_t - c_t \\ -m^e_{t+1} &=& (\Rfree/\widehat{\Gamma}) a_t + 1, \qquad \widehat{\Gamma} = \Gamma/(1-\mho)\\ -m^u_{t+1} &=& (\Rfree/\widehat{\Gamma}) a_t. -\end{eqnarray*} -His model while unemployed is simply: -\begin{eqnarray*} -\vFunc^u(m_t) &=& \max_{c_t} \utilFunc(c_t) + \beta \vFunc^u(m^u_{t+1}) \\ -a_t &=& m_t - c_t \\ -m^u_{t+1} &=& (\Rfree/\widehat{\Gamma}) a_t. -\end{eqnarray*} - -This model is solved by the class \texttt{TractableConsumerType} when its \texttt{solve()} method is invoked. An instance of this class is specified by the five parameters in the table below: -\begin{table}[h!] -\centering -\begin{tabular}{c c c} -Var & Description & Code \\ -\hline -$\CRRA$ & Coefficient of relative risk aversion & \texttt{CRRA} \\ -$\beta$ & Intertemporal discount factor & \texttt{DiscFac} \\ -$\Rfree$ & Interest factor on assets & \texttt{Rfree} \\ -$\Gamma$ & Permanent income growth factor & \texttt{PermGroFac} \\ -$\mho$ & Probability of becoming unemployed & \texttt{UnempPrb} \\ -\end{tabular} -\end{table} - -Unlike other models in HARK, tractable buffer stock is not solved by backward induction beginning from an initial guess of the solution. Because of the very specific form of risk faced by the agent, it is possible to calculate\footnote{As long as the consumer is both ``return impatient'' and ``growth impatient'', else there is no steady state or no solution at all.} analytical values of the steady state $(m_t,c_t)$ and to find several derivatives of the consumption function at this point (i.e.\ the MPC, MMPC, etc). Further, the Euler and transition equations can be inverted to yield $(m_{t-1},c_{t-1})$ as a function of $(m_t,c_t)$ conditional on being employed in both periods. Beginning from a small perturbation along a Taylor approximation of the consumption function around the steady state, the solution method generates a sequence of ``stable arm points'' along the consumption function. After reaching specified bounds (and appending the lower bound at $(0,0)$), the (employed) consumption function is constructed as a cubic spline interpolation. - -After running the \texttt{solve} method, the \texttt{solution} attribute of a \texttt{TractableConsumerType} will have a list with a single instance of \texttt{TractableConsumerSolution}. This object has the following attributes: - -\begin{table}[h!] -\centering -\begin{tabular}{c c c} -Var & Description & Code \\ -\hline -$\{m_t\}$ & List of market resources values on the stable arm & \texttt{mNrm\_list} \\ -$\{c_t\}$ & List of consumption values on the stable arm & \texttt{cNrm\_list} \\ -$\{\kappa_t\}$ & List of MPCs at points on the stable arm & \texttt{MPC\_list} \\ -$\cFunc^e(m_t)$ & Consumption function when employed & \texttt{cFunc} \\ -$\cFunc^u(m_t)$ & Consumption function when unemployed & \texttt{cFunc\_U} \\ -(none) & Number of stable arm points included & \texttt{PointCount} -\end{tabular} -\end{table} - -\subsection{Tractable Buffer Stock as Markov} - -The tractable buffer stock model can also be solved by the standard backward induction approach if it is framed in terms of the Markov model in section 3. There are two discrete state, \textit{employed} and \textit{unemployed}; transition probabilities from the former are $(1-\mho,\mho)$ and the latter is an absorbing state. The interest factor and permanent income growth rate are identical in the two states, and both have degenerate income distributions: $\psi_e = \theta_e = 1$, while $\psi_u = 1$ and $\theta_u = 0$ for sure. The model takes about 300 times longer to solve using the ``Markov formulation'' as the backshooting method, yielding a nearly identical solution. - -\end{document} diff --git a/HARK/ConsumptionSaving/ConsAggShockModel.py b/HARK/ConsumptionSaving/ConsAggShockModel.py index 4d68a20eb..3ef15137b 100644 --- a/HARK/ConsumptionSaving/ConsAggShockModel.py +++ b/HARK/ConsumptionSaving/ConsAggShockModel.py @@ -173,9 +173,9 @@ def reset(self): def pre_solve(self): # AgentType.pre_solve() - self.updateSolutionTerminal() + self.update_solution_terminal() - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Updates the terminal period solution for an aggregate shock consumer. Only fills in the consumption function and marginal value function. @@ -199,7 +199,7 @@ def updateSolutionTerminal(self): cFunc=cFunc_terminal, vPfunc=vPfunc_terminal, mNrmMin=mNrmMin_terminal ) - def getEconomyData(self, economy): + def get_economy_data(self, economy): """ Imports economy-determined objects into self from a Market. Instances of AggShockConsumerType "live" in some macroeconomy that has @@ -236,14 +236,14 @@ def getEconomyData(self, economy): self.PermGroFacAgg = ( economy.PermGroFacAgg ) # Aggregate permanent productivity growth - self.addAggShkDstn( + self.add_AggShkDstn( economy.AggShkDstn ) # Combine idiosyncratic and aggregate shocks into one dstn self.add_to_time_inv( "Mgrid", "AFunc", "Rfunc", "wFunc", "DeprFac", "PermGroFacAgg" ) - def addAggShkDstn(self, AggShkDstn): + def add_AggShkDstn(self, AggShkDstn): """ Updates attribute IncShkDstn by combining idiosyncratic shocks with aggregate shocks. @@ -330,7 +330,7 @@ def sim_death(self): self.state_now['aLvl'][who_lives] = self.state_now['aLvl'][who_lives] * Ractuarial return who_dies - def getRfree(self): + def get_Rfree(self): """ Returns an array of size self.AgentCount with self.RfreeNow in every entry. @@ -379,7 +379,7 @@ def get_controls(self): """ cNrmNow = np.zeros(self.AgentCount) + np.nan MPCnow = np.zeros(self.AgentCount) + np.nan - MaggNow = self.getMaggNow() + MaggNow = self.get_MaggNow() for t in range(self.T_cycle): these = t == self.t_cycle cNrmNow[these] = self.solution[t].cFunc(self.state_now['mNrm'][these], MaggNow[these]) @@ -391,10 +391,10 @@ def get_controls(self): self.MPCnow = MPCnow return None - def getMaggNow(self): # This function exists to be overwritten in StickyE model + def get_MaggNow(self): # This function exists to be overwritten in StickyE model return self.MaggNow * np.ones(self.AgentCount) - def marketAction(self): + def market_action(self): """ In the aggregate shocks model, the "market action" is to simulate one period of receiving income and choosing how much to consume. @@ -409,7 +409,7 @@ def marketAction(self): """ self.simulate(1) - def calcBoundingValues(self): + def calc_bounding_values(self): """ Calculate human wealth plus minimum and maximum MPC in an infinite horizon model with only one period repeated indefinitely. Store results @@ -430,7 +430,7 @@ def calcBoundingValues(self): """ raise NotImplementedError() - def makeEulerErrorFunc(self, mMax=100, approx_inc_dstn=True): + def make_euler_error_func(self, mMax=100, approx_inc_dstn=True): """ Creates a "normalized Euler error" function for this instance, mapping from market resources to "consumption error per dollar of consumption." @@ -497,11 +497,11 @@ def __init__(self, **kwds): self.shocks['Mrkv'] = None self.add_to_time_inv("MrkvArray") - self.solve_one_period = solveConsAggMarkov + self.solve_one_period = solve_ConsAggMarkov - def addAggShkDstn(self, AggShkDstn): + def add_AggShkDstn(self, AggShkDstn): """ - Variation on AggShockConsumerType.addAggShkDstn that handles the Markov + Variation on AggShockConsumerType.add_AggShkDstn that handles the Markov state. AggShkDstn is a list of aggregate productivity shock distributions for each Markov state. """ @@ -521,7 +521,7 @@ def addAggShkDstn(self, AggShkDstn): ) self.IncShkDstn = IncShkDstnOut - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Update the terminal period solution. This method should be run when a new AgentType is created or when CRRA changes. @@ -534,7 +534,7 @@ def updateSolutionTerminal(self): ------- None """ - AggShockConsumerType.updateSolutionTerminal(self) + AggShockConsumerType.update_solution_terminal(self) # Make replicated terminal period solution StateCount = self.MrkvArray.shape[0] @@ -619,7 +619,7 @@ def get_controls(self): """ cNrmNow = np.zeros(self.AgentCount) + np.nan MPCnow = np.zeros(self.AgentCount) + np.nan - MaggNow = self.getMaggNow() + MaggNow = self.get_MaggNow() MrkvNow = self.getMrkvNow() StateCount = self.MrkvArray.shape[0] @@ -706,21 +706,21 @@ def __init__(self, **kwds): "Mrkv" : None } - self.solve_one_period = solveKrusellSmith + self.solve_one_period = solve_KrusellSmith self.update() def pre_solve(self): self.update() - self.preComputeArrays() + self.precompute_arrays() def update(self): """ Construct objects used during solution from primitive parameters. """ - self.makeGrid() - self.updateSolutionTerminal() + self.make_grid() + self.update_solution_terminal() - def getEconomyData(self, Economy): + def get_economy_data(self, Economy): """ Imports economy-determined objects into self from a Market. @@ -771,7 +771,7 @@ def getEconomyData(self, Economy): "MrkvAggArray", ) - def makeGrid(self): + def make_grid(self): """ Construct the attribute aXtraGrid from the primitive attributes aMin, aMax, aCount, aNestFac. @@ -779,7 +779,7 @@ def makeGrid(self): self.aGrid = make_grid_exp_mult(self.aMin, self.aMax, self.aCount, self.aNestFac) self.add_to_time_inv("aGrid") - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Construct the trivial terminal period solution (initial guess). """ @@ -791,7 +791,7 @@ def updateSolutionTerminal(self): cFunc=cFunc_terminal, vPfunc=vPfunc_terminal ) - def preComputeArrays(self): + def precompute_arrays(self): """ Construct the attributes ProbArray, mNextArray, MnextArray, and RnextArray, which will be used by the one period solver. @@ -854,7 +854,7 @@ def preComputeArrays(self): self.RnextArray = Rnext_tiled self.add_to_time_inv("ProbArray", "mNextArray", "MnextArray", "RnextArray") - def makeEmpIdxArrays(self): + def make_emp_idx_arrays(self): """ Construct the attributes emp_permute and unemp_permute, each of which is a 2x2 nested list of boolean arrays. The j,k-th element of emp_permute @@ -973,14 +973,14 @@ def makeEmpIdxArrays(self): def reset(self): self.initialize_sim() - def marketAction(self): + def market_action(self): self.simulate(1) def initialize_sim(self): self.shocks['Mrkv'] = self.MrkvInit AgentType.initialize_sim(self) self.state_now["EmpNow"] = self.state_now["EmpNow"].astype(bool) - self.makeEmpIdxArrays() + self.make_emp_idx_arrays() def sim_birth(self, which): """ @@ -1280,7 +1280,7 @@ def solveConsAggShock( return solution_now -def solveConsAggShockNEW(solution_next, IncShkDstn, LivPrb, DiscFac, CRRA, PermGroFac, +def solve_ConsAggShock_new(solution_next, IncShkDstn, LivPrb, DiscFac, CRRA, PermGroFac, PermGroFacAgg, aXtraGrid, BoroCnstArt, Mgrid, AFunc, Rfunc, wFunc, DeprFac): ''' Solve one period of a consumption-saving problem with idiosyncratic and @@ -1411,7 +1411,7 @@ def vPnextFunc(a,M,psi,theta,Psi,Theta): ############################################################################### -def solveConsAggMarkov( +def solve_ConsAggMarkov( solution_next, IncShkDstn, LivPrb, @@ -1697,7 +1697,7 @@ def solveConsAggMarkov( ############################################################################### -def solveKrusellSmith( +def solve_KrusellSmith( solution_next, DiscFac, CRRA, @@ -1712,7 +1712,7 @@ def solveKrusellSmith( Solve the one period problem of an agent in Krusell & Smith's canonical 1998 model. Because this model is so specialized and only intended to be used with a very narrow case, many arrays can be precomputed, making the code here very short. See the - method KrusellSmithType.preComputeArrays() for details. + method KrusellSmithType.precompute_arrays() for details. Parameters ---------- @@ -1899,20 +1899,20 @@ def __init__(self, agents=None, tolerance=0.0001, act_T=1200, **kwds): def mill_rule(self, aLvl, pLvl): """ Function to calculate the capital to labor ratio, interest factor, and - wage rate based on each agent's current state. Just calls calcRandW(). + wage rate based on each agent's current state. Just calls calc_R_and_W(). - See documentation for calcRandW for more information. + See documentation for calc_R_and_W for more information. """ - return self.calcRandW(aLvl, pLvl) + return self.calc_R_and_W(aLvl, pLvl) def calc_dynamics(self, MaggNow, AaggNow): """ Calculates a new dynamic rule for the economy: end of period savings as - a function of aggregate market resources. Just calls calcAFunc(). + a function of aggregate market resources. Just calls calc_AFunc(). - See documentation for calcAFunc for more information. + See documentation for calc_AFunc for more information. """ - return self.calcAFunc(MaggNow, AaggNow) + return self.calc_AFunc(MaggNow, AaggNow) def update(self): """ @@ -1930,7 +1930,7 @@ def update(self): """ self.kSS = ( ( - self.getPermGroFacAggLR() ** (self.CRRA) / self.DiscFac + self.get_PermGroFacAggLR() ** (self.CRRA) / self.DiscFac - (1.0 - self.DeprFac) ) / self.CapShare @@ -1956,10 +1956,10 @@ def update(self): self.sow_init["wRteNow"] = self.wFunc(self.kSS) self.sow_init["PermShkAggNow"] = 1.0 self.sow_init["TranShkAggNow"] = 1.0 - self.makeAggShkDstn() + self.make_AggShkDstn() self.AFunc = AggregateSavingRule(self.intercept_prev, self.slope_prev) - def getPermGroFacAggLR(self): + def get_PermGroFacAggLR(self): """ A trivial function that returns self.PermGroFacAgg. Exists to be overwritten and extended by ConsAggShockMarkov model. @@ -1976,7 +1976,7 @@ def getPermGroFacAggLR(self): """ return self.PermGroFacAgg - def makeAggShkDstn(self): + def make_AggShkDstn(self): """ Creates the attributes TranShkAggDstn, PermShkAggDstn, and AggShkDstn. Draws on attributes TranShkAggStd, PermShkAddStd, TranShkAggCount, PermShkAggCount. @@ -2013,7 +2013,7 @@ def reset(self): self.Shk_idx = 0 Market.reset(self) - def makeAggShkHist(self): + def make_AggShkHist(self): """ Make simulated histories of aggregate transitory and permanent shocks. Histories are of length self.act_T, for use in the general equilibrium @@ -2037,7 +2037,7 @@ def makeAggShkHist(self): self.PermShkAggHist = PermShkAggHist * self.PermGroFacAgg self.TranShkAggHist = TranShkAggHist - def calcRandW(self, aLvlNow, pLvlNow): + def calc_R_and_W(self, aLvlNow, pLvlNow): """ Calculates the interest factor and wage rate this period using each agent's capital stock to get the aggregate capital ratio. @@ -2102,7 +2102,7 @@ def calcRandW(self, aLvlNow, pLvlNow): KtoLnow, ) - def calcAFunc(self, MaggNow, AaggNow): + def calc_AFunc(self, MaggNow, AaggNow): """ Calculate a new aggregate savings rule based on the history of the aggregate savings and aggregate market resources from a simulation. @@ -2227,10 +2227,10 @@ def update(self): self.sow_init["AaggNow"] = self.kSS self.sow_init["PermShkAggNow"] = 1.0 self.sow_init["TranShkAggNow"] = 1.0 - self.makeAggShkDstn() + self.make_AggShkDstn() self.AFunc = ConstantFunction(1.0) - def makeAggShkDstn(self): + def make_AggShkDstn(self): """ Creates the attributes TranShkAggDstn, PermShkAggDstn, and AggShkDstn. Draws on attributes TranShkAggStd, PermShkAddStd, TranShkAggCount, PermShkAggCount. @@ -2256,9 +2256,9 @@ def mill_rule(self): No aggregation occurs for a small open economy, because the wage and interest rates are exogenously determined. However, aggregate shocks may occur. - See documentation for getAggShocks() for more information. + See documentation for get_AggShocks() for more information. """ - return self.getAggShocks() + return self.get_AggShocks() def calc_dynamics(self, KtoLnow): """ @@ -2284,7 +2284,7 @@ def reset(self): self.Shk_idx = 0 Market.reset(self) - def makeAggShkHist(self): + def make_AggShkHist(self): """ Make simulated histories of aggregate transitory and permanent shocks. Histories are of length self.act_T, for use in the general equilibrium simulation. This replicates the same @@ -2308,7 +2308,7 @@ def makeAggShkHist(self): self.PermShkAggHist = PermShkAggHist self.TranShkAggHist = TranShkAggHist - def getAggShocks(self): + def get_AggShocks(self): """ Returns aggregate state variables and shocks for this period. The capital-to-labor ratio is irrelevant and thus treated as constant, and the wage and interest rates are also @@ -2449,7 +2449,7 @@ def update(self): ) self.AFunc = AFunc_all - def getPermGroFacAggLR(self): + def get_PermGroFacAggLR(self): """ Calculates and returns the long run permanent income growth factor. This is the average growth factor in self.PermGroFacAgg, weighted by the long @@ -2474,7 +2474,7 @@ def getPermGroFacAggLR(self): PermGroFacAggLR = np.dot(LR_dstn, np.array(self.PermGroFacAgg)) return PermGroFacAggLR - def makeAggShkDstn(self): + def make_AggShkDstn(self): """ Creates the attributes TranShkAggDstn, PermShkAggDstn, and AggShkDstn. Draws on attributes TranShkAggStd, PermShkAddStd, TranShkAggCount, PermShkAggCount. @@ -2510,12 +2510,12 @@ def makeAggShkDstn(self): self.PermShkAggDstn = PermShkAggDstn self.AggShkDstn = AggShkDstn - def makeAggShkHist(self): + def make_AggShkHist(self): """ Make simulated histories of aggregate transitory and permanent shocks. Histories are of length self.act_T, for use in the general equilibrium simulation. Draws on history of aggregate Markov states generated by - internal call to makeMrkvHist(). + internal call to make_Mrkv_history(). Parameters ---------- @@ -2525,7 +2525,7 @@ def makeAggShkHist(self): ------- None """ - self.makeMrkvHist() # Make a (pseudo)random sequence of Markov states + self.make_Mrkv_history() # Make a (pseudo)random sequence of Markov states sim_periods = self.act_T # For each Markov state in each simulated period, draw the aggregate shocks @@ -2551,7 +2551,7 @@ def makeAggShkHist(self): self.PermShkAggHist = PermShkAggHist self.TranShkAggHist = TranShkAggHist - def makeMrkvHist(self): + def make_Mrkv_history(self): """ Makes a history of macroeconomic Markov states, stored in the attribute MrkvNow_hist. This version ensures that each state is reached a sufficient @@ -2640,7 +2640,7 @@ def makeMrkvHist(self): if loops >= loops_max: go = False print( - "makeMrkvHist reached maximum number of loops without generating a valid sequence!" + "make_Mrkv_history reached maximum number of loops without generating a valid sequence!" ) else: MrkvNow_new = np.zeros(self.act_T_orig, dtype=int) @@ -2654,10 +2654,10 @@ def makeMrkvHist(self): def mill_rule(self, aLvl, pLvl): """ Function to calculate the capital to labor ratio, interest factor, and - wage rate based on each agent's current state. Just calls calcRandW() + wage rate based on each agent's current state. Just calls calc_R_and_W() and adds the Markov state index. - See documentation for calcRandW for more information. + See documentation for calc_R_and_W for more information. Params ------- @@ -2680,11 +2680,11 @@ def mill_rule(self, aLvl, pLvl): Binary indicator for bad (0) or good (1) macroeconomic state. """ MrkvNow = self.MrkvNow_hist[self.Shk_idx] - temp = self.calcRandW(aLvl, pLvl) + temp = self.calc_R_and_W(aLvl, pLvl) return temp + (MrkvNow,) - def calcAFunc(self, MaggNow, AaggNow): + def calc_AFunc(self, MaggNow, AaggNow): """ Calculate a new aggregate savings rule based on the history of the aggregate savings and aggregate market resources from a simulation. @@ -2776,20 +2776,20 @@ def update(self): StateCount = self.MrkvArray.shape[0] self.AFunc = StateCount * [IdentityFunction()] - def makeAggShkDstn(self): - CobbDouglasMarkovEconomy.makeAggShkDstn(self) + def make_AggShkDstn(self): + CobbDouglasMarkovEconomy.make_AggShkDstn(self) def mill_rule(self): MrkvNow = self.MrkvNow_hist[self.Shk_idx] - temp = SmallOpenEconomy.getAggShocks(self) + temp = SmallOpenEconomy.get_AggShocks(self) temp(MrkvNow=MrkvNow) return temp def calc_dynamics(self, KtoLnow): return MetricObject() - def makeAggShkHist(self): - CobbDouglasMarkovEconomy.makeAggShkHist(self) + def make_AggShkHist(self): + CobbDouglasMarkovEconomy.make_AggShkHist(self) init_KS_economy = { @@ -2888,7 +2888,7 @@ def update(self): self.PermShkAggNow_init = 1.0 self.TranShkAggNow_init = 1.0 self.sow_init["Mrkv"] = 0 - self.makeMrkvArray() + self.make_MrkvArray() def reset(self): """ @@ -2898,7 +2898,7 @@ def reset(self): self.Shk_idx = 0 Market.reset(self) - def makeMrkvArray(self): + def make_MrkvArray(self): """ Construct the attributes MrkvAggArray and MrkvIndArray from the primitive attributes DurMeanB, DurMeanG, SpellMeanB, SpellMeanG, UrateB, UrateG, @@ -2950,7 +2950,7 @@ def makeMrkvArray(self): self.MrkvArray = MrkvAggArray self.MrkvIndArray = MrkvIndArray - def makeMrkvHist(self): + def make_Mrkv_history(self): """ Makes a history of macroeconomic Markov states, stored in the attribute MrkvNow_hist. This variable is binary (0 bad, 1 good) in the KS model. @@ -2968,9 +2968,9 @@ def makeMrkvHist(self): def mill_rule(self, aNow, EmpNow): """ Method to calculate the capital to labor ratio, interest factor, and - wage rate based on each agent's current state. Just calls calcRandW(). + wage rate based on each agent's current state. Just calls calc_R_and_W(). - See documentation for calcRandW for more information. + See documentation for calc_R_and_W for more information. Returns ------- @@ -2986,16 +2986,16 @@ def mill_rule(self, aNow, EmpNow): Wage rate for labor in the economy this period. """ - return self.calcRandW(aNow, EmpNow) + return self.calc_R_and_W(aNow, EmpNow) def calc_dynamics(self, Mnow, Aprev): """ Method to update perceptions of the aggregate saving rule in each - macroeconomic state; just calls calcAFunc. + macroeconomic state; just calls calc_AFunc. """ - return self.calcAFunc(Mnow, Aprev) + return self.calc_AFunc(Mnow, Aprev) - def calcRandW(self, aNow, EmpNow): + def calc_R_and_W(self, aNow, EmpNow): """ Calculates the interest factor and wage rate this period using each agent's capital stock to get the aggregate capital ratio. @@ -3052,7 +3052,7 @@ def calcRandW(self, aNow, EmpNow): # Returns a tuple of these values return Mnow, Aprev, MrkvNow, Rnow, Wnow - def calcAFunc(self, Mnow, Aprev): + def calc_AFunc(self, Mnow, Aprev): """ Calculate a new aggregate savings rule based on the history of the aggregate savings and aggregate market resources from a simulation. diff --git a/HARK/ConsumptionSaving/ConsGenIncProcessModel.py b/HARK/ConsumptionSaving/ConsGenIncProcessModel.py index 081dba87c..d732bb7d1 100644 --- a/HARK/ConsumptionSaving/ConsGenIncProcessModel.py +++ b/HARK/ConsumptionSaving/ConsGenIncProcessModel.py @@ -184,9 +184,9 @@ def __init__( self.CubicBool = CubicBool self.PermGroFac = 0.0 - self.defUtilityFuncs() + self.def_utility_funcs() - def setAndUpdateValues(self, solution_next, IncShkDstn, LivPrb, DiscFac): + def set_and_update_values(self, solution_next, IncShkDstn, LivPrb, DiscFac): """ Unpacks some of the inputs (and calculates simple objects based on them), storing the results in self for use by other methods. These include: @@ -214,7 +214,7 @@ def setAndUpdateValues(self, solution_next, IncShkDstn, LivPrb, DiscFac): None """ # Run basic version of this method - ConsIndShockSetup.setAndUpdateValues( + ConsIndShockSetup.set_and_update_values( self, solution_next, IncShkDstn, LivPrb, DiscFac ) self.mLvlMinNext = solution_next.mLvlMin @@ -243,7 +243,7 @@ def setAndUpdateValues(self, solution_next, IncShkDstn, LivPrb, DiscFac): np.insert(self.pLvlGrid, 0, 0.0), np.insert(hLvlGrid, 0, 0.0) ) - def defBoroCnst(self, BoroCnstArt): + def def_BoroCnst(self, BoroCnstArt): """ Defines the constrained portion of the consumption function as cFuncNowCnst, an attribute of self. @@ -303,7 +303,7 @@ def defBoroCnst(self, BoroCnstArt): ) self.cFuncNowCnst = VariableLowerBoundFunc2D(cFuncNowCnstBase, self.mLvlMinNow) - def prepareToCalcEndOfPrdvP(self): + def prepare_to_calc_EndOfPrdvP(self): """ Prepare to calculate end-of-period marginal value by creating an array of market resources that the agent could have next period, considering @@ -358,7 +358,7 @@ def prepareToCalcEndOfPrdvP(self): self.aLvlNow = aLvlNow return aLvlNow, pLvlNow - def calcEndOfPrdvP(self): + def calc_EndOfPrdvP(self): """ Calculates end-of-period marginal value of assets at each state space point in aLvlNow x pLvlNow. Does so by taking a weighted sum of next @@ -384,7 +384,7 @@ def calcEndOfPrdvP(self): ) return EndOfPrdvP - def makeEndOfPrdvFunc(self, EndOfPrdvP): + def make_EndOfPrdvFunc(self, EndOfPrdvP): """ Construct the end-of-period value function for this period, storing it as an attribute of self for use by other methods. @@ -500,7 +500,7 @@ def get_points_for_interpolation(self, EndOfPrdvP, aLvlNow): return c_for_interpolation, m_for_interpolation - def usePointsForInterpolation(self, cLvl, mLvl, pLvl, interpolator): + def use_points_for_interpolation(self, cLvl, mLvl, pLvl, interpolator): """ Constructs a basic solution for this period, including the consumption function and marginal value function. @@ -529,13 +529,13 @@ def usePointsForInterpolation(self, cLvl, mLvl, pLvl, interpolator): cFuncNow = LowerEnvelope2D(cFuncNowUnc, self.cFuncNowCnst) # Make the marginal value function - vPfuncNow = self.makevPfunc(cFuncNow) + vPfuncNow = self.make_vPfunc(cFuncNow) # Pack up the solution and return it solution_now = ConsumerSolution(cFunc=cFuncNow, vPfunc=vPfuncNow, mNrmMin=0.0) return solution_now - def makevPfunc(self, cFunc): + def make_vPfunc(self, cFunc): """ Constructs the marginal value function for this period. @@ -553,7 +553,7 @@ def makevPfunc(self, cFunc): vPfunc = MargValueFuncCRRA(cFunc, self.CRRA) return vPfunc - def makevFunc(self, solution): + def make_vFunc(self, solution): """ Creates the value function for this period, defined over market resources m and persistent income p. self must have the attribute EndOfPrdvFunc in @@ -627,7 +627,7 @@ def makevFunc(self, solution): vFuncNow = ValueFuncCRRA(vNvrsFuncNow, self.CRRA) return vFuncNow - def makeBasicSolution(self, EndOfPrdvP, aLvl, pLvl, interpolator): + def make_basic_solution(self, EndOfPrdvP, aLvl, pLvl, interpolator): """ Given end of period assets and end of period marginal value, construct the basic solution for this period. @@ -656,12 +656,12 @@ def makeBasicSolution(self, EndOfPrdvP, aLvl, pLvl, interpolator): (np.reshape(self.pLvlGrid, (self.pLvlGrid.size, 1)), pLvl), axis=-1 ) pLvl_temp = np.concatenate((np.zeros((1, mLvl.shape[1])), pLvl_temp)) - solution_now = self.usePointsForInterpolation( + solution_now = self.use_points_for_interpolation( cLvl, mLvl, pLvl_temp, interpolator ) return solution_now - def makeLinearcFunc(self, mLvl, pLvl, cLvl): + def make_linear_cFunc(self, mLvl, pLvl, cLvl): """ Makes a quasi-bilinear interpolation to represent the (unconstrained) consumption function. @@ -708,7 +708,7 @@ def makeLinearcFunc(self, mLvl, pLvl, cLvl): ) # Re-adjust for natural borrowing constraint (as lower bound) return cFuncUnc - def makeCubiccFunc(self, mLvl, pLvl, cLvl): + def make_cubic_cFunc(self, mLvl, pLvl, cLvl): """ Makes a quasi-cubic spline interpolation of the unconstrained consumption function for this period. Function is cubic splines with respect to mLvl, @@ -776,7 +776,7 @@ def makeCubiccFunc(self, mLvl, pLvl, cLvl): # Re-adjust for lower bound of natural borrowing constraint return cFuncUnc - def addMPCandHumanWealth(self, solution): + def add_MPC_and_human_wealth(self, solution): """ Take a solution and add human wealth and the bounding MPCs to it. @@ -791,14 +791,14 @@ def addMPCandHumanWealth(self, solution): The solution to this period's consumption-saving problem, but now with human wealth and the bounding MPCs. """ - solution.hNrm = 0.0 # Can't have None or setAndUpdateValues breaks, should fix + solution.hNrm = 0.0 # Can't have None or set_and_update_values breaks, should fix solution.hLvl = self.hLvlNow solution.mLvlMin = self.mLvlMinNow solution.MPCmin = self.MPCminNow solution.MPCmax = 0.0 # MPCmax is actually a function in this model return solution - def addvPPfunc(self, solution): + def add_vPPfunc(self, solution): """ Adds the marginal marginal value function to an existing solution, so that the next solver can evaluate vPP and thus use cubic interpolation. @@ -837,20 +837,20 @@ def solve(self): tion of persistent income. Might also include a value function and marginal marginal value function, depending on options selected. """ - aLvl, pLvl = self.prepareToCalcEndOfPrdvP() - EndOfPrdvP = self.calcEndOfPrdvP() + aLvl, pLvl = self.prepare_to_calc_EndOfPrdvP() + EndOfPrdvP = self.calc_EndOfPrdvP() if self.vFuncBool: - self.makeEndOfPrdvFunc(EndOfPrdvP) + self.make_EndOfPrdvFunc(EndOfPrdvP) if self.CubicBool: - interpolator = self.makeCubiccFunc + interpolator = self.make_cubic_cFunc else: - interpolator = self.makeLinearcFunc - solution = self.makeBasicSolution(EndOfPrdvP, aLvl, pLvl, interpolator) - solution = self.addMPCandHumanWealth(solution) + interpolator = self.make_linear_cFunc + solution = self.make_basic_solution(EndOfPrdvP, aLvl, pLvl, interpolator) + solution = self.add_MPC_and_human_wealth(solution) if self.vFuncBool: - solution.vFunc = self.makevFunc(solution) + solution.vFunc = self.make_vFunc(solution) if self.CubicBool: - solution = self.addvPPfunc(solution) + solution = self.add_vPPfunc(solution) return solution @@ -923,7 +923,7 @@ def __init__(self, cycles=0, **kwds): def pre_solve(self): # AgentType.pre_solve() - self.updateSolutionTerminal() + self.update_solution_terminal() def update(self): """ @@ -939,10 +939,10 @@ def update(self): None """ IndShockConsumerType.update(self) - self.updatepLvlNextFunc() - self.updatepLvlGrid() + self.update_pLvlNextFunc() + self.update_pLvlGrid() - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Update the terminal period solution. This method should be run when a new AgentType is created or when CRRA changes. @@ -966,7 +966,7 @@ def updateSolutionTerminal(self): self.solution_terminal.mLvlMin = lambda p: np.zeros_like(p) # And minimum allowable market resources by perm inc - def updatepLvlNextFunc(self): + def update_pLvlNextFunc(self): """ A dummy method that creates a trivial pLvlNextFunc attribute that has no persistent income dynamics. This method should be overwritten by @@ -984,13 +984,13 @@ def updatepLvlNextFunc(self): self.pLvlNextFunc = self.T_cycle * [pLvlNextFuncBasic] self.add_to_time_vary("pLvlNextFunc") - def installRetirementFunc(self): + def install_retirement_func(self): """ Installs a special pLvlNextFunc representing retirement in the correct element of self.pLvlNextFunc. Draws on the attributes T_retire and pLvlNextFuncRet. If T_retire is zero or pLvlNextFuncRet does not exist, this method does nothing. Should only be called from within the - method updatepLvlNextFunc, which ensures that time is flowing forward. + method update_pLvlNextFunc, which ensures that time is flowing forward. Parameters ---------- @@ -1005,7 +1005,7 @@ def installRetirementFunc(self): t = self.T_retire self.pLvlNextFunc[t] = self.pLvlNextFuncRet - def updatepLvlGrid(self): + def update_pLvlGrid(self): """ Update the grid of persistent income levels. Currently only works for infinite horizon models (cycles=0) and lifecycle models (cycles=1). Not @@ -1124,7 +1124,7 @@ def transition(self): mLvlNow """ aLvlPrev = self.state_prev['aLvl'] - RfreeNow = self.getRfree() + RfreeNow = self.get_Rfree() # Calculate new states: normalized market resources # and persistent income level @@ -1207,7 +1207,7 @@ class IndShockExplicitPermIncConsumerType(GenIncProcessConsumerType): state variable during solution. There is no real economic use for it. """ - def updatepLvlNextFunc(self): + def update_pLvlNextFunc(self): """ A method that creates the pLvlNextFunc attribute as a sequence of linear functions, indicating constant expected permanent income growth @@ -1261,7 +1261,7 @@ def __init__(self, cycles=0, **kwds): GenIncProcessConsumerType.__init__(self, cycles=cycles, **params) - def updatepLvlNextFunc(self): + def update_pLvlNextFunc(self): """ A method that creates the pLvlNextFunc attribute as a sequence of AR1-style functions. Draws on the attributes PermGroFac and PrstIncCorr. diff --git a/HARK/ConsumptionSaving/ConsIndShockModel.py b/HARK/ConsumptionSaving/ConsIndShockModel.py index 4bd07a53e..ce7564d56 100644 --- a/HARK/ConsumptionSaving/ConsIndShockModel.py +++ b/HARK/ConsumptionSaving/ConsIndShockModel.py @@ -145,7 +145,7 @@ def __init__( self.MPCmin = MPCmin self.MPCmax = MPCmax - def appendSolution(self, new_solution): + def append_solution(self, new_solution): """ Appends one solution to another to create a ConsumerSolution whose attributes are lists. Used in ConsMarkovModel, where we append solutions @@ -167,7 +167,7 @@ def appendSolution(self, new_solution): # Begin by checking this is so. assert ( NullFunc().distance(self.cFunc) == 0 - ), "appendSolution called incorrectly!" + ), "append_solution called incorrectly!" # We will need the attributes of the solution instance to be lists. Do that here. self.cFunc = [new_solution.cFunc] @@ -239,7 +239,7 @@ def __init__( self.BoroCnstArt = BoroCnstArt self.MaxKinks = MaxKinks - def defUtilityFuncs(self): + def def_utility_funcs(self): """ Defines CRRA utility function for this period (and its derivatives), saving them as attributes of self for other methods to use. @@ -258,7 +258,7 @@ def defUtilityFuncs(self): c, gam=self.CRRA ) # marginal marginal utility function - def defValueFuncs(self): + def def_value_funcs(self): """ Defines the value and marginal value functions for this period. Uses the fact that for a perfect foresight CRRA utility problem, @@ -511,10 +511,11 @@ def solve(self): solution : ConsumerSolution The solution to this period's problem. """ - self.defUtilityFuncs() + self.def_utility_funcs() self.DiscFacEff = self.DiscFac * self.LivPrb # Effective=pure x LivPrb self.make_cFunc_PF() - self.defValueFuncs() + self.def_value_funcs() + solution = ConsumerSolution( cFunc=self.cFunc, vFunc=self.vFunc, @@ -603,9 +604,9 @@ def __init__( self.vFuncBool = vFuncBool self.CubicBool = CubicBool - self.defUtilityFuncs() + self.def_utility_funcs() - def defUtilityFuncs(self): + def def_utility_funcs(self): """ Defines CRRA utility function for this period (and its derivatives, and their inverses), saving them as attributes of self for other methods @@ -619,14 +620,14 @@ def defUtilityFuncs(self): ------- none """ - ConsPerfForesightSolver.defUtilityFuncs(self) + ConsPerfForesightSolver.def_utility_funcs(self) self.uPinv = lambda u: utilityP_inv(u, gam=self.CRRA) self.uPinvP = lambda u: utilityP_invP(u, gam=self.CRRA) self.uinvP = lambda u: utility_invP(u, gam=self.CRRA) if self.vFuncBool: self.uinv = lambda u: utility_inv(u, gam=self.CRRA) - def setAndUpdateValues(self, solution_next, IncShkDstn, LivPrb, DiscFac): + def set_and_update_values(self, solution_next, IncShkDstn, LivPrb, DiscFac): """ Unpacks some of the inputs (and calculates simple objects based on them), storing the results in self for use by other methods. These include: @@ -692,7 +693,7 @@ def setAndUpdateValues(self, solution_next, IncShkDstn, LivPrb, DiscFac): self.cFuncLimitIntercept = self.MPCminNow * self.hNrmNow self.cFuncLimitSlope = self.MPCminNow - def defBoroCnst(self, BoroCnstArt): + def def_BoroCnst(self, BoroCnstArt): """ Defines the constrained portion of the consumption function as cFuncNowCnst, an attribute of self. Uses the artificial and natural borrowing constraints. @@ -734,7 +735,7 @@ def defBoroCnst(self, BoroCnstArt): np.array([self.mNrmMinNow, self.mNrmMinNow + 1]), np.array([0.0, 1.0]) ) - def prepareToSolve(self): + def prepare_to_solve(self): """ Perform preparatory work before calculating the unconstrained consumption function. @@ -747,10 +748,10 @@ def prepareToSolve(self): ------- none """ - self.setAndUpdateValues( + self.set_and_update_values( self.solution_next, self.IncShkDstn, self.LivPrb, self.DiscFac ) - self.defBoroCnst(self.BoroCnstArt) + self.def_BoroCnst(self.BoroCnstArt) #################################################################################################### @@ -769,7 +770,7 @@ class ConsIndShockSolverBasic(ConsIndShockSetup): inherits. """ - def prepareToCalcEndOfPrdvP(self): + def prepare_to_calc_EndOfPrdvP(self): """ Prepare to calculate end-of-period marginal value by creating an array of market resources that the agent could have next period, considering @@ -814,7 +815,7 @@ def m_nrm_next(self, shocks, a_nrm): return self.Rfree / (self.PermGroFac * shocks[0]) \ * a_nrm + shocks[1] - def calcEndOfPrdvP(self): + def calc_EndOfPrdvP(self): """ Calculate end-of-period marginal value of assets at each point in aNrmNow. Does so by taking a weighted sum of next period marginal values across @@ -879,7 +880,7 @@ def get_points_for_interpolation(self, EndOfPrdvP, aNrmNow): return c_for_interpolation, m_for_interpolation - def usePointsForInterpolation(self, cNrm, mNrm, interpolator): + def use_points_for_interpolation(self, cNrm, mNrm, interpolator): """ Constructs a basic solution for this period, including the consumption function and marginal value function. @@ -914,7 +915,7 @@ def usePointsForInterpolation(self, cNrm, mNrm, interpolator): ) return solution_now - def makeBasicSolution(self, EndOfPrdvP, aNrm, interpolator): + def make_basic_solution(self, EndOfPrdvP, aNrm, interpolator): """ Given end of period assets and end of period marginal value, construct the basic solution for this period. @@ -937,10 +938,11 @@ def makeBasicSolution(self, EndOfPrdvP, aNrm, interpolator): consumption function, marginal value function, and minimum m. """ cNrm, mNrm = self.get_points_for_interpolation(EndOfPrdvP, aNrm) - solution_now = self.usePointsForInterpolation(cNrm, mNrm, interpolator) + solution_now = self.use_points_for_interpolation(cNrm, mNrm, interpolator) + return solution_now - def addMPCandHumanWealth(self, solution): + def add_MPC_and_human_wealth(self, solution): """ Take a solution and add human wealth and the bounding MPCs to it. @@ -994,7 +996,7 @@ def add_stable_points(self, solution): return solution - def makeLinearcFunc(self, mNrm, cNrm): + def make_linear_cFunc(self, mNrm, cNrm): """ Makes a linear interpolation to represent the (unconstrained) consumption function. @@ -1030,10 +1032,11 @@ def solve(self): """ self.aNrmNow = np.asarray(self.aXtraGrid) + self.BoroCnstNat aNrm = self.aNrmNow - EndOfPrdvP = self.calcEndOfPrdvP() - solution = self.makeBasicSolution(EndOfPrdvP, aNrm, self.makeLinearcFunc) - solution = self.addMPCandHumanWealth(solution) + EndOfPrdvP = self.calc_EndOfPrdvP() + solution = self.make_basic_solution(EndOfPrdvP, aNrm, self.make_linear_cFunc) + solution = self.add_MPC_and_human_wealth(solution) solution = self.add_stable_points(solution) + return solution @@ -1048,7 +1051,7 @@ class ConsIndShockSolver(ConsIndShockSolverBasic): interpolation and to calculate the value function. """ - def makeCubiccFunc(self, mNrm, cNrm): + def make_cubic_cFunc(self, mNrm, cNrm): """ Makes a cubic spline interpolation of the unconstrained consumption function for this period. @@ -1089,7 +1092,7 @@ def vpp_next(shocks, a_nrm): ) return cFuncNowUnc - def makeEndOfPrdvFunc(self, EndOfPrdvP): + def make_EndOfPrdvFunc(self, EndOfPrdvP): """ Construct the end-of-period value function for this period, storing it as an attribute of self for use by other methods. @@ -1124,7 +1127,7 @@ def v_lvl_next(shocks, a_nrm): EndOfPrdvNvrsFunc = CubicInterp(aNrm_temp, EndOfPrdvNvrs, EndOfPrdvNvrsP) self.EndOfPrdvFunc = ValueFuncCRRA(EndOfPrdvNvrsFunc, self.CRRA) - def addvFunc(self, solution, EndOfPrdvP): + def add_vFunc(self, solution, EndOfPrdvP): """ Creates the value function for this period and adds it to the solution. @@ -1143,11 +1146,11 @@ def addvFunc(self, solution, EndOfPrdvP): The single period solution passed as an input, but now with the value function (defined over market resources m) as an attribute. """ - self.makeEndOfPrdvFunc(EndOfPrdvP) - solution.vFunc = self.makevFunc(solution) + self.make_EndOfPrdvFunc(EndOfPrdvP) + solution.vFunc = self.make_vFunc(solution) return solution - def makevFunc(self, solution): + def make_vFunc(self, solution): """ Creates the value function for this period, defined over market resources m. self must have the attribute EndOfPrdvFunc in order to execute. @@ -1186,7 +1189,7 @@ def makevFunc(self, solution): vFuncNow = ValueFuncCRRA(vNvrsFuncNow, self.CRRA) return vFuncNow - def addvPPfunc(self, solution): + def add_vPPfunc(self, solution): """ Adds the marginal marginal value function to an existing solution, so that the next solver can evaluate vPP and thus use cubic interpolation. @@ -1226,28 +1229,28 @@ def solve(self): The solution to the single period consumption-saving problem. """ # Make arrays of end-of-period assets and end-of-period marginal value - aNrm = self.prepareToCalcEndOfPrdvP() - EndOfPrdvP = self.calcEndOfPrdvP() + aNrm = self.prepare_to_calc_EndOfPrdvP() + EndOfPrdvP = self.calc_EndOfPrdvP() # Construct a basic solution for this period if self.CubicBool: - solution = self.makeBasicSolution( - EndOfPrdvP, aNrm, interpolator=self.makeCubiccFunc + solution = self.make_basic_solution( + EndOfPrdvP, aNrm, interpolator=self.make_cubic_cFunc ) else: - solution = self.makeBasicSolution( - EndOfPrdvP, aNrm, interpolator=self.makeLinearcFunc + solution = self.make_basic_solution( + EndOfPrdvP, aNrm, interpolator=self.make_linear_cFunc ) - solution = self.addMPCandHumanWealth(solution) # add a few things + solution = self.add_MPC_and_human_wealth(solution) # add a few things solution = self.add_stable_points(solution) # Add the value function if requested, as well as the marginal marginal # value function if cubic splines were used (to prepare for next period) if self.vFuncBool: - solution = self.addvFunc(solution, EndOfPrdvP) + solution = self.add_vFunc(solution, EndOfPrdvP) if self.CubicBool: - solution = self.addvPPfunc(solution) + solution = self.add_vPPfunc(solution) return solution @@ -1343,7 +1346,7 @@ def __init__( self.Rboro = Rboro self.Rsave = Rsave - def makeCubiccFunc(self, mNrm, cNrm): + def make_cubic_cFunc(self, mNrm, cNrm): """ Makes a cubic spline interpolation that contains the kink of the unconstrained consumption function for this period. @@ -1360,8 +1363,8 @@ def makeCubiccFunc(self, mNrm, cNrm): cFuncUnc : CubicInterp The unconstrained consumption function for this period. """ - # Call the makeCubiccFunc from ConsIndShockSolver. - cFuncNowUncKink = super().makeCubiccFunc(mNrm, cNrm) + # Call the make_cubic_cFunc from ConsIndShockSolver. + cFuncNowUncKink = super().make_cubic_cFunc(mNrm, cNrm) # Change the coeffients at the kinked points. cFuncNowUncKink.coeffs[self.i_kink + 1] = [ @@ -1399,7 +1402,7 @@ def add_stable_points(self, solution): """ return solution - def prepareToCalcEndOfPrdvP(self): + def prepare_to_calc_EndOfPrdvP(self): """ Prepare to calculate end-of-period marginal value by creating an array of market resources that the agent could have next period, considering @@ -1458,7 +1461,7 @@ def prepareToCalcEndOfPrdvP(self): ) # Recalculate the minimum MPC and human wealth using the interest factor on saving. - # This overwrites values from setAndUpdateValues, which were based on Rboro instead. + # This overwrites values from set_and_update_values, which were based on Rboro instead. if KinkBool: PatFacTop = ( (self.Rsave * self.DiscFacEff) ** (1.0 / self.CRRA) @@ -1563,7 +1566,7 @@ def __init__(self, cycles=1, verbose=1, quiet=False, **kwds): set_verbosity_level((4 - verbose) * 10) def pre_solve(self): - self.updateSolutionTerminal() # Solve the terminal period problem + self.update_solution_terminal() # Solve the terminal period problem # Fill in BoroCnstArt and MaxKinks if they're not specified or are irrelevant. if not hasattr(self, "BoroCnstArt"): # If no borrowing constraint specified... @@ -1589,7 +1592,7 @@ def check_restrictions(self): return - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Update the terminal period solution. This method should be run when a new AgentType is created or when CRRA changes. @@ -1608,7 +1611,7 @@ def updateSolutionTerminal(self): self.cFunc_terminal_, self.CRRA ) - def unpackcFunc(self): + def unpack_cFunc(self): """ DEPRECATED: Use solution.unpack('cFunc') instead. "Unpacks" the consumption functions into their own field for easier access. After the model has been solved, the consumption functions reside in the @@ -1623,7 +1626,7 @@ def unpackcFunc(self): none """ _log.critical( - "unpackcFunc is deprecated and it will soon be removed, " + "unpack_cFunc is deprecated and it will soon be removed, " "please use unpack('cFunc') instead." ) self.unpack("cFunc") @@ -1718,7 +1721,7 @@ def get_shocks(self): ] # cycle time has already been advanced self.shocks['TranShk'] = np.ones(self.AgentCount) - def getRfree(self): + def get_Rfree(self): """ Returns an array of size self.AgentCount with self.Rfree in every entry. @@ -1737,7 +1740,7 @@ def getRfree(self): def transition(self): pLvlPrev = self.state_prev['pLvl'] aNrmPrev = self.state_prev['aNrm'] - RfreeNow = self.getRfree() + RfreeNow = self.get_Rfree() # Calculate new states: normalized market resources and permanent income level pLvlNow = pLvlPrev*self.shocks['PermShk'] # Updated permanent income level @@ -2029,7 +2032,7 @@ def __init__(self, cycles=1, verbose=1, quiet=False, **kwds): self.update() # Make assets grid, income process, terminal solution - def updateIncomeProcess(self): + def update_income_process(self): """ Updates this agent's income process based on his own attributes. @@ -2045,13 +2048,13 @@ def updateIncomeProcess(self): IncShkDstn, PermShkDstn, TranShkDstn, - ) = self.constructLognormalIncomeProcessUnemployment() + ) = self.construct_lognormal_income_process_unemployment() self.IncShkDstn = IncShkDstn self.PermShkDstn = PermShkDstn self.TranShkDstn = TranShkDstn self.add_to_time_vary("IncShkDstn", "PermShkDstn", "TranShkDstn") - def updateAssetsGrid(self): + def update_assets_grid(self): """ Updates this agent's end-of-period assets grid by constructing a multi- exponentially spaced grid of aXtra values. @@ -2064,7 +2067,7 @@ def updateAssetsGrid(self): ------- none """ - aXtraGrid = constructAssetsGrid(self) + aXtraGrid = construct_assets_grid(self) self.aXtraGrid = aXtraGrid self.add_to_time_inv("aXtraGrid") @@ -2080,9 +2083,9 @@ def update(self): ------- None """ - self.updateIncomeProcess() - self.updateAssetsGrid() - self.updateSolutionTerminal() + self.update_income_process() + self.update_assets_grid() + self.update_solution_terminal() def reset_rng(self): """ @@ -2161,7 +2164,7 @@ def get_shocks(self): self.shocks['PermShk'] = PermShkNow self.shocks['TranShk'] = TranShkNow - def calcBoundingValues(self): + def calc_bounding_values(self): """ Calculate human wealth plus minimum and maximum MPC in an infinite horizon model with only one period repeated indefinitely. Store results @@ -2212,7 +2215,7 @@ def calcBoundingValues(self): self.MPCmin = MPCmin self.MPCmax = MPCmax - def makeEulerErrorFunc(self, mMax=100, approx_inc_dstn=True): + def make_euler_error_func(self, mMax=100, approx_inc_dstn=True): """ Creates a "normalized Euler error" function for this instance, mapping from market resources to "consumption error per dollar of consumption." @@ -2311,8 +2314,8 @@ def pre_solve(self): # AgentType.pre_solve(self) # Update all income process variables to match any attributes that might # have been changed since `__init__` or `solve()` was last called. - # self.updateIncomeProcess() - self.updateSolutionTerminal() + # self.update_income_process() + self.update_solution_terminal() if not self.quiet: self.check_conditions(verbose=self.verbose) @@ -2553,7 +2556,7 @@ def calc_stable_points(self): # simulated income shocks = # ======================================================== - def constructLognormalIncomeProcessUnemployment(self): + def construct_lognormal_income_process_unemployment(self): """ Generates a list of discrete approximations to the income process for each life period, from end of life to beginning of life. Permanent shocks are mean @@ -2725,9 +2728,9 @@ def __init__(self, cycles=1, **kwds): def pre_solve(self): # AgentType.pre_solve(self) - self.updateSolutionTerminal() + self.update_solution_terminal() - def calcBoundingValues(self): + def calc_bounding_values(self): """ Calculate human wealth plus minimum and maximum MPC in an infinite horizon model with only one period repeated indefinitely. Store results @@ -2784,7 +2787,7 @@ def calcBoundingValues(self): self.MPCmin = MPCmin self.MPCmax = MPCmax - def makeEulerErrorFunc(self, mMax=100, approx_inc_dstn=True): + def make_euler_error_func(self, mMax=100, approx_inc_dstn=True): """ Creates a "normalized Euler error" function for this instance, mapping from market resources to "consumption error per dollar of consumption." @@ -2815,7 +2818,7 @@ def makeEulerErrorFunc(self, mMax=100, approx_inc_dstn=True): """ raise NotImplementedError() - def getRfree(self): + def get_Rfree(self): """ Returns an array of size self.AgentCount with self.Rboro or self.Rsave in each entry, based on whether self.aNrmNow >< 0. @@ -2852,7 +2855,7 @@ def check_conditions(self): raise NotImplementedError() -def applyFlatIncomeTax( +def apply_flat_income_tax( IncShkDstn, tax_rate, T_retire, unemployed_indices=None, transitory_index=2 ): """ @@ -2895,7 +2898,7 @@ def applyFlatIncomeTax( # ======================================================= -def constructAssetsGrid(parameters): +def construct_assets_grid(parameters): """ Constructs the base grid of post-decision states, representing end-of-period assets above the absolute minimum. diff --git a/HARK/ConsumptionSaving/ConsIndShockModelFast.py b/HARK/ConsumptionSaving/ConsIndShockModelFast.py index 30c7391c6..8e4086669 100644 --- a/HARK/ConsumptionSaving/ConsIndShockModelFast.py +++ b/HARK/ConsumptionSaving/ConsIndShockModelFast.py @@ -403,7 +403,7 @@ def _np_insert(arr, obj, values, axis=-1): @njit(cache=True) -def _prepareToSolveConsIndShockNumba( +def _prepare_to_solveConsIndShockNumba( DiscFac, LivPrb, CRRA, @@ -573,7 +573,7 @@ class ConsIndShockSolverBasicFast(ConsIndShockSolverBasic): inherits. """ - def prepareToSolve(self): + def prepare_to_solve(self): """ Perform preparatory work before calculating the unconstrained consumption function. @@ -604,7 +604,7 @@ def prepareToSolve(self): self.PermShkVals_temp, self.ShkPrbs_temp, self.aNrmNow, - ) = _prepareToSolveConsIndShockNumba( + ) = _prepare_to_solveConsIndShockNumba( self.DiscFac, self.LivPrb, self.CRRA, @@ -771,7 +771,7 @@ def _cFuncLinear(aXtraGrid, mNrmMinNow, mNrmNow, cNrmNow, MPCminNow, hNrmNow): @njit(cache=True) -def _addvFuncNumba( +def _add_vFuncNumba( mNrmNext, mNrmGridNext, vNvrsNext, @@ -1035,7 +1035,7 @@ def solve(self): self.hNrmNow, ) - self.mNrmGrid, self.vNvrs, self.vNvrsP, self.MPCminNvrs = _addvFuncNumba( + self.mNrmGrid, self.vNvrs, self.vNvrsP, self.MPCminNvrs = _add_vFuncNumba( self.mNrmNext, self.solution_next.mNrmGrid, self.solution_next.vNvrs, @@ -1088,7 +1088,7 @@ def __init__(self, **kwargs): self.solve_one_period = make_one_period_oo_solver(ConsPerfForesightSolverFast) - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Update the terminal period solution. This method should be run when a new AgentType is created or when CRRA changes. @@ -1181,8 +1181,8 @@ def __init__(self, **kwargs): self.solve_one_period = make_one_period_oo_solver(solver) - def updateSolutionTerminal(self): - PerfForesightConsumerTypeFast.updateSolutionTerminal(self) + def update_solution_terminal(self): + PerfForesightConsumerTypeFast.update_solution_terminal(self) with np.errstate( divide="ignore", over="ignore", under="ignore", invalid="ignore" ): diff --git a/HARK/ConsumptionSaving/ConsLaborModel.py b/HARK/ConsumptionSaving/ConsLaborModel.py index ce11b11b8..8f4d6f5d6 100644 --- a/HARK/ConsumptionSaving/ConsLaborModel.py +++ b/HARK/ConsumptionSaving/ConsLaborModel.py @@ -68,7 +68,7 @@ def __init__(self, cFunc=None, LbrFunc=None, vFunc=None, vPfunc=None, bNrmMin=No self.bNrmMin = bNrmMin -def solveConsLaborIntMarg( +def solve_ConsLaborIntMarg( solution_next, PermShkDstn, TranShkDstn, @@ -367,7 +367,7 @@ def __init__(self, cycles=1, **kwds): IndShockConsumerType.__init__(self, cycles=cycles, **params) self.pseudo_terminal = False - self.solve_one_period = solveConsLaborIntMarg + self.solve_one_period = solve_ConsLaborIntMarg self.update() def update(self): @@ -382,12 +382,12 @@ def update(self): ------- None """ - self.updateIncomeProcess() - self.updateAssetsGrid() - self.updateTranShkGrid() - self.updateLbrCost() + self.update_income_process() + self.update_assets_grid() + self.update_TranShkGrid() + self.update_LbrCost() - def updateLbrCost(self): + def update_LbrCost(self): """ Construct the age-varying cost of working LbrCost using the attribute LbrCostCoeffs. This attribute should be a 1D array of arbitrary length, representing polynomial @@ -411,7 +411,7 @@ def updateLbrCost(self): self.LbrCost = LbrCost.tolist() self.add_to_time_vary("LbrCost") - def calcBoundingValues(self): + def calc_bounding_values(self): """ Calculate human wealth plus minimum and maximum MPC in an infinite horizon model with only one period repeated indefinitely. Store results @@ -432,7 +432,7 @@ def calcBoundingValues(self): """ raise NotImplementedError() - def makeEulerErrorFunc(self, mMax=100, approx_inc_dstn=True): + def make_euler_error_func(self, mMax=100, approx_inc_dstn=True): """ Creates a "normalized Euler error" function for this instance, mapping from market resources to "consumption error per dollar of consumption." @@ -539,10 +539,10 @@ def get_poststates(self): # moves now to prev super().get_poststates() - def updateTranShkGrid(self): + def update_TranShkGrid(self): """ Create a time-varying list of arrays for TranShkGrid using TranShkDstn, - which is created by the method updateIncomeProcess(). Simply takes the + which is created by the method update_income_process(). Simply takes the transitory shock values and uses them as a state grid; can be improved. Creates the attribute TranShkGrid. @@ -564,7 +564,7 @@ def updateTranShkGrid(self): "TranShkGrid" ) # Run the method add_to_time_vary from AgentType to add TranShkGrid as one parameter of time_vary list - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Updates the terminal period solution and solves for optimal consumption and labor when there is no future. @@ -639,7 +639,7 @@ def updateSolutionTerminal(self): bNrmMin=bNrmMin_terminal, ) - def plotcFunc(self, t, bMin=None, bMax=None, ShkSet=None): + def plot_cFunc(self, t, bMin=None, bMax=None, ShkSet=None): """ Plot the consumption function by bank balances at a given set of transitory shocks. @@ -682,7 +682,7 @@ def plotcFunc(self, t, bMin=None, bMax=None, ShkSet=None): plt.ylabel("Normalized consumption level") plt.show() - def plotLbrFunc(self, t, bMin=None, bMax=None, ShkSet=None): + def plot_LbrFunc(self, t, bMin=None, bMax=None, ShkSet=None): """ Plot the labor supply function by bank balances at a given set of transitory shocks. diff --git a/HARK/ConsumptionSaving/ConsMarkovModel.py b/HARK/ConsumptionSaving/ConsMarkovModel.py index fb2aa65e7..27d3bc617 100644 --- a/HARK/ConsumptionSaving/ConsMarkovModel.py +++ b/HARK/ConsumptionSaving/ConsMarkovModel.py @@ -143,7 +143,7 @@ def __init__( self.MrkvArray=MrkvArray self.StateCount=MrkvArray.shape[0] - self.defUtilityFuncs() + self.def_utility_funcs() def solve(self): """ @@ -167,7 +167,7 @@ def solve(self): when in the i=0 Markov state this period. """ # Find the natural borrowing constraint in each current state - self.defBoundary() + self.def_boundary() # Initialize end-of-period (marginal) value functions self.EndOfPrdvFunc_list = [] @@ -183,7 +183,7 @@ def solve(self): # (marginal) value function for j in range(self.StateCount): # Condition values on next period's state (and record a couple for later use) - self.conditionOnState(j) + self.condition_on_state(j) self.Ex_IncNextAll[j] = np.dot( self.ShkPrbsNext, self.PermShkValsNext * self.TranShkValsNext ) @@ -191,21 +191,21 @@ def solve(self): # Construct the end-of-period marginal value function conditional # on next period's state and add it to the list of value functions - EndOfPrdvPfunc_cond = self.makeEndOfPrdvPfuncCond() + EndOfPrdvPfunc_cond = self.make_EndOfPrdvPfuncCond() self.EndOfPrdvPfunc_list.append(EndOfPrdvPfunc_cond) # Construct the end-of-period value functional conditional on next # period's state and add it to the list of value functions if self.vFuncBool: - EndOfPrdvFunc_cond = self.makeEndOfPrdvFuncCond() + EndOfPrdvFunc_cond = self.make_EndOfPrdvFuncCond() self.EndOfPrdvFunc_list.append(EndOfPrdvFunc_cond) # EndOfPrdvP_cond is EndOfPrdvP conditional on *next* period's state. # Take expectations to get EndOfPrdvP conditional on *this* period's state. - self.calcEndOfPrdvP() + self.calc_EndOfPrdvP() # Calculate the bounding MPCs and PDV of human wealth for each state - self.calcHumWealthAndBoundingMPCs() + self.calc_HumWealth_and_BoundingMPCs() # Find consumption and market resources corresponding to each end-of-period # assets point for each state (and add an additional point at the lower bound) @@ -221,10 +221,10 @@ def solve(self): # Package and return the solution for this period self.BoroCnstNat = self.BoroCnstNat_list - solution = self.makeSolution(cNrm, mNrm) + solution = self.make_solution(cNrm, mNrm) return solution - def defBoundary(self): + def def_boundary(self): """ Find the borrowing constraint for each current state and save it as an attribute of self for use by other methods. @@ -271,7 +271,7 @@ def defBoundary(self): # Also creates a Boolean array indicating whether the natural borrowing # constraint *could* be hit when transitioning from i to j. - def conditionOnState(self, state_index): + def condition_on_state(self, state_index): """ Temporarily assume that a particular Markov state will occur in the succeeding period, and condition solver attributes on this assumption. @@ -294,7 +294,7 @@ def conditionOnState(self, state_index): self.vPfuncNext = self.solution_next.vPfunc[state_index] self.mNrmMinNow = self.mNrmMin_list[state_index] self.BoroCnstNat = self.BoroCnstNatAll[state_index] - self.setAndUpdateValues( + self.set_and_update_values( self.solution_next, self.IncShkDstn, self.LivPrb, self.DiscFac ) self.DiscFacEff = ( @@ -302,14 +302,14 @@ def conditionOnState(self, state_index): ) # survival probability LivPrb represents probability from # *current* state, so DiscFacEff is just DiscFac for now - # These lines have to come after setAndUpdateValues to override the definitions there + # These lines have to come after set_and_update_values to override the definitions there self.vPfuncNext = self.solution_next.vPfunc[state_index] if self.CubicBool: self.vPPfuncNext = self.solution_next.vPPfunc[state_index] if self.vFuncBool: self.vFuncNext = self.solution_next.vFunc[state_index] - def calcEndOfPrdvPP(self): + def calc_EndOfPrdvPP(self): """ Calculates end-of-period marginal marginal value using a pre-defined array of next period market resources in self.mNrmNext. @@ -341,11 +341,11 @@ def vpp_next(shocks, a_nrm): ) return EndOfPrdvPP - def makeEndOfPrdvFuncCond(self): + def make_EndOfPrdvFuncCond(self): """ Construct the end-of-period value function conditional on next period's state. NOTE: It might be possible to eliminate this method and replace - it with ConsIndShockSolver.makeEndOfPrdvFunc, but the self.X_cond + it with ConsIndShockSolver.make_EndOfPrdvFunc, but the self.X_cond variables must be renamed. Parameters @@ -374,7 +374,7 @@ def makeEndOfPrdvFuncCond(self): EndofPrdvFunc_cond = ValueFuncCRRA(EndOfPrdvNvrsFunc_cond, self.CRRA) return EndofPrdvFunc_cond - def calcEndOfPrdvPcond(self): + def calc_EndOfPrdvPcond(self): """ Calculate end-of-period marginal value of assets at each point in aNrmNow conditional on a particular state occuring in the next period. @@ -388,10 +388,10 @@ def calcEndOfPrdvPcond(self): EndOfPrdvP : np.array A 1D array of end-of-period marginal value of assets. """ - EndOfPrdvPcond = ConsIndShockSolver.calcEndOfPrdvP(self) + EndOfPrdvPcond = ConsIndShockSolver.calc_EndOfPrdvP(self) return EndOfPrdvPcond - def makeEndOfPrdvPfuncCond(self): + def make_EndOfPrdvPfuncCond(self): """ Construct the end-of-period marginal value function conditional on next period's state. @@ -407,13 +407,13 @@ def makeEndOfPrdvPfuncCond(self): state occuring in the succeeding period. """ # Get data to construct the end-of-period marginal value function (conditional on next state) - self.aNrm_cond = self.prepareToCalcEndOfPrdvP() - self.EndOfPrdvP_cond = self.calcEndOfPrdvPcond() + self.aNrm_cond = self.prepare_to_calc_EndOfPrdvP() + self.EndOfPrdvP_cond = self.calc_EndOfPrdvPcond() EndOfPrdvPnvrs_cond = self.uPinv( self.EndOfPrdvP_cond ) # "decurved" marginal value if self.CubicBool: - EndOfPrdvPP_cond = self.calcEndOfPrdvPP() + EndOfPrdvPP_cond = self.calc_EndOfPrdvPP() EndOfPrdvPnvrsP_cond = EndOfPrdvPP_cond * self.uPinvP( self.EndOfPrdvP_cond ) # "decurved" marginal marginal value @@ -435,7 +435,7 @@ def makeEndOfPrdvPfuncCond(self): ) # "recurve" the interpolated marginal value function return EndofPrdvPfunc_cond - def calcEndOfPrdvP(self): + def calc_EndOfPrdvP(self): """ Calculates end of period marginal value (and marginal marginal) value at each aXtra gridpoint for each current state, unconditional on the @@ -498,7 +498,7 @@ def calcEndOfPrdvP(self): if self.CubicBool: self.EndOfPrdvPP = LivPrb_tiled * EndOfPrdvPP - def calcHumWealthAndBoundingMPCs(self): + def calc_HumWealth_and_BoundingMPCs(self): """ Calculates human wealth and the maximum and minimum MPC for each current period state, then stores them as attributes of self for use by other methods. @@ -550,7 +550,7 @@ def calcHumWealthAndBoundingMPCs(self): ) ** (1.0 / self.CRRA) self.MPCminNow = 1.0 / (1.0 + temp) - def makeSolution(self, cNrm, mNrm): + def make_solution(self, cNrm, mNrm): """ Construct an object representing the solution to this period's problem. @@ -586,9 +586,9 @@ def makeSolution(self, cNrm, mNrm): self.MPC_temp = np.hstack( (np.reshape(self.MPCmaxNow, (self.StateCount, 1)), MPC) ) - interpfunc = self.makeCubiccFunc + interpfunc = self.make_cubic_cFunc else: - interpfunc = self.makeLinearcFunc + interpfunc = self.make_linear_cFunc # Loop through each current period state and add its solution to the overall solution for i in range(self.StateCount): @@ -613,23 +613,23 @@ def makeSolution(self, cNrm, mNrm): if ( self.CubicBool ): # Add the state-conditional marginal marginal value function (if desired) - solution_cond = self.addvPPfunc(solution_cond) + solution_cond = self.add_vPPfunc(solution_cond) # Add the current-state-conditional solution to the overall period solution - solution.appendSolution(solution_cond) + solution.append_solution(solution_cond) # Add the lower bounds of market resources, MPC limits, human resources, # and the value functions to the overall solution solution.mNrmMin = self.mNrmMin_list - solution = self.addMPCandHumanWealth(solution) + solution = self.add_MPC_and_human_wealth(solution) if self.vFuncBool: - vFuncNow = self.makevFunc(solution) + vFuncNow = self.make_vFunc(solution) solution.vFunc = vFuncNow # Return the overall solution to this period return solution - def makeLinearcFunc(self, mNrm, cNrm): + def make_linear_cFunc(self, mNrm, cNrm): """ Make a linear interpolation to represent the (unconstrained) consumption function conditional on the current period state. @@ -650,7 +650,7 @@ def makeLinearcFunc(self, mNrm, cNrm): ) return cFuncUnc - def makeCubiccFunc(self, mNrm, cNrm): + def make_cubic_cFunc(self, mNrm, cNrm): """ Make a cubic interpolation to represent the (unconstrained) consumption function conditional on the current period state. @@ -675,7 +675,7 @@ def makeCubiccFunc(self, mNrm, cNrm): ) return cFuncUnc - def makevFunc(self, solution): + def make_vFunc(self, solution): """ Construct the value function for each current state. @@ -733,7 +733,7 @@ def makevFunc(self, solution): return vFuncNow -def _solveConsMarkov( +def _solve_ConsMarkov( solution_next, IncShkDstn, LivPrb, @@ -848,12 +848,12 @@ class MarkovConsumerType(IndShockConsumerType): def __init__(self, cycles=1, **kwds): IndShockConsumerType.__init__(self, cycles=1, **kwds) - self.solve_one_period = _solveConsMarkov + self.solve_one_period = _solve_ConsMarkov if not hasattr(self, "global_markov"): self.global_markov = False - def checkMarkovInputs(self): + def check_markov_inputs(self): """ Many parameters used by MarkovConsumerType are arrays. Make sure those arrays are the right shape. @@ -929,9 +929,9 @@ def pre_solve(self): None """ AgentType.pre_solve(self) - self.checkMarkovInputs() + self.check_markov_inputs() - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Update the terminal period solution. This method should be run when a new AgentType is created or when CRRA changes. @@ -944,7 +944,7 @@ def updateSolutionTerminal(self): ------- none """ - IndShockConsumerType.updateSolutionTerminal(self) + IndShockConsumerType.update_solution_terminal(self) # Make replicated terminal period solution: consume all resources, no human wealth, minimum m is 0 StateCount = self.MrkvArray[0].shape[0] @@ -1048,7 +1048,7 @@ def sim_birth(self, which_agents): Cutoffs, base_draws ).astype(int) - def getMarkovStates(self): + def get_markov_states(self): """ Draw new Markov states for each agent in the simulated population, using the attribute MrkvArray to determine transition probabilities. @@ -1098,7 +1098,7 @@ def get_shocks(self): ------- None """ - self.getMarkovStates() + self.get_markov_states() MrkvNow = self.shocks['Mrkv'] # Now get income shocks for each consumer, by cycle-time and discrete state @@ -1143,7 +1143,7 @@ def read_shocks_from_history(self): IndShockConsumerType.read_shocks_from_history(self) self.shocks['Mrkv'] = self.shocks['Mrkv'].astype(int) - def getRfree(self): + def get_Rfree(self): """ Returns an array of size self.AgentCount with interest factor that varies with discrete state. @@ -1189,7 +1189,7 @@ def get_controls(self): self.controls['cNrm'] = cNrmNow self.MPCnow = MPCnow - def calcBoundingValues(self): + def calc_bounding_values(self): """ Calculate human wealth plus minimum and maximum MPC in an infinite horizon model with only one period repeated indefinitely. Store results @@ -1211,7 +1211,7 @@ def calcBoundingValues(self): """ raise NotImplementedError() - def makeEulerErrorFunc(self, mMax=100, approx_inc_dstn=True): + def make_euler_error_func(self, mMax=100, approx_inc_dstn=True): """ Creates a "normalized Euler error" function for this instance, mapping from market resources to "consumption error per dollar of consumption." diff --git a/HARK/ConsumptionSaving/ConsMedModel.py b/HARK/ConsumptionSaving/ConsMedModel.py index 979dda78d..e4dc84972 100644 --- a/HARK/ConsumptionSaving/ConsMedModel.py +++ b/HARK/ConsumptionSaving/ConsMedModel.py @@ -585,7 +585,7 @@ def __init__(self, cycles=0, **kwds): self.add_to_time_vary("MedPrice") def pre_solve(self): - self.updateSolutionTerminal() + self.update_solution_terminal() def update(self): """ @@ -600,14 +600,14 @@ def update(self): ------- None """ - self.updateIncomeProcess() - self.updateAssetsGrid() - self.updatepLvlNextFunc() - self.updatepLvlGrid() - self.updateMedShockProcess() - self.updateSolutionTerminal() + self.update_income_process() + self.update_assets_grid() + self.update_pLvlNextFunc() + self.update_pLvlGrid() + self.update_med_shock_process() + self.update_solution_terminal() - def updateMedShockProcess(self): + def update_med_shock_process(self): """ Constructs discrete distributions of medical preference shocks for each period in the cycle. Distributions are saved as attribute MedShkDstn, @@ -637,7 +637,7 @@ def updateMedShockProcess(self): self.MedShkDstn = MedShkDstn self.add_to_time_vary("MedShkDstn") - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Update the terminal period solution for this type. Similar to other models, optimal behavior involves spending all available market resources; however, @@ -754,7 +754,7 @@ def updateSolutionTerminal(self): p ) # And minimum allowable market resources by perm inc - def updatepLvlGrid(self): + def update_pLvlGrid(self): """ Update the grid of permanent income levels. Currently only works for infinite horizon models (cycles=0) and lifecycle models (cycles=1). Not @@ -771,7 +771,7 @@ def updatepLvlGrid(self): None """ # Run basic version of this method - PersistentShockConsumerType.updatepLvlGrid(self) + PersistentShockConsumerType.update_pLvlGrid(self) for j in range(len(self.pLvlGrid)): # Then add 0 to the bottom of each pLvlGrid this_grid = self.pLvlGrid[j] self.pLvlGrid[j] = np.insert(this_grid, 0, 0.0001) @@ -961,9 +961,9 @@ def __init__( self.vFuncBool = vFuncBool self.CubicBool = CubicBool self.PermGroFac = 0.0 - self.defUtilityFuncs() + self.def_utility_funcs() - def setAndUpdateValues(self, solution_next, IncShkDstn, LivPrb, DiscFac): + def set_and_update_values(self, solution_next, IncShkDstn, LivPrb, DiscFac): """ Unpacks some of the inputs (and calculates simple objects based on them), storing the results in self for use by other methods. These include: @@ -991,7 +991,7 @@ def setAndUpdateValues(self, solution_next, IncShkDstn, LivPrb, DiscFac): None """ # Run basic version of this method - ConsGenIncProcessSolver.setAndUpdateValues( + ConsGenIncProcessSolver.set_and_update_values( self, self.solution_next, self.IncShkDstn, self.LivPrb, self.DiscFac ) @@ -999,7 +999,7 @@ def setAndUpdateValues(self, solution_next, IncShkDstn, LivPrb, DiscFac): self.MedShkPrbs = self.MedShkDstn.pmf self.MedShkVals = self.MedShkDstn.X - def defUtilityFuncs(self): + def def_utility_funcs(self): """ Defines CRRA utility function for this period (and its derivatives, and their inverses), saving them as attributes of self for other methods @@ -1014,12 +1014,12 @@ def defUtilityFuncs(self): ------- none """ - ConsGenIncProcessSolver.defUtilityFuncs(self) # Do basic version + ConsGenIncProcessSolver.def_utility_funcs(self) # Do basic version self.uMedPinv = lambda Med: utilityP_inv(Med, gam=self.CRRAmed) self.uMed = lambda Med: utility(Med, gam=self.CRRAmed) self.uMedPP = lambda Med: utilityPP(Med, gam=self.CRRAmed) - def defBoroCnst(self, BoroCnstArt): + def def_BoroCnst(self, BoroCnstArt): """ Defines the constrained portion of the consumption function as cFuncNowCnst, an attribute of self. Uses the artificial and natural borrowing constraints. @@ -1142,7 +1142,7 @@ def get_points_for_interpolation(self, EndOfPrdvP, aLvlNow): return x_for_interpolation, m_for_interpolation, p_for_interpolation - def usePointsForInterpolation(self, xLvl, mLvl, pLvl, MedShk, interpolator): + def use_points_for_interpolation(self, xLvl, mLvl, pLvl, MedShk, interpolator): """ Constructs a basic solution for this period, including the consumption function and marginal value function. @@ -1189,7 +1189,7 @@ def usePointsForInterpolation(self, xLvl, mLvl, pLvl, MedShk, interpolator): MedFuncNow = MedThruXfunc(xFuncNow, policyFuncNow.cFunc, self.MedPrice) # Make the marginal value function (and the value function if vFuncBool=True) - vFuncNow, vPfuncNow = self.makevAndvPfuncs(policyFuncNow) + vFuncNow, vPfuncNow = self.make_v_and_vP_funcs(policyFuncNow) # Pack up the solution and return it solution_now = ConsumerSolution( @@ -1199,7 +1199,7 @@ def usePointsForInterpolation(self, xLvl, mLvl, pLvl, MedShk, interpolator): solution_now.policyFunc = policyFuncNow return solution_now - def makevAndvPfuncs(self, policyFunc): + def make_v_and_vP_funcs(self, policyFunc): """ Constructs the marginal value function for this period. @@ -1311,7 +1311,7 @@ def makevAndvPfuncs(self, policyFunc): return vFunc, vPfunc - def makeLinearxFunc(self, mLvl, pLvl, MedShk, xLvl): + def make_linear_xFunc(self, mLvl, pLvl, MedShk, xLvl): """ Constructs the (unconstrained) expenditure function for this period using bilinear interpolation (over permanent income and the medical shock) among @@ -1359,7 +1359,7 @@ def makeLinearxFunc(self, mLvl, pLvl, MedShk, xLvl): xFuncUnc = VariableLowerBoundFunc3D(xFuncUncBase, self.BoroCnstNat) return xFuncUnc - def makeCubicxFunc(self, mLvl, pLvl, MedShk, xLvl): + def make_cubic_xFunc(self, mLvl, pLvl, MedShk, xLvl): """ Constructs the (unconstrained) expenditure function for this period using bilinear interpolation (over permanent income and the medical shock) among @@ -1434,7 +1434,7 @@ def makeCubicxFunc(self, mLvl, pLvl, MedShk, xLvl): xFuncUnc = VariableLowerBoundFunc3D(xFuncUncBase, self.BoroCnstNat) return xFuncUnc - def makeBasicSolution(self, EndOfPrdvP, aLvl, interpolator): + def make_basic_solution(self, EndOfPrdvP, aLvl, interpolator): """ Given end of period assets and end of period marginal value, construct the basic solution for this period. @@ -1460,12 +1460,12 @@ def makeBasicSolution(self, EndOfPrdvP, aLvl, interpolator): np.reshape(self.MedShkVals, (self.MedShkVals.size, 1, 1)), (1, mLvl.shape[1], mLvl.shape[2]), ) - solution_now = self.usePointsForInterpolation( + solution_now = self.use_points_for_interpolation( xLvl, mLvl, pLvl, MedShk_temp, interpolator ) return solution_now - def addvPPfunc(self, solution): + def add_vPPfunc(self, solution): """ Adds the marginal marginal value function to an existing solution, so that the next solver can evaluate vPP and thus use cubic interpolation. @@ -1504,16 +1504,16 @@ def solve(self): tion (defined over market resources and permanent income), and human wealth as a function of permanent income. """ - aLvl, trash = self.prepareToCalcEndOfPrdvP() - EndOfPrdvP = self.calcEndOfPrdvP() + aLvl, trash = self.prepare_to_calc_EndOfPrdvP() + EndOfPrdvP = self.calc_EndOfPrdvP() if self.vFuncBool: - self.makeEndOfPrdvFunc(EndOfPrdvP) + self.make_EndOfPrdvFunc(EndOfPrdvP) if self.CubicBool: - interpolator = self.makeCubicxFunc + interpolator = self.make_cubic_xFunc else: - interpolator = self.makeLinearxFunc - solution = self.makeBasicSolution(EndOfPrdvP, aLvl, interpolator) - solution = self.addMPCandHumanWealth(solution) + interpolator = self.make_linear_xFunc + solution = self.make_basic_solution(EndOfPrdvP, aLvl, interpolator) + solution = self.add_MPC_and_human_wealth(solution) if self.CubicBool: - solution = self.addvPPfunc(solution) + solution = self.add_vPPfunc(solution) return solution diff --git a/HARK/ConsumptionSaving/ConsPortfolioModel.py b/HARK/ConsumptionSaving/ConsPortfolioModel.py index be7872fb6..3e868e57a 100644 --- a/HARK/ConsumptionSaving/ConsPortfolioModel.py +++ b/HARK/ConsumptionSaving/ConsPortfolioModel.py @@ -151,16 +151,16 @@ def __init__(self, cycles=1, verbose=False, quiet=False, **kwds): def pre_solve(self): AgentType.pre_solve(self) - self.updateSolutionTerminal() + self.update_solution_terminal() def update(self): IndShockConsumerType.update(self) - self.updateRiskyDstn() - self.updateShockDstn() - self.updateShareGrid() - self.updateShareLimit() + self.update_RiskyDstn() + self.update_ShockDstn() + self.update_ShareGrid() + self.update_ShareLimit() - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Solves the terminal period of the portfolio choice problem. The solution is trivial, as usual: consume all market resources, and put nothing in the risky @@ -206,7 +206,7 @@ def updateSolutionTerminal(self): dvdsFuncFxd=dvdsFuncFxd_terminal, ) - def updateRiskyDstn(self): + def update_RiskyDstn(self): """ Creates the attributes RiskyDstn from the primitive attributes RiskyAvg, RiskyStd, and RiskyCount, approximating the (perceived) distribution of @@ -257,7 +257,7 @@ def updateRiskyDstn(self): ).approx(self.RiskyCount) self.add_to_time_inv("RiskyDstn") - def updateShockDstn(self): + def update_ShockDstn(self): """ Combine the income shock distribution (over PermShk and TranShk) with the risky return distribution (RiskyDstn) to make a new attribute called ShockDstn. @@ -286,7 +286,7 @@ def updateShockDstn(self): self.IndepDstnBool = True self.add_to_time_inv("IndepDstnBool") - def updateShareGrid(self): + def update_ShareGrid(self): """ Creates the attribute ShareGrid as an evenly spaced grid on [0.,1.], using the primitive parameter ShareCount. @@ -302,7 +302,7 @@ def updateShareGrid(self): self.ShareGrid = np.linspace(0.0, 1.0, self.ShareCount) self.add_to_time_inv("ShareGrid") - def updateShareLimit(self): + def update_ShareLimit(self): """ Creates the attribute ShareLimit, representing the limiting lower bound of risky portfolio share as mNrm goes to infinity. @@ -337,7 +337,7 @@ def updateShareLimit(self): self.ShareLimit = SharePF self.add_to_time_inv("ShareLimit") - def getRisky(self): + def get_Risky(self): """ Sets the shock RiskyNow as a single draw from a lognormal distribution. Uses the attributes RiskyAvgTrue and RiskyStdTrue if RiskyAvg is time-varying, @@ -366,7 +366,7 @@ def getRisky(self): mu, sigma, seed=self.RNG.randint(0, 2 ** 31 - 1) ).draw(1) - def getAdjust(self): + def get_Adjust(self): """ Sets the attribute AdjustNow as a boolean array of size AgentCount, indicating whether each agent is able to adjust their risky portfolio share this period. @@ -384,7 +384,7 @@ def getAdjust(self): self.AdjustPrb, seed=self.RNG.randint(0, 2 ** 31 - 1) ).draw(self.AgentCount) - def getRfree(self): + def get_Rfree(self): """ Calculates realized return factor for each agent, using the attributes Rfree, RiskyNow, and ShareNow. This method is a bit of a misnomer, as the return @@ -460,8 +460,8 @@ def get_shocks(self): None """ IndShockConsumerType.get_shocks(self) - self.getRisky() - self.getAdjust() + self.get_Risky() + self.get_Adjust() def get_controls(self): """ diff --git a/HARK/ConsumptionSaving/ConsPrefShockModel.py b/HARK/ConsumptionSaving/ConsPrefShockModel.py index 331bd10ed..feb294e37 100644 --- a/HARK/ConsumptionSaving/ConsPrefShockModel.py +++ b/HARK/ConsumptionSaving/ConsPrefShockModel.py @@ -89,7 +89,7 @@ def __init__(self, cycles=1, **kwds): self.solve_one_period = make_one_period_oo_solver(ConsPrefShockSolver) def pre_solve(self): - self.updateSolutionTerminal() + self.update_solution_terminal() def update(self): """ @@ -108,9 +108,9 @@ def update(self): IndShockConsumerType.update( self ) # Update assets grid, income process, terminal solution - self.updatePrefShockProcess() # Update the discrete preference shock process + self.update_pref_shock_process() # Update the discrete preference shock process - def updatePrefShockProcess(self): + def update_pref_shock_process(self): """ Make a discrete preference shock structure for each period in the cycle for this agent type, storing them as attributes of self for use in the @@ -203,7 +203,7 @@ def get_controls(self): self.controls['cNrm'] = cNrmNow return None - def calcBoundingValues(self): + def calc_bounding_values(self): """ Calculate human wealth plus minimum and maximum MPC in an infinite horizon model with only one period repeated indefinitely. Store results @@ -224,7 +224,7 @@ def calcBoundingValues(self): """ raise NotImplementedError() - def makeEulerErrorFunc(self, mMax=100, approx_inc_dstn=True): + def make_euler_error_func(self, mMax=100, approx_inc_dstn=True): """ Creates a "normalized Euler error" function for this instance, mapping from market resources to "consumption error per dollar of consumption." @@ -281,10 +281,10 @@ def __init__(self, cycles=1, **kwds): self.del_from_time_inv("Rfree") def pre_solve(self): - self.updateSolutionTerminal() + self.update_solution_terminal() - def getRfree(self): # Specify which getRfree to use - return KinkedRconsumerType.getRfree(self) + def get_Rfree(self): # Specify which get_Rfree to use + return KinkedRconsumerType.get_Rfree(self) ############################################################################### @@ -415,7 +415,7 @@ def get_points_for_interpolation(self, EndOfPrdvP, aNrmNow): ) return c_for_interpolation, m_for_interpolation - def usePointsForInterpolation(self, cNrm, mNrm, interpolator): + def use_points_for_interpolation(self, cNrm, mNrm, interpolator): """ Make a basic solution object with a consumption function and marginal value function (unconditional on the preference shock). @@ -472,7 +472,7 @@ def usePointsForInterpolation(self, cNrm, mNrm, interpolator): ) return solution_now - def makevFunc(self, solution): + def make_vFunc(self, solution): """ Make the beginning-of-period value function (unconditional on the shock). @@ -520,7 +520,7 @@ def makevFunc(self, solution): return vFuncNow -def solveConsPrefShock( +def solve_ConsPrefShock( solution_next, IncShkDstn, PrefShkDstn, @@ -602,7 +602,7 @@ def solveConsPrefShock( vFuncBool, CubicBool, ) - solver.prepareToSolve() + solver.prepare_to_solve() solution = solver.solve() return solution diff --git a/HARK/ConsumptionSaving/ConsRepAgentModel.py b/HARK/ConsumptionSaving/ConsRepAgentModel.py index 9562136a8..d67beb7ad 100644 --- a/HARK/ConsumptionSaving/ConsRepAgentModel.py +++ b/HARK/ConsumptionSaving/ConsRepAgentModel.py @@ -21,7 +21,7 @@ __all__ = ["RepAgentConsumerType", "RepAgentMarkovConsumerType"] -def solveConsRepAgent( +def solve_ConsRepAgent( solution_next, DiscFac, CRRA, IncShkDstn, CapShare, DeprFac, PermGroFac, aXtraGrid ): """ @@ -110,7 +110,7 @@ def solveConsRepAgent( return solution_now -def solveConsRepAgentMarkov( +def solve_ConsRepAgentMarkov( solution_next, MrkvArray, DiscFac, @@ -245,11 +245,11 @@ def __init__(self, **kwds): IndShockConsumerType.__init__(self, cycles=0, **params) self.AgentCount = 1 # Hardcoded, because this is rep agent - self.solve_one_period = solveConsRepAgent + self.solve_one_period = solve_ConsRepAgent self.del_from_time_inv("Rfree", "BoroCnstArt", "vFuncBool", "CubicBool") def pre_solve(self): - self.updateSolutionTerminal() + self.update_solution_terminal() def get_states(self): """ @@ -308,17 +308,17 @@ def __init__(self, **kwds): params.update(kwds) RepAgentConsumerType.__init__(self, **params) - self.solve_one_period = solveConsRepAgentMarkov + self.solve_one_period = solve_ConsRepAgentMarkov def pre_solve(self): - self.updateSolutionTerminal() + self.update_solution_terminal() def initialize_sim(self): #self.shocks["Mrkv"] = np.zeros(self.AgentCount, dtype=int) RepAgentConsumerType.initialize_sim(self) self.shocks["Mrkv"] = self.Mrkv - def updateSolutionTerminal(self): + def update_solution_terminal(self): """ Update the terminal period solution. This method should be run when a new AgentType is created or when CRRA changes. @@ -331,7 +331,7 @@ def updateSolutionTerminal(self): ------- None """ - RepAgentConsumerType.updateSolutionTerminal(self) + RepAgentConsumerType.update_solution_terminal(self) # Make replicated terminal period solution StateCount = self.MrkvArray.shape[0] diff --git a/HARK/ConsumptionSaving/TractableBufferStockModel.py b/HARK/ConsumptionSaving/TractableBufferStockModel.py index 3d3ecf764..9ffda0068 100644 --- a/HARK/ConsumptionSaving/TractableBufferStockModel.py +++ b/HARK/ConsumptionSaving/TractableBufferStockModel.py @@ -101,7 +101,7 @@ def __init__( # that captures the notion that the process is over when no points are added. -def findNextPoint( +def find_next_point( DiscFac, Rfree, CRRA, @@ -175,7 +175,7 @@ def findNextPoint( return mNow, cNow, MPCnow -def addToStableArmPoints( +def add_to_stable_arm_points( solution_next, DiscFac, Rfree, @@ -242,7 +242,7 @@ def addToStableArmPoints( MPCNext = solution_next.MPC_list[-1] # Calculate employed levels of c, m, and MPC from next period's values - mNow, cNow, MPCnow = findNextPoint( + mNow, cNow, MPCnow = find_next_point( DiscFac, Rfree, CRRA, @@ -269,7 +269,7 @@ def addToStableArmPoints( MPCNext = solution_next.MPC_list[0] # Calculate employed levels of c, m, and MPC from next period's values - mNow, cNow, MPCnow = findNextPoint( + mNow, cNow, MPCnow = find_next_point( DiscFac, Rfree, CRRA, @@ -328,7 +328,7 @@ def __init__(self, cycles=0, **kwds): ] self.shock_vars = ["eStateNow"] self.poststate_vars = ['aLvl', "eStateNow"] # For simulation - self.solve_one_period = addToStableArmPoints # set correct solver + self.solve_one_period = add_to_stable_arm_points # set correct solver def pre_solve(self): """ diff --git a/HARK/ConsumptionSaving/tests/test_ConsAggShockModel.py b/HARK/ConsumptionSaving/tests/test_ConsAggShockModel.py index 66665d3e6..50b6ede9a 100644 --- a/HARK/ConsumptionSaving/tests/test_ConsAggShockModel.py +++ b/HARK/ConsumptionSaving/tests/test_ConsAggShockModel.py @@ -32,7 +32,7 @@ def test_distribute_params(self): def test_agent(self): # Have one consumer type inherit relevant objects from the economy, # then solve their microeconomic problem - self.agents[0].getEconomyData(self.economy) + self.agents[0].get_economy_data(self.economy) self.agents[0].solve() self.assertAlmostEqual( self.agents[0].solution[0].cFunc(10.0, self.economy.MSS), 3.229078148576943 @@ -41,12 +41,12 @@ def test_agent(self): def test_macro(self): self.economy.act_T = 400 # Short simulation history self.economy.max_loops = 3 # Give up quickly for the sake of time - self.economy.makeAggShkHist() # Simulate a history of aggregate shocks + self.economy.make_AggShkHist() # Simulate a history of aggregate shocks self.economy.verbose = False # Turn off printed messages # Give data about the economy to all the agents in it for this_type in self.economy.agents: - this_type.getEconomyData(self.economy) + this_type.get_economy_data(self.economy) self.economy.solve() # Solve for the general equilibrium of the economy self.economy.AFunc = self.economy.dynamics.AFunc @@ -69,7 +69,7 @@ def setUp(self): def test_agent(self): # Have one consumer type inherit relevant objects from the economy, # then solve their microeconomic problem - self.agent.getEconomyData(self.economy) + self.agent.get_economy_data(self.economy) self.agent.solve() self.assertAlmostEqual( self.agent.solution[0].cFunc[0](10.0, self.economy.MSS), 2.5635896520991377 @@ -81,8 +81,8 @@ def test_economy(self): self.economy.max_loops = 3 # Just quiet solving early self.economy.verbose = False # Turn off printed messages - self.agent.getEconomyData(self.economy) - self.economy.makeAggShkHist() # Make a simulated history of aggregate shocks + self.agent.get_economy_data(self.economy) + self.economy.make_AggShkHist() # Make a simulated history of aggregate shocks self.economy.solve() # Solve for the general equilibrium of the economy self.economy.AFunc = self.economy.dynamics.AFunc @@ -112,7 +112,7 @@ def teardown(self): class KrusellSmithAgentTestCase(KrusellSmithTestCase): def test_agent(self): - self.agent.getEconomyData(self.economy) + self.agent.get_economy_data(self.economy) self.agent.solve() self.assertAlmostEqual( self.agent.solution[0].cFunc[0](10.0, self.economy.MSS), 1.23867751 @@ -121,7 +121,7 @@ def test_agent(self): class KrusellSmithMethodsTestCase(KrusellSmithTestCase): def test_methods(self): - self.agent.getEconomyData(self.economy) + self.agent.get_economy_data(self.economy) self.assertAlmostEqual( self.agent.AFunc[0].slope, @@ -149,14 +149,14 @@ def test_methods(self): 816 ) - self.economy.makeMrkvHist() # Make a simulated history of aggregate shocks + self.economy.make_Mrkv_history() # Make a simulated history of aggregate shocks self.assertAlmostEqual( np.mean(self.economy.MrkvNow_hist), 0.4818181818181818 ) # object attributes that are conditions - # for preComputeArrays + # for precompute_arrays self.assertEqual( self.agent.aGrid.size, 32 @@ -168,13 +168,13 @@ def test_methods(self): self.economy.solve_agents() - # testing preComputeArrays() + # testing precompute_arrays() self.assertAlmostEqual( self.agent.mNextArray[5,2,3,0], 0.34879574548563563 ) - # testing makeGrid() + # testing make_grid() self.assertAlmostEqual( self.agent.aGrid[1], 0.05531643953496124 ) @@ -183,7 +183,7 @@ def test_methods(self): self.economy.MSS, 13.327225348792547 ) - # testing updateSolutionTerminal() + # testing update_solution_terminal() self.assertEqual( self.agent.solution_terminal.cFunc[0](10,self.economy.MSS), 10 @@ -254,8 +254,8 @@ def test_economy(self): 1.0 ) - self.agent.getEconomyData(self.economy) - self.economy.makeMrkvHist() # Make a simulated history of aggregate shocks + self.agent.get_economy_data(self.economy) + self.economy.make_Mrkv_history() # Make a simulated history of aggregate shocks self.economy.solve() # Solve for the general equilibrium of the economy self.economy.AFunc = self.economy.dynamics.AFunc diff --git a/HARK/ConsumptionSaving/tests/test_ConsMarkovModel.py b/HARK/ConsumptionSaving/tests/test_ConsMarkovModel.py index a8aee1949..01217c76b 100644 --- a/HARK/ConsumptionSaving/tests/test_ConsMarkovModel.py +++ b/HARK/ConsumptionSaving/tests/test_ConsMarkovModel.py @@ -74,23 +74,23 @@ def setUp(self): ] ] - def test_checkMarkovInputs(self): + def test_check_markov_inputs(self): # check Rfree - self.assertRaises(ValueError, self.model.checkMarkovInputs) + self.assertRaises(ValueError, self.model.check_markov_inputs) # fix Rfree self.model.Rfree = np.array(4 * [self.model.Rfree]) # check MrkvArray, first mess up the setup self.MrkvArray = self.model.MrkvArray self.model.MrkvArray = np.random.rand(3, 3) - self.assertRaises(ValueError, self.model.checkMarkovInputs) + self.assertRaises(ValueError, self.model.check_markov_inputs) # then fix it back self.model.MrkvArray = self.MrkvArray # check LivPrb - self.assertRaises(ValueError, self.model.checkMarkovInputs) + self.assertRaises(ValueError, self.model.check_markov_inputs) # fix LivPrb self.model.LivPrb = [np.array(4 * self.model.LivPrb)] # check PermGroFac - self.assertRaises(ValueError, self.model.checkMarkovInputs) + self.assertRaises(ValueError, self.model.check_markov_inputs) # fix PermGroFac self.model.PermGroFac = [np.array(4 * self.model.PermGroFac)] diff --git a/HARK/ConsumptionSaving/tests/test_IndShockConsumerType.py b/HARK/ConsumptionSaving/tests/test_IndShockConsumerType.py index 6e645a2e4..a9ac28540 100644 --- a/HARK/ConsumptionSaving/tests/test_IndShockConsumerType.py +++ b/HARK/ConsumptionSaving/tests/test_IndShockConsumerType.py @@ -63,23 +63,23 @@ def test_ConsIndShockSolverBasic(self): LifecycleExample.CubicBool, ) - solver.prepareToSolve() + solver.prepare_to_solve() self.assertAlmostEqual(solver.DiscFacEff, 0.9586233599999999) self.assertAlmostEqual(solver.PermShkMinNext, 0.9037554719886154) self.assertAlmostEqual(solver.cFuncNowCnst(4).tolist(), 4.0) - self.assertAlmostEqual(solver.prepareToCalcEndOfPrdvP()[0], -0.2732742703949109) - self.assertAlmostEqual(solver.prepareToCalcEndOfPrdvP()[-1], 19.72572572960506) + self.assertAlmostEqual(solver.prepare_to_calc_EndOfPrdvP()[0], -0.2732742703949109) + self.assertAlmostEqual(solver.prepare_to_calc_EndOfPrdvP()[-1], 19.72572572960506) - EndOfPrdvP = solver.calcEndOfPrdvP() + EndOfPrdvP = solver.calc_EndOfPrdvP() self.assertAlmostEqual(EndOfPrdvP[0], 6710.672670733023) self.assertAlmostEqual(EndOfPrdvP[-1], 0.14122987153089447) - solution = solver.makeBasicSolution( - EndOfPrdvP, solver.aNrmNow, solver.makeLinearcFunc + solution = solver.make_basic_solution( + EndOfPrdvP, solver.aNrmNow, solver.make_linear_cFunc ) - solver.addMPCandHumanWealth(solution) + solver.add_MPC_and_human_wealth(solution) self.assertAlmostEqual(solution.cFunc(4).tolist(), 1.484118342351686) diff --git a/HARK/ConsumptionSaving/tests/test_IndShockConsumerTypeFast.py b/HARK/ConsumptionSaving/tests/test_IndShockConsumerTypeFast.py index 9c25a15ce..d14ad0310 100644 --- a/HARK/ConsumptionSaving/tests/test_IndShockConsumerTypeFast.py +++ b/HARK/ConsumptionSaving/tests/test_IndShockConsumerTypeFast.py @@ -89,7 +89,7 @@ def test_baseEx(self): baseEx.cycles = 100 # Make this type have a finite horizon (Set T = 100) baseEx.solve() - baseEx.unpackcFunc() + baseEx.unpack_cFunc() m = np.linspace(0, 9.5, 1000) @@ -116,7 +116,7 @@ def test_GICRawFails(self): ) GICRawFailExample.solve() - GICRawFailExample.unpackcFunc() + GICRawFailExample.unpack_cFunc() m = np.linspace(0, 5, 1000) c_m = GICRawFailExample.cFunc[0](m) @@ -129,7 +129,7 @@ def test_infinite_horizon(self): baseEx_inf = IndShockConsumerTypeFast(cycles=0, **self.base_params) baseEx_inf.solve() - baseEx_inf.unpackcFunc() + baseEx_inf.unpack_cFunc() m1 = np.linspace( 1, baseEx_inf.solution[0].mNrmStE, 50 diff --git a/HARK/ConsumptionSaving/tests/test_SmallOpenEconomy.py b/HARK/ConsumptionSaving/tests/test_SmallOpenEconomy.py index 54489433b..9b4ca9d78 100644 --- a/HARK/ConsumptionSaving/tests/test_SmallOpenEconomy.py +++ b/HARK/ConsumptionSaving/tests/test_SmallOpenEconomy.py @@ -32,11 +32,11 @@ def test_small_open(self): small_economy.act_T = 400 # Short simulation history small_economy.max_loops = 3 # Give up quickly for the sake of time - small_economy.makeAggShkHist() # Simulate a history of aggregate shocks + small_economy.make_AggShkHist() # Simulate a history of aggregate shocks small_economy.verbose = False # Turn off printed messages # Give data about the economy to all the agents in it for this_type in small_economy.agents: - this_type.getEconomyData(small_economy) + this_type.get_economy_data(small_economy) small_economy.solve() diff --git a/HARK/ConsumptionSaving/tests/test_modelcomparisons.py b/HARK/ConsumptionSaving/tests/test_modelcomparisons.py index 34b4b2262..8ccafe94e 100644 --- a/HARK/ConsumptionSaving/tests/test_modelcomparisons.py +++ b/HARK/ConsumptionSaving/tests/test_modelcomparisons.py @@ -51,7 +51,7 @@ def setUp(self): InfiniteType = IndShockConsumerType(**test_dictionary) InfiniteType.cycles = 0 - InfiniteType.updateIncomeProcess() + InfiniteType.update_income_process() InfiniteType.solve() InfiniteType.unpack("cFunc") diff --git a/HARK/core.py b/HARK/core.py index 624b053c6..d200c499a 100644 --- a/HARK/core.py +++ b/HARK/core.py @@ -1060,8 +1060,8 @@ def one_period_solver(**kwds): solver = solver_class(**kwds) # not ideal; better if this is defined in all Solver classes - if hasattr(solver, "prepareToSolve"): - solver.prepareToSolve() + if hasattr(solver, "prepare_to_solve"): + solver.prepare_to_solve() solution_now = solver.solve() return solution_now @@ -1304,9 +1304,9 @@ def mill(self): def cultivate(self): """ - Has each AgentType in agents perform their marketAction method, using + Has each AgentType in agents perform their market_action method, using variables sown from the market (and maybe also "private" variables). - The marketAction method should store new results in attributes named in + The market_action method should store new results in attributes named in reap_vars to be reaped later. Parameters @@ -1318,7 +1318,7 @@ def cultivate(self): none """ for this_type in self.agents: - this_type.marketAction() + this_type.market_action() def reset(self): """