Skip to content
Statistics LabMAST20005 · 2020

Statistics Lab / Appendix

The parity ledger

A port is only useful if it computes the same thing. Every number in this table was written down in the 2020 submission; the right-hand column is the TypeScript port recomputing it from the original inputs and printing it at the same precision. The comparison runs in the test suite on every push.

Printed R outputs reproduced exactly
34 / 34
Hand calculations agreeing to their rounding
6 / 6
Closed-form derivations evaluated
2 / 2
Reference implementation
R 4.6.1

42 values in all: 34 printed R outputs, 6 hand calculations and 2 symbolic derivations. marks an identical string, ≈ agreement to the table rounding the hand working used, and = a closed form evaluated numerically.

How it was checked

Reference values. A script in the repository (scripts/r_reference.R) re-runs the original computations in R — the same functions, data and seeds as the 2020 notebooks — and writes the results to a test fixture: summaries, quantiles, intervals, test statistics, the full lm fit with its diagnostics, and a grid of distribution functions.

Two levels of comparison. Internally every quantity must agree with R to about nine significant figures. The ledger then checks the stricter, human-facing claim: formatted at the precision printed in 2020, the port’s value is the same string. Even the full summary(lm) printout is reproduced character for character.

Hand calculations used rounded table values (for example t₉ = 2.262), so they agree to the last digit or two, not exactly; the ledger shows both.

Reproducing R’s random numbers

The midrange-versus-mean simulation (A1 Q4) depends on set.seed(2529). To replay it, the port re-implements R’s default generator: the seed-scrambling LCG, the Mersenne-Twister state, R’s guard against 0 and 1, and normal draws by inversion from two uniforms (2²⁷u₁ + u₂ fed to Wichura’s AS241). The first three uniforms to 17 significant digits (the port’s column is computed when this page is built):

The uniform stream is bit-identical to R’s over 100,000 draws. Normal and exponential draws can differ from R 4.6 on Apple silicon in the last bit or two (at most 4 and 1 units in the last place), because R’s build fuses multiply-adds inside qnorm and JavaScript cannot. That is far below any printed precision, so every 2020 value still matches.

  1. 1R  0.9589315231423825TS0.9589315231423825
  2. 2R  0.75501735182479024TS0.75501735182479024
  3. 3R  0.017361181322485209TS0.017361181322485209
# R
> set.seed(2529); sprintf("%.17g", runif(3))

// TypeScript (src/lib/rng.ts)
new RRandom(2529).runif(3)

Assignment 1 — estimation

Assignment 2 — intervals, regression and testing

Assignment 3 — nonparametric and likelihood methods

The ledger is generated by src/lib/__tests__/parity.test.ts in the web app; the original files are in coursework/ of the project repository (private for now).