time_series_with_matrices#

  • Series: lecture-python-intro

  • File: lectures/time_series_with_matrices.md

  • Audit date: 2026-08-26

  • Corpus snapshot: a12d17c0ef

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

  • Overall score: 7.4 / 10

  • Priority: HIGH

Score breakdown#

Category

Score

One-line note

Writing

3/10

qe-writing-004 ×7; qe-writing-001 ×2; qe-writing-005 ×4, +4 more.

Math

6/10

qe-math-003 ×7; qe-math-011 (proposed) ×1; qe-math-009 ×3.

Code

7.5/10

qe-code-001 ×6.

JAX

out of scope

JAX rules target lecture-jax.

Figures

7/10

qe-fig-005 ×9; qe-fig-008 ×9; qe-fig-001 ×1.

References

10/10

no mechanical violations detected.

Links

8/10

qe-link-002 ×3.

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: 394, 401, 473, 526, 550, 637. Example: 394 names a class population_moments where PEP8 asks for CapWords; the rule’s escape hatch is “unless closer to mathematical notation”, and there is no mathematics being approximated by a lowercase-with-underscores class name - contrast the Greek identifiers α_0, σ_u, μ_y, Σ_y, which are exactly the justified departure the rule has in mind. 637 writes β ** np.arange(0, T-i) with spaces around the exponentiation operator, which the rule names explicitly (“write a**b”), and the same file gets it right at 449 (σ_u**2). Missing space after the comma in a slice at 473 (ys[i,:]), 526 (Σ_y[72:,72:]) and 550 (A_inv[0:7,0:7]). And 24 lines carry trailing whitespace, most of it inside the class - every keyword argument line of the two constructor calls (401-407, 499-504) plus the blank-but-indented lines at 428, 450 and 455; in narrative text 214 and 514 end in two spaces, which Markdown reads as a hard line break in the middle of a paragraph.

  • [qe-fig-005] — Descriptive figure names for cross-referencing. Count: 9. Lines: 222, 254, 315, 328, 346, 466, 486, 655, 670. Example: code-cell figure without mystnb figure metadata.

  • [qe-fig-008] — Use lw=2 for line charts. Count: 9. Lines: 223, 255, 316, 474, 488, 656, 657, 673, 674. Example: plot() without lw=.

  • [qe-math-003] — Use square brackets for matrix notation. Count: 7. Lines: 93, 100, 107, 284, 607, 613, 619. Example: array used as matrix.

  • [qe-writing-004] — Avoid unnecessary capitalization in narrative text. Count: 7. Lines: 371, 518, 533. Example: mid-sentence ‘Distribution’.

  • [qe-writing-008] — Remove excessive whitespace between words. Count: 27. Lines: 40, 373, 391, 460, 462, 464, 496, 512, 516, 520, …. Example: 2 spaces.

