additive_functionals#

  • Series: lecture-python-advanced.myst

  • File: lectures/additive_functionals.md

  • Audit date: 2026-08-26

  • Corpus snapshot: b83d6da399

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

  • Overall score: 6.6 / 10

  • Priority: HIGH

Score breakdown#

Category

Score

One-line note

Writing

5.5/10

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

Math

3.5/10

qe-math-010 (proposed) ×16; qe-math-011 (proposed) ×4; qe-math-009 ×5.

Code

7/10

qe-code-001 ×11.

JAX

out of scope

JAX rules target lecture-jax.

Figures

3.5/10

qe-fig-003 ×11; qe-fig-005 ×10; qe-fig-008 ×23, +1 more.

References

9/10

qe-ref-001 ×1.

Links

7.5/10

qe-link-002 ×5.

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: 11. Lines: 283, 291, 312, 396, 482, 518, 563, 686, 1122, 1128, …. Example: the two long code cells carry most of the file’s style debt. Naming: 1122 and 1175 unpack a simulation into foo, bar and then read x = bar[0, :], y = bar[1, :]; 1128 names the path count I (PEP8 E741, and unlike the identity matrix at 372 it has no mathematical justification - it is n_paths); 1132-1133 use storeX/storeY, 516, 599 and 682 use LI, UI, and 562, 571 and 656 use Mdist/Sdist, all camel- or upper-case locals with no mathematical reading. Spacing and continuation: 482 and 648 write for t in range (T) (E211); 396 has obs =  temp * FFinv * temp with a double space; 572 has scale = np.exp(...) and 657 scale= np.exp(...) as keyword arguments (PEP8 asks for no spaces either side); the argument lists at 517-524, 601-609, 683-685, 1314-1316 and 1426-1434 are indented to arbitrary columns well past their opening delimiter (E128), and 563-570, 581-593, 657-664 and 671-676 add backslash continuations inside parentheses where they are inert; 615, 1086-1090, 1099-1101 and 1239 leave trailing whitespace; 461 and 615 follow a top-level def with one blank line where 531 uses two. Redundant or dead: (.5) at 386, 400, 564, 582, 589, 658 and 672 wraps a float literal in parentheses; 587 writes 1/np.exp(-y[...]) where np.exp(y[...]) is the same thing and is what 580 and 588 do; ldens_to_plot is built at 1252-1253 and never used; amf is a parameter of plot_given_paths (415) and plot_martingale_paths (615) and is never read in either body; and self.add_decomp is set to None at 279 and never assigned before construct_ss runs at 302, so the if self.add_decomp: branch at 312-313 is unreachable. Three items are latent defects rather than style: 283 and 289 test if not np.any(F) / if not np.any(ν) where the signature’s sentinel is None, so a genuine all-zero F or ν silently takes the default branch; 291 uses type(ν) == float instead of isinstance (E721); and 396’s temp * FFinv * temp is elementwise, which is a quadratic form only when k == 1, in a class whose docstring at 248 promises it “Handles both matrix and scalar inputs”. Finally 686-687 puts a backslash continuation inside a string literal, so the figure title reads Martingale components for many paths of followed by thirty-two spaces and then $y_1$.

  • [qe-fig-001] — Do not set figure size unless necessary. Count: 9. Lines: 422, 622, 718, 1059, 1085, 1255, 1312, 1367, 1425. Example: figsize=.

  • [qe-fig-003] — No matplotlib embedded titles. Count: 11. Lines: 431, 441, 451, 456, 526, 610, 686, 721, 724, 1258, …. Example: .set_title.

  • [qe-fig-005] — Descriptive figure names for cross-referencing. Count: 10. Lines: 696, 874, 930, 964, 1054, 1074, 1220, 1308, 1352, 1414. Example: code-cell figure without mystnb figure metadata.

  • [qe-fig-008] — Use lw=2 for line charts. Count: 23. Lines: 425, 426, 427, 429, 435, 436, 445, 446, 455, 720, …. Example: plot() without lw=.

  • [qe-link-002] — Use doc links for cross-series references. Count: 5. Lines: 128, 227, 773, 1279, 1285. Example: raw link to python-intro.quantecon.org.

  • [qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 5. Lines: 55, 900, 906, 970, 989. Example: \(\phi\) carries three unrelated meanings. At 55 it is the multiplicative functional itself (“if a process \(\{y_t\}\) is an additive functional and \(\phi_t = \exp(y_t)\)”), at 210 it is the autoregressive lag polynomial \(\phi(z)\), and at 202-204 (and ϕ_1..ϕ_4 in code at 697) it is the four AR coefficients - and the object introduced as \(\phi_t\) at 55 is renamed \(M_t\) at 892 without a word, 840 lines later. The tilde macro is inconsistent for the same symbol: \widetilde M_t at 906, 914, 950, 978, 984, 989, 1005-1030 against \tilde M_t at 970 and 1106 and \tilde{M}_t at 1111 and 1258, and {\widetilde M}_t at 989. Case is inconsistent inside a single pair of displays: 900 writes the martingale sum as \(\sum_{j=1}^t H \cdot Z_j\) with an uppercase \(Z\) where 914 and 984 use lowercase \(z_j\), and 906 writes \(\tilde e(X_0)/\tilde e(x_t)\) with an uppercase \(X_0\) where every other appearance of the initial state is \(x_0\) (103, 735, 881, 900, 920).

  • [qe-math-010 (proposed)] — Blackboard \mathbb{P}, \mathbb{E}, \mathbb{V} with braces. Count: 16. Lines: 999, 1005, 1008, 1013, 1030, 1099, 1295, 1297, 1328, 1339, …. Example: non-blackboard \mathrm{Var}.

  • [qe-writing-008] — Remove excessive whitespace between words. Count: 21. Lines: 38, 44, 57, 66, 68, 89, 207, 225, 229, 863, …. Example: 2 spaces.

Medium severity#

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

  • [qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 3. Lines: 38, 862, 943. Example: the opening four paragraphs (38-46) take four sentences to say that growth breaks stationarity and that two model classes accommodate it, with 44 running to 33 words and restating 42 (“But there are good ways to model time series that have persistent growth that still enable statistical learning based on a law of large numbers for an asymptotically stationary and ergodic process”). 862-867 is three paragraphs and a parenthetical to say that the class also handles multiplicative functionals, one of which is a gloss on the class’s own name. And two sentences are missing words: “It is interesting to how the martingale behaves as \(T \rightarrow +\infty\)” (943) and “only the squared norm \(H \cdot H\) and \(t\) matters” (1443).

  • [qe-writing-003] (reviewer) — Maintain logical flow. Count: 4. Lines: 243, 871, 927, 1252. Example: 160 lines of implementation arrive before the reader is told what they are for: the AMF_LSS_VAR class occupies 243-406 and the three plotting functions 412-690, while the section that explains the class is “## Code” at 858-867, which has to open by pointing backwards - “The class AMF_LSS_VAR mentioned {ref}`above <amf_lss>` does all that we want” - and only then reveals what AMF stands for (865-867). The prose at 871-872 and 927-928 then instructs the reader to do by hand what the executed notebook has already done: “If you run {ref}`the code that first simulated that example <addfunc_egcode>` again and then the method call you will generate (modulo randomness) the plot” (also missing a verb) and “If you run … again and then the method call in the cell below you’ll obtain the graph in the next cell” - both immediately above cells that run unconditionally. And the same object is named three different things in three consecutive paragraphs: “population 95% probability coverage sets” (879), “population 95% confidence bands” (935) and “purple 95 percent frequency coverage interval” (974), of which the middle one is the wrong term for a population object.

  • [qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 4. Lines: 124, 960, 1097, 1268. Example: the lecture’s named phenomenon is formatted three ways: peculiar property in bold at 960 (“The second is a peculiar property noted and proved by Hansen and Sargent”) and again in bold at 1268, but peculiar property in italic at 1097. The two growth types are handled the other way round from the two process classes: 50-51 bolds the definitions additive functionals and multiplicative functionals, while 124 and 55 italicise arithmetic growth and, at 51, quote “geometric growth” - three treatments for one pair of defined terms. 881 uses italic correctly for emphasis (“all starting from the same non-random initial conditions”), which is what makes the definitional italics stand out.

  • [qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 3. Lines: 615, 1252, 1255. Example: the figure that carries the lecture’s headline claim has no axes at all: plot_martingale_paths (615-631) draws a shaded band, a horizontal line and 25 paths, with no axis labels, no legend and no tick annotation, and it is the figure used for the \(T = 12000\) demonstration of the peculiar property at 964-967 - so the “purple 95 percent frequency coverage interval collapses around zero” that 974 asks the reader to see is unlabelled on both axes. Second, the six-panel density figure at 1255-1265 is built without sharex/sharey, so each panel auto-scales and the leftward collapse claimed at 1270-1272 has to be inferred across six differently scaled axes; and ldens_to_plot - the densities of \(\log \widetilde M_t\), the Gaussian object that 989 says the whole property follows from - is computed at 1252-1253 and then never plotted, so the one panel that would make the argument obvious is constructed and discarded. Third, plot_given_paths puts the titles inside the axes (431, 441, 451, 456) and the panels share a \(y\) axis (sharey=True, 422) even though \(y_t\), \(m_t\), \(s_t\) and \(\tau_t\) have very different scales, which is what forces the martingale panel’s band to be read against the trend panel’s range.

Low severity#

  • [qe-ref-001] — Use correct citation style. Count: 1. Lines: 82. Example: {cite} in narrative flow: ‘{cite}’.

Strengths#

  • The additive functional is built from two named pieces with every dimension stated - the VAR {eq}`old1_additive_functionals` with \(x_t\) \(n\times1\), \(A\) \(n \times n\) stable, \(z_{t+1}\) \(m \times 1\) IID, \(B\) \(n \times m\) (99-103), then the increment equation {eq}`old2_additive_functionals` as a function of exactly three listed objects (105-118) - so a reader can check any later matrix against a declared shape.

  • The state-space embedding is shown twice at increasing size and the second one is derived from the first: 132-183 builds the three-block system for \((1, x_t, y_t)\), and 780-853 extends it to the five-block system for \((1, t, x_t, y_t, m_t)\) whose observation matrix picks out \(\tau_t\), \(m_t\) and \(s_t\) directly (814-836) - which is precisely the Abar/Gbar construction the code assembles row by row with a comment naming each row’s target (328-352).

  • The decomposition is stated as an identity with each term labelled in the display itself - \underbrace{t\nu}_{\text{trend component}}, the martingale sum overbraced, \(-g x_t\) as the stationary component, \(g x_0 + y_0\) as initial conditions (753-760) - and 763 then asks the reader to verify that differencing it returns {eq}`old2_additive_functionals`, which is the one check that makes the whole decomposition credible.

  • The peculiar property is set up as two separately checkable claims - \(E_0 \widetilde M_t = 1\) for all \(t\), yet \(\widetilde M_t \to 0\) almost surely (952-955) - the first is explained in one line from the martingale property (957-958), and then 964-974 demonstrates both at once by extending the horizon to \(T = 12000\) and pointing at the mean line and the collapsing coverage band separately.

  • The moment section reduces everything to one scalar and says so: 999 defines \(a_t := t(H\cdot H) = \mathrm{Var}(\log \widetilde M_t)\), 1005 gives every raw moment as \(\exp(\tfrac12 k(k-1)a_t)\), 1013-1021 gives variance, skewness and kurtosis in terms of \(a_t\) alone, and 1026 states the consequence - which is exactly what Exercise 3 (1393-1443) then asks the reader to verify by choosing two different \(H\) vectors with the same norm.

  • 1099-1101 explains the shape of the distribution rather than describing the plot: “most probability density concentrates near zero, while a long right tail preserves the unit mean” is the reconciliation of the two properties at 952-955, and 1270-1275 restates it as four checkable observations about the six density panels.

  • The three exercises build on the two functions the lecture just defined (log10_raw_moment, log10_var_skew_kurt, squared_norm) rather than on new code, and each solution ends with the analytical reason for what the plot shows - the \(k=1\) slope is zero because \(E[\widetilde M_t]=1\) (1328), and \(\log_{10}(\mathrm{Var}+1) = a_t\log_{10} e\) is linear because \(\mathrm{Var}+1 = e^{a_t}\) (1387-1388).