Rewrite the math section as the formula actually computed, with every term defined
2 changed files+89−28
src/app.cssmodified+19−1View file
@@ -434,5 +434,23 @@ body {
434434 }
435435
436436 .math-section .katex-display {
437- margin: 12px 0;
437+ margin: 14px 0;
438+}
439+
440+.defs {
441+ display: grid;
442+ grid-template-columns: max-content 1fr;
443+ gap: 8px 18px;
444+ margin: 18px 0 0;
445+ max-width: 76ch;
446+}
447+
448+.defs dt {
449+ text-align: right;
450+ color: var(--ink);
451+}
452+
453+.defs dd {
454+ margin: 0;
455+ color: var(--ink-2);
438456 }
src/components/MathSection.tsxmodified+70−27View file
@@ -1,42 +1,85 @@
11 import { useMemo } from 'react'
22 import katex from 'katex'
33
4-function Display({ tex }: { tex: string }) {
5- const html = useMemo(() => katex.renderToString(tex, { displayMode: true, throwOnError: false }), [tex])
6- return <div dangerouslySetInnerHTML={{ __html: html }} />
4+function Tex({ tex, display }: { tex: string; display?: boolean }) {
5+ const html = useMemo(
6+ () => katex.renderToString(tex, { displayMode: !!display, throwOnError: false }),
7+ [tex, display],
8+ )
9+ return <span dangerouslySetInnerHTML={{ __html: html }} />
10+}
11+
12+/** One term of the formula: the symbol, then what it is. */
13+function Def({ tex, children }: { tex: string; children: React.ReactNode }) {
14+ return (
15+ <>
16+ <dt>
17+ <Tex tex={tex} />
18+ </dt>
19+ <dd>{children}</dd>
20+ </>
21+ )
722 }
823
924 /**
10- * Stub for the full derivation. It states the model and the formula the app
11- * plots; the reasoning connecting them is to come.
25+ * The theoretical rate R exactly as `model/theory.ts` computes it, with every
26+ * symbol defined. The derivation that justifies it is still to be written.
1227 */
1328 export default function MathSection() {
1429 return (
1530 <div className="math-section">
1631 <p>
17- The generating model: i.i.d. Gaussian noise, a FIR filter h, optional uniform dither, and
18- rounding to the integer quantization grid (the step is the unit, so σ is measured in
19- steps):
32+ The dashed line on the compression chart is R, the predicted bits per sample. It is
33+ computed in three steps: the spectrum of the stored signal, the residual an ideal
34+ predictor leaves, and the entropy of that residual on the integer grid.
2035 </p>
21- <Display tex="x_n \sim \mathcal{N}(0,\sigma^2)\ \text{i.i.d.}, \qquad y = h * x, \qquad z_n = \operatorname{round}(y_n + d_n), \quad d_n \sim \mathcal{U}[-\tfrac12,\tfrac12)\ \text{or}\ 0" />
22- <p>
23- The reference rate R treats the roundoff as an additive white noise floor on the spectrum
24- — σ<sub>q</sub>² = 1/12 without dither, 1/6 with it (the dither is stored in the
25- integers) — takes the one-step Wiener prediction error of the resulting process
26- (Szegő–Kolmogorov), and charges the exact entropy of that innovation quantized at unit
27- step:
28- </p>
29- <Display tex="S_z(f) = \sigma^2\,|H(f)|^2 + \sigma_q^2, \qquad \sigma_e^2 = \exp\!\Big(2\!\int_0^{1/2}\!\ln S_z(f)\,df\Big), \qquad R = H_{\Delta}(\sigma_e)" />
30- <Display tex="H_{\Delta}(s) = -\sum_{z\in\mathbb{Z}} p_z \log_2 p_z, \qquad p_z = \Phi\!\Big(\tfrac{z+\frac12}{s}\Big) - \Phi\!\Big(\tfrac{z-\frac12}{s}\Big)" />
31- <p>
32- with f in cycles per sample. In the fine-quantization regime (S ≫ 1 everywhere) this
33- reduces to the classical Gaussian entropy rate ½ log₂(2πe) + ∫ log₂ S(f) df — and with
34- no filter, to ½ log₂(2πe σ²). The noise floor keeps R finite and positive where a deep
35- stopband pushes S(f) below one step², which is where the classical formula diverges to
36- −∞. It is still an approximation: roundoff is not truly white, independent, or Gaussian,
37- prediction is from the quantized past, and everything degrades when the whole signal
38- hides inside the dead zone (σ_y ≪ 1). Quantifying that gap — and why LPC + ANS is the
39- right yardstick — is the subject of the full derivation, still to be written.
36+
37+ <Tex display tex="S_z(f) \;=\; \sigma^2\,\big|H(f)\big|^2 \;+\; \sigma_q^2, \qquad H(f) \;=\; \sum_{n=0}^{L-1} h_n\, e^{-2\pi i f n}" />
38+ <Tex display tex="\sigma_e \;=\; 2^{\,\int_0^{1/2} \log_2 S_z(f)\,df}" />
39+ <Tex display tex="R \;=\; -\sum_{z \in \mathbb{Z}} p_z \log_2 p_z, \qquad p_z \;=\; \Phi\!\left(\frac{z + \tfrac12}{\sigma_e}\right) - \Phi\!\left(\frac{z - \tfrac12}{\sigma_e}\right)" />
40+
41+ <dl className="defs">
42+ <Def tex="\sigma">
43+ standard deviation of the i.i.d. Gaussian input, in quantization steps (the step is the
44+ unit, so rounding is to the nearest integer)
45+ </Def>
46+ <Def tex="h_0,\dots,h_{L-1}">
47+ the FIR kernel the input is convolved with — the taps drawn in the kernel plot, L of
48+ them
49+ </Def>
50+ <Def tex="H(f)">
51+ the kernel's frequency response, the quantity plotted in dB as |H(f)|
52+ </Def>
53+ <Def tex="f">
54+ frequency in cycles per sample, running from 0 to ½ (Nyquist); the plots label the same
55+ axis in Hz, as f times the sample rate
56+ </Def>
57+ <Def tex="\sigma_q^2">
58+ variance charged to rounding, treated as additive white noise: 1/12 for the roundoff
59+ alone, 1/6 when dither is on (the dither is stored in the integers, so its 1/12 adds)
60+ </Def>
61+ <Def tex="S_z(f)">
62+ power spectrum of the stored integer signal, in steps² per unit frequency
63+ </Def>
64+ <Def tex="\sigma_e">
65+ standard deviation of the innovation — what an ideal linear predictor still cannot
66+ predict from all earlier samples. The exponent is the Szegő–Kolmogorov formula for the
67+ one-step prediction error, the geometric mean of the spectrum.
68+ </Def>
69+ <Def tex="\Phi">standard normal cumulative distribution function</Def>
70+ <Def tex="p_z">
71+ probability that the innovation, rounded to the integer grid, lands on z
72+ </Def>
73+ <Def tex="R">
74+ bits per sample; the compression ratio the chart marks is 16/R, against 16-bit integer
75+ storage
76+ </Def>
77+ </dl>
78+
79+ <p className="card-note">
80+ The integral is evaluated by the midpoint rule on 8192 points and the sum over z is taken
81+ out to where the remaining mass is negligible. A derivation — and an account of where
82+ modeling the roundoff as white noise stops being fair — is still to be written.
4083 </p>
4184 </div>
4285 )