[mccall_q] Fix typos, heading case and figure legend - #624
Conversation
|
📖 Netlify Preview Ready! Preview URL: https://pr-624--sunny-cactus-210e3e.netlify.app (c8814f3) 📚 Changed Lecture Pages: mccall_q |
|
📖 Netlify Preview Ready! Preview URL: https://pr-624--sunny-cactus-210e3e.netlify.app (c575e39) 📚 Changed Lecture Pages: mccall_q |
earlier the legend overlapped on the curves, making it difficult to interpret the graph. this version fixes it
|
📖 Netlify Preview Ready! Preview URL: https://pr-624--sunny-cactus-210e3e.netlify.app (211832b) 📚 Changed Lecture Pages: mccall_q |
|
📖 Netlify Preview Ready! Preview URL: https://pr-624--sunny-cactus-210e3e.netlify.app (d7b49a6) 📚 Changed Lecture Pages: mccall_q |
|
📖 Netlify Preview Ready! Preview URL: https://pr-624--sunny-cactus-210e3e.netlify.app (ef3e791) 📚 Changed Lecture Pages: mccall_q |
There was a problem hiding this comment.
Pull Request Overview
This PR converts the McCall job search model lecture from NumPy/Numba implementation to JAX, updating the code to use JAX's functional programming paradigm and JIT compilation. The conversion includes modernizing the code structure, fixing grammatical errors, and improving figure presentation.
Key changes include:
- Complete conversion from NumPy/Numba to JAX with functional programming approach
- Replacement of class-based structure with NamedTuple and standalone functions
- Implementation of JAX's immutable array operations and control flow primitives
| qtable, s, accept_count, t, key = state | ||
| # for first interaction, just continue since error is large | ||
| # for subsequent interactions, compute actual error | ||
| error = jnp.where(t==0, δ + 1, jnp.max(jnp.abs(qtable - state[0]))) |
There was a problem hiding this comment.
The error calculation references state[0] but state is a tuple where the first element is qtable. This creates a circular reference where the error is computed as the difference between qtable and itself, which will always be zero after the first iteration. This should reference a previous qtable value stored separately.
|
|
||
| for n in range(N): | ||
| if n%(N/10)==0: | ||
| if n % (N // 10) == 0: |
There was a problem hiding this comment.
Integer division N // 10 can result in zero when N < 10, causing a division by zero error in the modulo operation. This should use max(1, N // 10) to ensure the divisor is never zero.
| if n % (N // 10) == 0: | |
| if n % max(1, N // 10) == 0: |
| max_epochs = int(jnp.max(epochs_to_plot)) # Convert to Python int | ||
| # iterate on epoch numbers | ||
| for n in range(max_epochs + 1): | ||
| if n%(max_epochs/10)==0: |
There was a problem hiding this comment.
Division by zero error can occur when max_epochs is 0. The condition n%(max_epochs/10)==0 will fail. This should use max_epochs > 0 and n%(max_epochs/10)==0 or n%(max(1, max_epochs/10))==0.
| if n%(max_epochs/10)==0: | |
| if n % max(1, max_epochs // 10) == 0: |
HumphreyYang
left a comment
There was a problem hiding this comment.
Many thanks @bishmaybarik! Nice changes -- they are really good improvements. Here are some minor comments.
|
hi @HumphreyYang , these are extremely useful suggestions -- thanks a lot! I'll make all the necessary changes and push the updated version once ready. |
vectorized computation instead of repeatedly resetting arrays with for loops
|
📖 Netlify Preview Ready! Preview URL: https://pr-624--sunny-cactus-210e3e.netlify.app (9143f6b) 📚 Changed Lecture Pages: mccall_q |
|
📖 Netlify Preview Ready! Preview URL: https://pr-624--sunny-cactus-210e3e.netlify.app (a72d9b3) 📚 Changed Lecture Pages: mccall_q |
|
📖 Netlify Preview Ready! Preview URL: https://pr-624--sunny-cactus-210e3e.netlify.app (06e07c0) 📚 Changed Lecture Pages: mccall_q |
|
📖 Netlify Preview Ready! Preview URL: https://pr-624--sunny-cactus-210e3e.netlify.app (d5d2565) 📚 Changed Lecture Pages: mccall_q |
| qtable, s, accept_count, t, key = state | ||
| # for first interaction, just continue since error is large | ||
| # for subsequent interactions, compute actual error | ||
| error = jnp.where(t==0, δ + 1, jnp.max(jnp.abs(qtable - state[0]))) |
There was a problem hiding this comment.
The error calculation references state[0] which should be the previous qtable. This creates a circular reference since state is the current state tuple. Consider storing the previous qtable separately or using a different approach to calculate the error.
|
hi @HumphreyYang and @mmcky , may I know if you have any thoughts on these updates? It would be great to hear from you! |
|
🤖 Status note for a future session — from a maintainer investigation on 2026-07-08 into why open-PR previews 404. Context only, not instructions. Netlify preview: https://pr-624--sunny-cactus-210e3e.netlify.app/ currently returns 404. Why previews are down (repo-wide findings)1. This branch is stale — 175 commits behind 2. The arviz failure was a red herring — do NOT pin arviz or rewrite plotting. A 2026-07-07 rebuild also failed in Recommended first step for this PRUpdate this branch to This PR touches: |
|
From @bishmaybarik : hi @HumphreyYang and @mmcky , may I know if you have any thoughts on these updates? It would be great to hear from you! From me: I can handle this if you don't have time, just let me know. |
Resolve the mccall_q.md conflict by taking main's version. The JAX conversion is being dropped: mccall_q is inherently sequential Q-learning, which the style guide directs to Numba rather than JAX (see styleguide/jax.md, "Sequential: Numba wins"). Main has also since moved these functions to the np.random.default_rng Generator API in #959. The prose, heading and figure-legend improvements from this branch are reapplied in the next commit.
Reapplies the non-JAX improvements from the original JAX-conversion work on top of main's Numba implementation: - typo and wording fixes: "illegitmate", "previos", "prematurally", "algorthm", "objection to reject" -> "option to reject", "take existing wage if and update" -> "take the existing wage and update", "$Q$ map" -> "$Q$ maps", "vis a vis" -> "versus" - section headings to sentence case, per the style guide (the lecture title keeps title case) - move the crowded legend in plot_epochs below the axes in two columns, where it no longer covers the curves, and format the mean error to two decimals so the labels fit - drop a duplicated VFI computation that ran at the end of the wage distribution plotting cell and again in the cell immediately after - guard the progress-report modulus against small epoch counts Co-Authored-By: bishmaybarik <177107536+bishmaybarik@users.noreply.github.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Thanks @bishmaybarik, and apologies for the slow review — this sat much longer than it should have. I've taken the branch in a different direction rather than let it go stale, so I want to explain the reasoning. On the JAX conversion. I don't think
The branch itself makes the point: it sets This is a judgment call about the lecture, not about the work — the conversion itself is competent, and the One thing worth knowing for future conversions. There's a bug in the converted def cond_fun(state):
qtable, s, accept_count, t, key = state
error = jnp.where(t==0, δ + 1, jnp.max(jnp.abs(qtable - state[0])))
What I kept. The branch had real improvements independent of JAX, and those are now applied on top of main:
Main had also moved these functions to the Retitled accordingly. Thanks again for the work here — the reference material is in the style guide's when to use JAX checklist if you're picking up another conversion. |
📖 Netlify Preview Ready!Preview URL: https://pr-624--sunny-cactus-210e3e.netlify.app Commit: 📚 Changed LecturesBuild Info
|
✅ Translation sync completed (zh-cn)Target repo: QuantEcon/lecture-python.zh-cn
|
This PR is created to convert the
mccall_q.mdlecture codes into JAX equivalents.