calvo_machine_learn#

  • Series: lecture-python-advanced.myst

  • File: lectures/calvo_machine_learn.md

  • Audit date: 2026-08-26

  • Corpus snapshot: b83d6da399

  • Categories audited: writing, math, code, figures, references, links, admonitions (JAX out of scope)

  • Overall score: 7.2 / 10

  • Priority: HIGH

Score breakdown#

Category

Score

One-line note

Writing

3.5/10

qe-writing-002 ×12; qe-writing-005 ×9; qe-writing-003 ×4, +3 more.

Math

3/10

qe-math-002 ×14; qe-math-004 ×4; qe-math-013 (proposed) ×1, +1 more.

Code

6/10

qe-code-001 ×6; qe-code-003 ×4; qe-code-004 ×2.

JAX

out of scope

JAX rules target lecture-jax.

Figures

8/10

qe-fig-005 ×4; qe-fig-008 ×3.

References

10/10

no mechanical violations detected.

Links

10/10

no mechanical violations detected.

Admonitions

10/10

no mechanical violations detected.

Issues#

Critical#

None found.

High severity#

  • [qe-code-001] (reviewer) — Follow PEP8 unless closer to mathematical notation. Count: 6. Lines: 569, 602, 1078, 1082, 1089, 1131. Example: 161 lines carry trailing whitespace, most of them inside the code cells (554, 557, 561, 564, 567, 575, 577, 581, 583, 586, 590, 611-613, 631, 636, 638, 1084, 1087, 1091, 1094, 1098, 1131, 1133, 1313, 1317). Top-level definitions are separated by one blank line where PEP8 asks for two, at 569-570 and 577-578, and the file uses two elsewhere. T is defined two different ways for the same object: T = len(μ) - 1 in compute_θ (552) and compute_V (584), matching the mathematics where \(\tilde\mu\) has \(T+1\) components (345), but T = len(μ) in compute_vt (1082), which is why the line that the comment calls “# Define v_T” has to be written v_t[T-1] (1093). 1089-1090 gives the wrapper lambda the same parameter names as the enclosing scope, s_p = lambda θ, μ: s(θ, μ, ...), shadowing the θ and μ that the surrounding function is iterating over. Operator spacing is mixed inside single expressions: U(-α*θ) - (c / 2) * μ**2 at 1078, λ**(T - jnp.arange(T)) * μbar at 563. And 602 leaves a note to the author in the output cell, print(f'deviation = {np.abs(V_val - clq.J_series[0])}') # good!.

  • [qe-math-002] — Use \top for transpose notation. Count: 14. Lines: 860, 862, 865, 867, 870, 879, 880, 881. Example: ^T transpose in \vec{\beta}^T.

  • [qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 12. Lines: 46, 311, 367, 391, 417, 726, 1058, 1328, 1364, 1401. Example: the lecture has not been proofread, and eight of the breaks are inside sentences the reader needs. 311: “the government’s problem is static in the sense that it chooses treats that time-series as a single object”. 367: “Having specified a truncated vector \(\tilde \mu\) and and having computed”. 391: “We hope that answers will agree with those found obtained by other more structured methods”. 417: “We’ll eventually want to compare the results we obtain here to those that we obtain in those obtained in this quantecon lecture”. 726: “We start by recalling that the Ramsey problem that chooses \(\vec \mu\) to maximize the government’s value function {eq}`eq:Ramseyvalue`subject to equation {eq}`eq:inflation101`” - two relative clauses and a citation run into the next word. 1328: “appears at the peak of the function quadratic function”. 1364-1366: “Assembling these regressions, we have discovered run for our single Ramsey outcome path … that along a Ramsey plan”. 1191: “inflation at time \(t\) is determined \(\{\mu_s\}_{s=t}^\infty\)” is missing its preposition. Plus single-word typos at 46 (“money growh rates”), 1058 (“For subsquent analysis”), 1401 (“represenative agent’s”) and 1184 (“the reasoning that let Chang … to choose”).

  • [qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 9. Lines: 18, 24, 48, 59, 72, 1058, 1167, 1412. Example: prose phrases are wrapped in double backticks, which is reStructuredText quoting and renders in MyST as inline code: machine learning (18, 389, 724), dynamic programming squared (24), gradient descent (59), artificial intelligence (72) and continuation values (1058) all come out as code spans on the page. The same two terms are also given as bold - machine learning (48), human intelligence and artificial intelligence (1167) - so “machine learning” appears as code at 18, as bold at 48 and as plain text at 56 and 63, and “artificial intelligence” as code at 72 and bold at 1167. Meanwhile the double-backtick form is used correctly for a genuine identifier at 1412, 1414 and 1420 (ChangLQ), which is what makes the prose cases read as code to a reader. Italic is available and used once, for liquidity at 82, which is the treatment the scare-quoted phrases want; bold should be kept for the terms actually being defined, as at 77 (time inconsistency), 122 and 302.

  • [qe-writing-008] — Remove excessive whitespace between words. Count: 193. Lines: 18, 19, 21, 24, 27, 29, 31, 36, 39, 43, …. Example: 2 spaces.

Medium severity#

  • [qe-code-003] — Package installation at lecture top. Count: 4. Lines: 399. Example: non-Anaconda import with no install cell: [‘jax’].

  • [qe-code-004] — Use quantecon Timer context manager. Count: 2. Lines: 656, 941. Example: %%time.

  • [qe-fig-005] — Descriptive figure names for cross-referencing. Count: 4. Lines: 1035, 1221, 1262, 1308. Example: code-cell figure without mystnb figure metadata.

  • [qe-fig-008] — Use lw=2 for line charts. Count: 3. Lines: 1223, 1264, 1313. Example: plot() without lw=.

  • [qe-math-004] — Do not use bold face for matrices or vectors. Count: 4. Lines: 865, 867, 870, 872. Example: \mathbf.

  • [qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 3. Lines: 851, 865, 878. Example: 865, 867, 870 and 872 write the diagonal matrix of discount factors as \vec{\beta} \cdot \mathbf{I} - a \((T+1)\)-vector “times” an identity matrix, which is not a defined product and which the code implements as a diagonal; \(\mathrm{diag}(\vec\beta)\) says it in fewer symbols and is what the reader already knows. The vector itself is named \(\vec\beta\) (851-855) although \(\beta\) is the discount factor throughout, so \(\vec\beta\), \(\beta\) and \(\beta^t\) appear in the same three lines meaning three different things. And the truncated vector has two names: 345 and 353 introduce it as \(\tilde\mu\) and \(\tilde\theta\), which is what makes the truncation visible, but from 860 to 899 the same objects revert to \(\vec\mu\) and \(\vec\theta\) - the symbols 45-46 and 299 use for the infinite sequences - so the reader has to infer from context whether \(\vec\mu\) has \(T+1\) components or infinitely many.

  • [qe-writing-001] — Use one sentence per paragraph. Count: 1. Lines: 1151. Example: 2 sentences in one paragraph.

  • [qe-writing-003] (reviewer) — Maintain logical flow. Count: 4. Lines: 1163, 1350, 1416, 1075. Example: the numbers that carry the lecture’s conclusion are typed into the prose rather than read from the cells: 1347-1361 states the three fitted relations as \(\mu_t = .0645 + 1.5995 \theta_t\), \(\theta_{t+1} = -.0645 + .4005 \theta_t\) and \(v_t = 6.8052 - .7580\theta_t - 4.6991\theta_t^2\), all six coefficients hard-coded, while the cells at 1195-1290 recompute them from μs, θs and v_t - change \(\beta\), \(c\) or \(T\) anywhere above and the summary section silently goes stale. Second, 1416-1418 says “compute the parameters \(d_0, d_1\) for the decision rule for \(\mu_t\) and the parameters \(d_0, d_1\) in the updating rule for \(\theta_{t+1}\)” - the first pair is \(b_0, b_1\) in {eq}`eq_old9101` at 1375, and the cell at 1430 prints -(b_0, b_1), negated, with nothing said about why the sign flips before 1440 concludes that “these agree”. Third, 1163 says the two sequences “converge from above to the same constant \(\vec \mu\)”, using the sequence symbol for the scalar limit that 320 called \(\bar \mu\); the same slip appears at 311, where the pair is written (\vec mu, \vec \theta) and the missing backslash makes it render as \(\vec m u\). Fourth, two code comments point at section numbers from a different build: “# Compute g0, g1, and g2 (41.16)” (457) and “# Define function for s and U in section 41.3” (1075) - this lecture has no section 41.3, and 1191’s reference to {eq}`eq_grad_old3` is the kind of pointer that would work.

  • [qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 3. Lines: 664, 1201, 1221. Example: the three regressions that are the point of the lecture print full statsmodels OLS summaries (1201, 1247, 1290) - about twenty-five lines each of dependent-variable headers, F-statistics, AIC, BIC, skew, kurtosis and Durbin-Watson - when what the text then quotes is four coefficients and the \(R^2\) of unity (1347-1361, 1389); a three-row table of coefficient, standard error and \(R^2\) would carry the argument and leave the condition-number warning that 1297-1300 discusses visible instead of buried. Second, the comparisons against the sister lecture’s ChangLQ baseline are scattered across six bare cells that print a norm - 602, 669, 673, 677, 710, 719, 1111 - four of them consecutive and with no prose between them (664-678), so the reader meets four unexplained numbers in a row; one table of the three methods against \(\bar\mu\), \(V\) and the deviation would do the whole job. Third, only one of the five figures is named (continuation_values, 1121) and it is the only one the text can cross-reference with {numref} (1142); the three regression figures at 1221, 1262 and 1308 carry the punchline and cannot be referenced at all.

Low severity#

  • [qe-math-013 (proposed)] — Reference equations via {eq}`label`. Count: 1. Lines: 383. Example: manual reference ‘formula (1)’.

Strengths#

  • The lecture names the weakness of its own method in the introduction and then keeps the comparison running: 48 explains why “machine learning” is the right label - the approach ignores the structure that dynamic programming squared supplies and “proliferates parameters” - 52-54 casts the sister lecture as a laboratory for judging “promises and limits of machine learning approaches more generally”, and every computed object is checked against ChangLQ (602, 665-669, 710, 1440).

  • The truncation is stated as a guess, given a closed form, and then implemented as written: 316-338 assumes \(\mu_t = \bar\mu\) for \(t \geq T\) and notes that {eq}`eq:inflation101` then forces \(\theta_t \to \bar\mu\) too, 357-361 derives \(\theta_t = (1-\lambda)\sum_{j=0}^{T-1-t}\lambda^j \mu_{t+j} + \lambda^{T-t}\bar\mu\), 378-381 writes \(\tilde V\) with the \(\frac{\beta^T}{1-\beta}\) tail the truncation requires, and compute_θ (550-568) and compute_V (579-595) are those two formulas and nothing else.

  • The two approaches are distinguished by exactly what mental work each avoids (56-61): the first “hands it over to a gradient descent optimizer”, the second “exerts enough mental effort required to express the Ramsey planner’s objective as an affine quadratic form in \(\vec \mu\), computes first-order conditions …, arranges them into a system of simultaneous linear equations” - and 840-899 then does the second in full, naming \(g\), \(M\), \(F\) and \(G\) with their dimensions as it goes.

  • The restricted problem is defined against the unrestricted one rather than described loosely: 686-689 repeats the Ramsey objective and adds “the additional restriction that \(\mu_t = \bar\mu\) for all \(t\)”, 691 identifies the solution as the \(\mu^{CR}\) of {doc}`calvo`, and 710 prints the norm against clq.μ_CR.

  • The continuation values are set up as a backward recursion with a terminal condition (1060-1072), computed (1074-1101), and then used as a consistency check that the reader can see - 1104-1111 says \(v_0\) should equal the optimized \(V\) and prints the deviation - before 1142-1147 reads the orderings \(v_0 > V^{CR} > v_T\) off the figure and says what each inequality means.

  • The regression that looks backwards is flagged as such before it is run and revisited afterwards: 1189-1193 admits it “might seem strange because, after all, equation {eq}`eq_grad_old3` asserts that inflation at time \(t\) is determined [by] \(\{\mu_s\}_{s=t}^\infty\)”, and 1395-1403 returns to the discomfort - “wouldn’t that direction of fit have made more sense?” - and answers that settling it needs more economic theory.

  • The {note} at 1150-1153 does real work in two sentences: it identifies \(v_T\) as what some researchers call “the value of a Ramsey plan under a time-less perspective” and offers the more descriptive name, “the value of the worst continuation Ramsey plan”, which is exactly the reading the figure above it supports.