phillips_self_confirming#

  • Series: lecture-python.myst

  • File: lectures/phillips_self_confirming.md

  • Audit date: 2026-08-26

  • Corpus snapshot: e25fdf2345

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

  • Overall score: 8.1 / 10

  • Priority: LOW

Score breakdown#

Category

Score

One-line note

Writing

5.5/10

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

Math

7/10

qe-math-010 (proposed) ×3; qe-math-009 ×2.

Code

8.5/10

qe-code-001 ×3.

JAX

out of scope

JAX rules target lecture-jax.

Figures

6/10

qe-fig-005 ×2; qe-fig-004 ×4; qe-fig-001 ×6, +1 more.

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-fig-001] — Do not set figure size unless necessary. Count: 6. Lines: 242, 419, 463, 496, 545, 583. Example: figsize=.

  • [qe-math-010 (proposed)] — Blackboard \mathbb{P}, \mathbb{E}, \mathbb{V} with braces. Count: 3. Lines: 166, 172, 180. Example: non-blackboard \operatorname{cov}.

Medium severity#

  • [qe-code-001] (reviewer) — Follow PEP8 unless closer to mathematical notation. Count: 3. Lines: 200, 313, 465. Example: the class names the intercept one underscore away from the slope, and then renames it outside the class. 199-202 has γ1 = for \(\gamma_1\) and γ_1 = (γ1**2 + 1) * U_star for \(\gamma_{-1}\) - two names differing by a single underscore that denote opposite subscripts - and 218-219 unpacks them as γ1_C, γ0_C and γ1_K, γ0_K, so the intercept has three names within twenty lines: \(\gamma_{-1}\) in the maths, γ_1 inside the class, γ0_* outside it. The same pair appears again at 208-210. 313 unpacks three values and uses one, P, F, d = lq.stationary_values(), exactly as phillips_adaptive.md:220 does - pyflakes cannot see unused names bound by tuple unpacking, so this is invisible to flake8. 465 is the file’s one long line at 81 characters. Everything else is clean: flake8 (--select=E1,E2,E5,E7,W2,W3,W6,F,C4 --max-line-length=79) reports nothing further, Greek identifiers are used throughout, and ** is written tight.

  • [qe-fig-004] — Caption formatting conventions. Count: 4. Lines: 235, 405, 449, 476. Example: caption of 11 words.

  • [qe-fig-005] — Descriptive figure names for cross-referencing. Count: 2. Lines: 540, 577. Example: code-cell figure without mystnb figure metadata.

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

  • [qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 2. Lines: 175, 166. Example: the intercepts are subscripted \(-1\) (175, 184, 197, 205) where \(0\) is the conventional and simpler index for a constant term - and the lecture’s own code agrees with the convention rather than the notation, unpacking them as γ0_C and γ0_K at 218-219 and printing them as γ_(-1) at 222 and 224 to paper over the difference. Second, one display mixes two operator styles and two bracket conventions: {eq}`sc_moments` at 162-166 writes \(\mathbb{V}[U_t]\) and \(\mathbb{V}[y_t]\) with blackboard bold and square brackets, then \(\operatorname{cov}(U_t, y_t)\) with a lowercase roman operator and parentheses, all in one three-term equation - and 172 and 180 repeat the mixture. \(\mathbb{C}[U_t, y_t]\), or \(\mathbb{V}\) and \(\operatorname{Cov}\) consistently, would make the three moments read as three moments.

  • [qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 3. Lines: 399, 49, 58. Example: 399 is 41 words with an em-dash aside carrying a second claim: “The induction hypothesis embedded in the adaptive expectations scheme, together with a high discount factor, delivers this improvement — and because \(C\) is now an equilibrium outcome, the mechanism is sharper than in {doc}`phillips_adaptive`, where \(C\) could be manipulated independently of \(\delta\).” The two halves are independent and each is worth a paragraph. Both of the Overview’s load-bearing sentences are also overloaded: 49 is 38 words and is the definition of the lecture’s title concept split across three coordinated clauses, and 58 is 36 words that name a second equilibrium concept, cite two other lectures and state a result. 474 is 34 words with a nested em-dash citation, and 231 is 32. Five sentences past 32 words in a file whose qe-writing-001 count is zero.

  • [qe-writing-003] (reviewer) — Maintain logical flow. Count: 4. Lines: 107, 184, 77, 578. Example: the lecture introduces its general model and then never computes it. 97 says the actual Phillips curve “extends the one used in earlier lectures to allow for serially correlated shocks”, 102-105 gives {eq}`sc_actual` with \(\rho_1\), \(\rho_2\) and a vector white noise, and 107 immediately sets both to zero “for much of this lecture” - after which they are never nonzero anywhere in the file. The {note} at 142-151 then describes what the general case would take (a fixed point of \(\gamma = T(h(\gamma))\), moments from a discrete Lyapunov equation, a relaxation iteration \(\beta_{j+1} = \kappa\beta_j + (1-\kappa)S(\beta_j)\)) and no code implements any of it. That would be a fair scoping decision except that 276 makes \(\rho_1 = \rho_2 = 0\) the reason the induction hypothesis fails - “the self-confirming equilibria are serially uncorrelated, so lagged inflation drops out of the empirical Phillips curves” - so the reader is told that the interesting case is precisely the one not computed. Second, 184 asserts the Keynesian intercept \(\beta_{-1} = -\frac{\beta_1^2+1}{\beta_1}U^*\) with no derivation; it is not the analogue of 175’s classical formula but follows from imposing 175 on the inverted coefficients (I checked: \(\gamma_{-1} = -\beta_{-1}/\beta_1\) together with \(\gamma_{-1} = (\gamma_1^2+1)U^*\) and \(\gamma_1 = 1/\beta_1\) gives it), and 175’s own “requirement that the means lie on the regression line” silently uses \(\bar U = U^*\) and \(\bar y = \bar x\), neither stated. Third, \(X_{t-1}\) (77, 82, 122, 124) and the lag operator \(L\) (102, 323, 332) are used throughout and defined nowhere in this file - 71’s “Recall from {doc}`phillips_adaptive`” is the only pointer, and that lecture’s own indexing of \(X\) is off by one period (see its overlay), so the inheritance is of a defect. Fourth, exercise 2’s solution rebinds body state: 578 reassigns mp and 581 reassigns C_star, the objects the body established at 388-389 and that the figures at 456-457 and 492-493 depend on, and 456 also rebinds ν_star from 389. The values happen to agree because \(\delta = 0.97\) both times, so nothing visibly breaks - which is exactly why it will break later.

  • [qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 3. Lines: 58, 274, 53. Example: one concept carries two bolded names inside this lecture and a third in its sibling. 58 bolds equilibrium with misspecified beliefs and 335 bolds equilibrium under forecast misspecification - 277 lines apart, for the same object - while phillips_misspecified.md:227-231 defines it in a {prf:definition} titled “Equilibrium under forecast misspecification”. A reader cannot tell whether 58 and 335 name one thing or two. Second, 274 bolds induction hypothesis, which phillips_adaptive.md:366 has already bolded as its definition; this is the third instance of the suite bolding an already-defined term (phillips_adaptive.md:349 re-bolds Phelps problem, phillips_learning.md:206 re-bolds mean dynamics). Third, the two directions of fit are italicised in the Overview and bolded in the body of the same lecture: 53 has “(a classical identification) or … (a Keynesian identification)” and direction of fit, while 129 and 136 have classical and Keynesian inside {prf:definition} sc_def - and phillips_adaptive.md:335, 347 italicises all three. The genuine definition, self-confirming equilibrium at 49, is correctly bolded and is the one the lecture owns.

  • [qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 3. Lines: 235, 142, 540. Example: {numref}`fig-sce-two-curves` (235-261) draws the two perceived Phillips curves and marks the two mean outcomes, and omits the two things the section is arguing about: the actual Phillips curve \(U = U^* - \theta(y - x)\) that both beliefs are wrong about, and the Ramsey point. So 270’s claim - “Both self-confirming equilibria give a mean outcome worse than the Ramsey outcome” - cannot be read off the figure it follows, although phillips_credibility.md:213-246 draws exactly that comparison for the same economy, marking both Nash and Ramsey. Two ax.plot calls would fix it. Second, the {note} at 142-151 is the lecture’s account of how a general self-confirming equilibrium is computed, and it is three paragraphs of prose with no code and no picture; meanwhile the other fixed point in the lecture does get drawn, in a dropdown solution (577-593). The general case is the one that needs the picture. Third, exercise 1’s figure (540-553) is dominated by its own axis range: I ran it, and Keynesian mean inflation is 5.14 at \(\sigma_1 = 0.05\) and 60.6 at \(\sigma_1 = 1.0\), so the behaviour the exercise asks about (531, “What happens as \(\sigma_1 \to 0\), and why?”) is squeezed into the bottom twelfth of the axes next to the Nash line at 5. A log \(y\)-axis, or stopping the grid at \(\sigma_1 = 0.5\), would show the question being answered.

Low severity#

None found.

Strengths#

  • The two static equilibria are computed by hand and both formulas check out from first principles: the classical intercept \(\gamma_{-1} = (\gamma_1^2+1)U^*\) (175) follows from the static first-order condition \(\bar y = -\gamma_1\gamma_{-1}/(\gamma_1^2+1)\) together with \(\bar U = U^*\), and the Keynesian intercept (184) follows from imposing that same relation on the inverted coefficients. Running the code gives \(\gamma_1 = -1\), \(\gamma_{-1} = 10\), mean inflation \(5\) for the classical fit and \(\beta_1 = -0.5\), \(\gamma_1 = -2\), \(\gamma_{-1} = 25\), mean inflation \(10\) for the Keynesian - so 231’s “twice as high, at \(10\)” is exact and not approximate.

  • {eq}`sc_bray11` is derived correctly and the code transcribes it: substituting \(y_t = f_1 + f_2 x_t + v_{2t}\) into \(x_t = Cy_{t-1} + (1-C)x_{t-1}\) really does give the filter \(\frac{1-(1-C)L}{1-[1-C(1-f_2)]L}\) with mean \(f_1/(1-f_2)\), which is exactly ψ = 1 - C * (1 - f2) and ν = f1 / (1 - f2) at 356-357.

  • The central quantitative claims all hold when the code is run. 397’s “substantially below the Nash value of \(5\)” is a factor of five: \(C^* = 0.1138\), policy \(y = 0.711 + 0.335x\), mean inflation \(\nu = 1.069\). 434’s monotone decline toward Ramsey holds across the whole grid: \(\nu = 1.397, 1.244, 1.069, 0.858, 0.584, 0.393\) at \(\delta = 0.95, \ldots, 0.995\). 472’s “match well at all but the lowest frequencies” is quantitatively right - the log gap between the two spectra is 5.5 at \(\omega = 0\), 0.33 at the twentieth of 512 frequencies and under 0.02 beyond the hundredth. And 505’s “nonzero asymptote” is right: the approximating impulse response is still 0.097 at lag 24 against 0.006 for the true one.

  • Exercise 1’s answer is correct in both limits, and I checked both: as \(\sigma_1 \to 0\) the Keynesian slope really does approach \(-1/\theta\) (\(\beta_1 = -0.973\) at \(\sigma_1 = 0.05\)) and mean inflation approaches Nash (5.14), while at \(\sigma_1 = 1\) the slope flattens to \(-0.083\) and mean inflation reaches 60.6 - so 555-557’s mechanism is the right one and not a plausible story.

  • {prf:definition} sc_def at 117-130 lists conditions (a)-(d) separately and 136-138 then produces the second equilibrium by replacing exactly one of them with (d′), so the whole finding of the section - that the direction of minimization changes outcomes - is expressed as a one-clause difference between two definitions.

  • The impulse-response comparison at 483-502 is normalised consistently: {eq}`sc_bray11`’s \(f(L)\) carries no leading gain, so both responses are unit-innovation responses and both start at 1.0. This is the correct handling, and it is worth saying because the sibling lecture does the same comparison differently - phillips_misspecified.md:335 applies its scale factor to one series and not the other.

  • The spectrum is written the simple way, \(F(\omega; C) = |f(e^{i\omega})|^2\sigma_2^2\) (327), rather than as the product \(f(e^{i\omega})f(e^{-i\omega})\sigma^2\) that phillips_misspecified.md:142 uses for the same object.

  • 268-278 answers the question the section raises rather than leaving it: “Why not Ramsey?” is answered by naming what fails (the induction hypothesis), why it fails (\(\rho_1 = \rho_2 = 0\) makes the equilibria serially uncorrelated so lagged inflation drops out), and what the consequence is (the government in effect solves a one-period problem).

  • The {note} at 436-443 separates what is robust from what is an artefact of the near-unit-root approximation, and points at the lecture where that approximation is discussed - which is the honest way to report numbers that depend on a \(\rho\) chosen for numerical convenience.