Coding
The dit.coding module builds both source codes (which compress a source
Distribution) and channel codes (which add redundancy to protect
against channel noise), and exposes their code-theoretic properties.
Source coding
A source code maps the outcomes of a source to codewords over a radix-ary
alphabet (binary by default), with the goal of minimizing the expected number of
code symbols per source symbol – the rate. By the source coding theorem
[CT06], no uniquely decodable code can have a rate below the source
entropy \(\H{X}\).
Base classes
All source codes derive from SourceCoding, which defines the
encode(), decode(), and
rate() interface and provides the comparisons to the source
entropy that are common to every source code:
source_entropy()– \(\H{X}\) inradix-ary digits,redundancy()–rate - source_entropy,efficiency()–source_entropy / rate.
Channel codes derive from the companion ChannelCoding base class,
described under Channel coding below.
Symbol codes
A SymbolCode assigns one codeword to each source outcome. The classic
constructions are available:
shannon()– lengths \(\lceil \log_D 1/p \rceil\), codewords from the cumulative distribution,fano()– top-down balanced partitioning,shannon_fano_elias()– lengths \(\lceil \log_D 1/p \rceil + 1\), codewords from the midpoint cumulative distribution,huffman()– the optimal symbol code,length_limited_huffman()– the optimal code subject to a maximum codeword length (via package-merge),golomb()/rice()– optimal codes for geometric integer sources.
Beyond the rate-based properties, a SymbolCode reports the Kraft sum
(kraft_sum()), whether it is complete
(is_complete()), prefix-free (is_prefix_free()),
uniquely decodable (is_uniquely_decodable(), via
Sardinas-Patterson), and optimal (is_optimal()).
Example
In [1]: from dit.coding import huffman, shannon
In [2]: d = dit.Distribution(['a', 'b', 'c', 'd', 'e'], [0.4, 0.2, 0.2, 0.1, 0.1])
In [3]: code = huffman(d)
In [4]: code.average_length(), code.source_entropy()
Out[4]: (2.2, 2.1219280948873624)
In [5]: code.is_optimal(), code.is_prefix_free(), code.is_complete()
Out[5]: (True, True, True)
In [6]: seq = list(d.outcomes)
In [7]: code.decode(code.encode(seq)) == seq
Out[7]: True
Huffman is optimal, so its average length is no larger than the Shannon code’s:
In [8]: shannon(d).average_length()
Out[8]: 2.8000000000000003
Universal integer codes
The universal codes encode the positive integers without reference to a source
distribution, yet stay within a constant factor of optimal across a wide range of
sources: unary(), elias_gamma(), elias_delta(),
elias_omega(), and fibonacci(). The universal_code() helper wraps
a chosen family into a SymbolCode over an integer-valued source.
Tunstall codes
Where a symbol code maps each symbol to a variable-length codeword, a
tunstall() code parses the source into variable-length words and maps each
word to a fixed-length codeword. It is the variable-to-fixed dual of Huffman and
is realized by TunstallCode.
Polar source coding
Source polarization [Arikan10] applies the Arikan transform on the source side. For \(N = 2^m\) i.i.d. copies of a binary source \(X\) (optionally with side information \(Y\)), the transform \(U^N = X^N G_N\) produces synthesized coordinates whose conditional entropies \(\H{U_i \mid U^{i-1}, Y^N}\) polarize toward \(0\) (deterministic given the past) or \(1\) (uniform given the past) as \(N\) grows. The coordinates that stay near one – the high-entropy set – are exactly what a lossless source code must store; the rest are recovered by sequential decisions and the inverse transform. With side information this is the polar route to Slepian-Wolf coding.
The finite-block utilities are exact (no density evolution), so they are limited to small \(N\):
source_bhattacharyya()– the source Bhattacharyya parameter \(Z(X \mid Y) = 2 \sum_y \sqrt{p(0, y) p(1, y)}\), small when \(X\) is nearly determined by \(Y\) and near one when \(X\) is nearly uniform,source_polarization_profile()– the per-coordinate conditional entropy and source Bhattacharyya (and an optional Goela-stylemax_correlation_with_pastdiagnostic [Goe14]),source_high_entropy_set()– the coordinates a code keeps; by default the lossless set (every coordinate whose conditional entropy exceeds a tolerance).
The polar_source() constructor builds a PolarSourceCode – an exact
finite-block source code (binary source, power-of-two block length, optional
decoder side information). Its encode() returns the
high-entropy coordinates and decode() fills the low-entropy
coordinates by exact maximum a posteriori decisions before inverting the
transform. Because the joint table is enumerated exactly, a max_states guard
prevents accidental exponential blowups.
In [9]: from dit.coding import polar_source, source_polarization_profile
In [10]: dsbs = dit.Distribution(['00', '01', '10', '11'], [0.45, 0.05, 0.05, 0.45])
In [11]: [round(row['entropy'], 3) for row in source_polarization_profile(dsbs, 4, rv=0, crvs=[1])]
Out[11]: [0.875, 0.485, 0.438, 0.078]
In [12]: code = polar_source(dsbs, 8, rv=0, crvs=[1])
In [13]: code.rate(), code.high_entropy_set
Out[13]: (1.0, [0, 1, 2, 3, 4, 5, 6, 7])
Channel coding
A channel code adds redundancy to a message so that it can be recovered after
transmission over a noisy channel. All channel codes in dit.coding are
binary (over \(\mathrm{GF}(2)\)), and a channel is supplied as a conditional
Distribution \(p(Y \mid X)\) – a discrete memoryless channel
applied independently to each transmitted symbol. The Channels page
catalogs ready-made channels, including binary_symmetric_channel()
and binary_erasure_channel() (re-exported from
dit.coding for convenience).
Every channel code derives from ChannelCoding, which provides the
information-theoretic evaluation common to all of them:
capacity_gap()–channel_capacity(channel) - rate, the gap to the channel coding theorem’s limit [CT06],probability_of_error()– the block-error probability under the code’s own decoder, computed exactly for small codes (enumerating every message and received word) or by Monte Carlo otherwise.
Linear block codes
A LinearCode is specified by a generator matrix G; the parity-check
matrix H is derived as a basis for its null space. It supports
hard-decision syndrome decoding (and maximum-likelihood decoding when a channel is
given), and reports the minimum_distance(),
weight_enumerator(), and
error_correcting_capability(). The classical families are
available as constructors: repetition(), parity_check(),
hamming(), reed_muller(), and golay().
Modern codes
Three modern codes specialize the decoder:
ldpc()/gallager()build anLDPCCodedecoded by sum-product belief propagation over its Tanner graph [CT06],polar()builds aPolarCode, freezing the least reliable synthesized bit-channels (by Bhattacharyya parameter) and decoding by successive cancellation,convolutional()builds aConvolutionalCodefrom generator polynomials, decoded with the Viterbi algorithm (soft-decision when a channel is given).
Channel coding example
The Hamming [7, 4, 3] code corrects any single error; over a binary symmetric
channel its exact block-error probability matches the closed form
\(1 - (1-p)^7 - 7p(1-p)^6\):
In [14]: from dit.coding import hamming, binary_symmetric_channel
In [15]: code = hamming(3)
In [16]: code.length, code.dimension, code.minimum_distance()
Out[16]: (7, 4, 3)
In [17]: bsc = binary_symmetric_channel(0.05)
In [18]: code.capacity_gap(bsc)
Out[18]: 0.14217447145547224
In [19]: code.probability_of_error(bsc, method='exact')
Out[19]: 0.04438054218749993
In [20]: 1 - 0.95**7 - 7 * 0.05 * 0.95**6
Out[20]: 0.044380542187500316
APIs
- class SourceCoding(dist=None, radix=2)[source]
Abstract base class for source codes.
A source code maps the outcomes of a
Distributionto codewords over a radix-ary code alphabet. Concrete subclasses define how outcomes are encoded and decoded, and what the code’s rate is; this base class provides the comparisons to the source entropy that are common to all source codes.- Parameters:
dist (Distribution, None) – The source distribution the code is built for. Required for any of the rate-based properties.
radix (int) – The size of the code alphabet. Default is 2 (binary).
- abstractmethod decode(encoded)[source]
Decode a sequence of code symbols back into source outcomes.
- efficiency()[source]
The ratio of the source entropy to the rate, in
[0, 1].- Returns:
e – The coding efficiency,
source_entropy / rate.- Return type:
- abstractmethod encode(source)[source]
Encode a sequence of source outcomes into a sequence of code symbols.
- class ChannelCoding(channel=None, radix=2)[source]
Abstract base class for channel codes.
A channel code adds redundancy to a message so that it can be recovered after transmission across a noisy channel. This class is scaffolding for future channel codes (repetition, polar, LDPC, …); no concrete subclass is provided yet.
Concrete subclasses are expected to implement
encode()(message -> codeword),decode()(received word -> message), andrate()(message symbols per channel use), and may additionally expose channel-code properties such as the minimum distance, the block error probability for a given channel, and the gap to capacity (viadit.algorithms.channel_capacity()).- Parameters:
channel (Distribution, None) – The channel, as a conditional distribution
p(output | input).radix (int) – The size of the code alphabet. Default is 2 (binary).
- capacity_gap(channel)[source]
The gap between the channel capacity and the code rate.
- Parameters:
channel (Distribution) – The channel, as a conditional distribution
p(Y|X).- Returns:
gap –
capacity(channel) - rate, in bits per channel use. Positive when the code operates below capacity.- Return type:
- abstractmethod decode(received, channel=None)[source]
Decode a received word back into a message.
Soft-decision decoders use channel (a conditional
p(Y|X)distribution) to form log-likelihood ratios; hard-decision decoders ignore it.
- probability_of_error(channel, method='auto', samples=10000, prng=None)[source]
The block error probability of the code over a channel.
The code’s own
decode()is used (passing channel so soft-decision decoders engage). Withmethod='exact'every message and every received word is enumerated – feasible only for small codes – whilemethod='montecarlo'estimates the probability by sampling.- Parameters:
channel (Distribution) – The channel, as a conditional distribution
p(Y|X).method (str) –
'exact','montecarlo', or'auto'(exact when small).samples (int) – The number of Monte Carlo samples.
prng (numpy.random.Generator, None) – The random number generator for Monte Carlo sampling.
- Returns:
pe – The probability that the decoded message differs from the sent one.
- Return type:
- class SymbolCode(codebook, dist=None, radix=2)[source]
A source code that maps each outcome to a single codeword.
- Parameters:
codebook (dict) – A mapping from source outcomes to codeword strings (e.g.
'010').dist (Distribution, None) – The source distribution. Required for the rate-based properties (
rate(),average_length(),redundancy(), …).radix (int) – The size of the code alphabet. Default is 2 (binary).
- average_length()[source]
The expected codeword length,
sum_x p(x) * len(codeword(x)).- Returns:
L
- Return type:
- encode(source)[source]
Encode a sequence of source outcomes into a string of code symbols.
- Parameters:
source (iterable) – A sequence of source outcomes.
- Returns:
encoded – The concatenated codewords.
- Return type:
- is_complete()[source]
Whether the code is complete (its Kraft sum equals 1).
- Returns:
complete
- Return type:
- is_optimal()[source]
Whether the code achieves the minimal average length (Huffman optimal).
- Returns:
optimal
- Return type:
- is_prefix_free()[source]
Whether no codeword is a prefix of another (the code is instantaneous).
- Returns:
prefix_free
- Return type:
- is_uniquely_decodable()[source]
Whether the code is uniquely decodable, via the Sardinas-Patterson test.
- Returns:
unique
- Return type:
- kraft_sum()[source]
The Kraft sum
sum_x radix ** -len(codeword(x)).By the Kraft-McMillan inequality this is
<= 1for any uniquely decodable code, with equality iff the code is complete.- Returns:
K
- Return type:
- class TunstallCode(word_to_code, word_probs, code_length, dist=None, radix=2)[source]
A variable-to-fixed-length source code.
- Parameters:
word_to_code (dict) – A mapping from source words (tuples of outcomes) to fixed-length codeword strings.
word_probs (dict) – A mapping from source words to their probabilities (used for the rate).
code_length (int) – The fixed codeword length, in code symbols.
dist (Distribution, None) – The source distribution.
radix (int) – The size of the code alphabet. Default is 2.
- encode(source)[source]
Encode a sequence of source outcomes by greedily parsing it into words.
- Parameters:
source (iterable) – A sequence of source outcomes whose symbols form complete words.
- Returns:
encoded
- Return type:
- class PolarSourceCode(dist, block_length, rv=0, crvs=None, rank_by='entropy', rate=None, size=None, tol=1e-09, max_states=65536)[source]
An exact finite-block polar source code for a small binary source.
The code applies the Arikan transform
U^N = X^N G_Nto a block ofNsource bits and stores only the coordinates in the high-entropy set (those that stay nearly uniform given the past and any side information). Decoding fills in the remaining low-entropy coordinates by sequential maximum a posteriori (MAP) decisions against the exactp(U^N, Y^N)table and then inverts the transform.Because the code enumerates the joint distribution exactly (no density evolution or list decoding), it is intended for small blocks: the number of enumerated states is
|copy support|^N, guarded bymax_states.- Parameters:
dist (Distribution) – A single-copy source
(X)or source-with-side-information(X, Y, ...)distribution.X(indexed byrv) must be binary.block_length (int) – The block length
N; must be a power of two.rv (int) – The index of the binary source variable. Default is 0.
crvs (list, None) – Indices of the side-information variables available at the decoder. If None, the code is a plain (side-information-free) polar source code.
rank_by (str) – How to rank coordinates for the high-entropy set:
"entropy"(default) or"bhattacharyya".rate (float, None) – A fixed target rate in
[0, 1](keepround(rate * N)coordinates). Mutually exclusive withsize.size (int, None) – The exact high-entropy set size. By default the set is chosen losslessly – every coordinate whose conditional entropy exceeds
tolis kept, so the code reconstructs each block exactly. Fixingsize(orrate) below the lossless size yields a fixed-rate code that may not be exact.tol (float) – The conditional-entropy threshold used by the lossless default.
max_states (int) – A guard on the number of enumerated joint outcomes.
- decode(encoded, side_information=None)[source]
Decode a block from its high-entropy coordinates (and any side info).
The high-entropy coordinates are filled from
encoded; the low-entropy coordinates are recovered one at a time by an exact MAP decision againstp(U_i | U^{i-1}, Y^N). The inverse Arikan transform then returns the source bits.- Parameters:
encoded (sequence of int) – The stored high-entropy bits, in ascending index order.
side_information (sequence, None) – The decoder side information
Y^N: one symbol per copy when the code was built withcrvs(flattened copy-major when multiple side variables). Required iff the code has side information.
- Returns:
x_block – The recovered length-
Nblock of source bits.- Return type:
- property message_length
The number of stored (high-entropy) coordinates per block.
- polar_source(dist, block_length, rv=0, crvs=None, rank_by='entropy', rate=None, size=None, tol=1e-09, max_states=65536)[source]
Build an exact finite-block polar source code.
- Parameters:
dist (Distribution) – A single-copy binary source
(X)or(X, Y, ...)distribution.block_length (int) – The block length
N; must be a power of two.rv (int) – The index of the binary source variable. Default is 0.
crvs (list, None) – Indices of the side-information variables available at the decoder.
rank_by (str) –
"entropy"(default) or"bhattacharyya".rate (float, None) – A fixed target rate in
[0, 1]. Mutually exclusive withsize.size (int, None) – The high-entropy set size. Defaults to the lossless set (see
PolarSourceCode).tol (float) – The conditional-entropy threshold used by the lossless default.
max_states (int) – A guard on the number of enumerated joint outcomes.
- Returns:
code
- Return type:
- source_bhattacharyya(dist, rv=0, crvs=None)[source]
The source Bhattacharyya parameter of a binary variable.
For a binary
Xwith side informationY,\[Z(X \mid Y) = 2 \sum_y \sqrt{p(0, y)\,p(1, y)},\]which reduces to
2 sqrt(p(0) p(1))when there is no side information. It satisfies0 <= Z <= 1, withZnear1whenXis nearly uniform givenYand near0whenXis nearly determined byY.
- source_polarization_profile(dist, block_length, rv=0, crvs=None, metrics=('entropy', 'bhattacharyya'))[source]
The exact source-polarization profile of
N = block_lengthi.i.d. copies.Applies the Arikan transform
U^N = X^N G_Nand reports, for each synthesized coordinatei, the requested metrics conditioned on the pastU^{i-1}and the side informationY^N:"entropy"– the conditional entropyH(U_i | U^{i-1}, Y^N),"bhattacharyya"– the conditional source Bhattacharyya parameterZ(U_i | U^{i-1}, Y^N).
The conditional entropies sum to
N * H(X | Y)(entropy conservation), and asNgrows they polarize toward0or1.A third, optional Goela-style diagnostic reuses
dit.divergences.maximum_correlation():"max_correlation_with_past"– the maximal correlationrho_m(U_i ; U^{i-1})between each coordinate and its past (0.0ati = 0, and ignoring side information). Goela et al. (2014) show these also polarize.
- Parameters:
dist (Distribution) – The source distribution for a single copy
(X)or(X, Y, ...).block_length (int) – The number of i.i.d. copies
N; must be a power of two.rv (int) – The index of the binary source variable. Default is 0.
crvs (list, None) – Indices of the side-information variables. If None, no side information.
metrics (tuple of str) – Which metrics to compute per coordinate.
- Returns:
profile – One dict per coordinate
i(in[0, N)), keyed"index"plus the requested metric names.- Return type:
- source_high_entropy_set(dist, block_length, rate=None, size=None, rv=0, crvs=None, rank_by='entropy', tol=1e-09)[source]
The high-entropy indices selected by a polar source code.
Ranks the
Nsynthesized coordinates by their conditional metric (largest conditional entropy, or largest source Bhattacharyya, given the past and any side information) and returns the top indices – those a lossless polar source code must transmit. At most one ofrateorsizemay be given:size– keep exactly this many coordinates,rate– keepround(rate * N)coordinates,neither – keep every coordinate whose conditional entropy exceeds
tol, i.e. the lossless set (the dropped coordinates are deterministic given the past and side information, so the code reconstructs the block exactly).
- Parameters:
dist (Distribution) – The source distribution.
block_length (int) – The number of i.i.d. copies
N; must be a power of two.rate (float, None) – The target fraction of coordinates to keep, in
[0, 1]. The set size isround(rate * N).size (int, None) – The exact number of coordinates to keep.
rv (int) – The index of the binary source variable. Default is 0.
crvs (list, None) – Indices of the side-information variables.
rank_by (str) –
"entropy"(default) or"bhattacharyya".tol (float) – The conditional-entropy threshold for the lossless default; coordinates at or below
tolare treated as deterministic and dropped.
- Returns:
indices – The selected coordinate indices, sorted ascending.
- Return type:
- shannon(dist, radix=2)[source]
Build a Shannon code.
Codeword lengths are
ceil(log_radix(1/p))and codewords are read off the base-radix expansion of the cumulative distribution (outcomes sorted by decreasing probability).- Parameters:
dist (Distribution) – The source distribution.
radix (int) – The size of the code alphabet. Default is 2.
- Returns:
code
- Return type:
- fano(dist, radix=2)[source]
Build a Fano code (the Shannon-Fano top-down splitting method).
Outcomes are sorted by probability and recursively partitioned into two groups of as-equal-as-possible total probability; one bit distinguishes the groups at each level.
- Parameters:
dist (Distribution) – The source distribution.
radix (int) – The size of the code alphabet. Only
radix=2is currently supported.
- Returns:
code
- Return type:
- shannon_fano_elias(dist, radix=2)[source]
Build a Shannon-Fano-Elias code.
Codeword lengths are
ceil(log_radix(1/p)) + 1and codewords are read off the base-radix expansion of the midpoint cumulative distributionF_bar(x) = sum_{y<x} p(y) + p(x)/2. The result is prefix-free.- Parameters:
dist (Distribution) – The source distribution.
radix (int) – The size of the code alphabet. Default is 2.
- Returns:
code
- Return type:
- huffman(dist, radix=2)[source]
Build a Huffman code, the optimal symbol code for the source.
For
radix > 2the alphabet is padded with zero-probability dummy symbols so that every internal node has exactly radix children.- Parameters:
dist (Distribution) – The source distribution.
radix (int) – The size of the code alphabet. Default is 2.
- Returns:
code
- Return type:
- length_limited_huffman(dist, max_length, radix=2)[source]
Build an optimal prefix code whose codewords are at most max_length long.
Uses the package-merge algorithm (Larmore & Hirschberg, 1990).
- Parameters:
- Returns:
code
- Return type:
- golomb(dist, m=None, radix=2)[source]
Build a Golomb code over non-negative-integer outcomes.
Each codeword is the unary-coded quotient
n // mfollowed by the truncated-binary remaindern % m. Golomb codes are optimal prefix codes for geometrically distributed sources.- Parameters:
dist (Distribution) – The source distribution; its outcomes must be non-negative integers.
m (int, None) – The Golomb parameter. If None, the parameter optimal for the (assumed geometric) source is chosen from its mean.
radix (int) – The size of the code alphabet. Only
radix=2is currently supported.
- Returns:
code
- Return type:
- rice(dist, k=None)[source]
Build a Rice code, the Golomb code with parameter
m = 2 ** k.- Parameters:
dist (Distribution) – The source distribution; its outcomes must be non-negative integers.
k (int, None) – The Rice parameter. If None, it is chosen from the optimal Golomb parameter for the source.
- Returns:
code
- Return type:
- tunstall(dist, code_length, radix=2)[source]
Build a Tunstall code for a memoryless source.
- Parameters:
- Returns:
code
- Return type:
- universal_code(dist, kind='gamma')[source]
Build a
SymbolCodeover integer outcomes using a universal code.- Parameters:
dist (Distribution) – The source distribution; its outcomes must be positive integers.
kind (str) – One of
'unary','gamma','delta','omega', or'fibonacci'.
- Returns:
code
- Return type:
- elias_gamma(n)[source]
The Elias gamma codeword for
n >= 1.The codeword is
floor(log2(n))zeros followed by the binary representation ofn.
- elias_delta(n)[source]
The Elias delta codeword for
n >= 1.The codeword is the gamma code of the bit-length of
nfollowed by the bits ofnbelow its leading one.
- class LinearCode(G, channel=None)[source]
A linear block code over GF(2).
- Parameters:
G (array-like) – A
k x nbinary generator matrix of full row rank.channel (Distribution, None) – A default channel, as a conditional distribution
p(Y|X).
- decode(received, channel=None)[source]
Decode a received word.
With no channel, hard-decision syndrome decoding is used. With a channel, maximum-likelihood decoding over the codebook is used.
- property dimension
The number of information bits
k.
- error_correcting_capability()[source]
The number of errors the code can correct,
floor((d - 1) / 2).
- property generator_matrix
The generator matrix
G.
- property length
The block length
n.
- property message_length
The number of message bits per codeword (
k).
- property parity_check_matrix
The parity-check matrix
H.
- class LDPCCode(H, channel=None, max_iterations=50)[source]
A linear code decoded by belief propagation on a sparse parity-check matrix.
- Parameters:
H (array-like) – An
m x nbinary parity-check matrix (typically sparse).channel (Distribution, None) – A default channel.
max_iterations (int) – The maximum number of belief-propagation iterations.
- class PolarCode(n, k, channel)[source]
A polar code of length
n = 2^mwithkinformation bits.- Parameters:
- property message_length
The number of message bits per codeword (
k).
- class ConvolutionalCode(generators, message_length, channel=None)[source]
A rate-
1/nconvolutional code.- Parameters:
- repetition(n, channel=None)[source]
The
[n, 1, n]repetition code.- Parameters:
n (int) – The block length.
channel (Distribution, None) – A default channel.
- Returns:
code
- Return type:
- parity_check(k, channel=None)[source]
The
[k+1, k, 2]single-parity-check code.- Parameters:
k (int) – The number of information bits.
channel (Distribution, None) – A default channel.
- Returns:
code
- Return type:
- hamming(r, channel=None)[source]
The
[2^r - 1, 2^r - 1 - r, 3]Hamming code.- Parameters:
r (int) – The number of parity bits (
r >= 2).channel (Distribution, None) – A default channel.
- Returns:
code
- Return type:
- reed_muller(r, m, channel=None)[source]
The Reed-Muller code
RM(r, m).- Parameters:
- Returns:
code
- Return type:
- golay(extended=False, channel=None)[source]
The binary Golay code.
- Parameters:
extended (bool) – If True, return the extended
[24, 12, 8]code; otherwise the perfect[23, 12, 7]code.channel (Distribution, None) – A default channel.
- Returns:
code
- Return type:
- gallager(n, wc, wr, prng=None, channel=None)[source]
Build a regular Gallager LDPC code.
- Parameters:
n (int) – The block length; must be divisible by
wr.wc (int) – The column weight (variable degree).
wr (int) – The row weight (check degree);
wc < wr.prng (numpy.random.Generator, None) – The random number generator used to permute the sub-bands.
channel (Distribution, None) – A default channel.
- Returns:
code
- Return type: