chang_ramsey#
Series: lecture-python-advanced.myst
File:
lectures/chang_ramsey.mdAudit date: 2026-08-26
Corpus snapshot:
b83d6da399Categories audited: writing, math, code, figures, references, links (JAX out of scope)
Overall score: 7.5 / 10
Priority: HIGH
Score breakdown#
Category |
Score |
One-line note |
|---|---|---|
Writing |
3/10 |
|
Math |
9/10 |
|
Code |
8.5/10 |
|
JAX |
out of scope |
JAX rules target |
Figures |
6/10 |
|
References |
8.5/10 |
|
Links |
10/10 |
no mechanical violations detected. |
Admonitions |
N/A |
no admonitions, exercises or solutions. |
Issues#
Critical#
None found.
High severity#
[qe-fig-001] — Do not set figure size unless necessary. Count: 5. Lines: 941, 1054, 1071, 1101, 1124. Example: figsize=.
[qe-fig-008] — Use lw=2 for line charts. Count: 5. Lines: 1057, 1079, 1104, 1105, 1131. Example: plot() without lw=.
[qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 5. Lines: 189, 330, 415, 655, 882. Example: the same construct is spelled two ways throughout. Fractions:
{M_{t-1}\over M_t}with the plain-TeX\overat 189 and 339,\fracat 202, 208, 211, 261, 905. Text inside math:{\rm if}at 330 and 574,{\rm there \ is }and{\rm with }with hand-typed spaces at 655 and 713, against\text{ such that }and\text{ if }at 345, 496, 595, 634, 665, 717, 747, 782 and 800. Multi-line displays:\begin{aligned}at 315 and 327,\begin{split}at 415 for the same job. Spacing:\hspace{2mm}hand-set at 882 where the surrounding displays use\quad. Each pair is a choice between two reasonable options where the lecture makes both choices, and in each pair the simpler and more portable form is already in use elsewhere in the file.[qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 6. Lines: 199, 750, 766, 779, 919, 980. Example: 779-801 restates a definition the reader has just read: “Above we have defined the \(D(Z)\) operator as:” is followed by the whole operator again, all four equations, in a second and differently formatted copy (the first at 712-748 uses labelled
{math}blocks, the second at 782-800 uses\existsand an inline parenthetical for the complementary-slackness clause) - twenty lines that add nothing. Three sentences are broken: 750 is “It is possible to establish.” with its object missing, 766-767 reads “This \((w, \theta)\) pair i associated with a Ramsey plan”, and 980 has “decomposed into a two subproblems”. 199 has “meassured”. And 919-920 leaves a note to the author in the text: “(Here we have set the number of subgradients to 10 in order to speed up the code for now - we can increase accuracy by increasing the number of subgradients)”, whereN_gsilently becomes 50 at 1030-1033 with no comment.[qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 11. Lines: 36, 380, 643, 669, 752, 849. Example: the two conventions are exactly inverted through most of the lecture. Bold is spent on run-in headings - Definition: at 378, 386, 460, 643, 668 and 676, Proposition: at 473, 535, 605, 752 and 757, Remark: at 663, plus Example parameterizations (252), The tax distortion function (268), Ramsey plan: (277) and Step 1/Step 2/Step 3 (849, 851, 894) - while the terms those blocks actually define are set in italic: government policy, price system, allocation (380-382), competitive equilibrium (389), admissible (643), allocation rule (669), competitive (678), outer hyperplane approximation algorithm (810-811). The rule’s assignment does appear elsewhere in the same file - competitive equilibria and Ramsey plan (36), dynamic programming squared (57), continuation Ramsey planner (978), sustainable (1140) are all bolded definitions - so the lecture contradicts itself rather than following a different convention.
[qe-writing-008] — Remove excessive whitespace between words. Count: 26. Lines: 36, 44, 46, 109, 125, 137, 214, 232, 249, 270, …. Example: 2 spaces.
Medium severity#
[qe-code-001] (reviewer) — Follow PEP8 unless closer to mathematical notation. Count: 4. Lines: 934, 943, 946, 962. Example: 934 names the function’s parameter after the class it receives,
def plot_competitive(ChangModel):, so inside the body the nameChangModelno longer refers to the class the:load:cell defined - a CapWords parameter name that PEP8 reserves for classes, and a shadowing that would break the moment the function needed to construct a second model. 946 drops the space after the comma inext_C[:,0]while 947 and 948 writeext_C[:, 1]. 962 leaves one blank line between the end of the function and the top-level callplot_competitive(ch1)where PEP8 asks for two. And 943 labels the horizontal axis'w'as a plain string withfontsize=16while 944 labels the vertical oner"$\theta$"withfontsize=18, so one axis of the same figure is typeset as maths and the other is not.[qe-fig-003] — No matplotlib embedded titles. Count: 3. Lines: 1072, 1106, 1125. Example: .suptitle.
[qe-fig-005] — Descriptive figure names for cross-referencing. Count: 2. Lines: 1053, 1100. Example: code-cell figure without mystnb figure metadata.
[qe-ref-001] — Use correct citation style. Count: 2. Lines: 44, 581. Example:
{cite}in narrative flow: ’{cite}’.[qe-writing-001] — Use one sentence per paragraph. Count: 2. Lines: 831, 851. Example: 2 sentences in one paragraph.
[qe-writing-003] (reviewer) — Maintain logical flow. Count: 4. Lines: 490, 594, 897, 1022. Example: 1022-1023 says “The two sets of parameters differ only in the level of \(\beta\)”, and the cell immediately below differs in five arguments:
ch1 = ChangModel(β=0.3, mbar=30, h_min=0.99, h_max=1/0.3, n_h=8, n_m=35, N_g=50)againstch2 = ChangModel(β=0.8, mbar=30, h_min=0.1, h_max=1/0.8, n_h=20, n_m=50, N_g=50)(1030-1033). Worse, the \(\Omega\) bounds quoted at 1025-1027 as coming “From the figures earlier in this lecture” were produced by the earlier pair of models (929, 967), which usedh_min=0.9,h_max=2andN_g=10, so the sets and the value functions that 1050-1051 says “trace out the right edges of the sets of equilibrium values plotted above” were computed from different economies; and 1038 then solves withθ_min=0.045, θ_max=0.15against the \(\Omega = [0.0395, 0.2193]\) just quoted. Second, \(\theta\) is defined at 353 as \(u'(f(x_{t+1})) m_{t+1} h_{t+1}\) and from 490 onward is used as \(u'(f(x))(m+x)\) (490, 496, 506, 514, 558, 731, 792, 874, 999) with no word about why the two agree - the reader has to notice that{eq}`eqn_chang_ramsey2a`, \(-x = m(1-h)\), gives \(mh = m+x\). Third, the two set-valued operators are broken across display blocks in a way that leaves their delimiters unmatched: 594-597 writesB(Q) = \theta \in \mathbb{R} \text{ such that there is } (m,x,h,\theta') \in E \times Qwith no set braces at all, and \(D(Z)\) opens\Bigl\{at 713 and closes\Bigr\}at 747, five separate displays and two prose lines later. Fourth, 897 promises “We have created a Python class that solves the model” and the cell at 922-926 is a bare:load:of_static/lecture_specific/chang_credible/changecon.py- a file in another lecture’s directory - with no listing and no link, so the nine-step algorithm just described at 837-895 cannot be checked against the code that implements it.[qe-writing-004] — Avoid unnecessary capitalization in narrative text. Count: 2. Lines: 852, 887. Example: mid-sentence ‘Step’.
[qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 3. Lines: 378, 815, 837. Example: the lecture’s subject is a set - \(S\), approximated as an intersection of half-spaces, \(\tilde S = \{(w,\theta) \mid H \cdot (w,\theta) \leq C\}\) (828) - and the algorithm that finds it is described in nine steps of prose and linear programs (837-895) with no picture of the mechanism: one sketch of a convex set with three or four supporting hyperplanes, their subgradients \(h_i\) and levels \(C_{i,t}\), and the next iterate nested inside, would make “constructs the smallest convex set that contains the fixed point” (815-816) and “a sequence of progressively smaller sets \(S_{t+1} \subset S_t \subset \cdots \subset S_0\)” (890-892) immediate. The lecture plots the converged set (938-963) but never the construction. Second, six Definitions and five Propositions are bold text (378, 386, 460, 473, 535, 605, 643, 668, 676, 752, 757) rather than
{prf:definition}and{prf:proposition}directives, so none of them is numbered or linkable and the prose has to refer back by phrase - “the proposition relies on knowing the set \(\Omega\)” (577-578), “The proposition characterizes \(\Omega\)” (610). Third, the lecture has no admonition of any kind, although the parenthetical asides at 479 and 919-920 and the Remark at 663-666 are exactly what{note}renders.
Low severity#
None found.
Strengths#
The recursive representation is earned rather than assumed: 348-353 defines \(\theta_{t+1} \equiv u'(f(x_{t+1})) m_{t+1} h_{t+1}\), 360-363 says what it does (“\(\theta_{t+1}\) intermediates the influences of \((\vec x_{t+1}, \vec m_{t+1})\) on the household’s choice of real balances \(m_t\)”), 365-367 then defines “intermediates” - the future paths act on \(m_t\) only through that one scalar - and 369-371 says why this is the step that makes a recursive representation possible.
The “Inventory of objects in play” section (395-450) lists the four constructions the lecture will build, each with its role, before any of them is used: the set \(\Omega\) of initial marginal utilities, recursive competitive equilibria as a four-tuple \((h, m, x, \Psi)\), the recursive Ramsey plan, and the revolution experiment at 438-450 that gives time-inconsistency an operational meaning.
The Abreu-Pearce-Stacchetti step is stated in the smallest form the argument needs - “The continuation of a competitive equilibrium is a competitive equilibrium” (474), with the formal version beside it at 476-477 - and then used at 607-611 to characterise \(\Omega\) as the largest fixed point of \(B\), with monotonicity (613-614) supplying the iteration that computes it.
The outer hyperplane algorithm is given as three numbered steps (839-847) and then each is unpacked in order (849-895), including the linear program that implements Step 2 written out in full with its five constraints (859-883), so the reader can see where the discretisation of \((m, h)\) enters.
The two discount factors are chosen to produce a contrast that the figures then verify: 1086-1098 predicts that \(\theta'\) hits the upper limit of \(\Omega\) for \(\beta = 0.3\) but settles in the interior for \(\beta = 0.8\), and the cell at 1100-1109 plots \(\theta'(\theta)\) against the 45-degree line, which is exactly the diagnostic that claim needs.
The wasteful operator \(D\) is introduced with its own justification attached (688-698): it works with a larger state vector than a Ramsey plan needs, and the lecture says so, then gives the two reasons to meet it anyway - it prepares the reader for \(\tilde D(Z)\) in the sequel and its fixed point is a good initial set for those iterations.
The value-function approximation is checked before it is used: 1041-1047 prints the maximum residual between iterates on a fine grid for both models, so the policy and simulation figures that follow rest on a stated accuracy rather than on trust.
Recommended actions#
Delete the duplicated \(D(Z)\) definition at 779-801 and have the section that needs it refer back to 712-748.
Fix the parameter claim at 1022-1023: the two models differ in \(\beta\),
h_min,h_max,n_handn_m(1030-1033), and the \(\Omega\) bounds quoted at 1025-1027 come from the earlier pair (929, 967), which used differenth_min,h_maxandN_g- either re-solve the value functions on the models that produced the plotted sets, or say which parameters changed and why.Repair the three broken sentences (750, 766-767, 980) and the typo at 199, and either drop the “for now” aside at 919-920 or say there why
N_gis 10 here and 50 at 1030.Close the set-builder notation: give \(B(Q)\) its braces at 594-597, and bring \(D(Z)\) (713-747) into a single display so the
\Bigl\{and\Bigr\}are in the same block.Convert the six Definitions and five Propositions (378, 386, 460, 473, 535, 605, 643, 668, 676, 752, 757) to
{prf:definition}and{prf:proposition}so they are numbered and referenceable, and swap the bold and italic: bold the terms being defined (380-382, 389, 643, 669, 678, 810), italicise the emphasis.Add one diagram of the outer hyperplane approximation - a convex set, three supporting hyperplanes with their subgradients, and the smaller next iterate - beside the algorithm at 837-895, and add the one-line derivation \(mh = m + x\) where \(\theta\) changes form at 490.
Make the model code visible: link or list
changecon.pywhere 897 promises the class, and note that it is loaded fromchang_credible’s static directory rather than this lecture’s.Sweep the mechanical items: rename the
ChangModelparameter at 934, drop the 5figsize=overrides (941, 1054, 1071, 1101, 1124) and thefontsize=overrides (943, 944, 1072, 1080, 1081), move the 3suptitle/titlecalls (1072, 1106, 1125) intomystnbcaptions and give the two figure cells names (1053, 1100), addlw=2to the 5 line plots, switch the 2 narrative{cite}roles at 44 and 581 to{cite:t}, lowercase “Step” at 852 and 887, and clear the 26 double spaces and the two two-sentence paragraphs at 831 and 851.