Skip to content

feat(math): classify resonances high-Z/low-Z; avoid only high-Z#128

Merged
dc0sk merged 2 commits into
mainfrom
feat/resonance-impedance-class
Jul 4, 2026
Merged

feat(math): classify resonances high-Z/low-Z; avoid only high-Z#128
dc0sk merged 2 commits into
mainfrom
feat/resonance-impedance-class

Conversation

@dc0sk

@dc0sk dc0sk commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

Adds the physically-nuanced resonance handling deferred from #127. A wire is resonant at every quarter-wave multiple, but the feedpoint impedance alternates:

  • low-Z — odd multiples (λ/4, 3λ/4, …), current-fed, ~35–50 Ω, near 50 Ω and easy to match;
  • high-Z — even multiples (half-wave multiples λ/2, λ, …), voltage-fed, hundreds–thousands of Ω, genuinely hard to match.

The non-resonant optimizer now avoids only the high-Z resonances, leaving the desirable low-Z lengths available, and every resonant point is tagged in the display and exports so the recommendation stays reconcilable against the list.

Why this is the consistent version of the earlier idea

#127 deliberately did not split resonances into high/low-Z, because doing so partially would create a second, conflicting definition of "resonance" versus the display/export. This PR does it fully: the tags appear everywhere, so recommending a length near a low-Z point (e.g. 30.15 m near the low-Z 3× = 30.14 m) is self-explanatory rather than contradictory.

Changes

  • new ImpedanceClass (Low/High) from harmonic parity
  • build_non_resonant_resonance_points keeps only even (half-wave) harmonics, padded by one half-wave per band so near-edge clearance stays honest and the set is never spuriously empty
  • ResonantPoint gains impedance_class; display lines are tagged [low-Z]/[high-Z] with a legend; JSON export gains "impedance_class"; text/CSV points tagged inline
  • docs/math.md §5 updated

Test plan

  • impedance_class_follows_harmonic_parity, non_resonant_avoids_only_high_z_resonances (asserts even harmonics avoided, odd left available, first beyond-edge high-Z included), resonant_points_display_lines_tag_impedance_class_and_legend
  • cargo test all pass (370 lib + integration), clippy + fmt clean
  • Verified: non-resonant 40m now recommends near the low-Z 30.14 m point with honest 33% clearance vs the high-Z points

🤖 Generated with Claude Code

https://claude.ai/code/session_01Jf8uBU8AYxkrG8fa8yo6tC

dc0sk and others added 2 commits July 4, 2026 13:43
Adds the physically-nuanced refinement previously deferred. A wire is resonant
at every quarter-wave multiple, but the feed sees very different impedances:
odd multiples (lambda/4, 3lambda/4, ...) are current-fed low-Z (~35-50 ohm, easy
to match) while even multiples (half-wave multiples) are voltage-fed high-Z
(hundreds to thousands of ohm, genuinely hard to match).

- new ImpedanceClass (Low/High) derived from harmonic parity
- the non-resonant optimizer now avoids ONLY the high-Z (half-wave) resonances;
  the desirable low-Z lengths are left available. Per-band the avoid-set is
  padded by one half-wave so the nearest high-Z point just outside the window is
  still counted (honest edge clearance)
- every on-screen and exported resonant point is tagged low-Z/high-Z, with a
  legend, so a recommended length that sits near a low-Z resonance is clearly
  reconcilable against the listed points (resolves the old clearance-vs-points
  confusion without a second resonance definition)
- ResonantPoint gains an impedance_class field; JSON export gains
  "impedance_class"; text/CSV points are tagged inline
- docs/math.md §5 updated; tests for classification, high-Z-only avoidance, and
  the tagged display/legend

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses the #128 code-review findings:

- [1][3] Since the non-resonant optimizer now avoids only high-Z resonances,
  min_resonance_clearance_pct measures distance to high-Z points only. Relabel it
  "high-Z clearance" in the non-resonant view and the advise notes, and add a
  one-line explanation, so the figure is no longer read as a generic
  "resonance clearance" (a recommendation may intentionally sit on an easy-match
  low-Z resonance).
- [2] Revert the resonant_points_in_window CSV/text value format to the stable
  `{h}x={len}{unit}` contract (no inline "(low-Z)"); the class stays a first-class
  field in the JSON export and tagged in the on-screen view. Added a contract
  guard test.
- [4] Fix stale docs/math.md wording that still said "within 1 m outside the
  window" (padding is now one half-wave per band).
- [5] Move the ImpedanceClass enum out from between band_resonant_points_m's doc
  comment and its fn, so each doc heads its own item.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dc0sk

dc0sk commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

Applied the high-effort review findings:

  • [1][3] Relabeled the non-resonant clearance as high-Z clearance (it measures distance to the hard-to-match high-Z resonances) in the results view and advise notes, with a one-line explanation — a recommendation may intentionally sit on an easy-match low-Z resonance, so the generic 'resonance clearance' label was misleading.
  • [2] Reverted the resonant_points_in_window CSV/text value to the stable {h}x={len}{unit} contract format; the class stays a first-class JSON field and is shown tagged in the results view. Added a contract-guard test.
  • [4] Fixed stale docs ("within 1 m outside" → one half-wave pad).
  • [5] Moved the ImpedanceClass enum out from between band_resonant_points_m's doc and its fn.

All 461 tests pass; clippy + fmt clean.

@dc0sk
dc0sk merged commit 0954a62 into main Jul 4, 2026
10 checks passed
@dc0sk
dc0sk deleted the feat/resonance-impedance-class branch July 4, 2026 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant