Source code for dit.example_channels.qary

"""
q-ary example channels.
"""

from ..exceptions import ditException
from ._util import conditional_from_matrix

__all__ = (
    "noisy_typewriter",
    "q_ary_erasure_channel",
    "q_ary_symmetric_channel",
)


[docs] def q_ary_symmetric_channel(q, p): """ The q-ary symmetric channel. A symbol is received correctly with probability ``1 - p`` and is otherwise received as one of the other ``q - 1`` symbols, chosen uniformly. Its capacity is :math:`\\log_2 q - H_b(p) - p \\log_2(q - 1)`. The binary symmetric channel is the case ``q == 2``. Parameters ---------- q : int The alphabet size (``q >= 2``). p : float The total probability that a symbol is received incorrectly. Returns ------- channel : Distribution The conditional distribution ``p(Y | X)`` over ``{0, ..., q - 1}``. """ if q < 2: raise ditException("The alphabet size q must be at least 2.") if not 0 <= p <= 1: raise ditException("The error probability p must lie in [0, 1].") off = p / (q - 1) P = [[1 - p if i == j else off for j in range(q)] for i in range(q)] return conditional_from_matrix(P, list(range(q)), list(range(q)))
[docs] def q_ary_erasure_channel(q, epsilon): """ The q-ary erasure channel. A symbol is erased with probability ``epsilon`` and otherwise received unchanged. Its capacity is :math:`(1 - \\epsilon) \\log_2 q`. The binary erasure channel is the case ``q == 2``. Parameters ---------- q : int The alphabet size (``q >= 2``). epsilon : float The probability that a symbol is erased. Returns ------- channel : Distribution The conditional distribution ``p(Y | X)`` with output alphabet ``{0, ..., q - 1, q}``, where ``q`` denotes an erasure. """ if q < 2: raise ditException("The alphabet size q must be at least 2.") if not 0 <= epsilon <= 1: raise ditException("The erasure probability epsilon must lie in [0, 1].") erasure = q P = [[(1 - epsilon if j == i else 0) for j in range(q)] + [epsilon] for i in range(q)] return conditional_from_matrix(P, list(range(q)), list(range(q)) + [erasure])
[docs] def noisy_typewriter(n=26): """ The noisy typewriter channel (Cover & Thomas). Each of the ``n`` letters is received either unchanged or as the next letter (cyclically), each with probability one half. Its capacity is :math:`\\log_2(n / 2)`, achieved by using every other input letter. Parameters ---------- n : int The alphabet size (``n >= 2``). Returns ------- channel : Distribution The conditional distribution ``p(Y | X)`` over ``{0, ..., n - 1}``. """ if n < 2: raise ditException("The alphabet size n must be at least 2.") P = [[0.0] * n for _ in range(n)] for i in range(n): P[i][i] = 0.5 P[i][(i + 1) % n] = 0.5 return conditional_from_matrix(P, list(range(n)), list(range(n)))