Medium severity#

  • [qe-link-002] — Use doc links for cross-series references. Count: 3. Lines: 371, 518, 533. Example: raw link to python.quantecon.org.

  • [qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 3. Lines: 93, 275, 388. Example: the two stacked systems (93-114, 607-625) annotate each block with \underset{\equiv A}{\underbrace{...}} - two nested decoration commands wrapped around a \left[ \begin{array} \right] - four times, where the lecture’s own plainer idiom twenty lines later does the same job better: 119-127 writes A y = b and then names \(y\) in a separate display. The normal distribution is written two different ways: plain N\left(0, \sigma_{u}^{2}\right) at 275 and {\mathcal N}(\mu_y, \Sigma_y) at 376, so the same object carries a decoration in one place and not the other (the decoration itself is what qe-math-011 (proposed) counts; the inconsistency is the simplicity problem). And 388 writes the identity as I_{T \times T}, spelling its dimensions as a subscripted product where plain \(I\) suffices because \(T\) is fixed for the whole lecture, and writes the transpose as (A^{-1})^T rather than (A^{-1})^\top - the drafted report shows no qe-math-002 finding because the checker cannot see this shape (see scanner_doubts). \left( \right) also wraps contents that can never grow tall at 275, 302 and 590.

  • [qe-math-011 (proposed)] — Distribution names in plain letters, not \mathcal / \mathbb. Count: 1. Lines: 376. Example: decorated distribution {\mathcal N}.

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

  • [qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 3. Lines: 464, 535, 543. Example: 535 is a sentence whose content is that there will be no content: “There is a lot to be learned about the process by staring at the off diagonal elements of \(\Sigma_y\) corresponding to different time periods \(t\), but we resist the temptation to do so here.” 541-547 spends four lines and a one-item bullet list getting to a single print call at 550: “Let’s print out \(A^{-1}\) and stare at its structure”, then a bulleted rhetorical question “* is it triangular or almost triangular or \(\ldots\) ?” (543), then “To study the structure of \(A^{-1}\), we shall print just up to \(3\) decimals” (545) - which describes nothing the cell does, since the precision was set globally at line 57 - and then “Let’s begin by printing out just the upper left hand corner” (547). And 464 has lost a conjunction: “generating \(N\) time realizations of \(y\) plotting them together with population mean \(\mu_y\)”.

  • [qe-writing-003] (reviewer) — Maintain logical flow. Count: 3. Lines: 499, 645, 665. Example: 499-509 silently replaces the model. Line 496 says “let’s print out the covariance matrix \(\Sigma_y\) for a time series \(y\)”, but the cell instantiates population_moments(α_0=0, α_1=.8, α_2=0, T=6, y_neg1=0., y_0=0., σ_u=1) - a first-order autoregression with zero drift and zero initial conditions, not the Samuelson second-order model the reader has followed for 400 lines - and the conclusions at 512-514 about the superdiagonal of \(\Sigma_y\) are drawn from that unannounced substitute, after which 523 switches back to the defaults just as silently. 645 does the same to the shocks: σ_u = 0. turns off the randomness the preceding three sections were built around, so both price figures (655, 670) are deterministic, while the display at 589-591 still writes \(y = A^{-1}(b + u)\) and nothing in the prose says \(u\) has been set to zero. And 665 asks the reader “Can you explain why the trend of the price is downward over time?” in a lecture that has no exercises and no solutions, so the question has nowhere to land - the one-sentence answer (the sum \(\sum_{j=0}^{T-t}\) in 596 loses a term every period) is never given.

  • [qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 4. Lines: 31, 78, 85, 574. Example: definitions are set in italic about as often as in bold, and one term appears both ways. Bold is used correctly for second-order linear difference equation (29-30), national income and gross domestic product (75-76), autoregressive and moving average (40, 567, 570), second-order stochastic linear difference equation (266-267), statistical stationarity (462) and stationary (514). But multiplier-accelerator model - the model the whole lecture is built on - is introduced in italic at 31; the {note} at 83-88 defines three terms in italic (boundary conditions 85, initial conditions and terminal conditions 86, after initial conditions already appeared in italic at 73); and the forward-looking section defines four more the same way (backward looking 574, forward looking 577, perfect foresight 579-580 and again 593). Worst, line 78 sets “Equation {eq}`tswm_1` is called a second-order linear difference equation” in italic - the same term the lecture bolded at 29-30, and 78 is the sentence that actually defines it. Genuine emphasis in italic is rare and correct (not at 512), so the file is not overusing italic; it is using it for the wrong job. One markup slip in the same family: 230 nests the emphasis inside a cross-reference label, {ref}steady statescalar-dynam:steady-state``.

  • [qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 3. Lines: 255, 474, 488. Example: the lecture draws nine figures and never once puts two series on one set of axes where the comparison is the point. 237-238 announces the contrast between the general path and the constant steady-state path and then plots them in two separate figures (222, 254) that a reader has to flip between; the same happens for the price paths (655, 670), which differ only in the initial conditions. The lecture already knows the idiom - 656-660 plots \(y\) and \(p\) together with a legend - so it is a missed application, not a missing skill. 466-479 plots the population mean inside the sampling loop (474), so the red line is drawn a hundred times, and it is given no label and no legend, which means nothing on the figure identifies the one curve the figure exists to show. And 486-489 is the only figure in the file with no axis labels at all - every other plot sets xlabel and ylabel - even though 492 immediately asks the reader to notice how “the population variance increases and asymptotes”, a claim about the very axes that are unlabelled.

Low severity#

  • [qe-fig-001] — Do not set figure size unless necessary. Count: 1. Lines: 54. Example: style override.

Strengths#

  • The lecture checks its own claims in code at the moment it makes them: 198-202 solves the system a second way and asserts np.allclose(y, y_second_method), and 205 claims \(A\) is lower triangular with 209 verifying np.allclose(A, np.tril(A)) in the very next cell - so two statements a reader would otherwise have to take on trust are executable.

  • Both {note} admonitions earn their place by carrying a caveat the main argument does not need: 83-88 states the two-boundary-condition requirement exactly where a reader starts wondering why \(y_0\) and \(y_{-1}\) are handed over, and 212-218 explains why the lecture keeps using np.linalg.inv after having just recommended np.linalg.solve - the honest answer being that A_inv is reused later.

  • Unicode Greek is used throughout the code as qe-code-002 asks (α_0, α_1, α_2, σ_u, β, μ_y, Σ_y) and the naming keeps code and algebra in one-to-one correspondence even in the awkward case - y_neg1 for \(y_{-1}\) at 150 with the maths spelled out in a trailing comment.

  • The moving-average representation is read off something the reader can see rather than asserted: 549-550 prints the top-left corner of \(A^{-1}\), 553-555 states what its structure is (“every row ends with the previous row’s pre-diagonal entries”), and only then does 564 write the time-varying-coefficient moving average - and 569-570 closes the loop by naming {eq}`eq:eqma` and {eq}`eq:eqar` as the two representations of the same system.

  • The lw=0.5 on the two hundred-path figures (335, 353) is a correct and deliberate departure from the house lw=2, since a hundred thick overlaid lines are unreadable - and the drafted qe-fig-008 count leaves those two cells alone, so the file’s judgment and the checker’s agree.

  • The two cross-series references that are done right are done right in the way the rule asks - {doc}`intermediate:samuelson` at 36 and 140, with automatic titles - so the correct idiom is already in the file for the three raw URLs at 371, 518 and 533 to be rewritten against.