Skip to content

Capacity bounds for epsilon-transducers; trapdoor and Ising example channels - #32

Merged
Autoplectic merged 3 commits into
mainfrom
channel-capacity
Oct 23, 2026
Merged

Autoplectic merged 3 commits into
mainfrom
channel-capacity

Conversation

@Autoplectic

Copy link
Copy Markdown
Member

Summary

Adds capacity bounds for finite ε-transducers. A finite ε-transducer is a unifilar finite-state channel: (s, x, y) determines the next causal state. The bounds cover both the feedback and no-feedback settings. The PR also adds two classic channels with memory as examples.

Feedback capacity of finite-state channels is not computable in general (Grigorescu et al. 2024), so every method returns a CapacityBounds(lower, upper, ...) bracket rather than a single number.

Changes

  • Examples (sofic/examples/processes.py): trapdoor() / trapdoor_et() and ising_channel() / ising_channel_et(). Each starts in state 0 or 1 with probability 1/2. _transducer gains an initials= keyword so a factory can declare several initial states.
  • sofic.generators.capacity (new package):
    • Feedback:
      • Q-graph upper bound max I(X,S;Y|Q), solved as a convex program over the stationary joint (Sabag–Permuter–Pfister 2017; Sabag–Huleihel–Permuter 2020).
      • Certified lower bound from optimized graph-based encoders. Any input that depends on the current causal state and Q-graph node is a valid feedback input, and its directed-information rate is bounded below with block entropy bounds. When the input is also BCJR-invariant, the single-letter rate is credited as well.
      • Q-graph duality upper bound, which for unifilar channels is a finite MDP (Huleihel et al. 2025).
      • Belief-state value iteration (Permuter et al. 2008; Yang–Kavčić–Tatikonda 2005), returned with certified=False.
    • No feedback:
      • Lower bound from an optimized order-k Markov input. The rate is h(Y) - E H(Y|X,S), with h(Y) bounded below by block entropies. This is the objective of the generalized Blahut–Arimoto algorithm, optimized directly here.
      • Q-graph duality upper bound as a dynamic program over P(S,Q|x^t) (Huleihel et al. 2021). The value function is convex in that belief, so linear interpolation on the grid over-estimates it and the gridded bound stays valid at any resolution.
    • Shared pieces: a QGraph class, and a simplex grid with Freudenthal-triangulation interpolation plus relative value iteration.
  • API: EpsilonTransducer.feedback_capacity(method=...) and EpsilonTransducer.capacity(method=...).
  • Optional extra: capacity = ["cvxpy"]. Without cvxpy the convex step uses scipy SLSQP, and solutions from either solver are polished with SLSQP.
  • Docs: new page docs/generators/channel_capacity.rst, 10 new bib entries (DOIs checked on Crossref), and a CHANGELOG entry.

Validation (tests/test_channel_capacity.py)

Channel Feedback bracket No-feedback bracket
Binary memoryless equals the Blahut–Arimoto capacity from dit (agrees to about 1e-6) equals the same value
Trapdoor 0.694236 – 0.694242; the true value is log2(φ) = 0.694242 0.5727 – 0.5936; best published is 0.572 – 0.584
Ising 0.5755215 – 0.5755216; the published value is 0.575522 —

Hypothesis tests check, on random 2-state channels, that every lower bound is at most the matching upper bound, that the no-feedback lower bound is at most the feedback upper bound, and that every bound lies in [0, 1]. DP-heavy tests are marked slow.

Notes

  • Markov Q-graphs (nodes are the last k outputs) are not tight for the trapdoor or Ising channels. The tight graphs, [[0,1],[0,2],[1,2]] for the trapdoor and [[1,2],[0,2],[0,3],[0,2]] for Ising, were found by exhaustive search and must be passed explicitly. The docs show how.
  • The no-feedback bounds require every input to be allowed in every state.
  • Q-graph upper bounds are accurate to the optimizer's tolerance (about 1e-12 in the tests).

Test plan

  • uv run pytest (full default suite): 2039 passed
  • uv run pytest tests/test_channel_capacity.py -m "" (includes slow): 23 passed
  • ruff check, ruff format --check, and ty check clean on the new code
  • Sphinx build: citations resolve and the ipython doctest on the new page passes

Ryan James and others added 3 commits October 23, 2026 11:42
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@Autoplectic
Autoplectic merged commit 2e6518f into main Oct 23, 2026
10 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.

1 participant