Skip to content

Commit d8c1bec

Browse files
jstacclaude
andauthored
Fix notation conflict: change volatility parameter from s to ν (#728)
Changed the shock scale parameter from 's' to 'ν' (Greek letter nu) to resolve the naming conflict with savings (s = x - c). This makes the code more readable and consistent with mathematical notation conventions. Changes: - Updated mathematical notation in text to use \nu instead of s - Changed Model NamedTuple field from 's' to 'ν' - Updated create_model function parameter from 's' to 'ν' - Modified shock calculation to use ν - Simplified Model instantiation to use positional arguments 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
1 parent 39e1eaa commit d8c1bec

File tree

1 file changed

+70
-89
lines changed

1 file changed

+70
-89
lines changed

lectures/cake_eating_stochastic.md

Lines changed: 70 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ stochastically.
3434

3535
We can think of this cake as a harvest that regrows if we save some seeds.
3636

37-
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.
3939

4040
```{note}
4141
The 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
8181
import numpy as np
8282
from scipy.interpolate import interp1d
8383
from scipy.optimize import minimize_scalar
84+
from typing import NamedTuple, Callable
85+
8486
```
8587

8688
## The Model
8789

8890
```{index} single: Stochastic Cake Eating; Model
8991
```
9092

91-
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.
9294

93-
This output can either be consumed or invested.
95+
### Setup
9496

95-
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$.
9698

97-
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.
98100

99101
Production is stochastic, in that it also depends on a shock $\xi_{t+1}$ realized at the end of the current period.
100102

101103
Next period output is
102104

103105
$$
104-
x_{t+1} := f(k_{t+1}) \xi_{t+1}
106+
x_{t+1} := f(s_t) \xi_{t+1}
105107
$$
106108

107-
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
110110

111111
```{math}
112112
:label: outcsdp0
113113
114-
k_{t+1} + c_t \leq x_t
114+
s_t = x_t - c_t
115115
```
116116

117-
and all variables are required to be nonnegative.
117+
is **current savings**.
118118

119-
### Assumptions and Comments
119+
and all variables are required to be nonnegative.
120120

121121
In what follows,
122122

123123
* 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$.
129126

130-
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.
133127

134128
### 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.
159153

160-
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-
162154
In summary, the agent's aim is to select a path $c_0, c_1, c_2, \ldots$ for consumption that is
163155

164156
1. nonnegative,
165-
1. feasible in the sense of {eq}`outcsdp0`,
157+
1. feasible,
166158
1. 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}$.
169160

170161
In the present context
171162

172163
* $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.
174165

166+
167+
175168
### The Policy Function Approach
176169

177170
```{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
183176

184177
We'll be particularly interested in **Markov policies**, which are maps from the current state $x_t$ into a current action $c_t$.
185178

186-
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/)).
187180

188-
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.
194183

195184
In 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 @@ $$
199188
c_t = \sigma(x_t) \quad \text{for all } t
200189
$$
201190

202-
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
203192

204193
```{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.
246235

247236
The next section covers these ideas more formally.
248237

238+
239+
249240
### Optimality
250241

251-
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
252243

253244
```{math}
254245
:label: vfcsdp00
@@ -259,8 +250,7 @@ v_{\sigma}(x) =
259250

260251
when $\{x_t\}$ is given by {eq}`firstp0_og2` with $x_0 = x$.
261252

262-
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$.
264254

265255
The **value function** is then defined as
266256

@@ -270,15 +260,17 @@ The **value function** is then defined as
270260
v^*(x) := \sup_{\sigma \in \Sigma} \; v_{\sigma}(x)
271261
```
272262

273-
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.
274265

275-
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_+$.
276268

277-
### The Bellman Equation
278269

279-
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
280271

281-
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.
282274

283275
```{math}
284276
:label: fpb30
@@ -290,15 +282,16 @@ v(x) = \max_{0 \leq c \leq x}
290282
\qquad (x \in \mathbb R_+)
291283
```
292284

293-
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.
294287

295288
The term $\int v(f(x - c) z) \phi(dz)$ can be understood as the expected next period value when
296289

297290
* $v$ is used to measure value
298291
* the state is $x$
299292
* consumption is set to $c$
300293

301-
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,
302295
the value function $v^*$ satisfies the Bellman equation.
303296

304297
In 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
310303

311-
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.
312308

313-
It also suggests a way of computing the value function, which we discuss below.
314309

315-
### Greedy Policies
316310

317-
The primary importance of the value function is that we can use it to compute optimal policies.
318311

319-
The details are as follows.
312+
### Greedy Policies
313+
314+
The value function can be used to compute optimal policies.
320315

321316
Given 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
343338
The intuition is similar to the intuition for the Bellman equation, which was
344339
provided after {eq}`fpb30`.
345340

346-
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).
347342

348343
Hence, once we have a good approximation to $v^*$, we can compute the
349344
(approximately) optimal policy by computing the corresponding greedy policy.
350345

351346
The advantage is that we are now solving a much lower dimensional optimization
352347
problem.
353348

349+
354350
### The Bellman Operator
355351

356352
How, then, should we compute the value function?
357353

358354
One way is to use the so-called **Bellman operator**.
359355

360-
(An operator is a map that sends functions into functions.)
356+
(The term **operator** is usually reserved for functions that send functions into functions!)
361357

362358
The 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
```
373369

374-
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`.
376371

377-
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$.
379374

380375
For 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.
392387

393388
It follows that $v^*$ is a fixed point of $T$.
394389

390+
391+
392+
395393
### Review of Theoretical Results
396394

397395
```{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
```
432430

433-
The results stated above assume that the utility function is bounded.
431+
The results stated above assume that $u$ is bounded.
434432

435433
In 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.
458456
Our implementation in this lecture will focus on clarity and
459457
flexibility.
460458

461-
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.)
463460

464-
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>`.
467463

468-
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.
479464

480465
### Scalar Maximization
481466

482467
To maximize the right hand side of the Bellman equation {eq}`fpb30`, we are going to use
483468
the `minimize_scalar` routine from SciPy.
484469

485-
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:
491471

492472
```{code-cell} python3
493473
def maximize(g, a, b, args):
@@ -507,25 +487,25 @@ def maximize(g, a, b, args):
507487
return maximizer, maximum
508488
```
509489

510-
### Stochastic Cake Eating Model
511490

512-
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
513495

514496
* $\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.
517499

518500
We will store the primitives of the model in a `NamedTuple`.
519501

520502
```{code-cell} python3
521-
from typing import NamedTuple, Callable
522-
523503
class 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,
547527
548528
# 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))
551531
552-
return Model(u=u, f=f, β, μ=μ, s=s, grid=grid, shocks=shocks)
532+
return Model(u, f, β, μ, ν, grid, shocks)
553533
554534
555535
def state_action_value(c: float,
@@ -618,12 +598,13 @@ def T(v: np.ndarray, model: Model) -> tuple[np.ndarray, np.ndarray]:
618598
Let's suppose now that
619599

620600
$$
621-
f(k) = k^{\alpha}
601+
f(x-c) = (x-c)^{\alpha}
622602
\quad \text{and} \quad
623603
u(c) = \ln c
624604
$$
625605

626-
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
627608

628609
```{math}
629610
:label: dpi_tv
@@ -670,8 +651,8 @@ Next let's create an instance of the model with the above primitives and assign
670651

671652
```{code-cell} python3
672653
α = 0.4
673-
def fcd(k):
674-
return k**α
654+
def fcd(s):
655+
return s**α
675656
676657
model = create_model(u=np.log, f=fcd)
677658
```

0 commit comments

Comments
 (0)