linear_models#

  • Series: lecture-python.myst

  • File: lectures/linear_models.md

  • Audit date: 2026-08-26

  • Corpus snapshot: e25fdf2345

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

  • Overall score: 6.5 / 10

  • Priority: HIGH

Score breakdown#

Category

Score

One-line note

Writing

3/10

qe-writing-006 ×25; qe-writing-005 ×5; qe-writing-003 ×5, +4 more.

Math

3/10

qe-math-002 ×40; qe-math-010 (proposed) ×4; qe-math-009 ×4.

Code

6/10

qe-code-002 ×7; qe-code-001 ×5.

JAX

out of scope

JAX rules target lecture-jax.

Figures

8/10

qe-fig-005 ×2; qe-fig-001 ×1.

References

N/A

no citations in this lecture.

Links

9/10

qe-link-002 ×1.

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: 5. Lines: 191, 657, 663, 911, 914. Example: all three function signatures mis-indent their continuation lines (E128): 191-195 opens def plot_lss(A, with the paren at column 13 and continues at column 10; 657-664 opens at column 23 and continues at 20; 911-918 opens at column 15 and continues at 13. Keyword defaults are spaced in five places where the same signatures get it right elsewhere: sample_size = 20 at 663 beside T=20 and ymin=-0.8 at 660-661, and T0 = 10, T1 = 50, T2 = 75, T4 = 100 at 915-918 (E251). 914 uses the string 'False' as a boolean flag, tested as steady_state == 'True' at 922 and 939 and passed as steady_state='True' at 996 - so calling cross_plot(..., steady_state=True) silently takes the else branch. 800 writes label='$\\bar y_t$', escaping the backslash in a plain string, where the adjacent call at 808 uses the raw form r'$G\mu_t$'. And 74 imports the standard-library random purely for random.choice at 685 and 937, adding a second unseeded generator to a lecture built on numpy simulation. Note that the column-aligned matrix literals at 212-214, 278-281 and 704-707 are not counted here - that is the mathematical-notation exception the rule grants.

  • [qe-code-002] — Use Unicode symbols for Greek letters in code. Count: 7. Lines: 737, 738. Example: spelled-out mu.

  • [qe-math-002] — Use \top for transpose notation. Count: 40. Lines: 239, 404, 431, 444, 488, 535, 543, 575, 609, 635, …. Example: apostrophe transpose A'.

  • [qe-math-010 (proposed)] — Blackboard \mathbb{P}, \mathbb{E}, \mathbb{V} with braces. Count: 4. Lines: 575, 1218. Example: non-blackboard \textrm{Var}.

  • [qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 5. Lines: 549, 583, 823, 1161, 1232. Example: 583-598 takes five consecutive paragraphs to reach “everything here is Gaussian”: “In general, knowing the mean and variance-covariance matrix … is not quite as good as knowing the full distribution” / “However, there are some situations where these moments alone tell us all we need to know” / “These are situations in which the mean vector and covariance matrix are all of the parameters that pin down the population distribution” / “One such situation is when the vector in question is Gaussian” / “This is the case here, given …”. 549-558 hedges three times in a row about a naming choice. 823-825 uses a term in scare quotes and then defines it in a parenthetical on the next line. 1161-1164 states ergodicity twice, the second time announced as “More formally” without being any more formal (“time series and ensemble averages coincide” / “time series sample averages converge to their expectation under the stationary distribution”). And 1232-1233 is the entire body of the H2 “Prediction”: “The theory of prediction for linear state space systems is elegant and simple” - a value claim carrying no information, where the section’s actual content starts under the next heading.

  • [qe-writing-003] (reviewer) — Maintain logical flow. Count: 5. Lines: 222, 372, 521, 1345, 1378. Example: three promises are not kept. 222 says “Later you’ll be asked to recreate this figure” - the Exercises section (1347-1405) has one exercise, on forecasting geometric sums, and no figure task; the anchor lss_sode_fig planted at 188 for that purpose is never referenced. 521 says “We’ll explain what unconditional and conditional mean soon” and 554-555 repeats the promise (“related objects that use conditioning information, to be defined below”); “unconditional” is defined at 549-552, but “conditional” is never defined - it first appears in use 700 lines later at 1238-1243 with no back-reference. 1345 says “Examples of usage are given in the solutions to the exercises”, and the single solution (1381-1403) is pure algebra with no code cell at all, so there is no example of using the LinearStateSpace class anywhere in the exercises. 372 asserts that “The indeterministic seasonal produces recurrent, but aperiodic, seasonal fluctuations” and stops there, while the deterministic seasonal beside it gets \(A^4 = I\), a displayed consequence and a footnote (1407). And 1378 tacks “what must the modulus for every eigenvalue of \(A\) be less than?” onto the end of an exercise after two displayed equations, in lower case and without an introduction, and then the solution answers it in its opening line (1384) before addressing the two displays the exercise actually asked about.

  • [qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 5. Lines: 372, 825, 1046, 1135, 1159. Example: the bold-for-definitions half of the rule is followed carefully - about twenty terms, from state and transition matrix (84-89) through martingale with drift (506), covariance stationary (1019) and conditional covariance matrix (1316) - but five terms are introduced in italic instead, and two of those are also bolded elsewhere in the same file. 372 italicises indeterministic where 349 bolds indeterministic seasonal; 1135 italicises discrete Lyapunov equation where 1327 bolds discrete Lyapunov; 825 defines long-run average in a parenthetical, in italic, immediately after using it in scare quotes at 823; 1046 italicises globally stable case, which is also the H4 heading at 1028; and 1159 italicises ergodicity on its introduction, with the definition following at 1161. Since 144, 521, 845, 1030 and 1147 use italic correctly for emphasis, the same marker is carrying both jobs.

  • [qe-writing-006] — Capitalize lecture titles properly. Count: 25. Lines: 77, 119, 147, 224, 293, 374, 446, 508, 516, 560, …. Example: H2 Title Case: ‘The Linear State Space Model’ (Linear, State, Space, Model).

  • [qe-writing-008] — Remove excessive whitespace between words. Count: 30. Lines: 87, 88, 465, 469, 488, 551, 552, 589, 613, 614, …. Example: 2 spaces.

Medium severity#

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

  • [qe-link-002] — Use doc links for cross-series references. Count: 1. Lines: 1343. Example: raw link to python-programming.quantecon.org.

  • [qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 4. Lines: 908, 1033, 1081, 1305. Example: the prime carries three different meanings in this file. It is the transpose at 239, 404, 431, 488, 543, 575, 635, 830, 1052, 1108 and 1116; it indexes time at 908 and 935 (\(T, T', T''\) for three dates, with the same marks reused as tick labels at 935); and it is spelled two different ways for the same operation - ' in most places but ^\prime at 444, 1305 and 1313, twice inside a single display. 1305 also mis-places one: A^{k^\prime} renders as \(A^{k'}\), a prime on the exponent, where the intended object is \((A^k)'\). 1081 nests the mark inside itself, \(x_t = \begin{bmatrix} x_{1t}' & 1\end{bmatrix}'\), transposing a column to a row so it can be stacked and then transposing the stack back. And 1033 states a mathematical condition as a Python expression - “That is, if (np.absolute(np.linalg.eigvals(A)) < 1).all() == True” - restating in code what the preceding sentence has just said in words, with a redundant == True.

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

  • [qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 4. Lines: 341, 374, 1145, 1290. Example: the lecture’s figures all sit in its first half: eight of them between 190 and 995, then nothing at all in the 390 lines from 1026 to the end. The two most expensive omissions are in that stretch. 1145-1172 “Averages over Time” makes the ensemble-versus-time-average distinction the point of the section - 1147 says “in real life, we usually observe only a single realization” - states three ergodic limits at 1168-1170 and plots none of them, although the ensemble side of exactly that comparison is drawn at 782-814 and the time-average version is the same loop with the axis swapped. 1290-1331 derives the \(j\)-step prediction-error covariance \(V_j = CC' + AV_{j-1}A'\) and its Lyapunov limit and never draws the forecast fan, which is the standard picture for this material and is a few lines from the moment_sequence() generator the lecture already introduces at 1341. Earlier, 341-372 “Seasonals” defines a deterministic and an indeterministic seasonal and plots neither, even though plot_lss (191-207) is already defined and accepts the \(A\) given at 356 as-is, and 374-444 “Time Trends” gives three trend models with no picture. Related: the {note} at 1131-1137 is the only admonition in 1413 lines, and it holds a technical aside, while the two things a reader most needs flagged - the dictum at 144 and the warning at 557-558 that the “unconditional” moments still depend on \(N(\mu_0,\Sigma_0)\) - are plain paragraphs.

Low severity#

  • [qe-fig-001] — Do not set figure size unless necessary. Count: 1. Lines: 668. Example: figsize=.

Strengths#

  • The six examples at 138-444 are ordered by how much of the state-space machinery each one needs and every one is mapped explicitly: the second-order difference equation gets its \(x_t\), \(A\), \(C\), \(G\) written out at 161-182 with \(C = 0\) so the reader sees a deterministic special case first, then the AR(4) at 241-260, then its vector version at 308-337 with \(I\) substituted for \(1\) block by block, then seasonals and trends - and 184 asks the reader to confirm the mapping rather than asserting it.

  • The ensemble interpretation is built in three figures of increasing sample size and the prose says what each adds: 20 paths with the cross-section marked by dots (656-714), 100 (721-724), then 500,000 with the analytic density from {eq}`lss_mgs_y` drawn on top (728-749) and 751-753 pointing out that the histogram and the population density coincide - the theory is checked, not just stated.

  • The stationarity section proves its point by changing one input and re-running the same figure: 950-951 draws the cross-sections at \(T, T', T''\) from \(\mu_0 = \mathbf{1}\), then 995-996 calls the identical function with steady_state='True' so that \(x_0 \sim N(\mu_\infty,\Sigma_\infty)\), and 999 explains that the remaining differences are now sampling noise only.

  • 1048-1129 does not stop at the globally stable case: it points out at 1050-1054 that the second-order example has a constant state component and so can never have \(\mu_t \to 0\), asks the question that follows (1056), and then works out the block structure at 1063-1108 that gives a stationary solution with \(\mu_{1\infty} = (I-A_1)^{-1}a\) - a special case most treatments leave to the reader.

  • The matrix literals are laid out in columns to match the displayed algebra (212-214, 278-281, 704-707), so A = [[1, 0, 0], [ϕ_0, ϕ_1, ϕ_2], [0, 1, 0]] reads as the matrix at 169-173 - and the Greek code identifiers ϕ_0, σ, μ_x, Σ_x (210, 276, 805) keep the code and the mathematics in one notation.

  • The two footnotes carry exactly the technical detail that would interrupt the argument: 1407 gives the eigenvalues \((1,-1,i,-i)\) that make \(A^4 = I\) at 364, and 1409-1413 supplies the induction that the Gaussian claim at 612-614 actually rests on.