rational M2: the design spike pins every stage length - #57
Merged
Merged
Conversation
The pinned table (notebooks/design_spike.ipynb, executed; design.h's profile docstring): for every band of the vocabulary (2, 3, 4, 6, 8) and every profile, the smallest m whose L-th-band design meets the stopband with >= 1 dB margin on a 16384-point grid, N = 2mB - 1. profile carries the pins as taps_per_branch (0 = search), design_stage<R> reads them, a custom profile without pins is searched on the same grid, and stage_taps_per_phase<R> gives the mixed stages' ceil(N / L). The notebook is the independent leg, as bridge's M2 spike was: the designer re-derived in numpy from the same published math, the search, the minimality check, the measured worst stopband and ripple per row, the mixed ratios' taps per phase, and the economy half-band decimator checked end to end through scipy's upfirdn (a tone just past the stopband edge aliases at -72.1 dB, passband tones within 0.001 dB). test_design.cpp enforces every row against the shipping designer: the pin equals the search, m - 1 misses the margin, the worst stopband is the table's within 0.05 dB, the ripple is within PLAN.md 2.3's candidate (now a bound). Finding: nyquist.h's 1024-point default grid steps over a sidelobe of the long designs (the 8th-band transparent candidate reads -121.7 dB on 1024 points and -119.3 dB on 8192) and under-pins two rows, band 4 balanced (103 -> 111) and band 8 transparent (383 -> 399); 16384 points agree with 65536 within 0.003 dB. The search's grid became a parameter in DspTap first (tap/DspTap#50) and the pin moves to that merge. The emulated legs skip the fine-grid sweeps of the long designs and the searches (bare_metal_main.cpp; Hexagon also the throw tests): the 70 dB rows' pins, minimality and structure run on target (67 s on M33). rational/PLAN.md v0.5 fills the M2 table from the measurements and records M2 done; the family plan, READMEs and CLAUDE files follow. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015VR1VC4SDGxHZQQsQvPBaA
tap
force-pushed
the
claude/sample-rate-expansion-strategies-ezqzu6
branch
from
October 2, 2026 00:47
5918e11 to
1ca7762
Compare
tap
marked this pull request as ready for review
October 2, 2026 00:47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Milestone M2 of
rational/PLAN.md: the stage lengths are pinned numbers.design.h'sprofiledocstring, PLAN.md section 6): for every band of the vocabulary (2, 3, 4, 6, 8) and every profile, the smallest m whose L-th-band design meets the stopband with ≥ 1 dB margin on a 16384-point grid, N = 2mB − 1.profilecarries the pins astaps_per_branch(0 = search),design_stage<R>reads them, a custom profile without pins is searched on the same grid (bounded at 128 branch taps), andstage_taps_per_phase<R>gives the mixed stages' ⌈N / L⌉.notebooks/design_spike.ipynb, committed executed — the independent leg, asbridge's M2 spike was: the designer re-derived in numpy from the same published math, the search, the minimality check, the measured worst stopband and ripple per row, the mixed ratios' taps per phase, and theeconomyhalf-band decimator checked end to end through scipy'supfirdn(a tone just past the stopband edge aliases at −72.1 dB; passband tones within 0.001 dB).figure_digest.pyas inbridge/notebooks/.test_design.cppenforces every row against the shipping designer: the pin equals the search, m − 1 misses the margin, the worst stopband is the table's within 0.05 dB, the ripple is within PLAN.md 2.3's candidate (now a bound: 0.01 dB per 70 dB stage, 0.0001 dB at transparent; measured ≤ 0.0025 / 0.00001), the mixed T values, the unpinned-profile search, and the two rows the coarse grid gets wrong.8994f2f, nyquist: the spec search's grid is a parameter DspTap#50's merge onmain(search_nyquist_mwith agrid_pointsparameter; the identical tree to the branch commit this PR was drafted against).bare_metal_main.cpp; Hexagon also the two throw tests); the 70 dB rows' pins, minimality and structure run on target.rational/PLAN.mdv0.5 fills the M2 table from the measurements and records M2 done; the familyPLAN.md, both READMEs and both CLAUDE files follow.Why
PLAN.md section 6, M2: a deployed stage's length must be a number in a table, not a search at construction, and the table must be measured from the designer that ships, not estimated.
Finding.
nyquist.h's 1024-point default grid steps over a sidelobe of the long designs: the 8th-bandtransparentcandidate reads −121.7 dB on 1024 points and −119.3 dB on 8192, so a 1024-point search under-pins two rows of the full table — band 4balanced(103 → 111 taps) and band 8transparent(383 → 399). 16384 points agree with 65536 within 0.003 dB for every design up to N = 399. Per the substrate rule the search's grid became a parameter in DspTap first (#50, default unchanged so DspTap's own pins hold); the rational engine pins on 16384 and states the grid as part of the pin. The half- and third-band rows of v0.3 are unchanged.Verification
-Werrorand GCC-Werror(all threeTAP_SR_*_WERROR): the whole family battery, 200 / 200 (rational 25, with the pinned table measured throughdesign_stage).requirements.lockenvironment (numpy 2.4.6, scipy 1.17.1): every row's N, worst stopband and ripple match the C++ measurement; its assertions (margin, minimality, grid convergence, structure, the upfirdn check) pass.scripts/tidy.shover the changed TUs: clean.The measured table (N / nonzero, worst stopband on 16384 points):
Mixed stages' taps per phase at economy: 3/2 22, 2/3 33, 4/3 22, 3/4 29, 8/3 24, 3/8 64 (a 2/3 stage costs 33 MACs per output, not the 26 the v0.2 estimate carried; the matrix's MAC figures are regenerated at M4, risk S1).
Notes for the reviewer
main(8994f2f), so it stays reachable.profilegainstaps_per_branchanddesign_stageno longer searches for the four named profiles; nothing shipped consumes the engine yet (M1 landed yesterday).🤖 Generated with Claude Code
https://claude.ai/code/session_015VR1VC4SDGxHZQQsQvPBaA