Repository navigation
Capacity bounds for epsilon-transducers; trapdoor and Ising example channels - #32
Merged
Merged
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
sofic/examples/processes.py):trapdoor()/trapdoor_et()andising_channel()/ising_channel_et(). Each starts in state 0 or 1 with probability 1/2._transducergains aninitials=keyword so a factory can declare several initial states.sofic.generators.capacity(new package):max I(X,S;Y|Q), solved as a convex program over the stationary joint (Sabag–Permuter–Pfister 2017; Sabag–Huleihel–Permuter 2020).certified=False.kMarkov input. The rate ish(Y) - E H(Y|X,S), withh(Y)bounded below by block entropies. This is the objective of the generalized Blahut–Arimoto algorithm, optimized directly here.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.QGraphclass, and a simplex grid with Freudenthal-triangulation interpolation plus relative value iteration.EpsilonTransducer.feedback_capacity(method=...)andEpsilonTransducer.capacity(method=...).capacity = ["cvxpy"]. Without cvxpy the convex step uses scipy SLSQP, and solutions from either solver are polished with SLSQP.docs/generators/channel_capacity.rst, 10 new bib entries (DOIs checked on Crossref), and a CHANGELOG entry.Validation (
tests/test_channel_capacity.py)dit(agrees to about 1e-6)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
koutputs) 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.Test plan
uv run pytest(full default suite): 2039 passeduv run pytest tests/test_channel_capacity.py -m ""(includes slow): 23 passedruff check,ruff format --check, andty checkclean on the new code