From 6573f2a262dd454a5621e2c596fbd8870cbb89a1 Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Mon, 10 Nov 2025 19:28:40 +0900 Subject: [PATCH 01/13] Fix JAX compatibility issues in Job Search III lecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated mccall_model_with_sep_markov.md to fix several JAX-related issues: - Refactored vfi() to return only v_final instead of tuple, making it more consistent with VFI pattern - Removed separate successive_approx() function and integrated iteration logic directly into vfi() - Fixed JAX decorators: changed @jit to @jax.jit and @partial(jit, ...) to @partial(jax.jit, ...) - Rewrote get_reservation_wage() to use jnp.argmax() instead of jnp.where() to avoid JAX concretization errors in JIT compilation - Updated all vfi() call sites to explicitly compute policy with get_greedy(v_star, model) - Removed @jit decorators from T() and get_greedy() functions (not needed) Also improved wording in mccall_model_with_separation.md for clarity. Tested: Converted to Python and ran successfully without errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- lectures/mccall_model_with_sep_markov.md | 115 +++++++++-------------- lectures/mccall_model_with_separation.md | 4 +- 2 files changed, 48 insertions(+), 71 deletions(-) diff --git a/lectures/mccall_model_with_sep_markov.md b/lectures/mccall_model_with_sep_markov.md index 76342a870..c6eb48101 100644 --- a/lectures/mccall_model_with_sep_markov.md +++ b/lectures/mccall_model_with_sep_markov.md @@ -4,11 +4,11 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.17.1 + jupytext_version: 1.17.2 kernelspec: - name: python3 display_name: Python 3 (ipykernel) language: python + name: python3 --- (mccall_with_sep_markov)= @@ -58,7 +58,7 @@ We use the following imports: from quantecon.markov import tauchen import jax.numpy as jnp import jax -from jax import jit, lax +from jax import lax from typing import NamedTuple import matplotlib.pyplot as plt from functools import partial @@ -138,48 +138,11 @@ The optimal policy turns out to be a reservation wage strategy: accept all wages ## Code - -First, we implement the successive approximation algorithm. - -This algorithm takes an operator $T$ and an initial condition and iterates until -convergence. - -We will use it for value function iteration. - -```{code-cell} ipython3 -@partial(jit, static_argnums=(0,)) -def successive_approx( - T, # Operator (callable) - marked as static - x_0, # Initial condition - tolerance: float = 1e-6, # Error tolerance - max_iter: int = 100_000, # Max iteration bound - ): - """Computes the approximate fixed point of T via successive - approximation using lax.while_loop.""" - - def cond_fn(carry): - x, error, k = carry - return (error > tolerance) & (k <= max_iter) - - def body_fn(carry): - x, error, k = carry - x_new = T(x) - error = jnp.max(jnp.abs(x_new - x)) - return (x_new, error, k + 1) - - initial_carry = (x_0, tolerance + 1, 1) - x_final, _, _ = lax.while_loop(cond_fn, body_fn, initial_carry) - - return x_final -``` - - -Next let's set up a `Model` class to store information needed to solve the model. +Let's set up a `Model` class to store information needed to solve the model. We include `P_cumsum`, the row-wise cumulative sum of the transition matrix, to optimize the simulation -- the details are explained below. - ```{code-cell} ipython3 class Model(NamedTuple): n: int @@ -215,7 +178,6 @@ def create_js_with_sep_model( Here's the Bellman operator for the unemployed worker's value function: ```{code-cell} ipython3 -@jit def T(v: jnp.ndarray, model: Model) -> jnp.ndarray: """The Bellman operator for the value of being unemployed.""" n, w_vals, P, P_cumsum, β, c, α = model @@ -229,7 +191,6 @@ The next function computes the optimal policy under the assumption that $v$ is the value function: ```{code-cell} ipython3 -@jit def get_greedy(v: jnp.ndarray, model: Model) -> jnp.ndarray: """Get a v-greedy policy.""" n, w_vals, P, P_cumsum, β, c, α = model @@ -247,14 +208,34 @@ The second routine requires a policy function, which we will typically obtain by applying the `vfi` function. ```{code-cell} ipython3 -def vfi(model: Model): - """Solve by VFI.""" +@jax.jit +def vfi( + model: Model, + tolerance: float = 1e-6, # Error tolerance + max_iter: int = 100_000, # Max iteration bound + ): + v_init = jnp.zeros(model.w_vals.shape) - v_star = successive_approx(lambda v: T(v, model), v_init) - σ_star = get_greedy(v_star, model) - return v_star, σ_star + + def cond(loop_state): + v, error, i = loop_state + return (error > tolerance) & (i <= max_iter) + + def update(loop_state): + v, error, i = loop_state + v_new = T(v, model) + error = jnp.max(jnp.abs(v_new - v)) + new_loop_state = v_new, error, i + 1 + return new_loop_state + + initial_state = (v_init, tolerance + 1, 1) + final_loop_state = lax.while_loop(cond, update, initial_state) + v_final, error, i = final_loop_state + return v_final + +@jax.jit def get_reservation_wage(σ: jnp.ndarray, model: Model) -> float: """ Calculate the reservation wage from a given policy. @@ -268,17 +249,15 @@ def get_reservation_wage(σ: jnp.ndarray, model: Model) -> float: """ n, w_vals, P, P_cumsum, β, c, α = model - # Find all wage indices where policy indicates acceptance - accept_indices = jnp.where(σ == 1)[0] - - if len(accept_indices) == 0: - return jnp.inf # Agent never accepts any wage + # Find the first index where policy indicates acceptance + # σ is a boolean array, argmax returns the first True value + first_accept_idx = jnp.argmax(σ) - # Return the lowest wage that is accepted - return w_vals[accept_indices[0]] + # If no acceptance (all False), return infinity + # Otherwise return the wage at the first acceptance index + return jnp.where(jnp.any(σ), w_vals[first_accept_idx], jnp.inf) ``` - ## Computing the Solution Let's solve the model: @@ -286,7 +265,8 @@ Let's solve the model: ```{code-cell} ipython3 model = create_js_with_sep_model() n, w_vals, P, P_cumsum, β, c, α = model -v_star, σ_star = vfi(model) +v_star = vfi(model) +σ_star = get_greedy(v_star, model) ``` Next we compute some related quantities, including the reservation wage. @@ -312,19 +292,18 @@ ax.set_xlabel(r"$w$") plt.show() ``` - ## Sensitivity Analysis Let's examine how reservation wages change with the separation rate. - ```{code-cell} ipython3 α_vals: jnp.ndarray = jnp.linspace(0.0, 1.0, 10) w_star_vec = jnp.empty_like(α_vals) for (i_α, α) in enumerate(α_vals): model = create_js_with_sep_model(α=α) - v_star, σ_star = vfi(model) + v_star = vfi(model) + σ_star = get_greedy(v_star, model) w_star = get_reservation_wage(σ_star, model) w_star_vec = w_star_vec.at[i_α].set(w_star) @@ -356,9 +335,8 @@ This is implemented via `jnp.searchsorted` on the precomputed cumulative sum The function `update_agent` advances the agent's state by one period. - ```{code-cell} ipython3 -@jit +@jax.jit def update_agent(key, is_employed, wage_idx, model, σ): """ Updates an agent by one period. Updates their employment status and their @@ -439,7 +417,8 @@ Let's create a comprehensive plot of the employment simulation: model = create_js_with_sep_model() # Calculate reservation wage for plotting -v_star, σ_star = vfi(model) +v_star = vfi(model) +σ_star = get_greedy(v_star, model) w_star = get_reservation_wage(σ_star, model) wage_path, employment_status = simulate_employment_path(model, σ_star) @@ -486,7 +465,6 @@ plt.tight_layout() plt.show() ``` - The simulation helps to visualize outcomes associated with this model. The agent follows a reservation wage strategy. @@ -568,7 +546,7 @@ update_agents_vmap = jax.vmap( Next we define the core simulation function, which uses `lax.fori_loop` to efficiently iterate many agents forward in time: ```{code-cell} ipython3 -@partial(jit, static_argnums=(3, 4)) +@partial(jax.jit, static_argnums=(3, 4)) def _simulate_cross_section_compiled( key: jnp.ndarray, model: Model, @@ -627,7 +605,8 @@ def simulate_cross_section( key = jax.random.PRNGKey(seed) # Solve for optimal policy - v_star, σ_star = vfi(model) + v_star = vfi(model) + σ_star = get_greedy(v_star, model) # Run JIT-compiled simulation final_employment = _simulate_cross_section_compiled( @@ -655,7 +634,8 @@ def plot_cross_sectional_unemployment(model: Model, t_snapshot: int = 200, """ # Get final employment state directly key = jax.random.PRNGKey(42) - v_star, σ_star = vfi(model) + v_star = vfi(model) + σ_star = get_greedy(v_star, model) final_employment = _simulate_cross_section_compiled( key, model, σ_star, n_agents, t_snapshot ) @@ -751,4 +731,3 @@ plt.show() ```{solution-end} ``` - diff --git a/lectures/mccall_model_with_separation.md b/lectures/mccall_model_with_separation.md index 2911dc139..22807cf36 100644 --- a/lectures/mccall_model_with_separation.md +++ b/lectures/mccall_model_with_separation.md @@ -135,9 +135,7 @@ Our first aim is to obtain these functions. ### The Bellman Equations -Suppose for now that the worker can calculate the functions $v_e$ and $v_u$ and use them in his decision making. - -Then $v_e$ and $v_u$ should satisfy +The functions $v_e$ and $v_u$ must satisfy ```{math} :label: bell1_mccall From b941636beff5d7176b7c7fbfd08ebda98e7fffd8 Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Tue, 11 Nov 2025 05:16:37 +0900 Subject: [PATCH 02/13] Standardize continuation value notation in Job Search II lecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated the McCall model with separation to use h = u(c) + β * sum_w v_u(w) q(w) as the continuation value, matching the notation from the basic McCall model lecture. This makes the progression between lectures more intuitive for readers: - Basic model: h = c + β * sum_w v*(w) q(w) - Separation model: h = u(c) + β * sum_w v_u(w) q(w) Key changes: - Replaced scalar d with h throughout mathematical derivations - Updated closed-form expression for v_e(w) to use h - Modified iteration algorithm to solve for h instead of d - Simplified Bellman equations using h notation - Updated all code functions (compute_v_e, update_h, solve_model) - Changed plots and comments to reference h This improves consistency across the job search lecture series and makes the mathematical structure clearer by explicitly showing the continuation value includes both current utility and discounted future value. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- lectures/mccall_model_with_separation.md | 209 +++++++++++++---------- 1 file changed, 123 insertions(+), 86 deletions(-) diff --git a/lectures/mccall_model_with_separation.md b/lectures/mccall_model_with_separation.md index 22807cf36..99a07c84d 100644 --- a/lectures/mccall_model_with_separation.md +++ b/lectures/mccall_model_with_separation.md @@ -34,16 +34,16 @@ In addition to what's in Anaconda, this lecture will need the following librarie ```{code-cell} ipython3 :tags: [hide-output] -!pip install quantecon +!pip install quantecon jax ``` ## Overview Previously {doc}`we looked ` at the McCall job search model {cite}`McCall1970` as a way of understanding unemployment and worker decisions. -One unrealistic feature of the model is that every job is permanent. +One unrealistic feature of that version of the model was that every job is permanent. -In this lecture, we extend the McCall model by introducing job separation. +In this lecture, we extend the model by introducing job separation. Once separation enters the picture, the agent comes to view @@ -125,51 +125,78 @@ We drop time subscripts in what follows and primes denote next period values. Let -* $v_e(w)$ be total lifetime value accruing to a worker who enters the current period *employed* with existing wage $w$ -* $v_u(w)$ be total lifetime value accruing to a worker who who enters the current period *unemployed* and receives - wage offer $w$. +* $v_e(w)$ be maximum lifetime value accruing to a worker who enters the current + period *employed* with existing wage $w$ +* $v_u(w)$ be maximum lifetime value accruing to a worker who who enters the + current period *unemployed* and receives wage offer $w$. -Here *value* means the value of the objective function {eq}`objective` when the worker makes optimal decisions at all future points in time. +Here **maximum lifetime value** means the value of {eq}`objective` when +the worker makes optimal decisions at all future points in time. -Our first aim is to obtain these functions. +As we now show, these obtaining these functions is key to solving the new model. ### The Bellman Equations -The functions $v_e$ and $v_u$ must satisfy +We recall that, in {doc}`the original job search model `, the +value function (the value of being unemployed with a given wage offer) satisfied +a Bellman equation. -```{math} -:label: bell1_mccall - -v_e(w) = u(w) + \beta - \left[ - (1-\alpha)v_e(w) + \alpha \sum_{w' \in \mathbb W} v_u(w') q(w') - \right] -``` +Here this function again satisfies a Bellman equation that looks very similar. -and ```{math} :label: bell2_mccall -v_u(w) = \max \left\{ v_e(w), \, u(c) + \beta \sum_{w' \in \mathbb W} v_u(w') q(w') \right\} + v_u(w) = \max + \left\{ + v_e(w), \, + u(c) + \beta \sum_{w' \in \mathbb W} v_u(w') q(w') + \right\} ``` -Equation {eq}`bell1_mccall` expresses the value of being employed at wage $w$ in terms of +The difference is that the value of accepting is $v_e(w)$ rather than +$w/(1-\beta)$. -* current reward $u(w)$ plus -* discounted expected reward tomorrow, given the $\alpha$ probability of being fired +We have to make this change because jobs are not permanent. + +Accepting transitions the worker to employment and hence yields reward $v_e(w)$. + +Rejecting leads to unemployment compensation and unemployment tomorrow. Equation {eq}`bell2_mccall` expresses the value of being unemployed with offer $w$ in hand as a maximum over the value of two options: accept or reject the current offer. -Accepting transitions the worker to employment and hence yields reward $v_e(w)$. +The function $v_e$ also satisfies a Bellman equation: -Rejecting leads to unemployment compensation and unemployment tomorrow. +```{math} +:label: bell1_mccall -Equations {eq}`bell1_mccall` and {eq}`bell2_mccall` are the Bellman equations for this model. + v_e(w) = u(w) + \beta + \left[ + (1-\alpha)v_e(w) + \alpha \sum_{w' \in \mathbb W} v_u(w') q(w') + \right] +``` -They provide enough information to solve for both $v_e$ and $v_u$. +```{note} +This equation differs from a traditional Bellman equation because there is no max. + +There is no max because an employed agent has no choices. + +Nonetheless, in keeping with most of the literature, we also refer to it as a +Bellman equation. + +``` + +Equation {eq}`bell1_mccall` expresses the value of being employed at wage $w$ in terms of + +* current reward $u(w)$ plus +* discounted expected reward tomorrow, given the $\alpha$ probability of being fired + +As we will see, equations {eq}`bell1_mccall` and {eq}`bell2_mccall` provide +enough information to solve for both $v_e$ and $v_u$. + +Once we have them in hand, we will be able to make optimal choices. (ast_mcm)= ### A Simplifying Transformation @@ -178,66 +205,79 @@ Rather than jumping straight into solving these equations, let's see if we can simplify them somewhat. (This process will be analogous to our {ref}`second pass ` at the plain vanilla -McCall model, where we simplified the Bellman equation.) +McCall model, where we reduced the Bellman equation to an equation in an unknown +scalar value, rather than an unknown vector.) First, let ```{math} -:label: defd_mm +:label: defh_mm -d := \sum_{w' \in \mathbb W} v_u(w') q(w') +h := u(c) + \beta \sum_{w' \in \mathbb W} v_u(w') q(w') ``` -be the expected value of unemployment tomorrow. +be the continuation value associated with unemployment (the value of rejecting the current offer). We can now write {eq}`bell2_mccall` as $$ -v_u(w) = \max \left\{ v_e(w), \, u(c) + \beta d \right\} +v_u(w) = \max \left\{ v_e(w), \, h \right\} $$ or, shifting time forward one period $$ \sum_{w' \in \mathbb W} v_u(w') q(w') - = \sum_{w' \in \mathbb W} \max \left\{ v_e(w'), \, u(c) + \beta d \right\} q(w') + = \sum_{w' \in \mathbb W} \max \left\{ v_e(w'), \, h \right\} q(w') $$ -Using {eq}`defd_mm` again now gives +Using {eq}`defh_mm` again now gives ```{math} :label: bell02_mccall -d = \sum_{w' \in \mathbb W} \max \left\{ v_e(w'), \, u(c) + \beta d \right\} q(w') +h = u(c) + \beta \sum_{w' \in \mathbb W} \max \left\{ v_e(w'), \, h \right\} q(w') ``` -Finally, {eq}`bell1_mccall` can now be rewritten as +Finally, from {eq}`defh_mm` we have + +$$ +\sum_{w' \in \mathbb W} v_u(w') q(w') = \frac{h - u(c)}{\beta} +$$ + +so {eq}`bell1_mccall` can now be rewritten as ```{math} :label: bell01_mccall v_e(w) = u(w) + \beta \left[ - (1-\alpha)v_e(w) + \alpha d + (1-\alpha)v_e(w) + \alpha \frac{h - u(c)}{\beta} \right] ``` ### Simplifying to a Single Equation -We can simplify further by solving {eq}`bell01_mccall` for $v_e$ as a function of $d$. +We can simplify further by solving {eq}`bell01_mccall` for $v_e$ as a function of $h$. Rearranging {eq}`bell01_mccall` gives $$ -v_e(w) - \beta(1-\alpha)v_e(w) = u(w) + \beta\alpha d +v_e(w) = u(w) + \beta(1-\alpha)v_e(w) + \alpha(h - u(c)) $$ or +$$ +v_e(w) - \beta(1-\alpha)v_e(w) = u(w) + \alpha(h - u(c)) +$$ + +Solving for $v_e(w)$: + ```{math} :label: v_e_closed -v_e(w) = \frac{u(w) + \beta\alpha d}{1 - \beta(1-\alpha)} +v_e(w) = \frac{u(w) + \alpha(h - u(c))}{1 - \beta(1-\alpha)} ``` Substituting this into {eq}`bell02_mccall` yields @@ -245,23 +285,23 @@ Substituting this into {eq}`bell02_mccall` yields ```{math} :label: bell_scalar -d = \sum_{w' \in \mathbb W} \max \left\{ \frac{u(w') + \beta\alpha d}{1 - \beta(1-\alpha)}, \, u(c) + \beta d \right\} q(w') +h = u(c) + \beta \sum_{w' \in \mathbb W} \max \left\{ \frac{u(w') + \alpha(h - u(c))}{1 - \beta(1-\alpha)}, \, h \right\} q(w') ``` -This is a single scalar equation in $d$. +This is a single scalar equation in $h$. ### The Reservation Wage -Suppose we can use {eq}`bell_scalar` to solve for $d$. +Suppose we can use {eq}`bell_scalar` to solve for $h$. -Once we have $d$, we can obtain $v_e$ from {eq}`v_e_closed`. +Once we have $h$, we can obtain $v_e$ from {eq}`v_e_closed`. We can then determine optimal behavior for the worker. From {eq}`bell2_mccall`, we see that an unemployed agent accepts current offer -$w$ if $v_e(w) \geq u(c) + \beta d$. +$w$ if $v_e(w) \geq h$. -This means precisely that the value of accepting is higher than the expected value of rejecting. +This means precisely that the value of accepting is higher than the value of rejecting. It is clear that $v_e$ is (at least weakly) increasing in $w$, since the agent is never made worse off by a higher wage offer. @@ -270,7 +310,7 @@ Hence, we can express the optimal choice as accepting wage offer $w$ if and only $$ w \geq \bar w \quad \text{where} \quad -\bar w \text{ solves } v_e(\bar w) = u(c) + \beta d +\bar w \text{ solves } v_e(\bar w) = h $$ ### Solving the Bellman Equations @@ -279,28 +319,28 @@ We'll use the same iterative approach to solving the Bellman equations that we adopted in the {doc}`first job search lecture `. Since we have reduced the problem to a single scalar equation {eq}`bell_scalar`, -we only need to iterate on $d$. +we only need to iterate on $h$. The iteration rule is ```{math} :label: bell_iter -d_{n+1} = \sum_{w' \in \mathbb W} - \max \left\{ \frac{u(w') + \beta\alpha d_n}{1 - \beta(1-\alpha)}, \, u(c) + \beta d_n \right\} q(w') +h_{n+1} = u(c) + \beta \sum_{w' \in \mathbb W} + \max \left\{ \frac{u(w') + \alpha(h_n - u(c))}{1 - \beta(1-\alpha)}, \, h_n \right\} q(w') ``` -starting from some initial condition $d_0$. +starting from some initial condition $h_0$. Once convergence is achieved, we can compute $v_e$ from {eq}`v_e_closed`: ```{math} :label: bell_v_e_final -v_e(w) = \frac{u(w) + \beta\alpha d}{1 - \beta(1-\alpha)} +v_e(w) = \frac{u(w) + \alpha(h - u(c))}{1 - \beta(1-\alpha)} ``` -This approach is simpler than iterating on both $d$ and $v_e$ simultaneously, as +This approach is simpler than iterating on both $h$ and $v_e$ simultaneously, as we now only need to track a single scalar value. (Convergence can be established via the Banach contraction mapping theorem.) @@ -347,52 +387,52 @@ Now we iterate until successive realizations are closer together than some small We then return the current iterate as an approximate solution. -First, we define a function to compute $v_e$ from $d$: +First, we define a function to compute $v_e$ from $h$: ```{code-cell} ipython3 -def compute_v_e(model, d): - " Compute v_e from d using the closed-form expression. " - α, β, w = model.α, model.β, model.w - return (u(w) + β * α * d) / (1 - β * (1 - α)) +def compute_v_e(model, h): + " Compute v_e from h using the closed-form expression. " + α, β, c, w = model.α, model.β, model.c, model.w + return (u(w) + α * (h - u(c))) / (1 - β * (1 - α)) ``` -Now we implement the iteration on $d$ only: +Now we implement the iteration on $h$ only: ```{code-cell} ipython3 -def update_d(model, d): - " One update of the scalar d. " +def update_h(model, h): + " One update of the scalar h. " α, β, c, w, q = model.α, model.β, model.c, model.w, model.q - v_e = compute_v_e(model, d) - d_new = jnp.maximum(v_e, u(c) + β * d) @ q - return d_new + v_e = compute_v_e(model, h) + h_new = u(c) + β * (jnp.maximum(v_e, h) @ q) + return h_new @jax.jit def solve_model(model, tol=1e-5, max_iter=2000): " Iterates to convergence on the Bellman equations. " def cond_fun(state): - d, i, error = state + h, i, error = state return jnp.logical_and(error > tol, i < max_iter) def body_fun(state): - d, i, error = state - d_new = update_d(model, d) - error_new = jnp.abs(d_new - d) - return d_new, i + 1, error_new + h, i, error = state + h_new = update_h(model, h) + error_new = jnp.abs(h_new - h) + return h_new, i + 1, error_new - # Initial state: (d, i, error) - d_init = 1.0 + # Initial state: (h, i, error) + h_init = u(model.c) / (1 - model.β) i_init = 0 error_init = tol + 1 - init_state = (d_init, i_init, error_init) + init_state = (h_init, i_init, error_init) final_state = jax.lax.while_loop(cond_fun, body_fun, init_state) - d_final, _, _ = final_state + h_final, _, _ = final_state - # Compute v_e from the converged d - v_e_final = compute_v_e(model, d_final) + # Compute v_e from the converged h + v_e_final = compute_v_e(model, h_final) - return v_e_final, d_final + return v_e_final, h_final ``` ### The Reservation Wage: First Pass @@ -400,22 +440,20 @@ def solve_model(model, tol=1e-5, max_iter=2000): The optimal choice of the agent is summarized by the reservation wage. As discussed above, the reservation wage is the $\bar w$ that solves -$v_e(\bar w) = v_u^*$ where $v_u^* := u(c) + \beta d$ is the continuation -value. +$v_e(\bar w) = h$ where $h$ is the continuation value. -Let's compare $v_e$ and $v_u^*$ to see what they look like. +Let's compare $v_e$ and $h$ to see what they look like. We'll use the default parameterizations found in the code above. ```{code-cell} ipython3 model = Model() -v_e, d = solve_model(model) -v_u_star = u(model.c) + model.β * d +v_e, h = solve_model(model) fig, ax = plt.subplots() ax.plot(model.w, v_e, 'b-', lw=2, alpha=0.7, label='$v_e$') -ax.plot(model.w, [v_u_star] * len(model.w), - 'g-', lw=2, alpha=0.7, label='$v_u^*$') +ax.plot(model.w, [h] * len(model.w), + 'g-', lw=2, alpha=0.7, label='$h$') ax.set_xlim(min(model.w), max(model.w)) ax.legend() plt.show() @@ -433,13 +471,12 @@ and returns the associated reservation wage. def compute_reservation_wage(model): """ Computes the reservation wage of an instance of the McCall model - by finding the smallest w such that v_e(w) >= v_u^*. If no such w exists, then + by finding the smallest w such that v_e(w) >= h. If no such w exists, then w_bar is set to np.inf. """ - v_e, d = solve_model(model) - v_u_star = u(model.c) + model.β * d - i = jnp.searchsorted(v_e, v_u_star, side='left') + v_e, h = solve_model(model) + i = jnp.searchsorted(v_e, h, side='left') w_bar = jnp.where(i >= len(model.w), jnp.inf, model.w[i]) return w_bar ``` From 7ef79a9b8fe74befd0580f2a3b5694f8f151c09b Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Tue, 11 Nov 2025 05:28:05 +0900 Subject: [PATCH 03/13] Remove JAX from pip install in Job Search II lecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The JAX library is already included in the base environment and doesn't need to be explicitly installed, which was causing build failures. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- lectures/mccall_model_with_separation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/mccall_model_with_separation.md b/lectures/mccall_model_with_separation.md index 99a07c84d..12c0b5e58 100644 --- a/lectures/mccall_model_with_separation.md +++ b/lectures/mccall_model_with_separation.md @@ -34,7 +34,7 @@ In addition to what's in Anaconda, this lecture will need the following librarie ```{code-cell} ipython3 :tags: [hide-output] -!pip install quantecon jax +!pip install quantecon ``` ## Overview From 5264443121f0449efa58128ed218011c2dd8e4d2 Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Tue, 11 Nov 2025 05:30:24 +0900 Subject: [PATCH 04/13] Remove JAX from pip install in Job Search III lecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The JAX library is already included in the base environment and doesn't need to be explicitly installed, which was causing build failures. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- lectures/mccall_model_with_sep_markov.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/mccall_model_with_sep_markov.md b/lectures/mccall_model_with_sep_markov.md index c6eb48101..812a690cd 100644 --- a/lectures/mccall_model_with_sep_markov.md +++ b/lectures/mccall_model_with_sep_markov.md @@ -49,7 +49,7 @@ libraries ```{code-cell} ipython3 :tags: [hide-output] -!pip install quantecon jax +!pip install quantecon ``` We use the following imports: From 8ad69b1bc0aae1c3c68efca5546161a32e57812c Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Tue, 11 Nov 2025 08:30:10 +1100 Subject: [PATCH 05/13] Update PyTorch installation to use cu121 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3bc26f081..8d092c326 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: - name: Install JAX, Numpyro, PyTorch shell: bash -l {0} run: | - pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu128 + pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 pip install pyro-ppl pip install --upgrade "jax[cuda12-local]==0.6.2" pip install numpyro pyro-ppl From 66013bcfb6f6024474b05ae4edbb7353830d8143 Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Tue, 11 Nov 2025 08:49:04 +1100 Subject: [PATCH 06/13] Update CI workflow to install only PyTorch packages Removed 'torchaudio' from the installation command for PyTorch. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d092c326..9e2b49b74 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: - name: Install JAX, Numpyro, PyTorch shell: bash -l {0} run: | - pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 + pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 pip install pyro-ppl pip install --upgrade "jax[cuda12-local]==0.6.2" pip install numpyro pyro-ppl From 702773e5e6f935e3286f65aa8adbfc6f5106dea9 Mon Sep 17 00:00:00 2001 From: mmcky Date: Tue, 11 Nov 2025 12:13:13 +1100 Subject: [PATCH 07/13] fix: JAX version pinning --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9e2b49b74..61b09e300 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: run: | pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 pip install pyro-ppl - pip install --upgrade "jax[cuda12-local]==0.6.2" + pip install --upgrade "jax[cuda12-local]==0.8.0" pip install numpyro pyro-ppl python scripts/test-jax-install.py - name: Check nvidia Drivers From 949043ef711eecb2842ecb8c2982141fee78e0d1 Mon Sep 17 00:00:00 2001 From: mmcky Date: Tue, 11 Nov 2025 12:23:37 +1100 Subject: [PATCH 08/13] install new CUDANN binaries --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61b09e300..28a43deee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: run: | pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 pip install pyro-ppl - pip install --upgrade "jax[cuda12-local]==0.8.0" + pip install --upgrade "jax[cuda12]" pip install numpyro pyro-ppl python scripts/test-jax-install.py - name: Check nvidia Drivers From 7f7d6a5791c03e24a5cf4c61fdb1fee6728fe8f5 Mon Sep 17 00:00:00 2001 From: mmcky Date: Tue, 11 Nov 2025 12:34:39 +1100 Subject: [PATCH 09/13] remove pytorch --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28a43deee..80e4d9a83 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,9 +31,9 @@ jobs: - name: Install JAX, Numpyro, PyTorch shell: bash -l {0} run: | - pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 - pip install pyro-ppl - pip install --upgrade "jax[cuda12]" + # pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 + # pip install pyro-ppl + pip install "jax[cuda12-local]==0.6.2" pip install numpyro pyro-ppl python scripts/test-jax-install.py - name: Check nvidia Drivers From 2ad5d43afca6ad406aeb30f2349e0eb371c88aec Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Tue, 11 Nov 2025 15:26:32 +0900 Subject: [PATCH 10/13] misc --- lectures/mccall_model_with_separation.md | 42 ++++++++++++------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/lectures/mccall_model_with_separation.md b/lectures/mccall_model_with_separation.md index 12c0b5e58..550fbcb14 100644 --- a/lectures/mccall_model_with_separation.md +++ b/lectures/mccall_model_with_separation.md @@ -318,8 +318,7 @@ $$ We'll use the same iterative approach to solving the Bellman equations that we adopted in the {doc}`first job search lecture `. -Since we have reduced the problem to a single scalar equation {eq}`bell_scalar`, -we only need to iterate on $h$. +In this case we only need to iterate on the single scalar equation {eq}`bell_scalar`. The iteration rule is @@ -332,18 +331,9 @@ h_{n+1} = u(c) + \beta \sum_{w' \in \mathbb W} starting from some initial condition $h_0$. -Once convergence is achieved, we can compute $v_e$ from {eq}`v_e_closed`: +Once convergence is achieved, we can compute $v_e$ from {eq}`v_e_closed`. -```{math} -:label: bell_v_e_final - -v_e(w) = \frac{u(w) + \alpha(h - u(c))}{1 - \beta(1-\alpha)} -``` - -This approach is simpler than iterating on both $h$ and $v_e$ simultaneously, as -we now only need to track a single scalar value. - -(Convergence can be established via the Banach contraction mapping theorem.) +(It is possible to prove that {eq}`bell_iter` converges via the Banach contraction mapping theorem.) ## Implementation @@ -405,28 +395,32 @@ def update_h(model, h): v_e = compute_v_e(model, h) h_new = u(c) + β * (jnp.maximum(v_e, h) @ q) return h_new +``` + +Using this iteration rule, we can write our model solver. +```{code-cell} ipython3 @jax.jit def solve_model(model, tol=1e-5, max_iter=2000): " Iterates to convergence on the Bellman equations. " - def cond_fun(state): - h, i, error = state + def cond(loop_state): + h, i, error = loop_state return jnp.logical_and(error > tol, i < max_iter) - def body_fun(state): - h, i, error = state + def update(loop_state): + h, i, error = loop_state h_new = update_h(model, h) error_new = jnp.abs(h_new - h) return h_new, i + 1, error_new - # Initial state: (h, i, error) + # Initialize h_init = u(model.c) / (1 - model.β) i_init = 0 error_init = tol + 1 - init_state = (h_init, i_init, error_init) - final_state = jax.lax.while_loop(cond_fun, body_fun, init_state) + + final_state = jax.lax.while_loop(cond, update, init_state) h_final, _, _ = final_state # Compute v_e from the converged h @@ -461,7 +455,11 @@ plt.show() The value $v_e$ is increasing because higher $w$ generates a higher wage flow conditional on staying employed. -### The Reservation Wage: Computation + +The reservation wage is the $w$ where these lines meet. + + +### Computing the Reservation Wage Here's a function `compute_reservation_wage` that takes an instance of `Model` and returns the associated reservation wage. @@ -483,6 +481,8 @@ def compute_reservation_wage(model): Next we will investigate how the reservation wage varies with parameters. + + ## Impact of Parameters In each instance below, we'll show you a figure and then ask you to reproduce it in the exercises. From deb99b13adf3ecc284fcb7798d1390d5fb2148ac Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Tue, 11 Nov 2025 16:05:45 +0900 Subject: [PATCH 11/13] Update mccall_model_with_separation: Change utility parameter from sigma to gamma and use glue for figures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated the McCall model with separation lecture with the following changes: Key changes: - Changed utility function parameter from σ (sigma) to γ (gamma) - Moved γ default value from utility function to Model class (γ: float = 2.0) - Updated all functions (compute_v_e, update_h, solve_model) to pass γ parameter - Simplified model unpacking to use tuple unpacking directly (e.g., α, β, γ, c, w, q = model) - Replaced static PNG figures with myst-nb glue functionality - Added glue import and glue() calls in exercise solutions - Converted {figure} directives to {glue:figure} directives for dynamic figure generation Benefits: - More consistent parameter naming (gamma is standard for CRRA utility) - Better code organization with parameter defaults in Model class - Cleaner unpacking syntax - Dynamic figure generation eliminates need for static PNG files - Figures automatically stay in sync with code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- lectures/mccall_model_with_separation.md | 30 +++++++++++++++--------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/lectures/mccall_model_with_separation.md b/lectures/mccall_model_with_separation.md index 550fbcb14..612e1a290 100644 --- a/lectures/mccall_model_with_separation.md +++ b/lectures/mccall_model_with_separation.md @@ -62,6 +62,7 @@ import jax import jax.numpy as jnp from typing import NamedTuple from quantecon.distributions import BetaBinomial +from myst_nb import glue ``` ## The Model @@ -347,8 +348,8 @@ This helps to tidy up the code and provides an object that's easy to pass to fun The default utility function is a CRRA utility function ```{code-cell} ipython3 -def u(c, σ=2.0): - return (c**(1 - σ) - 1) / (1 - σ) +def u(c, γ): + return (c**(1 - γ) - 1) / (1 - γ) ``` Also, here's a default wage distribution, based around the BetaBinomial @@ -368,6 +369,7 @@ Here's our model class for the McCall model with separation. class Model(NamedTuple): α: float = 0.2 # job separation rate β: float = 0.98 # discount factor + γ: float = 2.0 # utility parameter (CRRA) c: float = 6.0 # unemployment compensation w: jnp.ndarray = w_default # wage outcome space q: jnp.ndarray = q_default # probabilities over wage offers @@ -382,8 +384,8 @@ First, we define a function to compute $v_e$ from $h$: ```{code-cell} ipython3 def compute_v_e(model, h): " Compute v_e from h using the closed-form expression. " - α, β, c, w = model.α, model.β, model.c, model.w - return (u(w) + α * (h - u(c))) / (1 - β * (1 - α)) + α, β, γ, c, w, q = model + return (u(w, γ) + α * (h - u(c, γ))) / (1 - β * (1 - α)) ``` Now we implement the iteration on $h$ only: @@ -391,9 +393,9 @@ Now we implement the iteration on $h$ only: ```{code-cell} ipython3 def update_h(model, h): " One update of the scalar h. " - α, β, c, w, q = model.α, model.β, model.c, model.w, model.q + α, β, γ, c, w, q = model v_e = compute_v_e(model, h) - h_new = u(c) + β * (jnp.maximum(v_e, h) @ q) + h_new = u(c, γ) + β * (jnp.maximum(v_e, h) @ q) return h_new ``` @@ -414,8 +416,8 @@ def solve_model(model, tol=1e-5, max_iter=2000): error_new = jnp.abs(h_new - h) return h_new, i + 1, error_new - # Initialize - h_init = u(model.c) / (1 - model.β) + # Initialize + h_init = u(model.c, model.γ) / (1 - model.β) i_init = 0 error_init = tol + 1 init_state = (h_init, i_init, error_init) @@ -494,7 +496,8 @@ First, let's look at how $\bar w$ varies with unemployment compensation. In the figure below, we use the default parameters in the `Model` class, apart from c (which takes the values given on the horizontal axis) -```{figure} /_static/lecture_specific/mccall_model_with_separation/mccall_resw_c.png +```{glue:figure} mccall_resw_c +:figwidth: 600px ``` @@ -509,7 +512,8 @@ Next, let's investigate how $\bar w$ varies with the discount factor. The next figure plots the reservation wage associated with different values of $\beta$ -```{figure} /_static/lecture_specific/mccall_model_with_separation/mccall_resw_beta.png +```{glue:figure} mccall_resw_beta +:figwidth: 600px ``` @@ -521,7 +525,8 @@ Finally, let's look at how $\bar w$ varies with the job separation rate $\alpha$ Higher $\alpha$ translates to a greater chance that a worker will face termination in each period once employed. -```{figure} /_static/lecture_specific/mccall_model_with_separation/mccall_resw_alpha.png +```{glue:figure} mccall_resw_alpha +:figwidth: 600px ``` @@ -569,6 +574,7 @@ fig, ax = plt.subplots() ax.set(xlabel='unemployment compensation', ylabel='reservation wage') ax.plot(c_vals, w_bar_vals, label=r'$\bar w$ as a function of $c$') ax.legend() +glue("mccall_resw_c", fig, display=False) plt.show() ``` @@ -586,6 +592,7 @@ fig, ax = plt.subplots() ax.set(xlabel='discount factor', ylabel='reservation wage') ax.plot(β_vals, w_bar_vals, label=r'$\bar w$ as a function of $\beta$') ax.legend() +glue("mccall_resw_beta", fig, display=False) plt.show() ``` @@ -603,6 +610,7 @@ fig, ax = plt.subplots() ax.set(xlabel='separation rate', ylabel='reservation wage') ax.plot(α_vals, w_bar_vals, label=r'$\bar w$ as a function of $\alpha$') ax.legend() +glue("mccall_resw_alpha", fig, display=False) plt.show() ``` From 4e6859a76c98d81a6825f39590b3297d963fb4a7 Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Tue, 11 Nov 2025 16:36:19 +0900 Subject: [PATCH 12/13] Remove redundant PNG files for mccall_model_with_separation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed static PNG files that are now dynamically generated using myst-nb glue: - mccall_resw_alpha.png - mccall_resw_beta.png - mccall_resw_c.png These figures are now generated from the exercise solution code and displayed via glue:figure directives, eliminating the need for static files and ensuring figures always match the code. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../mccall_resw_alpha.png | Bin 20778 -> 0 bytes .../mccall_resw_beta.png | Bin 25947 -> 0 bytes .../mccall_resw_c.png | Bin 23001 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 lectures/_static/lecture_specific/mccall_model_with_separation/mccall_resw_alpha.png delete mode 100644 lectures/_static/lecture_specific/mccall_model_with_separation/mccall_resw_beta.png delete mode 100644 lectures/_static/lecture_specific/mccall_model_with_separation/mccall_resw_c.png diff --git a/lectures/_static/lecture_specific/mccall_model_with_separation/mccall_resw_alpha.png b/lectures/_static/lecture_specific/mccall_model_with_separation/mccall_resw_alpha.png deleted file mode 100644 index 706fa128de0958e3edd013e2c2baa875b3d15caf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20778 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 U<6EbfP$gnAk_vaSZW%uNZ_^V=#{d8T diff --git a/lectures/_static/lecture_specific/mccall_model_with_separation/mccall_resw_beta.png b/lectures/_static/lecture_specific/mccall_model_with_separation/mccall_resw_beta.png deleted file mode 100644 index 80f320b25c2e1feefffe3c90280412eb0164c4dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25947 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 From 35aa16d43712587eefdc5fcc4336493775e386cb Mon Sep 17 00:00:00 2001 From: John Stachurski Date: Tue, 11 Nov 2025 16:44:57 +0900 Subject: [PATCH 13/13] misc --- lectures/mccall_model_with_sep_markov.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lectures/mccall_model_with_sep_markov.md b/lectures/mccall_model_with_sep_markov.md index 812a690cd..8ba89fa60 100644 --- a/lectures/mccall_model_with_sep_markov.md +++ b/lectures/mccall_model_with_sep_markov.md @@ -509,7 +509,7 @@ This holds because: These properties ensure the chain is ergodic with a unique stationary distribution $\pi$ over states $(s, w)$. -For an ergodic Markov chain, the ergodic theorem guarantees that time averages = ensemble averages. +For an ergodic Markov chain, the ergodic theorem guarantees that time averages = cross-sectional averages. In particular, the fraction of time a single agent spends unemployed (across all wage states) converges to the cross-sectional unemployment rate: @@ -661,7 +661,12 @@ def plot_cross_sectional_unemployment(model: Model, t_snapshot: int = 200, plt.show() ``` -Now let's compare the time-average unemployment rate (from a single agent's long simulation) with the cross-sectional unemployment rate (from many agents at a single point in time): +Now let's compare the time-average unemployment rate (from a single agent's long simulation) with the cross-sectional unemployment rate (from many agents at a single point in time). + +We claimed above that these numbers will be approximately equal in large +samples, due to ergodicity. + +Let's see if that's true. ```{code-cell} ipython3 model = create_js_with_sep_model() @@ -677,28 +682,31 @@ print(f"Cross-sectional unemployment rate (at t=200): " print(f"Difference: {abs(time_avg_unemp - cross_sectional_unemp):.4f}") ``` +Indeed, they are very close. + Now let's visualize the cross-sectional distribution: ```{code-cell} ipython3 plot_cross_sectional_unemployment(model) ``` -## Cross-Sectional Analysis with Lower Unemployment Compensation (c=0.5) +## Lower Unemployment Compensation (c=0.5) -Let's examine how the cross-sectional unemployment rate changes with lower unemployment compensation: +What happens to the cross-sectional unemployment rate with lower unemployment compensation? ```{code-cell} ipython3 model_low_c = create_js_with_sep_model(c=0.5) plot_cross_sectional_unemployment(model_low_c) ``` + ## Exercises ```{exercise-start} :label: mmwsm_ex1 ``` -Create a plot that shows how the steady state cross-sectional unemployment rate +Create a plot that investigates more carefully how the steady state cross-sectional unemployment rate changes with unemployment compensation. ```{exercise-end}