Skip to content

Observations instead of taps, and the QPSK of the standards - #44

Merged
vincentchoqueuse merged 3 commits into
mainfrom
claude/comnumpy-v1-architecture-5dtrz3
Aug 23, 2026
Merged

vincentchoqueuse merged 3 commits into
mainfrom
claude/comnumpy-v1-architecture-5dtrz3

Conversation

@vincentchoqueuse

Copy link
Copy Markdown
Owner

Two changes, both closing gaps between what the library says and what the reader expects.

taps becomes observations

The retained-signal mechanism of Sequential is renamed after what it is: an observation is simply the output of a named mechanism, explicitly retained for experimental analysis. It performs no computation and does not alter the signal — same shape, same dtype, dimensions never reduced; power, SNR or SER stay with the metrics, applied to the observation afterwards.

  • Sequential([...], observations=["tx"]) declares what to retain; chain.observation("tx") reads it back after the run.
  • Observation names are the block names already used by set_params, wiring and the profile table — no new naming system.
  • Renamed with it: tapped_ → observed_, the "taps" key of graph() and of the JSON export → "observations", the tapped mermaid class → observed; wiring sources are now "observed automatically".
  • An empty observations list retains nothing, so large batches and fibre propagations pay only for what they declare.
  • The FIR sense of the word (filter taps, channel taps, TappedDelayLine) is untouched.
  • Vocabulary swept through docstrings, CONVENTIONS.md, ARCHITECTURE.md, README, all tutorial and getting-started pages, examples (figure titles regenerated), validation scripts and the tutorial skill; tests/core/test_taps.py becomes test_chain_observations.py.

One breaking-change window, no compatibility layer (D9): taps=/tap() are gone.

QPSK carries the pi/4 offset of the standards

get_alphabet("PSK", 4) sampled the raw circle exp(2j*pi*m/4): points on the axes, a constellation rotated by pi/4 from the QPSK of the standards (3GPP, 802.11) and of every textbook figure. QPSK now sits on the diagonals — the same point set as QAM-4. BPSK and M ≥ 8 keep the phase-0 convention.

Rotation changes no error rate (mapper and demapper share the alphabet, the noise is circular), but it removes the pi/4 surprise against any other tool, and the tx-PSK/rx-QAM mixing trap whose points landed exactly on the decision boundaries.

  • The historical-table pin of tests/core/test_alphabet.py asserts the one deliberate deviation as the relationship it is: built = table × exp(j*pi/4), labelling untouched.
  • The Gauss–Hermite accuracy table of capacity.py is re-measured for the diagonal orientation (1.9e-5 bit at 40 nodes — the node grid is axis-aligned, so the quadrature error is not rotation-invariant even though the capacity is).
  • The Alamouti and MIMO pages are re-pasted from one fresh run each (their Monte-Carlo tables shift in the third digit — same noise draws on rotated symbols) and the constellation figures turn by 45°; the MIMO cost block also catches up with the script's actual output. The PAPR and PDM pages are re-checked and unchanged to the digit.

Verification

  • 1200 tests + 1225 subtests green (doctests included), examples smoke tests green
  • ruff check . clean, pyright 0 errors, sphinx -W clean

🤖 Generated with Claude Code

https://claude.ai/code/session_01Pn2F8X4HZhS8fEJcL5enzw


Generated by Claude Code

claude added 3 commits August 14, 2026 07:17
An observation is simply the output of a named mechanism, explicitly
retained for experimental analysis. It performs no computation and does
not alter the signal -- same shape, same dtype, dimensions never
reduced; power, SNR or SER stay with the metrics, applied to the
observation afterwards.

- Sequential(observations=["tx"]) declares what to retain;
  chain.observation("tx") reads it back after the run
- observation names are the block names already used by set_params,
  wiring and the profile table -- no new naming system
- renamed with it: tapped_ -> observed_, the "taps" key of graph() and
  of the JSON export -> "observations", the "tapped" mermaid class ->
  "observed"; wiring sources are now "observed automatically"
- an empty observations list retains nothing, so large batches and
  fibre propagations pay only for what they declare
- the FIR sense of the word (filter taps, channel taps,
  TappedDelayLine) is untouched
- vocabulary swept through the docstrings, CONVENTIONS.md,
  ARCHITECTURE.md, README, tutorials, getting-started pages, examples
  (figure titles regenerated), validation scripts and the tutorial
  skill; tests/core/test_taps.py becomes test_chain_observations.py

One breaking-change window, no compatibility layer (D9): taps=/tap()
are gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
get_alphabet("PSK", 4) sampled the raw circle exp(2j*pi*m/4): points on
the axes, a constellation rotated by pi/4 from the QPSK of the
standards (3GPP, 802.11) and of every textbook figure. QPSK now sits on
the diagonals -- the same point set as QAM-4. BPSK and M >= 8 keep the
phase-0 convention. Rotation changes no error rate (mapper and demapper
share the alphabet, the noise is circular), but it removes the pi/4
surprise against any other tool, and the tx-PSK/rx-QAM mixing trap
whose points landed exactly on the decision boundaries.

The table pin of tests/core/test_alphabet.py now asserts the documented
relationship for this one deliberate deviation: built = historical
table * exp(j*pi/4), labelling untouched. The Gauss-Hermite accuracy
note of capacity.py is re-measured for the diagonal orientation
(1.9e-5 bit at 40 nodes -- the node grid is axis-aligned, so the
quadrature error is not rotation-invariant even though the capacity
is).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Alamouti and MIMO Monte-Carlo tables shift in the third digit (the
same noise draws now land on rotated symbols) and the constellation
figures turn by 45 degrees; both pages are re-pasted from one fresh run
of their script. The MIMO cost block also catches up with the script's
actual output -- all seven SNR points, ML and SD interleaved, with the
title line -- where the page still showed a three-point grouped format
from an earlier version. The PAPR and PDM pages are re-checked and
unchanged: a global rotation moves neither an envelope nor the CMA+BPS
round trip, and their pasted numbers reproduce to the digit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vincentchoqueuse
vincentchoqueuse merged commit 8beb896 into main Aug 23, 2026
8 checks passed
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.

2 participants