fix(comb): k=0 periodic-chirp comb builder replaces the warped 2^N LFM path #50
No reviewers
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
ykp/gensig!50
Loading…
Reference in a new issue
No description provided.
Delete branch "fix-lfm-periodic-comb"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Operator-confirmed redesign of the comb's
CombOversampling == 0path: the LFM branch now synthesizes a periodic chirp of exactly one tone-spacing period,P = round(Fe/spacing)samples, with continuous phase — tiling it yields a frequency comb with the exact spacingFe/P(the requestedToneSpacingrounded to a whole-sample period), with no power-of-two bin warping.What was wrong with
create_lfm_tones_oldFe/nfftgrid → the realized comb spacing was warped and the block period wasnfft, not one comb periodP.nfftlong → phase discontinuities when tiled (no periodic chirp).IndexErroror silently wrapped via numpy negative indexing), duplicate bins overwrote instead of summing,max()on an empty array for all-zero scales, an inconsistent phase constant (−0.25vs the−0.125used increate_multi_tones' fallback), pseudo-docstring strings as comments.create_lfm_toneswas dead code with the same root flaw (tones quantized to thenfftgrid ⇒ theP-sample block was notP-periodic).The fix
create_lfm_tones(tones, scales, spacing_hz, fe)rewritten as the direct periodic builder: ONE block ofP = round(Fe/spacing)samples; full union comb (a line at everyFe/Pmultiple across the union span of all bands, edges nearest-snapped); uniform −π/4 quadratic (chirp) phase law anchored at the union's lowest line; whole chirp scaled tomax(|scales|)(per-band Levels intentionally not per-line — operator decision). StrictlyP-periodic ⇒ continuous phase when tiled. The tone sum is evaluated as a length-Pinverse DFT — the transform length is the comb period, so it is an exact, efficiency-equivalent evaluation with no 2^N spectral quantization.create_lfm_tones_olddeleted; dead code cleaned;__all__updated.multi_tones.synthesize_comb_block+ geometry single sourcecomb_block_samples/comb_period_samples:comb.pyandcomb_iq.pyboth routeoversampling == 0→ periodic-chirp builder (deterministic, RNG-free, iteration-cap-irrelevant) andk > 0→ the seeded PSO IFFT builder. Theiteration_cap == 0IFFT fallback insidecreate_multi_tonesis untouched (behavior unchanged; only its stale "linear-phase" docstring corrected).k = 0now bounds one comb period (round(Fe/spacing)/Fe) — the old2^floorbound could pass durations too short for a full period.k = 0documented as the periodic-chirp mode.Tests
create_lfm_tones: exact period (67 =round(200e6/3e6), NOT 2^N); tiled spectrum has lines ONLY atfe/Pmultiples across the union span (gap lines included) with uniform magnitude; peak =max(|scales|); empty/zero-scale/out-of-band → zeros; input validation.create_multi_tonescall.combandcomb-iqwithCombOversampling = 0produce exactlyP-periodic output under hard tiling.pytest1306 passed / 64 skipped (headless UI tier) ·ruff check gensig testsclean ·mypy gensig testsclean.