1import { useMemo } from 'react'
2import katex from 'katex'
4function 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}
12/** One term of the formula: the symbol, then what it is. */
13function 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 )
22}
24/**
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.
27 */
28export default function MathSection() {
29 return (
30 <div className="math-section">
31 <p>
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.
35 </p>
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)" />
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>
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.
83 </p>
84 </div>
85 )
86}