[ar1_turningpts] Removed PyMC and changed the style #584
Conversation
|
@xuanguang-li this is a big translation effort. Nice work! @HumphreyYang would you have time to review (no rush). |
|
@xuanguang-li sorry I just saw you have applied the |
There was a problem hiding this comment.
Pull Request Overview
This PR modernizes an econometric forecasting lecture by replacing PyMC with NumPyro and implementing JAX-based optimizations for significant performance improvements (3m → 2.7s). The changes maintain the educational content while improving computational efficiency through vectorization and functional programming patterns.
Key changes:
- Framework Migration: Replaced PyMC with NumPyro for Bayesian inference and switched to JAX for numerical computing
- Performance Optimization: Eliminated Python loops using JAX's
lax.scanand vectorized operations - Code Restructuring: Introduced an
AR1class and separated plotting functions for better organization
|
Thanks @mmcky. I will remove the |
|
Hi @mmcky and @HumphreyYang, this PR is ready for review. |
|
We don't need an instantiation function here. Defaults can be stored in the class. class AR1(NamedTuple):
"""
Represents a univariate first-order autoregressive (AR(1)) process.
Parameters
----------
ρ : float
Autoregressive coefficient, must satisfy |ρ| < 1 for stationarity.
σ : float
Standard deviation of the error term.
y0 : float
Initial value of the process at time t=0.
T0 : int, optional
Length of the initial observed path (default is 100).
T1 : int, optional
Length of the future path to simulate (default is 100).
"""
ρ: float
σ: float
y0: float
T0: int
T1: int
def make_ar1(ρ: float, σ: float, y0: float, T0: int = 100, T1: int = 100):
"""
Factory function to create an AR1 instance with default values for T0 and T1.
Returns
-------
AR1
AR1 named tuple containing the specified parameters.
"""
return AR1(ρ=ρ, σ=σ, y0=y0, T0=T0, T1=T1) |
|
I'm not in favor of dropping down into I recommend using def plot_Wecker(ar1: AR1, initial_path, ax, N=1000):
"""
Plot the predictive distributions from "pure" Wecker's method.
Parameters
----------
ar1 : AR1
An AR1 named tuple containing the process parameters (ρ, σ, T0, T1).
initial_path : array-like
The initial observed path of the AR(1) process.
N : int
Number of future sample paths to simulate for predictive distributions.
"""
# Plot simulated initial and future paths
y_T0 = initial_path[-1]
future_path = AR1_simulate_future(ar1, y_T0, N=N)
plot_path(ar1, initial_path, future_path, ax[0, 0])
# Simulate future paths and compute statistics
def step(carry, n):
future_temp = future_path[n, :]
(next_reces, severe_rec, min_val_8q, next_up_turn, next_down_turn
) = compute_path_statistics(initial_path, future_temp)
return carry, (next_reces, severe_rec, min_val_8q, next_up_turn, next_down_turn)
_, (next_reces, severe_rec, min_val_8q, next_up_turn, next_down_turn
) = lax.scan(step, None, jnp.arange(N))
# Plot path statistics
plot_path_stats(next_reces, severe_rec, min_val_8q,
next_up_turn, next_down_turn, ax)
fig, ax = plt.subplots(3, 2, figsize=(15, 12))
plot_Wecker(ar1, initial_path, ax)
plt.show() |
|
Hi @jstac, thanks for your comment.
Do you mean we should write the link as |
Thanks @xuanguang-li . I can't remember but it should be in the manual -- or @mmcky will know. |
|
Thanks for your reminding @jstac. I found it in the manual Referencing a lecture in a different lecture series. |
|
thanks @xuanguang-li -- glad you found it https://manual.quantecon.org/styleguide/doclinks.html#referencing-a-lecture-in-a-different-lecture-series -- let me know if we need to configure |
|
📖 Netlify Preview Ready! Preview URL: https://pr-584--sunny-cactus-210e3e.netlify.app (f802f51) 📚 Changed Lecture Pages: ar1_turningpts |
|
Hi @jstac, I have implemented the review comments in the latest commit. Thanks, @mmcky. I realized this link points to a lecture in the same series, so we can reference it directly. However, a warning is raised when using the standard Markdown link |
|
Thanks @xuanguang-li . We appreciate you thinking carefully about this and correctly diagnosing the problem. But we always want consistency @xuanguang-li , not special cases. The best action here is to change the name of the subsection and anything that refers to it --- and then use the standard method from the manual for the link to the lecture. Such a section name should never have been created -- since it interferes with links across lectures -- and this is a good opportunity to fix it. |
|
Thanks @jstac. Sorry, I didn't look into the problem explicitly. You are right; no subsection used this label. According to the log, the issue seems to arise because
I agree that we should avoid special cases, but I think we are not making an exception because the |
|
Thanks for further thoughts @xuanguang-li . They are appreciated. @mmcky -- perhaps you could add your input? |
|
🤖 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-584--sunny-cactus-210e3e.netlify.app/ currently returns 404. Why previews are down (repo-wide findings)1. This branch is stale — 181 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 ⭐ Directly relevant to this PRThis PR edits Recommended first step for this PRUpdate this branch to This PR touches: |
Bring PR #584 to a mergeable, style-compliant state. Verified end-to-end on a GPU box (numpyro NUTS + JAX), ~110s, all 5 figures render. Blocking fixes: - Correct `NamedTuplep` import typo that broke the whole build - Vectorize the NumPyro likelihood (was a per-observation Python loop creating one sample site per datum) to match ar1_bayes.md - Fix plot_extended_Wecker plotting an undefined `future_path` (it fell back to the true-parameter global); now plots the posterior-draw paths - Adapt to arviz 1.x: az.plot_trace -> az.plot_trace_dist (new API drops data=/compact=/lines=/backend_kwargs=); update prose for the new left-column densities / right-column traces layout Style-guide compliance (QuantEcon.manual): - Add create_ar1() factory with parameter validation - @jax.jit the hot compute_path_statistics - lw=2 on line charts; tidy figure captions; revert header to .myst - Restore the true-parameters vs posterior legend on the comparison plot - Remove orphaned `colors` variable Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Pushed fixes on top of this branch (merged latest Correctness / build blockers
arviz 1.x
Style / polish
Note: the NumPy→JAX RNG switch changes every figure's exact values (expected per the migration guide); shapes/scales and the narrative still hold. |
|
Many thanks @xuanguang-li for your hard work on this PR! I've asked Claude to make some minor edits. I'll merge when it's green. |
📖 Netlify Preview Ready!Preview URL: https://pr-584--sunny-cactus-210e3e.netlify.app Commit: 📚 Changed LecturesBuild Info
|
Redone on top of the numpyro/JAX rewrite of ar1_turningpts (#584). - Cross-reference ar1_bayes from ar1_turningpts (overview, model setup, and posterior section) and add a forward {seealso} link back - Frame the posterior computation as the "conditioning assumption" of ar1_bayes, apt here since the path starts from an atypical y_0 - Match the AR(1) model introduction to the bulleted style of ar1_bayes (and write IID rather than i.i.d.) - Add a Conclusion and interpretation for the original/extended Wecker figures, tying back to the two sources of uncertainty Note: N_t is already defined and figures already use MyST captions in the rewritten lecture, so those earlier fixes are no longer needed. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for your review, @jstac! The commit helped to fix many typos and style issues. |

Key changes:
Numpyroto compute posteriors instead.AR1class to pack parameters, separated plotting functions, and packed path statistics computation functions.forloops: Usedlax.scanin almost all loops except for plotting functions and theNumpyromodel.numpy.random: Usedjax.randomfor simulation and fixed the random seed withPRNGKey(0).This improved the efficiency of the main function from 3m to 2.7s on my computer!