Skip to content

Commit 8a84067

Browse files
committed
misc
1 parent 8cce1a7 commit 8a84067

File tree

1 file changed

+52
-52
lines changed

1 file changed

+52
-52
lines changed

lectures/lake_model.md

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -210,47 +210,36 @@ This follows from the fact that the columns of $R$ sum to 1.
210210

211211
Let's code up these equations.
212212

213-
To do this we're going to use a class that we'll call `LakeModel` that stores the primitives $\alpha, \lambda, b, d$
213+
### Model
214+
215+
To begin, we set up a class called `LakeModel` that stores the primitives $\alpha, \lambda, b, d$.
214216

215217
```{code-cell} ipython3
216218
class LakeModel(NamedTuple):
217219
"""
218220
Parameters for the lake model
219221
"""
220-
λ: float = 0.283
221-
α: float = 0.013
222-
b: float = 0.0124
223-
d: float = 0.00822
224-
A: jnp.ndarray = None
225-
R: jnp.ndarray = None
226-
g: float = None
227-
228-
229-
def create_lake_model(λ: float = 0.283,
230-
α: float = 0.013,
231-
b: float = 0.0124,
232-
d: float = 0.00822) -> LakeModel:
222+
λ: float
223+
α: float
224+
b: float
225+
d: float
226+
A: jnp.ndarray
227+
R: jnp.ndarray
228+
g: float
229+
230+
231+
def create_lake_model(
232+
λ: float = 0.283, # job finding rate
233+
α: float = 0.013, # separation rate
234+
b: float = 0.0124, # birth rate
235+
d: float = 0.00822 # death rate
236+
) -> LakeModel:
233237
"""
234238
Create a LakeModel instance with default parameters.
235239
236240
Computes and stores the transition matrices A and R,
237241
and the labor force growth rate g.
238242
239-
Parameters
240-
----------
241-
λ : float, optional
242-
Job finding rate (default: 0.283)
243-
α : float, optional
244-
Job separation rate (default: 0.013)
245-
b : float, optional
246-
Entry rate into labor force (default: 0.0124)
247-
d : float, optional
248-
Exit rate from labor force (default: 0.00822)
249-
250-
Returns
251-
-------
252-
LakeModel
253-
A LakeModel instance with computed matrices A, R, and growth rate g
254243
"""
255244
# Compute growth rate
256245
g = b - d
@@ -267,11 +256,33 @@ def create_lake_model(λ: float = 0.283,
267256
return LakeModel(λ=λ, α=α, b=b, d=d, A=A, R=R, g=g)
268257
```
269258

259+
As an experiment, let's create two instances, one with $α=0.013$ and another with $α=0.03$
260+
261+
```{code-cell} ipython3
262+
model = create_lake_model()
263+
print(f"Default α: {model.α}")
264+
print(f"A matrix:\n{model.A}")
265+
print(f"R matrix:\n{model.R}")
266+
```
267+
268+
```{code-cell} ipython3
269+
model_new = create_lake_model(α=0.03)
270+
print(f"New α: {model_new.α}")
271+
print(f"New A matrix:\n{model_new.A}")
272+
print(f"New R matrix:\n{model_new.R}")
273+
```
274+
275+
### Code for dynamics
276+
270277
We will also use a specialized function to generate time series in an efficient
271278
JAX-compatible manner.
272279

273-
(Iteratively generating time series is somewhat nontrivial in JAX because arrays
274-
are immutable.)
280+
Iteratively generating time series is somewhat nontrivial in JAX because arrays
281+
are immutable.
282+
283+
Here we use `lax.scan`, which allows the function to be jit-compiled.
284+
285+
Readers who prefer to skip the details can safely continue reading after the function definition.
275286

276287
```{code-cell} ipython3
277288
@partial(jax.jit, static_argnames=['f', 'num_steps'])
@@ -307,7 +318,7 @@ def generate_path(f, initial_state, num_steps, **kwargs):
307318
return path.T
308319
```
309320

310-
Now we can simulate the dynamics.
321+
Here are functions to update $X_t$ and $x_t$.
311322

312323
```{code-cell} ipython3
313324
def stock_update(X: jnp.ndarray, model: LakeModel) -> jnp.ndarray:
@@ -321,26 +332,12 @@ def rate_update(x: jnp.ndarray, model: LakeModel) -> jnp.ndarray:
321332
return R @ x
322333
```
323334

324-
We create two instances, one with $α=0.013$ and another with $α=0.03$
325-
326-
```{code-cell} ipython3
327-
model = create_lake_model()
328-
model_new = create_lake_model(α=0.03)
329-
330-
print(f"Default α: {model.α}")
331-
print(f"A matrix:\n{model.A}")
332-
print(f"R matrix:\n{model.R}")
333-
```
334-
335-
```{code-cell} ipython3
336-
print(f"New α: {model_new.α}")
337-
print(f"New A matrix:\n{model_new.A}")
338-
print(f"New R matrix:\n{model_new.R}")
339-
```
340335

341336
### Aggregate dynamics
342337

343-
Let's run a simulation under the default parameters (see above) starting from $X_0 = (12, 138)$.
338+
Let's run a simulation under the default parameters starting from $X_0 = (12, 138)$.
339+
340+
We will plot the sequences $\{E_t\}$, $\{U_t\}$ and $\{N_t\}$.
344341

345342
```{code-cell} ipython3
346343
N_0 = 150 # Population
@@ -351,23 +348,26 @@ T = 50 # Simulation length
351348
U_0 = u_0 * N_0
352349
E_0 = e_0 * N_0
353350
354-
fig, axes = plt.subplots(3, 1, figsize=(10, 8))
351+
# Generate X path
355352
X_0 = jnp.array([U_0, E_0])
356353
X_path = generate_path(stock_update, X_0, T, model=model)
357354
355+
# Plot
356+
fig, axes = plt.subplots(3, 1, figsize=(10, 8))
358357
titles = ['unemployment', 'employment', 'labor force']
359358
data = [X_path[0, :], X_path[1, :], X_path.sum(0)]
360-
361359
for ax, title, series in zip(axes, titles, data):
362360
ax.plot(series, lw=2)
363361
ax.set_title(title)
364-
365362
plt.tight_layout()
366363
plt.show()
367364
```
368365

369366
The aggregates $E_t$ and $U_t$ don't converge because their sum $E_t + U_t$ grows at rate $g$.
370367

368+
369+
### Rate dynamics
370+
371371
On the other hand, the vector of employment and unemployment rates $x_t$ can be in a steady state $\bar x$ if
372372
there exists an $\bar x$ such that
373373

0 commit comments

Comments
 (0)