@@ -34,8 +34,8 @@ stochastically.
34343535We can think of this cake as a harvest that regrows if we save some seeds.
363637-Specifically, if we save (invest) part of today's cake, it grows into next
38-period's cake according to a stochastic production process.
37+Specifically, if we save and invest part of today's harvest $x_t$, it grows into next
38+period's harvest $x_{t+1}$ according to a stochastic production process.
39394040```{note}
4141The term "cake eating" is not such a good fit now that we have a stochastic and
@@ -81,55 +81,49 @@ import matplotlib.pyplot as plt
8181import numpy as np
8282from scipy.interpolate import interp1d
8383from scipy.optimize import minimize_scalar
84+from typing import NamedTuple, Callable
85+8486```
85878688## The Model
87898890```{index} single: Stochastic Cake Eating; Model
8991```
909291-Consider an agent who owns an amount $x_t \in \mathbb R_+ := [0, \infty)$ of a consumption good at time $t$.
93+Here we described the new model and the optimization problem.
929493-This output can either be consumed or invested.
95+### Setup
949695-When the good is invested, it is transformed one-for-one into capital.
97+Consider an agent who owns an amount $x_t \in \mathbb R_+ := [0, \infty)$ of a consumption good at time $t$.
969897-The resulting capital stock, denoted here by $k_{t+1}$, will then be used for production.
99+This output can either be consumed or saved and used for production.
9810099101Production is stochastic, in that it also depends on a shock $\xi_{t+1}$ realized at the end of the current period.
100102101103Next period output is
102104103105$$
104-x_{t+1} := f(k_{t+1}) \xi_{t+1}
106+x_{t+1} := f(s_t) \xi_{t+1}
105107$$
106108107-where $f \colon \mathbb R_+ \to \mathbb R_+$ is called the production function.
108-109-The resource constraint is
109+where $f \colon \mathbb R_+ \to \mathbb R_+$ is the **production function** and
110110111111```{math}
112112:label: outcsdp0
113113114-k_{t+1} + c_t \leq x_t
114+s_t = x_t - c_t
115115```
116116117-and all variables are required to be nonnegative.
117+is **current savings**.
118118119-### Assumptions and Comments
119+and all variables are required to be nonnegative.
120120121121In what follows,
122122123123* The sequence $\{\xi_t\}$ is assumed to be IID.
124124* The common distribution of each $\xi_t$ will be denoted by $\phi$.
125125* The production function $f$ is assumed to be increasing and continuous.
126-* Depreciation of capital is not made explicit but can be incorporated into the production function.
127-128-While many other treatments of stochastic consumption-saving models use $k_t$ as the state variable, we will use $x_t$.
129126130-This will allow us to treat a stochastic model while maintaining only one state variable.
131-132-We consider alternative states and timing specifications in some of our other lectures.
133127134128### Optimization
135129@@ -157,21 +151,20 @@ where
157151* $u$ is a bounded, continuous and strictly increasing utility function and
158152* $\beta \in (0, 1)$ is a discount factor.
159153160-In {eq}`og_conse` we are assuming that the resource constraint {eq}`outcsdp0` holds with equality --- which is reasonable because $u$ is strictly increasing and no output will be wasted at the optimum.
161-162154In summary, the agent's aim is to select a path $c_0, c_1, c_2, \ldots$ for consumption that is
1631551641561. nonnegative,
165-1. feasible in the sense of {eq}`outcsdp0`,
157+1. feasible,
1661581. optimal, in the sense that it maximizes {eq}`texs0_og2` relative to all other feasible consumption sequences, and
167-1. **adapted**, in the sense that the action $c_t$ depends only on
168- observable outcomes, not on future outcomes such as $\xi_{t+1}$.
159+1. **adapted**, in the sense that the current action $c_t$ depends only on current and historical outcomes, not on future outcomes such as $\xi_{t+1}$.
169160170161In the present context
171162172163* $x_t$ is called the **state** variable --- it summarizes the "state of the world" at the start of each period.
173164* $c_t$ is called the **control** variable --- a value chosen by the agent each period after observing the state.
174165166+167+175168### The Policy Function Approach
176169177170```{index} single: Stochastic Cake Eating; Policy Function Approach
@@ -183,14 +176,10 @@ A policy function is a map from past and present observables into current action
183176184177We'll be particularly interested in **Markov policies**, which are maps from the current state $x_t$ into a current action $c_t$.
185178186-For dynamic programming problems such as this one (in fact for any [Markov decision process](https://en.wikipedia.org/wiki/Markov_decision_process)), the optimal policy is always a Markov policy.
179+For dynamic programming problems such as this one, the optimal policy is always a Markov policy (see, e.g., [DP1](https://dp.quantecon.org/)).
187180188-In other words, the current state $x_t$ provides a [sufficient statistic](https://en.wikipedia.org/wiki/Sufficient_statistic)
189-for the history in terms of making an optimal decision today.
190-191-This is quite intuitive, but if you wish you can find proofs in texts such as {cite}`StokeyLucas1989` (section 4.1).
192-193-Hereafter we focus on finding the best Markov policy.
181+In other words, the current state $x_t$ provides a sufficient statistic for the history
182+in terms of making an optimal decision today.
194183195184In our context, a Markov policy is a function $\sigma \colon
196185\mathbb R_+ \to \mathbb R_+$, with the understanding that states are mapped to actions via
@@ -199,7 +188,7 @@ $$
199188c_t = \sigma(x_t) \quad \text{for all } t
200189$$
201190202-In what follows, we will call $\sigma$ a *feasible consumption policy* if it satisfies
191+In what follows, we will call $\sigma$ a **feasible consumption policy** if it satisfies
203192204193```{math}
205194:label: idp_fp_og2
@@ -246,9 +235,11 @@ The aim is to select a policy that makes this number as large as possible.
246235247236The next section covers these ideas more formally.
248237238+239+249240### Optimality
250241251-The $\sigma$ associated with a given policy $\sigma$ is the mapping defined by
242+The lifetime value $v_{\sigma}$ associated with a given policy $\sigma$ is the mapping defined by
252243253244```{math}
254245:label: vfcsdp00
@@ -259,8 +250,7 @@ v_{\sigma}(x) =
259250260251when $\{x_t\}$ is given by {eq}`firstp0_og2` with $x_0 = x$.
261252262-In other words, it is the lifetime value of following policy $\sigma$
263-starting at initial condition $x$.
253+In other words, it is the lifetime value of following policy $\sigma$ forever, starting at initial condition $x$.
264254265255The **value function** is then defined as
266256@@ -270,15 +260,17 @@ The **value function** is then defined as
270260v^*(x) := \sup_{\sigma \in \Sigma} \; v_{\sigma}(x)
271261```
272262273-The value function gives the maximal value that can be obtained from state $x$, after considering all feasible policies.
263+The value function gives the maximal value that can be obtained from state $x$,
264+after considering all feasible policies.
274265275-A policy $\sigma \in \Sigma$ is called **optimal** if it attains the supremum in {eq}`vfcsdp0` for all $x \in \mathbb R_+$.
266+A policy $\sigma \in \Sigma$ is called **optimal** if it attains the supremum in
267+{eq}`vfcsdp0` for all $x \in \mathbb R_+$.
276268277-### The Bellman Equation
278269279-With our assumptions on utility and production functions, the value function as defined in {eq}`vfcsdp0` also satisfies a **Bellman equation**.
270+### The Bellman Equation
280271281-For this problem, the Bellman equation takes the form
272+The following equation is called the **Bellman equation** associated with this
273+dynamic programming problem.
282274283275```{math}
284276:label: fpb30
@@ -290,15 +282,16 @@ v(x) = \max_{0 \leq c \leq x}
290282\qquad (x \in \mathbb R_+)
291283```
292284293-This is a *functional equation in* $v$.
285+This is a *functional equation in* $v$, in the sense that a given $v$ can either
286+satisfy it or not satisfy it.
294287295288The term $\int v(f(x - c) z) \phi(dz)$ can be understood as the expected next period value when
296289297290* $v$ is used to measure value
298291* the state is $x$
299292* consumption is set to $c$
300293301-As shown in [EDTC](https://johnstachurski.net/edtc.html), theorem 10.1.11 and a range of other texts,
294+As shown in [EDTC](https://johnstachurski.net/edtc.html), Theorem 10.1.11 and a range of other texts,
302295the value function $v^*$ satisfies the Bellman equation.
303296304297In other words, {eq}`fpb30` holds when $v=v^*$.
@@ -308,15 +301,17 @@ The intuition is that maximal value from a given state can be obtained by optima
308301* current reward from a given action, vs
309302* expected discounted future value of the state resulting from that action
310303311-The Bellman equation is important because it gives us more information about the value function.
304+The Bellman equation is important because it
305+306+1. gives us more information about the value function and
307+2. suggests a way of computing the value function, which we discuss below.
312308313-It also suggests a way of computing the value function, which we discuss below.
314309315-### Greedy Policies
316310317-The primary importance of the value function is that we can use it to compute optimal policies.
318311319-The details are as follows.
312+### Greedy Policies
313+314+The value function can be used to compute optimal policies.
320315321316Given a continuous function $v$ on $\mathbb R_+$, we say that
322317$\sigma \in \Sigma$ is $v$-**greedy** if $\sigma(x)$ is a solution to
@@ -343,21 +338,22 @@ In our setting, we have the following key result
343338The intuition is similar to the intuition for the Bellman equation, which was
344339provided after {eq}`fpb30`.
345340346-See, for example, theorem 10.1.11 of [EDTC](https://johnstachurski.net/edtc.html).
341+See, for example, Theorem 10.1.11 of [EDTC](https://johnstachurski.net/edtc.html).
347342348343Hence, once we have a good approximation to $v^*$, we can compute the
349344(approximately) optimal policy by computing the corresponding greedy policy.
350345351346The advantage is that we are now solving a much lower dimensional optimization
352347problem.
353348349+354350### The Bellman Operator
355351356352How, then, should we compute the value function?
357353358354One way is to use the so-called **Bellman operator**.
359355360-(An operator is a map that sends functions into functions.)
356+(The term **operator** is usually reserved for functions that send functions into functions!)
361357362358The Bellman operator is denoted by $T$ and defined by
363359@@ -371,11 +367,10 @@ Tv(x) := \max_{0 \leq c \leq x}
371367\qquad (x \in \mathbb R_+)
372368```
373369374-In other words, $T$ sends the function $v$ into the new function
375-$Tv$ defined by {eq}`fcbell20_optgrowth`.
370+In other words, $T$ sends the function $v$ into the new function $Tv$ defined by {eq}`fcbell20_optgrowth`.
376371377-By construction, the set of solutions to the Bellman equation
378-{eq}`fpb30` *exactly coincides with* the set of fixed points of $T$.
372+By construction, the set of solutions to the Bellman equation {eq}`fpb30`
373+*exactly coincides with* the set of fixed points of $T$.
379374380375For example, if $Tv = v$, then, for any $x \geq 0$,
381376@@ -392,6 +387,9 @@ which says precisely that $v$ is a solution to the Bellman equation.
392387393388It follows that $v^*$ is a fixed point of $T$.
394389390+391+392+395393### Review of Theoretical Results
396394397395```{index} single: Dynamic Programming; Theory
@@ -430,7 +428,7 @@ Our problem now is how to compute it.
430428```{index} single: Dynamic Programming; Unbounded Utility
431429```
432430433-The results stated above assume that the utility function is bounded.
431+The results stated above assume that $u$ is bounded.
434432435433In practice economists often work with unbounded utility functions --- and so will we.
436434@@ -458,36 +456,18 @@ Let's now look at computing the value function and the optimal policy.
458456Our implementation in this lecture will focus on clarity and
459457flexibility.
460458461-Both of these things are helpful, but they do cost us some speed --- as you
462-will see when you run the code.
459+(In subsequent lectures we will focus on efficiency and speed.)
463460464-The algorithm we will use is fitted value function iteration, which was
465-described in earlier lectures {doc}`the McCall model <mccall_fitted_vfi>` and
466-{doc}`cake eating <cake_eating_numerical>`.
461+We will use fitted value function iteration, which was
462+already described in {doc}`cake eating <cake_eating_numerical>`.
467463468-The algorithm will be
469-470-(fvi_alg)=
471-1. Begin with an array of values $\{ v_1, \ldots, v_I \}$ representing
472- the values of some initial function $v$ on the grid points $\{ x_1, \ldots, x_I \}$.
473-1. Build a function $\hat v$ on the state space $\mathbb R_+$ by
474- linear interpolation, based on these data points.
475-1. Obtain and record the value $T \hat v(x_i)$ on each grid point
476- $x_i$ by repeatedly solving {eq}`fcbell20_optgrowth`.
477-1. Unless some stopping condition is satisfied, set
478- $\{ v_1, \ldots, v_I \} = \{ T \hat v(x_1), \ldots, T \hat v(x_I) \}$ and go to step 2.
479464480465### Scalar Maximization
481466482467To maximize the right hand side of the Bellman equation {eq}`fpb30`, we are going to use
483468the `minimize_scalar` routine from SciPy.
484469485-Since we are maximizing rather than minimizing, we will use the fact that the
486-maximizer of $g$ on the interval $[a, b]$ is the minimizer of
487-$-g$ on the same interval.
488-489-To this end, and to keep the interface tidy, we will wrap `minimize_scalar`
490-in an outer function as follows:
470+To keep the interface tidy, we will wrap `minimize_scalar` in an outer function as follows:
491471492472```{code-cell} python3
493473def maximize(g, a, b, args):
@@ -507,25 +487,25 @@ def maximize(g, a, b, args):
507487 return maximizer, maximum
508488```
509489510-### Stochastic Cake Eating Model
511490512-We will assume for now that $\phi$ is the distribution of $\xi := \exp(\mu + s \zeta)$ where
491+492+### Model
493+494+We will assume for now that $\phi$ is the distribution of $\xi := \exp(\mu + \nu \zeta)$ where
513495514496* $\zeta$ is standard normal,
515497* $\mu$ is a shock location parameter and
516-* $s$ is a shock scale parameter.
498+* $\nu$ is a shock scale parameter.
517499518500We will store the primitives of the model in a `NamedTuple`.
519501520502```{code-cell} python3
521-from typing import NamedTuple, Callable
522-523503class Model(NamedTuple):
524504 u: Callable # utility function
525505 f: Callable # production function
526506 β: float # discount factor
527507 μ: float # shock location parameter
528- s: float # shock scale parameter
508+ ν: float # shock scale parameter
529509 grid: np.ndarray # state grid
530510 shocks: np.ndarray # shock draws
531511@@ -534,7 +514,7 @@ def create_model(u: Callable,
534514 f: Callable,
535515 β: float = 0.96,
536516 μ: float = 0.0,
537- s: float = 0.1,
517+ ν: float = 0.1,
538518 grid_max: float = 4.0,
539519 grid_size: int = 120,
540520 shock_size: int = 250,
@@ -547,9 +527,9 @@ def create_model(u: Callable,
547527548528 # Store shocks (with a seed, so results are reproducible)
549529 np.random.seed(seed)
550- shocks = np.exp(μ + s * np.random.randn(shock_size))
530+ shocks = np.exp(μ + ν * np.random.randn(shock_size))
551531552- return Model(u=u, f=f, β=β, μ=μ, s=s, grid=grid, shocks=shocks)
532+ return Model(u, f, β, μ, ν, grid, shocks)
553533554534555535def state_action_value(c: float,
@@ -618,12 +598,13 @@ def T(v: np.ndarray, model: Model) -> tuple[np.ndarray, np.ndarray]:
618598Let's suppose now that
619599620600$$
621-f(k) = k^{\alpha}
601+f(x-c) = (x-c)^{\alpha}
622602\quad \text{and} \quad
623603u(c) = \ln c
624604$$
625605626-For this particular problem, an exact analytical solution is available (see {cite}`Ljungqvist2012`, section 3.1.2), with
606+For this particular problem, an exact analytical solution is available (see
607+{cite}`Ljungqvist2012`, section 3.1.2), with
627608628609```{math}
629610:label: dpi_tv
@@ -670,8 +651,8 @@ Next let's create an instance of the model with the above primitives and assign
670651671652```{code-cell} python3
672653α = 0.4
673-def fcd(k):
674- return k**α
654+def fcd(s):
655+ return s**α
675656676657model = create_model(u=np.log, f=fcd)
677658```