var_dmd#
Series: lecture-python.myst
File:
lectures/var_dmd.mdAudit date: 2026-08-26
Corpus snapshot:
e25fdf2345Categories audited: writing, math, references, links, admonitions (JAX out of scope)
Overall score: 7.8 / 10
Priority: HIGH
Score breakdown#
Category |
Score |
One-line note |
|---|---|---|
Writing |
3/10 |
|
Math |
9.5/10 |
|
Code |
N/A |
no executable code cells. |
JAX |
out of scope |
JAX rules target |
Figures |
N/A |
no figures or plotting code. |
References |
7.5/10 |
|
Links |
9/10 |
|
Admonitions |
10/10 |
no mechanical violations detected. |
Issues#
Critical#
None found.
High severity#
[qe-ref-001] — Use correct citation style. Count: 6. Lines: 272, 443, 455, 518, 598, 726. Example:
{cite}in narrative flow: ‘and{cite}’.[qe-writing-002] (reviewer) — Keep writing clear, concise, and valuable. Count: 6. Lines: 126, 154, 168, 206, 283, 289. Example: 154 and 212 are the same sentence verbatim, 58 lines apart: “The \(i\)th row of \(\hat A\) is an \(m\times1\) vector of regression coefficients of \(X_{i,t+1}\) on \(X_{j,t}, j = 1,\ldots,m\)”. The case descriptions are also written twice - 87 at 108 and 88 at 135, word for word except that “variables” becomes “attributes”. 168-171 announces its own repetition (“To reiterate, in the tall-skinny case … we want to fit equation
{eq}`eq:VARfirstorder`”) of 44 and 133-165. 283-296 gives the same guidance in two consecutive bold-headed paragraphs, “Guide to three representations: In practice, we’ll mainly be interested in Representation 3” and “Guide to impatient reader: In our applications, we’ll be using Representation 3”. 287 and 289 are the same statement twice (“we’ll use only a small subset of DMD modes to approximate dynamics” / “We use such a small subset of DMD modes to construct a reduced-rank approximation to \(A\)”). 124 and 126 also say one thing twice, and 126 misspells it (“It is used to estimate vector autorgressions”). Two sentences are ungrammatical: 206 (“we’ll use efficient algorithms to constructing a reduced-rank approximation”) and 811 (“or use compute a decoded \(\hat X_{t+j}\)”); 585 has “matix”.[qe-writing-003] (reviewer) — Maintain logical flow. Count: 6. Lines: 238, 270, 377, 642, 766, 783. Example: 238 names the wrong identity: the string of equalities at 229-233 goes from \((V\Sigma U^\top U \Sigma V^\top)^{-1}\) to \((V\Sigma\Sigma V^\top)^{-1}\), which cancels \(U^\top U\), but the parenthetical says “Since we are in the \(m>>n\) case in which \(V^\top V = I_{p\times p}\) in a reduced SVD”. 270 ends its sentence with a comma - “Dynamic mode decomposition was introduced by
{cite}`schmid2010`,” - and the next paragraph starts fresh. 377-383 contradicts itself: (a) says “for a full SVD \(UU^\top = I_{m\times m}\) and \(U^\top U = I_{p\times p}\) are both identity matrices” (for a full SVD \(U\) is \(m\times m\), so the second is \(I_{m\times m}\), not \(I_{p\times p}\)), (b) says “for a reduced SVD of \(X\), \(U^\top U\) is not an identity matrix”, and 383 then says “requirements (a) and (b) are both satisfied” - (b) is the negation of half of (a), so they cannot both be. The H3 at 642, “Decoder of \(\check b\) as a linear projection”, names the wrong direction: what the section derives is \(\check b_t = \Phi^+ X_t\) (665, 678), which 423-432 would call the encoder; the decoder is \(\check X = \Phi\check b\) at 685. 766 misquotes its own equation - “Recall that from equation{eq}`eq:tildeAverify`, \(\tilde A = \tilde U^\top X' \tilde V \tilde\Sigma^{-1}\)” - where 523-524 has a trailing \(\tilde U^\top\). And the chain at 777-783 cannot hold as written: 777 gives \(\hat b_1 = \tilde W \Lambda \check b_1\) and 783 then says “Consequently, \(\hat b_1 = (\tilde W\Lambda)^{-1}\tilde b_1\)”, inverting the same factor and substituting \(\tilde b_1\) for \(\check b_1\) in one step, with \(\hat b_1\) on the left of both.[qe-writing-004] — Avoid unnecessary capitalization in narrative text. Count: 16. Lines: 106, 133, 265, 272, 275, 283, 285, 294, 369, 487, …. Example: mid-sentence ‘Case’.
[qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 8. Lines: 55, 109, 163, 291, 371, 506, 589, 596. Example: the file contains no italic text at all in 840 lines, and bold carries three different jobs. Definitions, correctly: first-order vector autoregression (26), Moore-Penrose pseudo-inverse (102), right-inverse (115), left-inverse (142), underdetermined least-squares (165), encoder/decoder (327, 329, 423, 429), projected modes (462), exact/approximate modes (802). Emphasis, which the rule assigns to italic: everything twice at 55, rows (109) and columns (135), fits perfectly (163), reduced and full at 291 and again at 302, 319, 371, 383, 487, 491 and 758, not at 371 and 381, not/are eigenvectors at 585 and 596, can at 589. And ten section headings are set as bold paragraphs rather than markdown headings: Short-Fat Case: (106), Tall-Skinny Case: (133), Guide to three representations: (283), Guide to impatient reader: (294), Computing Dominant Eigenvectors of \(\hat A\) (506), Interpretation as projection coefficients (515), An Inverse Challenge (539), A Blind Alley (552), An Approach That Works (587), Variance Decomposition of \(X\) (690) - so the seven-step structure of Representation 3 appears nowhere in the table of contents.
[qe-writing-006] — Capitalize lecture titles properly. Count: 5. Lines: 23, 261, 720, 821, 836. Example: H2 Title Case: ‘First-Order Vector Autoregressions’ (First-Order, Vector, Autoregressions).
[qe-writing-008] — Remove excessive whitespace between words. Count: 180. Lines: 16, 32, 33, 40, 47, 53, 55, 63, 75, 77, …. Example: 2 spaces.
Medium severity#
[qe-link-002] — Use doc links for cross-series references. Count: 1. Lines: 692. Example: bare URL to python-advanced.quantecon.org.
[qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 4. Lines: 75, 87, 181, 489. Example: the notation needs a disclaimer to survive: 75 has to say “Here \('\) is part of the name of the matrix \(X'\) and does not indicate matrix transposition”, because the file also uses \(^\top\) for transpose 92 times. Any of \(X_+\), \(Y\) or \(X^{(2)}\) would carry the shifted-data meaning without a warning, and would also stop the prime colliding with the five other diacritics in use - \(\tilde X\), \(\hat A\), \(\tilde A\), \(\check A\) (181), \(\tilde b\), \(\hat b\), \(\check b\), \(\overline X\), \(\check X\), \(\hat X\), \(\tilde U\), \(\tilde\Sigma\), \(\tilde V\), \(\tilde W\), \(\tilde\Phi_s\). “Much greater than” is spelled three ways and never with
\gg:> >at 87, 88, 108, 135 and 238, which renders as two separate relations, and>>at 265. 181 writes\textrm{argmin}and|| \cdot ||_Fwhere\operatorname*{argmin}and\|\cdot\|_Fare the standard forms, and 489 writes\textrm{min}(m,n)for the quantity that 83 writes correctly as\min(m, n). And the transpose convention is defined twice in different words, at 40 (“\(\cdot^\top\) again denotes complex transposition”, on its first appearance) and at 77.[qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 4. Lines: 327, 690, 823, 838. Example: 840 lines, no figure, no code cell and no admonition other than the one
prf:proposition/prf:proofpair at 604-637 - in a lecture whose entire subject is geometric. 327-329 defines an encoder that rotates the \(m\times1\) vector \(X_t\) into \(\tilde b_t\) and a decoder that rotates it back, and the rotation is never drawn; the three representations differ only in which SVD they use (full at 302 and 371, reduced at 487) and in the encoder/decoder pair each induces (308/314, 426/432, 665/685), which is one small table or diagram and is instead spread over 500 lines of cross-reference. 690-714 is titled “Variance Decomposition of \(X\)” and derives \(X = \check X + \epsilon\) with \(\epsilon^\top \Phi = 0\) - the orthogonal-projection triangle - and points the reader atorth_proj(692) for the picture rather than drawing it. 823 says “In applications, we’ll actually use only a few modes, often three or less” without the singular-value spectrum that is the standard way to choose \(r\). And 836-840, “Source for Some Python Code”, is the lecture’s entire computational content: a bare URL topydmd, in a Python lecture series.
Low severity#
[qe-writing-009 (proposed)] — Write “IID” — not “i.i.d.” or “iid”. Count: 1. Lines: 32. Example: i.i.d…
Strengths#
The lecture is honest about which representation matters and says so before the reader invests in the other two: 283-296 marks Representations 1 and 2 as stage-setting, tells the impatient reader to skip them, and gives the reason - representations 1 and 2 need a full SVD, and applications need a reduced one (291).
Representation 3 is built as a narrative of a failed attempt and its repair, with the wrong turn labelled: 552-585 “A Blind Alley” constructs \(\tilde\Phi_s = \tilde U\tilde W\) by analogy with Representation 2, computes \(\hat A \tilde\Phi_s\) and shows it is not \(\tilde\Phi_s\Lambda\) (576-580), and only then does 587-596 “An Approach That Works” define \(\Phi \equiv \hat A\tilde\Phi_s\) - a reader who tried the obvious thing is told why it fails.
The Tu et al. result is stated as a
prf:propositionand actually proved (604-637) rather than cited: the proof runs \(\hat A\Phi = \Phi\Lambda\) through four lines of matrix algebra, then descends to the column-wise statement \(\hat A\phi_i = \lambda_i\phi_i\) (633) so the eigenvector claim is checkable one column at a time.The pseudo-inverse is derived from the SVD in a single displayed chain of five equalities (228-234) rather than quoted, which is what makes the estimator \(\hat A = X'\tilde V\tilde\Sigma^{-1}\tilde U^\top\) at 502 legible later.
521-537 does not just assert that \(\tilde A\) is a projection of \(\hat A\) onto \(\tilde U\) - it computes the standard least-squares coefficient \((\tilde U^\top\tilde U)^{-1}\tilde U^\top\hat A\) explicitly and shows it collapses to \(\tilde A\), and 690-714 does the same for \(\check b\), deriving the orthogonality condition \((X-\Phi\check b)^\top\Phi = 0\) and rearranging it back into
{eq}`eq:checkbform`.Both special cases get their own pseudo-inverse formula with the invertibility condition stated - independent rows and a right-inverse for \(n>>m\) (108-115), independent columns and a left-inverse for \(m>>n\) (135-142) - and 150 then asks the reader to compare the two resulting estimators side by side.
Recommended actions#
Rename the shifted data matrix so the file stops needing the disclaimer at 75: \(X'\) collides with the transpose that appears 92 times as \(^\top\), and every one of the 28
qe-math-002hits is this one symbol. \(X_+\) or \(Y\) would cost one line of definition at 72 and remove both the warning and the finding.Fix the four derivation breaks: 238 cancels \(U^\top U\) but says \(V^\top V\); 377 gives \(U^\top U = I_{p\times p}\) for a full SVD, where \(U\) is \(m\times m\); 383 claims requirements (a) and (b) are both satisfied when (b) negates half of (a); and 777-783 inverts \(\tilde W\Lambda\) and swaps \(\check b_1\) for \(\tilde b_1\) in one unexplained step. While in that stretch, restore the dropped \(\tilde U^\top\) in the recall at 766, the tilde on \(\tilde\Sigma\) at 615 and the tilde on \(\tilde V\) at 754.
Add the two figures the argument is already asking for: the encoder/decoder rotation of 327-329 (a vector, a rotated basis, the same vector recovered), and the projection triangle of 690-714 that the lecture currently outsources to
orth_projvia a bare URL at 692 - which is also the oneqe-link-002violation and should be a{doc}reference.Promote the ten bold pseudo-headings (106, 133, 283, 294, 506, 515, 539, 552, 587, 690) to real
###headings so the structure of Representation 3 reaches the table of contents, and rename the H3 at 642, which calls the encoder \(\check b_t = \Phi^+X_t\) a decoder.Delete the verbatim repetitions: 212 duplicates 154, 108 duplicates 87, 135 duplicates 88, 294-296 duplicates 283-285, 289 duplicates 287, and 168-171 announces itself as a restatement of 44. That is roughly 20 lines out of 840 and it is the fastest single improvement to the lecture’s density.
Write “much greater than” as
\ggat 87, 88, 108, 135, 238 and 265 -> >currently renders as two relations - and use\operatorname*{argmin},\|\cdot\|_Fand\minat 181 and 489, matching the correct\minalready at 83.Sweep the mechanical remainder: 180 double spaces (16, 32, 33, 40, 47, 53, 55, 63, 75, 77 and 170 more, by far the largest count in this batch), the five title-case H2 headings (23, 261, 720, 821, 836), the sixteen mid-sentence capitalisations, “i.i.d.” at 32, and the typos “autorgressions” (126), “matix” (585), “to constructing” (206) and “use compute” (811).
Give the lecture at least one executable cell. 836-840 currently hands the reader a URL; the formulas at 502, 593 and 807 are four lines of NumPy each, and computing them on any of the corpus datasets would let 823’s “often three or less” modes be shown rather than asserted.