feat(chirp): Double Chirp — up+down sum with deterministic 1-D phase optimisation (ticket 41) #37
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!37
Loading…
Reference in a new issue
No description provided.
Delete branch "double-chirp"
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?
Backlog ticket 41 (chirp-directions round, third ticket). Adds the Double Chirp waveform: the sum of the Up Chirp base and the Down Chirp base — identical geometry, element-wise aligned — rotated by a relative phase θ found by a deterministic 1-D search minimising the PAPR of the summed base (operator-confirmed option B: NOT the comb's PSO; no RNG, seed-free).
Phase search (pinned constants)
[0, 2π)— vectorised pointwise|s(θ)|² = |up|² + |down|² + 2·Re(e^{−jθ}·up·conj(down)), chunked over samples so the working set stays O(base)PAPR(θ) = 20·log10(max|s(θ)| / sqrt(mean|s(θ)|²))(full-scale-complex, the preview's formula), evaluated on the phase-1 base, never the repeated overallchirp.optimal_double_chirp_phase(base_up, base_down) -> (θ*, papr)exposes the optimum for tests; no JSON/UI surface in this versionLevel semantics (A1 default, operator left standing)
Each component carries the full band
Levelgain — no amplitude compensation of the sum; the combined peak can approach 2× a single chirp's (the operator's CFR/PAPR post-chain remains available).Implementation
chirp.py: both bases built through the sharedSWEEP_UP/SWEEP_DOWNmachinery (identical_PhaseOnegeometry); phase-2 repeat factored into_repeat_base_to_overall(shared by all three chirp types);generate_double_chirpsums withexp(1j·θ*)and rides the shared stitching pathmodel.py:WAVEFORM_DOUBLE_CHIRP(8 options);CHIRP_WAVEFORM_TYPESgrows to the three-chirp family — validation L7/L8/L16 and the UI chirp controls/hints cover it automaticallygenerate.py: dispatch branch (same post chain + SigV3.1 write); Multi IQ / Other IQ still raiseNotImplementedErrorspec.md: §5.2.1c Double Chirp, §3.3 row, 8 options (§5.2.1b/c repositioned after §5.2.1's complete bullet list)Gate
pytest: 1203 passed / 63 skipped (headless tier), coverage 95.40 % ≥ 85 %ruff+mypy: cleantests/test_double_chirp.py(14 tests): determinism + θ* stability, search beats the grid neighbours, measured PAPR equals the reported optimum, single-block base == the phase-optimised sum (element-wise), A1 no-compensation bound, triangle-inequality envelope bound, shared contract, L8/policy family coverage, band isolation, dispatch, L14 preflight, phase-2 stitching; GUI Double-Chirp generate test addedAdds the "Double Chirp" waveform (operator-confirmed option B): the sum of the Up Chirp base and the Down Chirp base — identical geometry, element-wise aligned — rotated by a relative phase θ found by a DETERMINISTIC 1-D search minimising the PAPR of the summed base (NOT the comb's PSO; no RNG, seed-free): - chirp.py: optimal_double_chirp_phase (coarse 720-point grid over [0, 2π) computed vectorised pointwise |s(θ)|² = |up|² + |down|² + 2·Re(e^{-jθ}·up·conj(down)), chunked to keep the working set O(base), followed by golden-section refinement within ±1° of the best coarse candidate — kept only when it beats the coarse candidate, so the search never returns worse than the grid); generate_double_chirp builds both bases through the shared SWEEP_UP/SWEEP_DOWN machinery, sums with exp(1j·θ*) and repeats the combined base through the shared phase-2 stitching path (factored into _repeat_base_to_overall); PHASE_SEARCH_POINTS = 720 module constant - Level semantics (A1 default, operator left standing): each component carries the full band Level gain — no amplitude compensation of the sum (combined peak can approach 2×; CFR post-chain remains available) - model.py: WAVEFORM_DOUBLE_CHIRP (8 options) + CHIRP_WAVEFORM_TYPES grows to the three-chirp family - generate.py: dispatch branch (same post chain + write); Multi IQ / Other IQ still raise NotImplementedError - validation/ui: L7/L8/L16 and the chirp controls/hints cover the family automatically via CHIRP_WAVEFORM_TYPES - tests: new tests/test_double_chirp.py (14 tests: determinism + θ* stability, search beats the grid neighbours, measured PAPR equals the reported optimum, single-block base == the phase-optimised sum, A1 no-compensation bound, triangle-inequality envelope bound, shared contract, L8/policy family coverage, band isolation, dispatch, L14 preflight, phase-2 stitching); premise tests updated (8 options, __all__ surface); GUI Double Chirp generate test added - spec.md: §5.2.1c Double Chirp, §3.3 row, 8 options; §5.2.1b/c repositioned after §5.2.1's complete bullet list Gate: pytest 1203 passed / 63 skipped (headless tier), coverage 95.40%; ruff + mypy clean.