Chapter 37 — Instructor Notes
Teaching Notes
Where this sits. Chapter 36 made the solver navigable (a package); Chapter 37 makes it trustworthy (tested, documented, reproducible); Chapter 38 presents it as research. Frame 37 as the bridge: engineering, not new language features. Every idea here is a habit, and habits are taught by doing, so weight lab time over lecture.
Key ideas to emphasize (in order of importance).
1. The oracle problem is the crux of numerical testing. Students who have tested a sort routine think testing is
about arranging inputs. Here the inputs are trivial and the expected output is the hard part. Drill the four
oracle sources — exact special cases, invariants, symmetry, convergence order — until students reach for them
reflexively. This is the single most transferable idea in the chapter.
2. Compare with a tolerance, never ==. The 0.1 + 0.2 /= 0.3 demo lands every time; run it live. Tie it to
Ch. 20 (rounding) so it is a consequence, not a rule.
3. Bit-for-bit vs tolerance, and why bit-for-bit is fragile. The non-associativity demo ((a+b)+c vs
a+(b+c) giving 1.0 vs 0.0) is the money slide. Then the punchline: a different flag, compiler, or core count
reorders sums, so bit-for-bit across an unpinned build cries wolf. This is Case Study 1's whole spine.
4. The exit code is the contract. error stop 1 → nonzero exit → fpm test fails → CI red → merge blocked.
Draw the chain as a single arrow diagram. Without it, CI is a mystery; with it, it is obvious.
5. A result you can't reproduce is not a result (the Threshold Concept). Land this as the emotional/ethical
core, not just a technique. The Claerbout/Buckheit–Donoho "advertising vs scholarship" framing helps.
Misconceptions to preempt.
- "Bit-for-bit is stricter, so it's safer." No — stricter-than-the-problem-warrants is fragile; it fails on
legitimate changes until the team ignores it (the "cry wolf" pitfall). Stricter is better only under a pinned
build.
- "A test that passes is a good test." The allocated(u) test passes and tests nothing. Insist on the rule: a
test you cannot make fail by breaking the code tests nothing. Have students break the stencil and watch tests go
red — this is the most valuable 10 minutes of the unit.
- "The linear/zero oracle is enough." The 37.5 exercise shows a zero-valued oracle cannot catch a missing
multiplicative factor (/dx**2). You need a nonzero expected value. Great teachable moment about oracle design.
- "A fixed seed makes it reproducible." Only on the same compiler — the standard doesn't fix the generator. Honesty
about limits is itself the lesson.
- "FORD/pFUnit are exotic." They're just comments and just asserts-with-a-preprocessor. Build the hand-rolled
harness first so the framework is demystified.
Live-coding demo (≈25 min). (1) Write a laplacian unit test with the hand-rolled harness; run it green. (2)
Break laplacian (drop /dx**2); rerun; watch the quadratic test go red but the linear test stay green — ask why
(oracle design). (3) Fix it. (4) Show 0.1+0.2 == 0.3 failing, then the tolerance version passing. (5) Run the
non-associativity program (1.0 vs 0.0). (6) Show the golden regression with tolerance, and note bit-for-bit would
break under -ffast-math. If time: point at the CI YAML and trace the exit-code chain.
Time budget (≈5 h). 37.1 unit testing + oracles: 75 min (with the live demo). 37.2 regression + bit-for-bit + verification: 75 min. 37.3 CI: 40 min. 37.4 FORD + git: 40 min. 37.5 reproducibility: 40 min. Project Checkpoint + wrap: 30 min. The two case studies are a 1–1.5 h lab each; assign at least Case Study 1.
Prerequisites to review. Ch. 13 (error stop, exit codes, assertions) — 10 min recap is worth it, it's the
machinery. Ch. 20 (rounding, non-associativity) — the why behind tolerances. Ch. 24 (the 5×5 result, CFL) — the
oracle values. Ch. 22 (order-of-accuracy halving test) — the verification test. Ch. 36 (the package, build config).
Assessment. The Project Checkpoint (a filled test/ with all three test kinds, FORD docs, and a CI workflow) is
the natural graded artifact — and it is directly reusable in the Ch. 38 capstone, so grade it as capstone
infrastructure. Exercises 37.7, 37.12, 37.22 are the compilable core; 37.5 (break-it-predict) and 37.20
(reproducibility bug) are the best conceptual checks.