diff --git a/src/sage/coding/abstract_code.py b/src/sage/coding/abstract_code.py index ead76be288a..85cdce652b9 100644 --- a/src/sage/coding/abstract_code.py +++ b/src/sage/coding/abstract_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Codes @@ -151,9 +152,9 @@ class AbstractCode(Parent): To implement a code, you need to: - - inherit from AbstractCode + - inherit from :class:`AbstractCode` - - call AbstractCode ``__init__`` method in the subclass constructor. + - call :class:`AbstractCode` ``__init__`` method in the subclass constructor. Example: ``super().__init__(length, "EncoderName", "DecoderName", "metric")``. "EncoderName" and "DecoderName" are set to ``None`` by default, a generic code class such as AbstractCode does @@ -196,9 +197,9 @@ class AbstractCode(Parent): ``MyDecoderClass``. - As AbstractCode is not designed to be implemented, it does not have any - representation methods. You should implement ``_repr_`` and ``_latex_`` - methods in the subclass. + As the class :class:`AbstractCode` is not designed to be instantiated, it + does not have any representation methods. You should implement ``_repr_`` + and ``_latex_`` methods in the subclass. """ def __init__(self, length, default_encoder_name=None, @@ -226,7 +227,7 @@ def __init__(self, length, default_encoder_name=None, EXAMPLES: - The following example demonstrates how to use subclass `AbstractCode` + The following example demonstrates how to use a subclass of ``AbstractCode`` for representing a new family of codes:: sage: from sage.coding.abstract_code import AbstractCode @@ -665,7 +666,7 @@ def add_encoder(self, name, encoder): def decode_to_code(self, word, decoder_name=None, *args, **kwargs): r""" - Corrects the errors in ``word`` and returns a codeword. + Correct the errors in ``word`` and returns a codeword. INPUT: @@ -683,7 +684,8 @@ def decode_to_code(self, word, decoder_name=None, *args, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: w_err = word + vector(GF(2), (1, 0, 0, 0, 0, 0, 0)) @@ -720,7 +722,8 @@ def decode_to_message(self, word, decoder_name=None, *args, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: C.decode_to_message(word) @@ -759,7 +762,8 @@ def decoder(self, decoder_name=None, *args, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: C.decoder() Syndrome decoder for [7, 4] linear code over GF(2) handling errors of weight up to 1 @@ -790,7 +794,8 @@ def decoder(self, decoder_name=None, *args, **kwargs): sage: C.decoder('Try') Traceback (most recent call last): ... - ValueError: There is no Decoder named 'Try'. The known Decoders are: ['InformationSet', 'NearestNeighbor', 'Syndrome'] + ValueError: There is no Decoder named 'Try'. + The known Decoders are: ['InformationSet', 'NearestNeighbor', 'Syndrome'] Some decoders take extra arguments. If the user forgets to supply these, the error message attempts to be helpful:: @@ -798,11 +803,13 @@ def decoder(self, decoder_name=None, *args, **kwargs): sage: C.decoder('InformationSet') Traceback (most recent call last): ... - ValueError: Constructing the InformationSet decoder failed, possibly due to missing or incorrect parameters. + ValueError: Constructing the InformationSet decoder failed, + possibly due to missing or incorrect parameters. The constructor requires the arguments ['number_errors']. It takes the optional arguments ['algorithm']. - It accepts unspecified arguments as well. - See the documentation of sage.coding.information_set_decoder.LinearCodeInformationSetDecoder for more details. + It accepts unspecified arguments as well. See the documentation of + sage.coding.information_set_decoder.LinearCodeInformationSetDecoder + for more details. """ if not self._default_decoder_name: @@ -830,14 +837,15 @@ def decoders_available(self, classes=False): INPUT: - ``classes`` -- (default: ``False``) if ``classes`` is set to ``True``, - return instead a ``dict`` mapping available decoder name to the + return instead a :class:`dict` mapping available decoder name to the associated decoder class. - OUTPUT: a list of strings, or a `dict` mapping strings to classes. + OUTPUT: a list of strings, or a :class:`dict` mapping strings to classes. EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: C.decoders_available() ['InformationSet', 'NearestNeighbor', 'Syndrome'] @@ -878,7 +886,8 @@ def encode(self, word, encoder_name=None, *args, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: word = vector((0, 1, 1, 0)) sage: C.encode(word) @@ -928,7 +937,8 @@ def encoder(self, encoder_name=None, *args, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: C.encoder() Generator matrix-based encoder for [7, 4] linear code over GF(2) @@ -944,7 +954,8 @@ def encoder(self, encoder_name=None, *args, **kwargs): ....: def field(self): ....: return self._field ....: def _repr_(self): - ....: return "%d dummy code over GF(%s)" % (self.length(), self.field().cardinality()) + ....: return "%d dummy code over GF(%s)" % (self.length(), + ....: self.field().cardinality()) sage: D = MyCodeFamily(5, GF(2)) sage: D.encoder() Traceback (most recent call last): @@ -964,7 +975,8 @@ def encoder(self, encoder_name=None, *args, **kwargs): sage: C.encoder('NonExistingEncoder') Traceback (most recent call last): ... - ValueError: There is no Encoder named 'NonExistingEncoder'. The known Encoders are: ['GeneratorMatrix', 'Systematic'] + ValueError: There is no Encoder named 'NonExistingEncoder'. + The known Encoders are: ['GeneratorMatrix', 'Systematic'] Some encoders take extra arguments. If the user incorrectly supplies these, the error message attempts to be helpful:: @@ -972,10 +984,12 @@ def encoder(self, encoder_name=None, *args, **kwargs): sage: C.encoder('Systematic', strange_parameter=True) Traceback (most recent call last): ... - ValueError: Constructing the Systematic encoder failed, possibly due to missing or incorrect parameters. - The constructor requires no arguments. - It takes the optional arguments ['systematic_positions']. - See the documentation of sage.coding.linear_code_no_metric.LinearCodeSystematicEncoder for more details. + ValueError: Constructing the Systematic encoder failed, + possibly due to missing or incorrect parameters. + The constructor requires no arguments. It takes the optional + arguments ['systematic_positions']. See the documentation of + sage.coding.linear_code_no_metric.LinearCodeSystematicEncoder + for more details. """ if not self._default_encoder_name: raise NotImplementedError("No encoder implemented for this code.") @@ -1002,14 +1016,15 @@ def encoders_available(self, classes=False): INPUT: - ``classes`` -- (default: ``False``) if ``classes`` is set to ``True``, - return instead a ``dict`` mapping available encoder name to the + return instead a :class:`dict` mapping available encoder name to the associated encoder class. - OUTPUT: a list of strings, or a `dict` mapping strings to classes. + OUTPUT: a list of strings, or a :class:`dict` mapping strings to classes. EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: C.encoders_available() ['GeneratorMatrix', 'Systematic'] @@ -1051,7 +1066,8 @@ def unencode(self, c, encoder_name=None, nocheck=False, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: c = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: C.unencode(c) diff --git a/src/sage/coding/ag_code.py b/src/sage/coding/ag_code.py index 72bf5c37d5f..f705f75d476 100644 --- a/src/sage/coding/ag_code.py +++ b/src/sage/coding/ag_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings sage.schemes """ AG codes @@ -538,7 +539,8 @@ def basis_differentials(self): sage: Q, = C.places_at_infinity() sage: pls.remove(Q) sage: code = codes.DifferentialAGCode(pls, 3*Q) - sage: matrix([[w.residue(p) for p in pls] for w in code.basis_differentials()]) + sage: matrix([[w.residue(p) for p in pls] + ....: for w in code.basis_differentials()]) [ 1 0 0 0 0 a + 1 a + 1 1] [ 0 1 0 0 0 a + 1 a 0] [ 0 0 1 0 0 a 1 a] diff --git a/src/sage/coding/ag_code_decoders.pyx b/src/sage/coding/ag_code_decoders.pyx index 1ff9a5ed47b..ccd6c8c6912 100644 --- a/src/sage/coding/ag_code_decoders.pyx +++ b/src/sage/coding/ag_code_decoders.pyx @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.rings.finite_rings sage.schemes r""" Decoders for AG codes diff --git a/src/sage/coding/bch_code.py b/src/sage/coding/bch_code.py index 96d4691e554..40fa088354a 100644 --- a/src/sage/coding/bch_code.py +++ b/src/sage/coding/bch_code.py @@ -1,7 +1,8 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" BCH code -Let `F = GF(q)` and `\Phi` be the splitting field of `x^{n} - 1` over `F`, with +Let `F = \GF{q}` and `\Phi` be the splitting field of `x^{n} - 1` over `F`, with `n` a positive integer. Let also `\alpha` be an element of multiplicative order `n` in `\Phi`. Finally, let `b, \delta, \ell` be integers such that `0 \le b \le n`, `1 \le \delta \le n` and `\alpha^\ell` generates the multiplicative @@ -51,7 +52,7 @@ class BCHCode(CyclicCode): splitting field. It has to be of multiplicative order ``length`` over this field. If the splitting field is not ``field``, it also has to be a polynomial in ``zx``, where ``x`` is the degree of the extension field. - For instance, over `GF(16)`, it has to be a polynomial in ``z4``. + For instance, over `\GF{16}`, it has to be a polynomial in ``z4``. - ``offset`` -- (default: ``1``) the first element in the defining set @@ -79,7 +80,7 @@ class BCHCode(CyclicCode): sage: C.generator_polynomial() x^8 + x^7 + x^6 + x^4 + 1 - BCH codes are cyclic, and can be interfaced into the CyclicCode class. + BCH codes are cyclic, and can be interfaced into the :class:`CyclicCode` class. The smallest GRS code which contains a given BCH code can also be computed, and these two codes may be equal:: @@ -158,7 +159,7 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -172,7 +173,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -186,7 +187,7 @@ def _latex_(self): def jump_size(self): r""" - Returns the jump size between two consecutive elements of the defining + Return the jump size between two consecutive elements of the defining set of ``self``. EXAMPLES:: @@ -199,7 +200,7 @@ def jump_size(self): def offset(self): r""" - Returns the offset which was used to compute the elements in + Return the offset which was used to compute the elements in the defining set of ``self``. EXAMPLES:: @@ -212,7 +213,7 @@ def offset(self): def designed_distance(self): r""" - Returns the designed distance of ``self``. + Return the designed distance of ``self``. EXAMPLES:: @@ -224,7 +225,7 @@ def designed_distance(self): def bch_to_grs(self): r""" - Returns the underlying GRS code from which ``self`` was derived. + Return the underlying GRS code from which ``self`` was derived. EXAMPLES:: @@ -286,7 +287,7 @@ def __init__(self, code, grs_decoder="KeyEquationSyndrome", **kwargs): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -299,7 +300,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -313,7 +314,7 @@ def _latex_(self): def grs_code(self): r""" - Returns the underlying GRS code of :meth:`sage.coding.decoder.Decoder.code`. + Return the underlying GRS code of :meth:`sage.coding.decoder.Decoder.code`. .. NOTE:: @@ -366,7 +367,7 @@ def grs_code(self): def grs_decoder(self): r""" - Returns the decoder used to decode words of :meth:`grs_code`. + Return the decoder used to decode words of :meth:`grs_code`. EXAMPLES:: @@ -379,7 +380,7 @@ def grs_decoder(self): def bch_word_to_grs(self, c): r""" - Returns ``c`` converted as a codeword of :meth:`grs_code`. + Return ``c`` converted as a codeword of :meth:`grs_code`. EXAMPLES:: @@ -397,7 +398,7 @@ def bch_word_to_grs(self, c): def grs_word_to_bch(self, c): r""" - Returns ``c`` converted as a codeword of :meth:`sage.coding.decoder.Decoder.code`. + Return ``c`` converted as a codeword of :meth:`sage.coding.decoder.Decoder.code`. EXAMPLES:: @@ -406,7 +407,8 @@ def grs_word_to_bch(self, c): sage: Cgrs = D.grs_code() sage: Fgrs = Cgrs.base_field() sage: b = Fgrs.gen() - sage: c = vector(Fgrs, [0, b^2 + b, 1, b^2 + b, 0, 1, 1, 1, b^2 + b, 0, 0, b^2 + b + 1, b^2 + b, 0, 1]) + sage: c = vector(Fgrs, [0, b^2 + b, 1, b^2 + b, 0, 1, 1, 1, + ....: b^2 + b, 0, 0, b^2 + b + 1, b^2 + b, 0, 1]) sage: D.grs_word_to_bch(c) (0, a, 1, a, 0, 1, 1, 1, a, 0, 0, a + 1, a, 0, 1) """ @@ -424,7 +426,8 @@ def decode_to_code(self, y): sage: a = F.gen() sage: C = codes.BCHCode(F, 15, 3, jump_size=2) sage: D = codes.decoders.BCHUnderlyingGRSDecoder(C) - sage: y = vector(F, [a, a + 1, 1, a + 1, 1, a, a + 1, a + 1, 0, 1, a + 1, 1, 1, 1, a]) + sage: y = vector(F, [a, a + 1, 1, a + 1, 1, a, a + 1, + ....: a + 1, 0, 1, a + 1, 1, 1, 1, a]) sage: D.decode_to_code(y) (a, a + 1, 1, a + 1, 1, a, a + 1, a + 1, 0, 1, a + 1, 1, 1, 1, a) sage: D.decode_to_code(y) in C @@ -438,12 +441,18 @@ def decode_to_code(self, y): [31, 6] BCH Code over GF(2) with designed distance 15 sage: D = codes.decoders.BCHUnderlyingGRSDecoder(C, "GuruswamiSudan", tau=8) sage: Dgrs = D.grs_decoder() - sage: c = vector(GF(2), [1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0]) - sage: y = vector(GF(2), [1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0]) + sage: c = vector(GF(2), [1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, + ....: 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0]) + sage: y = vector(GF(2), [1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, + ....: 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0]) sage: print (c in C and (c-y).hamming_weight() == 8) True sage: Dgrs.decode_to_code(y) - [(1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0), (1, z5^3 + z5^2 + z5 + 1, z5^4 + z5^2 + z5, z5^4 + z5^3 + z5^2 + 1, 0, 0, z5^4 + z5 + 1, 1, z5^4 + z5^2 + z5, 0, 1, z5^4 + z5, 1, 0, 1, 1, 1, 0, 0, z5^4 + z5^3 + 1, 1, 0, 1, 1, 1, 1, z5^4 + z5^3 + z5 + 1, 1, 1, 0, 0)] + [(1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 0, 1, 0, 0), + (1, z5^3 + z5^2 + z5 + 1, z5^4 + z5^2 + z5, z5^4 + z5^3 + z5^2 + 1, 0, 0, + z5^4 + z5 + 1, 1, z5^4 + z5^2 + z5, 0, 1, z5^4 + z5, 1, 0, 1, 1, 1, 0, + 0, z5^4 + z5^3 + 1, 1, 0, 1, 1, 1, 1, z5^4 + z5^3 + z5 + 1, 1, 1, 0, 0)] sage: D.decode_to_code(y) == [c] True """ @@ -464,7 +473,7 @@ def decode_to_code(self, y): def decoding_radius(self): r""" - Returns maximal number of errors that ``self`` can decode. + Return maximal number of errors that ``self`` can decode. EXAMPLES:: diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index fcd569779f9..ebd262d3ffa 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -1,10 +1,11 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Optimized low-level binary code representation -Some computations with linear binary codes. Fix a basis for `GF(2)^n`. -A linear binary code is a linear subspace of `GF(2)^n`, together with +Some computations with linear binary codes. Fix a basis for `\GF{2}^n`. +A linear binary code is a linear subspace of `\GF{2}^n`, together with this choice of basis. A permutation `g \in S_n` of the fixed basis -gives rise to a permutation of the vectors, or words, in `GF(2)^n`, +gives rise to a permutation of the vectors, or words, in `\GF{2}^n`, sending `(w_i)` to `(w_{g(i)})`. The permutation automorphism group of the code `C` is the set of permutations of the basis that bijectively map `C` to itself. Note that if `g` is such a permutation, then @@ -15,7 +16,7 @@ map `C` to itself. Note that if `g` is such a permutation, then Over other fields, it is also required that the map be linear, which as per above boils down to scalar multiplication. However, over -`GF(2),` the only scalars are 0 and 1, so the linearity condition has +`\GF{2},` the only scalars are 0 and 1, so the linearity condition has trivial effect. AUTHOR: @@ -87,12 +88,12 @@ cdef int *hamming_weights(): def weight_dist(M): """ - Computes the weight distribution of the row space of M. + Computes the weight distribution of the row space of `M`. EXAMPLES:: sage: from sage.coding.binary_code import weight_dist - sage: M = Matrix(GF(2),[ + sage: M = Matrix(GF(2), [ ....: [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0], ....: [0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0], ....: [0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1], @@ -100,14 +101,14 @@ def weight_dist(M): ....: [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1]]) sage: weight_dist(M) [1, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 1] - sage: M = Matrix(GF(2),[ + sage: M = Matrix(GF(2), [ ....: [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0], ....: [0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0], ....: [0,0,0,0,0,1,0,1,0,0,0,1,1,1,1,1,1], ....: [0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,1]]) sage: weight_dist(M) [1, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 0, 0] - sage: M=Matrix(GF(2),[ + sage: M = Matrix(GF(2), [ ....: [1,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,0], ....: [0,1,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0], ....: [0,0,1,0,0,1,1,1,1,0,0,1,0,0,0,0,0], @@ -155,35 +156,37 @@ def weight_dist(M): return L def test_word_perms(t_limit=5.0): - """ - Tests the WordPermutation structs for at least t_limit seconds. + r""" + Test the :class:`WordPermutation` structs for at least ``t_limit`` seconds. These are structures written in pure C for speed, and are tested from this function, which performs the following tests: - 1. Tests create_word_perm, which creates a WordPermutation from a Python - list L representing a permutation i --> L[i]. Takes a random word and - permutes it by a random list permutation, and tests that the result - agrees with doing it the slow way. + 1. Tests :func:`create_word_perm`, which creates a :class:`WordPermutation` + from a Python list `L` representing a permutation `i \mapsto + L[i]`. Takes a random word and permutes it by a random list permutation, + and tests that the result agrees with doing it the slow way. - 1b. Tests create_array_word_perm, which creates a WordPermutation from a - C array. Does the same as above. + 1b. Tests :func:`create_array_word_perm`, which creates a + :class:`WordPermutation` from a C array. Does the same as above. - 2. Tests create_comp_word_perm, which creates a WordPermutation as a - composition of two WordPermutations. Takes a random word and - two random permutations, and tests that the result of permuting by the - composition is correct. + 2. Tests :func:`create_comp_word_perm`, which creates a + :class:`WordPermutation` as a composition of two + :class:`WordPermutation` objects. Takes a random word and two random + permutations, and tests that the result of permuting by the composition + is correct. - 3. Tests create_inv_word_perm and create_id_word_perm, which create a - WordPermutation as the inverse and identity permutations, resp. - Takes a random word and a random permutation, and tests that the result - permuting by the permutation and its inverse in either order, and - permuting by the identity both return the original word. + 3. Tests :func:`create_inv_word_perm` and :func:`create_id_word_perm`, + which create a :class:`WordPermutation` as the inverse and identity + permutations, resp. Takes a random word and a random permutation, and + tests that the result permuting by the permutation and its inverse in + either order, and permuting by the identity both return the original + word. .. NOTE:: - The functions permute_word_by_wp and dealloc_word_perm are implicitly - involved in each of the above tests. + The functions :func:`permute_word_by_wp` and :func:`dealloc_word_perm` + are implicitly involved in each of the above tests. TESTS:: @@ -524,7 +527,7 @@ def test_expand_to_ortho_basis(B=None): INPUT: - - B -- a BinaryCode in standard form + - ``B`` -- a :class:`BinaryCode` in standard form OUTPUT: @@ -536,7 +539,7 @@ def test_expand_to_ortho_basis(B=None): TESTS:: sage: from sage.coding.binary_code import test_expand_to_ortho_basis, BinaryCode - sage: M = Matrix(GF(2), [[1,1,1,1,1,1,0,0,0,0],[0,0,1,1,1,1,1,1,1,1]]) + sage: M = Matrix(GF(2), [[1,1,1,1,1,1,0,0,0,0], [0,0,1,1,1,1,1,1,1,1]]) sage: B = BinaryCode(M) sage: B.put_in_std_form() 0 @@ -865,12 +868,12 @@ cdef class BinaryCode: def matrix(self): """ - Returns the generator matrix of the BinaryCode, i.e. the code is the - rowspace of B.matrix(). + Return the generator matrix of the :class:`BinaryCode`, i.e. the code is + the rowspace of ``B.matrix()``. EXAMPLES:: - sage: M = Matrix(GF(2), [[1,1,1,1,0,0],[0,0,1,1,1,1]]) + sage: M = Matrix(GF(2), [[1,1,1,1,0,0], [0,0,1,1,1,1]]) sage: from sage.coding.binary_code import * sage: B = BinaryCode(M) sage: B.matrix() @@ -1212,7 +1215,7 @@ cdef class BinaryCode: EXAMPLES:: sage: from sage.coding.binary_code import * - sage: M = Matrix(GF(2), [[1,1,1,1,0,0],[0,0,1,1,1,1]]) + sage: M = Matrix(GF(2), [[1,1,1,1,0,0], [0,0,1,1,1,1]]) sage: B = BinaryCode(M); B Binary [6,2] linear code, generator matrix [111100] @@ -2878,7 +2881,8 @@ cdef class PartitionStack: sage: import sage.coding.binary_code sage: from sage.coding.binary_code import * - sage: M = Matrix(GF(2), [[1,1,1,1,0,0,0,0],[0,0,1,1,1,1,0,0],[0,0,0,0,1,1,1,1],[1,0,1,0,1,0,1,0]]) + sage: M = Matrix(GF(2), [[1,1,1,1,0,0,0,0], [0,0,1,1,1,1,0,0], + ....: [0,0,0,0,1,1,1,1], [1,0,1,0,1,0,1,0]]) sage: B = BinaryCode(M) sage: P = PartitionStack(4, 8) sage: P._refine(0, [[0,0],[1,0]], B) @@ -2930,7 +2934,11 @@ cdef class PartitionStack: sage: import sage.coding.binary_code sage: from sage.coding.binary_code import * sage: P = PartitionStack(4, 8) - sage: P._dangerous_dont_use_set_ents_lvls(list(range(8)), list(range(7))+[-1], [4,7,12,11,1,9,3,0,2,5,6,8,10,13,14,15], [0]*16) + sage: P._dangerous_dont_use_set_ents_lvls( + ....: list(range(8)), + ....: list(range(7)) + [-1], + ....: [4,7,12,11,1,9,3,0,2,5,6,8,10,13,14,15], + ....: [0]*16) sage: P ({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15}) ({0},{1,2,3,4,5,6,7}) ({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15}) ({0},{1},{2,3,4,5,6,7}) @@ -3164,12 +3172,12 @@ cdef class BinaryCodeClassifier: def _aut_gp_and_can_label(self, CC, verbosity=0): """ - Compute the automorphism group and canonical label of the code CC. + Compute the automorphism group and canonical label of the code ``CC``. INPUT: - - CC - a BinaryCode object - - verbosity -- a nonnegative integer + - ``CC`` -- a BinaryCode object + - ``verbosity`` -- a nonnegative integer OUTPUT: a tuple, (gens, labeling, size, base) @@ -3896,17 +3904,17 @@ cdef class BinaryCodeClassifier: def generate_children(self, BinaryCode B, int n, int d=2): """ - Use canonical augmentation to generate children of the code B. + Use canonical augmentation to generate children of the code `B`. INPUT: - - B -- a BinaryCode + - ``B`` -- a :class:`BinaryCode` - - n -- limit on the degree of the code + - ``n`` -- limit on the degree of the code - - d -- test whether new vector has weight divisible by d. If d==4, this - ensures that all doubly-even canonically augmented children are - generated. + - ``d`` -- test whether new vector has weight divisible by `d`. If + `d=4`, this ensures that all doubly-even canonically augmented + children are generated. EXAMPLES:: @@ -3931,7 +3939,8 @@ cdef class BinaryCodeClassifier: sage: for n in range(13): ....: s = 'n=%2d : '%n ....: for k in range(1,7): - ....: s += '%3d '%len([C for C in L if C.length() == n and C.dimension() == k]) + ....: s += '%3d '%len([C for C in L + ....: if C.length() == n and C.dimension() == k]) ....: print(s) n= 0 : 0 0 0 0 0 0 n= 1 : 0 0 0 0 0 0 diff --git a/src/sage/coding/bounds_catalog.py b/src/sage/coding/bounds_catalog.py index 25d422afee7..aa4c2dd9996 100644 --- a/src/sage/coding/bounds_catalog.py +++ b/src/sage/coding/bounds_catalog.py @@ -1,15 +1,13 @@ r""" Index of bounds on the parameters of codes -The ``codes.bounds`` object may be used to access the bounds that Sage can compute. +The :obj:`codes.bounds` object may be used to access the bounds that Sage can compute. {INDEX_OF_FUNCTIONS} -.. NOTE:: +To import these names into the global namespace, use:: - To import these names into the global namespace, use: - - sage: from sage.coding.bounds_catalog import * + sage: from sage.coding.bounds_catalog import * """ from sage.misc.lazy_import import lazy_import as _lazy_import _lazy_import("sage.coding.code_bounds", ["codesize_upper_bound", diff --git a/src/sage/coding/channel.py b/src/sage/coding/channel.py index ba59d756d1a..50ea5f5cb1f 100644 --- a/src/sage/coding/channel.py +++ b/src/sage/coding/channel.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Channels @@ -147,9 +148,9 @@ class Channel(SageObject): This abstract class provides the following parameters: - - ``input_space`` -- the space of the words to transmit + - ``input_space`` -- the space of the words to transmit - - ``output_space`` -- the space of the transmitted words + - ``output_space`` -- the space of the transmitted words """ def __init__(self, input_space, output_space): @@ -277,7 +278,7 @@ def transmit_unsafe(self, message): Return ``message``, modified accordingly with the algorithm of the channel it was transmitted through. - This method does not check if ``message`` belongs to the input space of``self``. + This method does not check if ``message`` belongs to the input space of ``self``. This is an abstract method which should be reimplemented in all the subclasses of Channel. @@ -309,7 +310,7 @@ class StaticErrorRateChannel(Channel): EXAMPLES: - We construct a StaticErrorRateChannel which adds 2 errors + We construct a :class:`StaticErrorRateChannel` which adds 2 errors to any transmitted message:: sage: n_err = 2 @@ -367,7 +368,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -383,12 +384,12 @@ def _latex_(self): def transmit_unsafe(self, message): r""" - Returns ``message`` with as many errors as ``self._number_errors`` in it. + Return ``message`` with as many errors as ``self._number_errors`` in it. If ``self._number_errors`` was passed as a tuple for the number of errors, it will pick a random integer between the bounds of the tuple and use it as the number of errors. - This method does not check if ``message`` belongs to the input space of``self``. + This method does not check if ``message`` belongs to the input space of ``self``. INPUT: @@ -429,7 +430,7 @@ def transmit_unsafe(self, message): def number_errors(self): r""" - Returns the number of errors created by ``self``. + Return the number of errors created by ``self``. EXAMPLES:: @@ -445,8 +446,8 @@ class ErrorErasureChannel(Channel): r""" Channel which adds errors and erases several positions in any message it transmits. - The output space of this channel is a Cartesian product - between its input space and a VectorSpace of the same dimension over GF(2) + The output space of this channel is a Cartesian product between its input + space and a VectorSpace of the same dimension over `\GF{2}`. INPUT: @@ -522,7 +523,7 @@ def __init__(self, space, number_errors, number_erasures): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -541,7 +542,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -560,8 +561,8 @@ def _latex_(self): def transmit_unsafe(self, message): r""" - Returns ``message`` with as many errors as ``self._number_errors`` in it, and as many erasures - as ``self._number_erasures`` in it. + Return ``message`` with as many errors as ``self._number_errors`` in it, + and as many erasures as ``self._number_erasures`` in it. If ``self._number_errors`` was passed as an tuple for the number of errors, it will pick a random integer between the bounds of the tuple and use it as the number of errors. @@ -572,7 +573,7 @@ def transmit_unsafe(self, message): the received message will always contains exactly as many errors and erasures as expected. - This method does not check if ``message`` belongs to the input space of``self``. + This method does not check if ``message`` belongs to the input space of ``self``. INPUT: @@ -582,9 +583,10 @@ def transmit_unsafe(self, message): - a couple of vectors, namely: - - the transmitted message, which is ``message`` with erroneous and erased positions - - the erasure vector, which contains ``1`` at the erased positions of the transmitted message - , 0 elsewhere. + - the transmitted message, which is ``message`` with erroneous and + erased positions + - the erasure vector, which contains ``1`` at the erased positions of + the transmitted message and ``0`` elsewhere. EXAMPLES:: @@ -617,7 +619,7 @@ def transmit_unsafe(self, message): def number_errors(self): r""" - Returns the number of errors created by ``self``. + Return the number of errors created by ``self``. EXAMPLES:: @@ -630,7 +632,7 @@ def number_errors(self): def number_erasures(self): r""" - Returns the number of erasures created by ``self``. + Return the number of erasures created by ``self``. EXAMPLES:: @@ -644,10 +646,10 @@ def number_erasures(self): class QarySymmetricChannel(Channel): r""" - The q-ary symmetric, memoryless communication channel. + The `q`-ary symmetric, memoryless communication channel. Given an alphabet `\Sigma` with `|\Sigma| = q` and an error probability - `\epsilon`, a q-ary symmetric channel sends an element of `\Sigma` into the + `\epsilon`, a `q`-ary symmetric channel sends an element of `\Sigma` into the same element with probability `1 - \epsilon`, and any one of the other `q - 1` elements with probability `\frac{\epsilon}{q - 1}`. This implementation operates over vectors in `\Sigma^n`, and "transmits" each element of the @@ -665,20 +667,21 @@ class QarySymmetricChannel(Channel): INPUT: - ``space`` -- the input and output space of the channel. It has to be - `GF(q)^n` for some finite field `GF(q)`. + `\GF{q}^n` for some finite field `\GF{q}`. - ``epsilon`` -- the transmission error probability of the individual elements. EXAMPLES: - We construct a QarySymmetricChannel which corrupts 30% of all transmitted - symbols:: + We construct a :class:`QarySymmetricChannel` which corrupts 30% of all + transmitted symbols:: sage: epsilon = 0.3 sage: Chan = channels.QarySymmetricChannel(GF(59)^50, epsilon) sage: Chan q-ary symmetric channel with error probability 0.300000000000000, - of input and output space Vector space of dimension 50 over Finite Field of size 59 + of input and output space + Vector space of dimension 50 over Finite Field of size 59 """ def __init__(self, space, epsilon): @@ -713,7 +716,7 @@ def __init__(self, space, epsilon): def __repr__(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -728,7 +731,7 @@ def __repr__(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -743,10 +746,10 @@ def _latex_(self): def transmit_unsafe(self, message): r""" - Returns ``message`` where each of the symbols has been changed to another from the alphabet with + Return ``message`` where each of the symbols has been changed to another from the alphabet with probability :meth:`error_probability`. - This method does not check if ``message`` belongs to the input space of``self``. + This method does not check if ``message`` belongs to the input space of ``self``. INPUT: @@ -776,7 +779,7 @@ def transmit_unsafe(self, message): def error_probability(self): r""" - Returns the error probability of a single symbol transmission of + Return the error probability of a single symbol transmission of ``self``. EXAMPLES:: @@ -790,7 +793,7 @@ def error_probability(self): def probability_of_exactly_t_errors(self, t): r""" - Returns the probability ``self`` has to return + Return the probability ``self`` has to return exactly ``t`` errors. INPUT: @@ -810,7 +813,7 @@ def probability_of_exactly_t_errors(self, t): def probability_of_at_most_t_errors(self, t): r""" - Returns the probability ``self`` has to return + Return the probability ``self`` has to return at most ``t`` errors. INPUT: diff --git a/src/sage/coding/channels_catalog.py b/src/sage/coding/channels_catalog.py index ed3aa0ce6c2..b121fe847d8 100644 --- a/src/sage/coding/channels_catalog.py +++ b/src/sage/coding/channels_catalog.py @@ -9,11 +9,9 @@ - :class:`channel.QarySymmetricChannel ` - :class:`channel.StaticErrorRateChannel ` -.. NOTE:: +To import these names into the global namespace, use:: - To import these names into the global namespace, use: - - sage: from sage.coding.channels_catalog import * + sage: from sage.coding.channels_catalog import * """ #***************************************************************************** diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index 8e1ce61cedb..9b82bb74b50 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -94,11 +94,11 @@ Sage, you can determine the best known estimates for this number in 2 ways: -1. Indirectly, using best_known_linear_code_www(n, k, F), - which connects to the website http://www.codetables.de by Markus Grassl; +1. Indirectly, using ``best_known_linear_code_www(n, k, F)``, + which connects to the website http://www.codetables.de by Markus Grassl; -2. codesize_upper_bound(n,d,q), dimension_upper_bound(n,d,q), - and best_known_linear_code(n, k, F). +2. ``codesize_upper_bound(n,d,q)``, ``dimension_upper_bound(n,d,q)``, + and ``best_known_linear_code(n, k, F)``. The output of :func:`best_known_linear_code`, :func:`best_known_linear_code_www`, or :func:`dimension_upper_bound` would @@ -108,52 +108,52 @@ This module implements: -- codesize_upper_bound(n,d,q), for the best known (as of May, - 2006) upper bound A(n,d) for the size of a code of length n, - minimum distance d over a field of size q. +- ``codesize_upper_bound(n,d,q)``, for the best known (as of May, + 2006) upper bound `A(n,d)` for the size of a code of length `n`, + minimum distance `d` over a field of size `q`. -- dimension_upper_bound(n,d,q), an upper bound +- ``dimension_upper_bound(n,d,q)``, an upper bound `B(n,d)=B_q(n,d)` for the dimension of a linear code of - length n, minimum distance d over a field of size q. + length `n`, minimum distance `d` over a field of size `q`. -- gilbert_lower_bound(n,q,d), a lower bound for number of - elements in the largest code of min distance d in +- ``gilbert_lower_bound(n,q,d)``, a lower bound for number of + elements in the largest code of min distance `d` in `\GF{q}^n`. -- gv_info_rate(n,delta,q), `log_q(GLB)/n`, where GLB is - the Gilbert lower bound and delta = d/n. +- ``gv_info_rate(n,delta,q)``, `log_q(GLB)/n`, where GLB is + the Gilbert lower bound and `\delta = d/n`. -- gv_bound_asymp(delta,q), asymptotic analog of Gilbert lower +- ``gv_bound_asymp(delta,q)``, asymptotic analog of Gilbert lower bound. -- plotkin_upper_bound(n,q,d) +- ``plotkin_upper_bound(n,q,d)`` -- plotkin_bound_asymp(delta,q), asymptotic analog of Plotkin +- ``plotkin_bound_asymp(delta,q)``, asymptotic analog of Plotkin bound. -- griesmer_upper_bound(n,q,d) +- ``griesmer_upper_bound(n,q,d)`` -- elias_upper_bound(n,q,d) +- ``elias_upper_bound(n,q,d)`` -- elias_bound_asymp(delta,q), asymptotic analog of Elias bound. +- ``elias_bound_asymp(delta,q)``, asymptotic analog of Elias bound. -- hamming_upper_bound(n,q,d) +- ``hamming_upper_bound(n,q,d)`` -- hamming_bound_asymp(delta,q), asymptotic analog of Hamming +- ``hamming_bound_asymp(delta,q)``, asymptotic analog of Hamming bound. -- singleton_upper_bound(n,q,d) +- ``singleton_upper_bound(n,q,d)`` -- singleton_bound_asymp(delta,q), asymptotic analog of Singleton +- ``singleton_bound_asymp(delta,q)``, asymptotic analog of Singleton bound. -- mrrw1_bound_asymp(delta,q), "first" asymptotic +- ``mrrw1_bound_asymp(delta,q)``, "first" asymptotic McEliese-Rumsey-Rodemich-Welsh bound for the information rate. - Delsarte (a.k.a. Linear Programming (LP)) upper bounds. -PROBLEM: In this module we shall typically either (a) seek bounds -on k, given n, d, q, (b) seek bounds on R, delta, q (assuming n is +PROBLEM: In this module we shall typically either (a) seek bounds on `k`, given +`n`, `d`, `q`, (b) seek bounds on `R`, `\delta`, `q` (assuming `n` is "infinity"). .. TODO:: @@ -174,16 +174,17 @@ # **************************************************************************** from sage.arith.misc import binomial, is_prime_power -from sage.libs.gap.libgap import libgap +from sage.features.gap import GapPackage from sage.misc.functional import sqrt, log +from sage.misc.lazy_import import lazy_import from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.real_double import RDF -from sage.rings.real_mpfr import RR from .delsarte_bounds import (delsarte_bound_hamming_space, delsarte_bound_additive_hamming_space) -from sage.features.gap import GapPackage + +lazy_import('sage.libs.gap.libgap', 'libgap') def _check_n_q_d(n, q, d, field_based=True): @@ -233,19 +234,19 @@ def codesize_upper_bound(n, d, q, algorithm=None): This function computes the minimum value of the upper bounds of Singleton, Hamming, Plotkin, and Elias. - If algorithm="gap" then this returns the best known upper - bound `A(n,d)=A_q(n,d)` for the size of a code of length n, - minimum distance d over a field of size q. The function first - checks for trivial cases (like d=1 or n=d), and if the value + If ``algorithm="gap"``, then this returns the best known upper + bound `A(n,d)=A_q(n,d)` for the size of a code of length `n`, + minimum distance `d` over a field of size `q`. The function first + checks for trivial cases (like `d=1` or `n=d`), and if the value is in the built-in table. Then it calculates the minimum value of the upper bound using the algorithms of Singleton, Hamming, Johnson, Plotkin and Elias. If the code is binary, `A(n, 2\ell-1) = A(n+1,2\ell)`, so the function takes the minimum of the values obtained from all algorithms for the parameters `(n, 2\ell-1)` and `(n+1, 2\ell)`. This - wraps GUAVA's (i.e. GAP's package Guava) UpperBound( n, d, q ). + wraps GUAVA's (i.e. GAP's package Guava) ``UpperBound(n, d, q)``. - If algorithm="LP" then this returns the Delsarte (a.k.a. Linear + If ``algorithm="LP"``, then this returns the Delsarte (a.k.a. Linear Programming) upper bound. EXAMPLES:: @@ -299,10 +300,11 @@ def dimension_upper_bound(n, d, q, algorithm=None): Return an upper bound for the dimension of a linear code. Return an upper bound `B(n,d) = B_q(n,d)` for the - dimension of a linear code of length n, minimum distance d over a - field of size q. + dimension of a linear code of length `n`, minimum distance `d` over a + field of size `q`. - Parameter "algorithm" has the same meaning as in :func:`codesize_upper_bound` + Parameter ``algorithm`` has the same meaning as in + :func:`codesize_upper_bound` EXAMPLES:: @@ -395,6 +397,7 @@ def plotkin_upper_bound(n,q,d, algorithm=None): return int(d/( d - t*n)) elif d < t*n + 1: fact = (d-1) / t + from sage.rings.real_mpfr import RR if RR(fact)==RR(int(fact)): fact = int(fact) + 1 return int(d/( d - t * fact)) * q**(n - fact) @@ -462,7 +465,7 @@ def elias_upper_bound(n,q,d,algorithm=None): Return the Elias upper bound for number of elements in the largest code of minimum distance `d` in `\GF{q}^n`, cf. [HP2003]_. - If the method is "gap", it wraps GAP's ``UpperBoundElias``. + If ``algorithm="gap"``, it wraps GAP's ``UpperBoundElias``. EXAMPLES:: @@ -497,8 +500,8 @@ def hamming_upper_bound(n,q,d): Return the Hamming upper bound. Return the Hamming upper bound for number of elements in the - largest code of length n and minimum distance d over alphabet - of size q. + largest code of length `n` and minimum distance `d` over alphabet + of size `q`. The Hamming bound (also known as the sphere packing bound) returns an upper bound on the size of a code of length `n`, minimum distance @@ -516,7 +519,7 @@ def hamming_upper_bound(n,q,d): where `M` is the maximum number of codewords and `V(n,e)` is - equal to the contents of a ball of radius e. This bound is useful + equal to the contents of a ball of radius `e`. This bound is useful for small values of `d`. Codes for which equality holds are called perfect. See e.g. [HP2003]_. @@ -534,7 +537,7 @@ def singleton_upper_bound(n, q, d): Return the Singleton upper bound. Return the Singleton upper bound for number of elements in a - largest code of minimum distance d in `\GF{q}^n`. + largest code of minimum distance `d` in `\GF{q}^n`. This bound is based on the shortening of codes. By shortening an `(n, M, d)` code `d-1` times, an `(n-d+1,M,1)` code @@ -580,9 +583,9 @@ def entropy(x, q=2): INPUT: - - ``x`` - real number in the interval `[0, 1]`. + - ``x`` -- real number in the interval `[0, 1]`. - - ``q`` - (default: 2) integer greater than 1. This is the base of the + - ``q`` -- (default: 2) integer greater than 1. This is the base of the logarithm. EXAMPLES:: @@ -621,7 +624,7 @@ def entropy(x, q=2): def entropy_inverse(x, q=2): """ - Find the inverse of the ``q``-ary entropy function at the point ``x``. + Find the inverse of the `q`-ary entropy function at the point ``x``. INPUT: diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index 812d5d88df9..f22ec507161 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Linear code constructors that do not preserve the structural information @@ -216,38 +217,40 @@ def _lift2smallest_field(a): def permutation_action(g, v): r""" - Returns permutation of rows g\*v. Works on lists, matrices, + Returns permutation of rows `g * v`. + + Works on lists, matrices, sequences and vectors (by permuting coordinates). The code requires - switching from i to i+1 (and back again) since the SymmetricGroup - is, by convention, the symmetric group on the "letters" 1, 2, ..., - n (not 0, 1, ..., n-1). + switching from `i` to `i+1` (and back again) since the :class:`SymmetricGroup` + is, by convention, the symmetric group on the "letters" `1`, `2`, ..., + `n` (not `0`, `1`, ..., `n-1`). EXAMPLES:: sage: V = VectorSpace(GF(3),5) sage: v = V([0,1,2,0,1]) - sage: G = SymmetricGroup(5) - sage: g = G([(1,2,3)]) - sage: permutation_action(g,v) + sage: G = SymmetricGroup(5) # optional - sage.groups + sage: g = G([(1,2,3)]) # optional - sage.groups + sage: permutation_action(g,v) # optional - sage.groups (1, 2, 0, 0, 1) - sage: g = G([()]) - sage: permutation_action(g,v) + sage: g = G([()]) # optional - sage.groups + sage: permutation_action(g,v) # optional - sage.groups (0, 1, 2, 0, 1) - sage: g = G([(1,2,3,4,5)]) - sage: permutation_action(g,v) + sage: g = G([(1,2,3,4,5)]) # optional - sage.groups + sage: permutation_action(g,v) # optional - sage.groups (1, 2, 0, 1, 0) sage: L = Sequence([1,2,3,4,5]) - sage: permutation_action(g,L) + sage: permutation_action(g,L) # optional - sage.groups [2, 3, 4, 5, 1] sage: MS = MatrixSpace(GF(3),3,7) sage: A = MS([[1,0,0,0,1,1,0],[0,1,0,1,0,1,0],[0,0,0,0,0,0,1]]) - sage: S5 = SymmetricGroup(5) - sage: g = S5([(1,2,3)]) + sage: S5 = SymmetricGroup(5) # optional - sage.groups + sage: g = S5([(1,2,3)]) # optional - sage.groups sage: A [1 0 0 0 1 1 0] [0 1 0 1 0 1 0] [0 0 0 0 0 0 1] - sage: permutation_action(g,A) + sage: permutation_action(g,A) # optional - sage.groups [0 1 0 1 0 1 0] [0 0 0 0 0 0 1] [1 0 0 0 1 1 0] @@ -255,16 +258,16 @@ def permutation_action(g, v): It also works on lists and is a "left action":: sage: v = [0,1,2,0,1] - sage: G = SymmetricGroup(5) - sage: g = G([(1,2,3)]) - sage: gv = permutation_action(g,v); gv + sage: G = SymmetricGroup(5) # optional - sage.groups + sage: g = G([(1,2,3)]) # optional - sage.groups + sage: gv = permutation_action(g,v); gv # optional - sage.groups [1, 2, 0, 0, 1] - sage: permutation_action(g,v) == g(v) + sage: permutation_action(g,v) == g(v) # optional - sage.groups True - sage: h = G([(3,4)]) - sage: gv = permutation_action(g,v) - sage: hgv = permutation_action(h,gv) - sage: hgv == permutation_action(h*g,v) + sage: h = G([(3,4)]) # optional - sage.groups + sage: gv = permutation_action(g,v) # optional - sage.groups + sage: hgv = permutation_action(h,gv) # optional - sage.groups + sage: hgv == permutation_action(h*g,v) # optional - sage.groups True AUTHORS: @@ -436,28 +439,28 @@ def ExtendedQuadraticResidueCode(n,F): INPUT: - - ``n`` - an odd prime + - ``n`` -- an odd prime - - ``F`` - a finite prime field F whose order must be a - quadratic residue modulo n. + - ``F`` -- a finite prime field whose order must be a + quadratic residue modulo `n`. OUTPUT: Returns an extended quadratic residue code. EXAMPLES:: - sage: C1 = codes.QuadraticResidueCode(7,GF(2)) + sage: C1 = codes.QuadraticResidueCode(7, GF(2)) sage: C2 = C1.extended_code() - sage: C3 = codes.ExtendedQuadraticResidueCode(7,GF(2)); C3 + sage: C3 = codes.ExtendedQuadraticResidueCode(7, GF(2)); C3 Extension of [7, 4] Cyclic Code over GF(2) sage: C2 == C3 True - sage: C = codes.ExtendedQuadraticResidueCode(17,GF(2)) + sage: C = codes.ExtendedQuadraticResidueCode(17, GF(2)) sage: C Extension of [17, 9] Cyclic Code over GF(2) - sage: C3 = codes.QuadraticResidueCodeOddPair(7,GF(2))[0] + sage: C3 = codes.QuadraticResidueCodeOddPair(7, GF(2))[0] sage: C3x = C3.extended_code() - sage: C4 = codes.ExtendedQuadraticResidueCode(7,GF(2)) + sage: C4 = codes.ExtendedQuadraticResidueCode(7, GF(2)) sage: C3x == C4 True @@ -496,37 +499,37 @@ def QuadraticResidueCode(n,F): A quadratic residue code (or QR code) is a cyclic code whose generator polynomial is the product of the polynomials `x-\alpha^i` (`\alpha` is a primitive - `n^{th}` root of unity; `i` ranges over the set of + `n`'th root of unity; `i` ranges over the set of quadratic residues modulo `n`). - See QuadraticResidueCodeEvenPair and QuadraticResidueCodeOddPair - for a more general construction. + See :class:`QuadraticResidueCodeEvenPair` and + :class:`QuadraticResidueCodeOddPair` for a more general construction. INPUT: - - ``n`` - an odd prime + - ``n`` -- an odd prime - - ``F`` - a finite prime field F whose order must be a - quadratic residue modulo n. + - ``F`` -- a finite prime field whose order must be a + quadratic residue modulo `n`. OUTPUT: Returns a quadratic residue code. EXAMPLES:: - sage: C = codes.QuadraticResidueCode(7,GF(2)) + sage: C = codes.QuadraticResidueCode(7, GF(2)) sage: C [7, 4] Cyclic Code over GF(2) - sage: C = codes.QuadraticResidueCode(17,GF(2)) + sage: C = codes.QuadraticResidueCode(17, GF(2)) sage: C [17, 9] Cyclic Code over GF(2) - sage: C1 = codes.QuadraticResidueCodeOddPair(7,GF(2))[0] - sage: C2 = codes.QuadraticResidueCode(7,GF(2)) + sage: C1 = codes.QuadraticResidueCodeOddPair(7, GF(2))[0] + sage: C2 = codes.QuadraticResidueCode(7, GF(2)) sage: C1 == C2 True - sage: C1 = codes.QuadraticResidueCodeOddPair(17,GF(2))[0] - sage: C2 = codes.QuadraticResidueCode(17,GF(2)) + sage: C1 = codes.QuadraticResidueCodeOddPair(17, GF(2))[0] + sage: C2 = codes.QuadraticResidueCode(17, GF(2)) sage: C1 == C2 True @@ -537,16 +540,16 @@ def QuadraticResidueCode(n,F): return QuadraticResidueCodeOddPair(n,F)[0] def QuadraticResidueCodeEvenPair(n,F): - """ + r""" Quadratic residue codes of a given odd prime length and base ring either don't exist at all or occur as 4-tuples - a pair of "odd-like" codes and a pair of "even-like" codes. If `n > 2` is prime - then (Theorem 6.6.2 in [HP2003]_) a QR code exists over `GF(q)` iff q is a + then (Theorem 6.6.2 in [HP2003]_) a QR code exists over `\GF{q}` iff q is a quadratic residue mod `n`. They are constructed as "even-like" duadic codes associated the - splitting (Q,N) mod n, where Q is the set of non-zero quadratic - residues and N is the non-residues. + splitting `(Q,N)` mod `n`, where `Q` is the set of non-zero quadratic + residues and `N` is the non-residues. EXAMPLES:: @@ -556,16 +559,16 @@ def QuadraticResidueCodeEvenPair(n,F): sage: codes.QuadraticResidueCodeEvenPair(17, GF(2)) ([17, 8] Cyclic Code over GF(2), [17, 8] Cyclic Code over GF(2)) - sage: codes.QuadraticResidueCodeEvenPair(13,GF(9,"z")) # known bug (#25896) + sage: codes.QuadraticResidueCodeEvenPair(13, GF(9,"z")) # known bug (#25896) ([13, 6] Cyclic Code over GF(9), [13, 6] Cyclic Code over GF(9)) - sage: C1,C2 = codes.QuadraticResidueCodeEvenPair(7,GF(2)) + sage: C1,C2 = codes.QuadraticResidueCodeEvenPair(7, GF(2)) sage: C1.is_self_orthogonal() True sage: C2.is_self_orthogonal() True - sage: C3 = codes.QuadraticResidueCodeOddPair(17,GF(2))[0] - sage: C4 = codes.QuadraticResidueCodeEvenPair(17,GF(2))[1] + sage: C3 = codes.QuadraticResidueCodeOddPair(17, GF(2))[0] + sage: C4 = codes.QuadraticResidueCodeEvenPair(17, GF(2))[1] sage: C3.systematic_generator_matrix() == C4.dual_code().systematic_generator_matrix() True @@ -577,11 +580,11 @@ def QuadraticResidueCodeEvenPair(n,F): Traceback (most recent call last): ... ValueError: the argument F must be a finite field - sage: codes.QuadraticResidueCodeEvenPair(14,GF(2)) + sage: codes.QuadraticResidueCodeEvenPair(14, GF(2)) Traceback (most recent call last): ... ValueError: the argument n must be an odd prime - sage: codes.QuadraticResidueCodeEvenPair(5,GF(2)) + sage: codes.QuadraticResidueCodeEvenPair(5, GF(2)) Traceback (most recent call last): ... ValueError: the order of the finite field must be a quadratic residue modulo n @@ -603,16 +606,16 @@ def QuadraticResidueCodeEvenPair(n,F): def QuadraticResidueCodeOddPair(n,F): - """ + r""" Quadratic residue codes of a given odd prime length and base ring either don't exist at all or occur as 4-tuples - a pair of "odd-like" codes and a pair of "even-like" codes. If n 2 is prime - then (Theorem 6.6.2 in [HP2003]_) a QR code exists over GF(q) iff q is a - quadratic residue mod n. + then (Theorem 6.6.2 in [HP2003]_) a QR code exists over `\GF{q} iff `q` is a + quadratic residue mod `n`. They are constructed as "odd-like" duadic codes associated the - splitting (Q,N) mod n, where Q is the set of non-zero quadratic - residues and N is the non-residues. + splitting `(Q,N)` mod `n`, where `Q` is the set of non-zero quadratic + residues and `N` is the non-residues. EXAMPLES:: @@ -641,7 +644,7 @@ def QuadraticResidueCodeOddPair(n,F): TESTS:: - sage: codes.QuadraticResidueCodeOddPair(9,GF(2)) + sage: codes.QuadraticResidueCodeOddPair(9, GF(2)) Traceback (most recent call last): ... ValueError: the argument n must be an odd prime @@ -699,23 +702,23 @@ def ToricCode(P,F): .. MATH:: - \mathrm{eval_T} : V \rightarrow F^n, + \operatorname{eval}_T : V \rightarrow F^n, where `x^e` is the multi-index notation (`x=(x_1,...,x_d)`, `e=(e_1,...,e_d)`, and `x^e = x_1^{e_1}...x_d^{e_d}`), where - `eval_T (f(x)) = (f(t_1),...,f(t_n))`, and where + `\operatorname{eval}_T (f(x)) = (f(t_1),...,f(t_n))`, and where `T=\{t_1,...,t_n\}`. This function returns the toric codes discussed in [Joy2004]_. INPUT: - - ``P`` - all the integer lattice points in a polytope + - ``P`` -- all the integer lattice points in a polytope defining the toric variety. - - ``F`` - a finite field. + - ``F`` -- a finite field. OUTPUT: Returns toric code with length n = , dimension k over field @@ -723,7 +726,7 @@ def ToricCode(P,F): EXAMPLES:: - sage: C = codes.ToricCode([[0,0],[1,0],[2,0],[0,1],[1,1]],GF(7)) + sage: C = codes.ToricCode([[0,0],[1,0],[2,0],[0,1],[1,1]], GF(7)) sage: C [36, 5] linear code over GF(7) sage: C.minimum_distance() @@ -731,18 +734,20 @@ def ToricCode(P,F): sage: C.minimum_distance(algorithm="guava") # optional - gap_packages (Guava package) ... 24 - sage: C = codes.ToricCode([[-2,-2],[-1,-2],[-1,-1],[-1,0],[0,-1],[0,0],[0,1],[1,-1],[1,0]],GF(5)) + sage: C = codes.ToricCode([[-2,-2],[-1,-2],[-1,-1],[-1,0], + ....: [0,-1],[0,0],[0,1],[1,-1],[1,0]], GF(5)) sage: C [16, 9] linear code over GF(5) sage: C.minimum_distance() 6 sage: C.minimum_distance(algorithm="guava") # optional - gap_packages (Guava package) 6 - sage: C = codes.ToricCode([ [0,0],[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[3,1],[3,2],[4,1]],GF(8,"a")) + sage: C = codes.ToricCode([[0,0],[1,1],[1,2],[1,3],[1,4],[2,1], + ....: [2,2],[2,3],[3,1],[3,2],[4,1]], GF(8,"a")) sage: C [49, 11] linear code over GF(8) - This is in fact a [49,11,28] code over GF(8). If you type next + This is in fact a [49,11,28] code over `\GF{8}`. If you type next ``C.minimum_distance()`` and wait overnight (!), you should get 28. @@ -784,7 +789,7 @@ def WalshCode(m): [1, 0, 0, 0, 7, 0, 0, 0, 0] sage: C.minimum_distance() 4 - sage: C.minimum_distance(algorithm='gap') # check d=2^(m-1) + sage: C.minimum_distance(algorithm='gap') # check d=2^(m-1) 4 REFERENCES: diff --git a/src/sage/coding/codecan/autgroup_can_label.pyx b/src/sage/coding/codecan/autgroup_can_label.pyx index c83b9264e44..c3a11c07e81 100644 --- a/src/sage/coding/codecan/autgroup_can_label.pyx +++ b/src/sage/coding/codecan/autgroup_can_label.pyx @@ -137,21 +137,21 @@ class LinearCodeAutGroupCanLabel: There are several notions of equivalence for linear codes: Let `C`, `D` be linear codes of length `n` and dimension `k`. - `C` and `D` are said to be + The codes `C` and `D` are said to be - - permutational equivalent, if there is some permutation `\pi \in S_n` - such that `(c_{\pi(0)}, \ldots, c_{\pi(n-1)}) \in D` for all `c \in C`. + - permutational equivalent, if there is some permutation `\pi \in S_n` + such that `(c_{\pi(0)}, \ldots, c_{\pi(n-1)}) \in D` for all `c \in C`. - - linear equivalent, if there is some permutation `\pi \in S_n` and a - vector `\phi \in {\GF{q}^*}^n` of units of length `n` such that - `(c_{\pi(0)} \phi_0^{-1}, \ldots, c_{\pi(n-1)} \phi_{n-1}^{-1}) \in D` - for all `c \in C`. + - linear equivalent, if there is some permutation `\pi \in S_n` and a + vector `\phi \in {\GF{q}^*}^n` of units of length `n` such that + `(c_{\pi(0)} \phi_0^{-1}, \ldots, c_{\pi(n-1)} \phi_{n-1}^{-1}) \in D` + for all `c \in C`. - - semilinear equivalent, if there is some permutation `\pi \in S_n`, a - vector `\phi` of units of length `n` and a field automorphism `\alpha` - such that - `(\alpha(c_{\pi(0)}) \phi_0^{-1}, \ldots, \alpha( c_{\pi(n-1)}) \phi_{n-1}^{-1} ) \in D` - for all `c \in C`. + - semilinear equivalent, if there is some permutation `\pi \in S_n`, a + vector `\phi` of units of length `n` and a field automorphism `\alpha` + such that + `(\alpha(c_{\pi(0)}) \phi_0^{-1}, \ldots, \alpha( c_{\pi(n-1)}) \phi_{n-1}^{-1} ) \in D` + for all `c \in C`. These are group actions. This class provides an algorithm that will compute a unique representative `D` in the orbit of the given linear code `C`. diff --git a/src/sage/coding/codecan/codecan.pyx b/src/sage/coding/codecan/codecan.pyx index 90f1fc76194..b0709155b57 100644 --- a/src/sage/coding/codecan/codecan.pyx +++ b/src/sage/coding/codecan/codecan.pyx @@ -110,10 +110,10 @@ cdef class InnerGroup: Those stabilizers can be stored as triples: - - ``rank`` - an integer in `\{0, \ldots, k\}` - - ``row_partition`` - a partition of `\{0, \ldots, k-1\}` with - discrete cells for all integers `i \geq rank`. - - ``frob_pow`` an integer in `\{0, \ldots, r-1\}` if `q = p^r` + - ``rank`` -- an integer in `\{0, \ldots, k\}` + - ``row_partition`` -- a partition of `\{0, \ldots, k-1\}` with + discrete cells for all integers `i` `\geq` ``rank``. + - ``frob_pow`` -- an integer `s` in `\{0, \ldots, r-1\}` if `q = p^r` The group `G_{\Pi^{(I)}(x)}` contains all elements `(A, \varphi, \alpha) \in G`, where @@ -126,8 +126,8 @@ cdef class InnerGroup: - The support of the columns given by `i \in I` intersect exactly one cell of the partition. The entry `\varphi_i` is equal to the entries of the corresponding diagonal entry of `A`. - - `\alpha` is a power of `\tau^{frob_pow}`, where `\tau` denotes the - Frobenius automorphism of the finite field `\GF{q}`. + - `\alpha` is a power of `\tau^s`, where `\tau` denotes the + Frobenius automorphism of the finite field `\GF{q}` and `s` = ``frob_pow``. See [Feu2009]_ for more details. """ @@ -143,8 +143,8 @@ cdef class InnerGroup: * "semilinear" -- full group * "linear" -- no field automorphisms, i.e. `G = (GL(k,q) \times \GF{q}^n )` * "permutational -- no field automorphisms and no column multiplications - i.e. `G = GL(k,q)` + - ``transporter`` (optional) -- set to an element of the group :class:`sage.groups.semimonomial_transformations.semimonomial_transformation_group.SemimonomialTransformationGroup` if you would like to modify this element simultaneously diff --git a/src/sage/coding/codes_catalog.py b/src/sage/coding/codes_catalog.py index 9535d364ce7..96021d5fdd3 100644 --- a/src/sage/coding/codes_catalog.py +++ b/src/sage/coding/codes_catalog.py @@ -57,11 +57,9 @@ :meth:`~sage.coding.extended_code.ExtendedCode` @ Extended codes :meth:`~sage.coding.punctured_code.PuncturedCode` @ Puncturedcodes -.. NOTE:: +To import these names into the global namespace, use:: - To import these names into the global namespace, use: - - sage: from sage.coding.codes_catalog import * + sage: from sage.coding.codes_catalog import * """ #***************************************************************************** diff --git a/src/sage/coding/cyclic_code.py b/src/sage/coding/cyclic_code.py index 77b72d4ba95..342b40d45c9 100644 --- a/src/sage/coding/cyclic_code.py +++ b/src/sage/coding/cyclic_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Cyclic code @@ -50,7 +51,7 @@ def find_generator_polynomial(code, check=True): r""" - Returns a possible generator polynomial for ``code``. + Return a possible generator polynomial for ``code``. If the code is cyclic, the generator polynomial is the gcd of all the polynomial forms of the codewords. Conversely, if this gcd exactly @@ -95,7 +96,7 @@ def find_generator_polynomial(code, check=True): def _to_complete_list(poly, length): r""" - Returns the vector of length exactly ``length`` corresponding to the + Return the vector of length exactly ``length`` corresponding to the coefficients of the provided polynomial. If needed, zeros are added. INPUT: @@ -122,7 +123,7 @@ def _to_complete_list(poly, length): def bch_bound(n, D, arithmetic=False): r""" - Returns the BCH bound obtained for a cyclic code of length ``n`` and + Return the BCH bound obtained for a cyclic code of length ``n`` and defining set ``D``. Consider a cyclic code `C`, with defining set `D`, length `n`, and minimum @@ -212,7 +213,7 @@ class CyclicCode(AbstractLinearCode): r""" Representation of a cyclic code. - We propose three different ways to create a new CyclicCode, either by + We propose three different ways to create a new :class:`CyclicCode`, either by providing: - the generator polynomial and the length (1) @@ -224,7 +225,7 @@ class CyclicCode(AbstractLinearCode): cyclic codes such that its length `n` and field order `q` are coprimes. Depending on which behaviour you want, you need to specify the names of the - arguments to CyclicCode. See EXAMPLES section below for details. + arguments to :class:`CyclicCode`. See EXAMPLES section below for details. INPUT: @@ -256,13 +257,13 @@ class CyclicCode(AbstractLinearCode): EXAMPLES: - We can construct a CyclicCode object using three different methods. + We can construct a :class:`CyclicCode` object using three different methods. First (1), we provide a generator polynomial and a code length:: sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: C [7, 4] Cyclic Code over GF(2) @@ -280,7 +281,7 @@ class CyclicCode(AbstractLinearCode): sage: F = GF(16, 'a') sage: n = 15 - sage: Cc = codes.CyclicCode(length = n, field = F, D = [1,2]) + sage: Cc = codes.CyclicCode(length=n, field=F, D = [1,2]) sage: Cc [15, 13] Cyclic Code over GF(16) """ @@ -299,7 +300,7 @@ def __init__(self, generator_pol=None, length=None, code=None, check=True, sage: F. = GF(2)[] sage: n = 2 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) Traceback (most recent call last): ... ValueError: Only cyclic codes whose length and field order are coprimes are implemented. @@ -465,7 +466,7 @@ def __init__(self, generator_pol=None, length=None, code=None, check=True, def __contains__(self, word): r""" - Returns ``True`` if ``word`` belongs to ``self``, ``False`` otherwise. + Return ``True`` if ``word`` belongs to ``self``, ``False`` otherwise. INPUT: @@ -513,7 +514,7 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -530,7 +531,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -547,7 +548,7 @@ def _latex_(self): def generator_polynomial(self): r""" - Returns the generator polynomial of ``self``. + Return the generator polynomial of ``self``. EXAMPLES:: @@ -562,7 +563,7 @@ def generator_polynomial(self): def field_embedding(self): r""" - Returns the base field embedding into the splitting field. + Return the base field embedding into the splitting field. EXAMPLES:: @@ -582,7 +583,7 @@ def field_embedding(self): def defining_set(self, primitive_root=None): r""" - Returns the set of exponents of the roots of ``self``'s generator + Return the set of exponents of the roots of ``self``'s generator polynomial over the extension field. Of course, it depends on the choice of the primitive root of the splitting field. @@ -674,7 +675,7 @@ def defining_set(self, primitive_root=None): def primitive_root(self): r""" - Returns the primitive root of the splitting field that is used + Return the primitive root of the splitting field that is used to build the defining set of the code. If it has not been specified by the user, it is set by default with the @@ -692,7 +693,8 @@ def primitive_root(self): sage: F = GF(16, 'a') sage: n = 15 sage: a = F.gen() - sage: Cc = codes.CyclicCode(length = n, field = F, D = [1,2], primitive_root = a^2 + 1) + sage: Cc = codes.CyclicCode(length=n, field=F, D=[1,2], + ....: primitive_root=a^2 + 1) sage: Cc.primitive_root() a^2 + 1 """ @@ -705,7 +707,7 @@ def primitive_root(self): @cached_method def check_polynomial(self): r""" - Returns the check polynomial of ``self``. + Return the check polynomial of ``self``. Let `C` be a cyclic code of length `n` and `g` its generator polynomial. The following: `h = \frac{x^n - 1}{g(x)}` is called `C`'s @@ -716,7 +718,7 @@ def check_polynomial(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: h = C.check_polynomial() sage: h == (x**n - 1)/C.generator_polynomial() True @@ -729,7 +731,7 @@ def check_polynomial(self): @cached_method def parity_check_matrix(self): r""" - Returns the parity check matrix of ``self``. + Return the parity check matrix of ``self``. The parity check matrix of a linear code `C` corresponds to the generator matrix of the dual code of `C`. @@ -739,7 +741,7 @@ def parity_check_matrix(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: C.parity_check_matrix() [1 0 1 1 1 0 0] [0 1 0 1 1 1 0] @@ -755,7 +757,7 @@ def parity_check_matrix(self): def bch_bound(self, arithmetic=False): r""" - Returns the BCH bound of ``self`` which is a bound on ``self`` + Return the BCH bound of ``self`` which is a bound on ``self`` minimum distance. See :meth:`sage.coding.cyclic_code.bch_bound` for details. @@ -776,14 +778,14 @@ def bch_bound(self, arithmetic=False): sage: F = GF(16, 'a') sage: n = 15 sage: D = [14,1,2,11,12] - sage: C = codes.CyclicCode(field = F, length = n, D = D) + sage: C = codes.CyclicCode(field=F, length=n, D = D) sage: C.bch_bound() (3, (1, 1)) sage: F = GF(16, 'a') sage: n = 15 sage: D = [14,1,2,11,12] - sage: C = codes.CyclicCode(field = F, length = n, D = D) + sage: C = codes.CyclicCode(field=F, length=n, D = D) sage: C.bch_bound(True) (4, (2, 12)) """ @@ -791,7 +793,7 @@ def bch_bound(self, arithmetic=False): def surrounding_bch_code(self): r""" - Returns the surrounding BCH code of ``self``. + Return the surrounding BCH code of ``self``. EXAMPLES:: @@ -818,7 +820,7 @@ class CyclicCodePolynomialEncoder(Encoder): and let `g` be its generator polynomial. This encoder encodes any polynomial `p \in F[x]_{ = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E Polynomial-style encoder for [7, 4] Cyclic Code over GF(2) @@ -842,7 +844,7 @@ def __init__(self, code): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E Polynomial-style encoder for [7, 4] Cyclic Code over GF(2) @@ -861,7 +863,7 @@ def __eq__(self, other): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E1 = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E2 = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E1 == E2 @@ -872,14 +874,14 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E Polynomial-style encoder for [7, 4] Cyclic Code over GF(2) @@ -888,14 +890,14 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: latex(E) \textnormal{Polynomial-style encoder for }[7, 4] \textnormal{ Cyclic Code over } \Bold{F}_{2} @@ -920,7 +922,7 @@ def encode(self, p): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: m = x ** 2 + 1 sage: E.encode(m) @@ -936,7 +938,7 @@ def encode(self, p): def unencode_nocheck(self, c): r""" - Returns the message corresponding to ``c``. + Return the message corresponding to ``c``. Does not check if ``c`` belongs to the code. INPUT: @@ -952,7 +954,7 @@ def unencode_nocheck(self, c): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: c = vector(GF(2), (1, 1, 1, 0, 0, 1, 0)) sage: E.unencode_nocheck(c) @@ -965,14 +967,14 @@ def unencode_nocheck(self, c): def message_space(self): r""" - Returns the message space of ``self`` + Return the message space of ``self`` EXAMPLES:: sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E.message_space() Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) @@ -991,8 +993,7 @@ class CyclicCodeVectorEncoder(Encoder): This codeword can be seen as a polynomial over `F[x]`, as follows: `P_m = \Sigma_{i=0}^{k-1} m_i \times x^i`. - To encode `m`, this encoder does the following multiplication: - `P_m \times g`. + To encode `m`, this encoder does the multiplication `P_m g`. INPUT: @@ -1003,7 +1004,7 @@ class CyclicCodeVectorEncoder(Encoder): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: E Vector-style encoder for [7, 4] Cyclic Code over GF(2) @@ -1017,7 +1018,7 @@ def __init__(self, code): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: E Vector-style encoder for [7, 4] Cyclic Code over GF(2) @@ -1036,7 +1037,7 @@ def __eq__(self, other): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E1 = codes.encoders.CyclicCodeVectorEncoder(C) sage: E2 = codes.encoders.CyclicCodeVectorEncoder(C) sage: E1 == E2 @@ -1047,14 +1048,14 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: E Vector-style encoder for [7, 4] Cyclic Code over GF(2) @@ -1063,14 +1064,14 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: latex(E) \textnormal{Vector-style encoder for }[7, 4] \textnormal{ Cyclic Code over } \Bold{F}_{2} @@ -1095,7 +1096,7 @@ def encode(self, m): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: m = vector(GF(2), (1, 0, 1, 0)) sage: E.encode(m) @@ -1116,7 +1117,7 @@ def encode(self, m): def unencode_nocheck(self, c): r""" - Returns the message corresponding to ``c``. + Return the message corresponding to ``c``. Does not check if ``c`` belongs to the code. INPUT: @@ -1132,7 +1133,7 @@ def unencode_nocheck(self, c): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: c = vector(GF(2), (1, 1, 1, 0, 0, 1, 0)) sage: E.unencode_nocheck(c) @@ -1148,14 +1149,14 @@ def unencode_nocheck(self, c): @cached_method def generator_matrix(self): r""" - Returns a generator matrix of ``self`` + Return a generator matrix of ``self`` EXAMPLES:: sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: E.generator_matrix() [1 1 0 1 0 0 0] @@ -1173,14 +1174,14 @@ def generator_matrix(self): def message_space(self): r""" - Returns the message space of ``self`` + Return the message space of ``self`` EXAMPLES:: sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: E.message_space() Vector space of dimension 4 over Finite Field of size 2 @@ -1239,7 +1240,7 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -1253,7 +1254,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -1267,7 +1268,7 @@ def _latex_(self): def bch_code(self): r""" - Returns the surrounding BCH code of + Return the surrounding BCH code of :meth:`sage.coding.encoder.Encoder.code`. EXAMPLES:: @@ -1281,14 +1282,15 @@ def bch_code(self): def bch_decoder(self): r""" - Returns the decoder that will be used over the surrounding BCH code. + Return the decoder that will be used over the surrounding BCH code. EXAMPLES:: sage: C = codes.CyclicCode(field=GF(16), length=15, D=[14, 1, 2, 11, 12]) sage: D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C) sage: D.bch_decoder() - Decoder through the underlying GRS code of [15, 12] BCH Code over GF(16) with designed distance 4 + Decoder through the underlying GRS code of [15, 12] BCH Code + over GF(16) with designed distance 4 """ return self._bch_decoder @@ -1302,7 +1304,9 @@ def decode_to_code(self, y): sage: C = codes.CyclicCode(field=F, length=15, D=[14, 1, 2, 11, 12]) sage: a = F.gen() sage: D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C) - sage: y = vector(F, [0, a^3, a^3 + a^2 + a, 1, a^2 + 1, a^3 + a^2 + 1, a^3 + a^2 + a, a^3 + a^2 + a, a^2 + a, a^2 + 1, a^2 + a + 1, a^3 + 1, a^2, a^3 + a, a^3 + a]) + sage: y = vector(F, [0, a^3, a^3 + a^2 + a, 1, a^2 + 1, a^3 + a^2 + 1, + ....: a^3 + a^2 + a, a^3 + a^2 + a, a^2 + a, a^2 + 1, + ....: a^2 + a + 1, a^3 + 1, a^2, a^3 + a, a^3 + a]) sage: D.decode_to_code(y) in C True """ @@ -1310,7 +1314,7 @@ def decode_to_code(self, y): def decoding_radius(self): r""" - Returns maximal number of errors that ``self`` can decode. + Return maximal number of errors that ``self`` can decode. EXAMPLES:: diff --git a/src/sage/coding/databases.py b/src/sage/coding/databases.py index ee753504f8b..9fd3b43485b 100644 --- a/src/sage/coding/databases.py +++ b/src/sage/coding/databases.py @@ -1,9 +1,13 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Access functions to online databases for coding theory """ -from sage.libs.gap.libgap import libgap from sage.features.gap import GapPackage +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.libs.gap.libgap', 'libgap') + +del lazy_import # Do not put any global imports here since this module is accessible as # sage.codes.databases. @@ -142,8 +146,8 @@ def best_linear_code_in_codetables_dot_de(n, k, F, verbose=False): last modified: 2002-03-20 - This function raises an ``IOError`` if an error occurs downloading data or - parsing it. It raises a ``ValueError`` if the ``q`` input is invalid. + This function raises an :class:`IOError` if an error occurs downloading data or + parsing it. It raises a :class:`ValueError` if the ``q`` input is invalid. AUTHORS: @@ -184,22 +188,22 @@ def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, INPUT: - - ``n`` - Integer, maximal length + - ``n`` -- Integer, maximal length - - ``k`` - Integer, maximal dimension + - ``k`` -- Integer, maximal dimension - - ``b`` - Integer, requires that the generators all have weight divisible + - ``b`` -- Integer, requires that the generators all have weight divisible by ``b`` (if ``b=2``, all self-orthogonal codes are generated, and if ``b=4``, all doubly even codes are generated). Must be an even positive integer. - - ``parent`` - Used in recursion (default: ``None``) + - ``parent``- - Used in recursion (default: ``None``) - - ``BC`` - Used in recursion (default: ``None``) + - ``BC`` -- Used in recursion (default: ``None``) - - ``equal`` - If ``True`` generates only [n, k] codes (default: ``False``) + - ``equal`` -- If ``True``, generates only [n, k] codes (default: ``False``) - - ``in_test`` - Used in recursion (default: ``None``) + - ``in_test`` -- Used in recursion (default: ``None``) EXAMPLES: diff --git a/src/sage/coding/decoder.py b/src/sage/coding/decoder.py index 8a8e6496f74..94fc99cdeef 100644 --- a/src/sage/coding/decoder.py +++ b/src/sage/coding/decoder.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Decoders @@ -106,7 +107,7 @@ def decoder_type(cls): sage: codes.decoders.LinearCodeSyndromeDecoder.decoder_type() {'dynamic', 'hard-decision'} - We can also call it on a instance of a Decoder class:: + We can also call it on a instance of a :class:`Decoder` class:: sage: G = Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 1, 1]]) sage: C = LinearCode(G) @@ -222,7 +223,7 @@ def __ne__(self, other): def decode_to_code(self, r): r""" - Correct the errors in ``r`` and returns a codeword. + Correct the errors in ``r`` and return a codeword. This is a default implementation which assumes that the method :meth:`decode_to_message` has been implemented, else it returns an exception. @@ -237,7 +238,8 @@ def decode_to_code(self, r): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: word in C @@ -261,7 +263,8 @@ def connected_encoder(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: D = C.decoder() sage: D.connected_encoder() @@ -287,7 +290,8 @@ def decode_to_message(self, r): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: w_err = word + vector(GF(2), (1, 0, 0, 0, 0, 0, 0)) @@ -304,7 +308,8 @@ def code(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: D = C.decoder() sage: D.code() @@ -318,7 +323,8 @@ def message_space(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: D = C.decoder() sage: D.message_space() @@ -332,7 +338,8 @@ def input_space(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: D = C.decoder() sage: D.input_space() @@ -352,7 +359,8 @@ def decoding_radius(self, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C) sage: D.decoding_radius() diff --git a/src/sage/coding/decoders_catalog.py b/src/sage/coding/decoders_catalog.py index a95912e51b6..a9f2417880e 100644 --- a/src/sage/coding/decoders_catalog.py +++ b/src/sage/coding/decoders_catalog.py @@ -12,6 +12,7 @@ - :class:`extended_code.ExtendedCodeOriginalCodeDecoder ` **Subfield subcode decoder** + - :class:`subfield_subcode.SubfieldSubcodeOriginalCodeDecoder ` **Generalized Reed-Solomon code decoders** @@ -45,11 +46,9 @@ - :class:`ag_code_decoders.EvaluationAGCodeUniqueDecoder ` - :class:`ag_code_decoders.DifferentialAGCodeUniqueDecoder ` -.. NOTE:: - - To import these names into the global namespace, use: +To import these names into the global namespace, use:: - sage: from sage.coding.decoders_catalog import * + sage: from sage.coding.decoders_catalog import * """ #***************************************************************************** # Copyright (C) 2009 David Joyner diff --git a/src/sage/coding/delsarte_bounds.py b/src/sage/coding/delsarte_bounds.py index 52eb8ce746c..47c84b2c59b 100644 --- a/src/sage/coding/delsarte_bounds.py +++ b/src/sage/coding/delsarte_bounds.py @@ -31,7 +31,7 @@ def krawtchouk(n, q, l, x, check=True): r""" - Compute ``K^{n,q}_l(x)``, the Krawtchouk (a.k.a. Kravchuk) polynomial. + Compute `K^{n,q}_l(x)`, the Krawtchouk (a.k.a. Kravchuk) polynomial. See :wikipedia:`Kravchuk_polynomials`. @@ -121,7 +121,7 @@ def krawtchouk(n, q, l, x, check=True): def eberlein(n, w, k, u, check=True): r""" - Compute ``E^{n,l}_k(x)``, the Eberlein polynomial. + Compute `E^{w,n}_k(x)`, the Eberlein polynomial. See :wikipedia:`Eberlein_polynomials`. @@ -399,7 +399,7 @@ def delsarte_bound_hamming_space(n, d, q, return_data=False, solver="PPL", isint EXAMPLES: - The bound on the size of the `F_2`-codes of length 11 and minimal distance 6:: + The bound on the size of the `\GF{2}`-codes of length 11 and minimal distance 6:: sage: codes.bounds.delsarte_bound_hamming_space(11, 6, 2) 12 @@ -407,7 +407,7 @@ def delsarte_bound_hamming_space(n, d, q, return_data=False, solver="PPL", isint sage: [j for i,j in p.get_values(a).items()] [1, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0] - The bound on the size of the `F_2`-codes of length 24 and minimal distance + The bound on the size of the `\GF{2}`-codes of length 24 and minimal distance 8, i.e. parameters of the extended binary Golay code:: sage: a,p,x = codes.bounds.delsarte_bound_hamming_space(24,8,2,return_data=True) @@ -416,7 +416,7 @@ def delsarte_bound_hamming_space(n, d, q, return_data=False, solver="PPL", isint sage: [j for i,j in p.get_values(a).items()] [1, 0, 0, 0, 0, 0, 0, 0, 759, 0, 0, 0, 2576, 0, 0, 0, 759, 0, 0, 0, 0, 0, 0, 0, 1] - The bound on the size of `F_4`-codes of length 11 and minimal distance 3:: + The bound on the size of `\GF{4}`-codes of length 11 and minimal distance 3:: sage: codes.bounds.delsarte_bound_hamming_space(11,3,4) 327680/3 @@ -457,10 +457,10 @@ def delsarte_bound_hamming_space(n, d, q, return_data=False, solver="PPL", isint def delsarte_bound_additive_hamming_space(n, d, q, d_star=1, q_base=0, return_data=False, solver="PPL", isinteger=False): r""" - Find a modified Delsarte bound on additive codes in Hamming space ``H_q^n`` of minimal distance ``d`` + Find a modified Delsarte bound on additive codes in Hamming space `H_q^n` of minimal distance `d` Find the Delsarte LP bound on ``F_{q_base}``-dimension of additive codes in - Hamming space ``H_q^n`` of minimal distance ``d`` with minimal distance of the dual + Hamming space `H_q^n` of minimal distance ``d`` with minimal distance of the dual code at least ``d_star``. If ``q_base`` is set to non-zero, then ``q`` is a power of ``q_base``, and the code is, formally, linear over ``F_{q_base}``. Otherwise it is assumed that ``q_base==q``. @@ -485,7 +485,7 @@ def delsarte_bound_additive_hamming_space(n, d, q, d_star=1, q_base=0, return_da data. ``W`` need not be a weight distribution of a code, or, if ``isinteger==False``, even have integer entries. - - ``solver`` -- the LP/ILP solver to be used. Defaults to ``PPL``. It is arbitrary + - ``solver`` -- the LP/ILP solver to be used. Defaults to ``'PPL'``. It is arbitrary precision, thus there will be no rounding errors. With other solvers (see :class:`MixedIntegerLinearProgram` for the list), you are on your own! @@ -494,7 +494,7 @@ def delsarte_bound_additive_hamming_space(n, d, q, d_star=1, q_base=0, return_da EXAMPLES: - The bound on dimension of linear `F_2`-codes of length 11 and minimal distance 6:: + The bound on dimension of linear `\GF{2}`-codes of length 11 and minimal distance 6:: sage: codes.bounds.delsarte_bound_additive_hamming_space(11, 6, 2) 3 @@ -503,12 +503,12 @@ def delsarte_bound_additive_hamming_space(n, d, q, d_star=1, q_base=0, return_da sage: [j for i,j in p.get_values(a).items()] [1, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0] - The bound on the dimension of linear `F_4`-codes of length 11 and minimal distance 3:: + The bound on the dimension of linear `\GF{4}`-codes of length 11 and minimal distance 3:: sage: codes.bounds.delsarte_bound_additive_hamming_space(11,3,4) 8 - The bound on the `F_2`-dimension of additive `F_4`-codes of length 11 and minimal + The bound on the `\GF{2}`-dimension of additive `\GF{4}`-codes of length 11 and minimal distance 3:: sage: codes.bounds.delsarte_bound_additive_hamming_space(11,3,4,q_base=2) @@ -679,9 +679,10 @@ def delsarte_bound_Q_matrix(q, d, return_data=False, solver="PPL", isinteger=Fal EXAMPLES: - The bound on dimension of linear `F_2`-codes of length 10 and minimal distance 6:: + The bound on dimension of linear `\GF{2}`-codes of length 10 and minimal distance 6:: - sage: q_matrix = Matrix([[codes.bounds.krawtchouk(10,2,i,j) for i in range(11)] for j in range(11)]) + sage: q_matrix = Matrix([[codes.bounds.krawtchouk(10,2,i,j) for i in range(11)] + ....: for j in range(11)]) sage: codes.bounds.delsarte_bound_Q_matrix(q_matrix, 6) 2 diff --git a/src/sage/coding/encoder.py b/src/sage/coding/encoder.py index ba1070633fd..177b3e50e58 100644 --- a/src/sage/coding/encoder.py +++ b/src/sage/coding/encoder.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Encoders @@ -143,7 +144,8 @@ def encode(self, word): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: word = vector(GF(2), (0, 1, 1, 0)) sage: E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C) @@ -156,7 +158,8 @@ def encode(self, word): sage: E.encode(word) Traceback (most recent call last): ... - ValueError: The value to encode must be in Vector space of dimension 4 over Finite Field of size 2 + ValueError: The value to encode must be in + Vector space of dimension 4 over Finite Field of size 2 """ M = self.message_space() if word not in M: @@ -215,7 +218,8 @@ def unencode(self, c, nocheck=False): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: c = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: c in C @@ -299,7 +303,8 @@ def unencode_nocheck(self, c): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: c = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: c in C @@ -332,7 +337,8 @@ def code(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: E = C.encoder() sage: E.code() == C @@ -348,7 +354,8 @@ def message_space(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: E = C.encoder() sage: E.message_space() @@ -368,7 +375,8 @@ def generator_matrix(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: E = C.encoder() sage: E.generator_matrix() diff --git a/src/sage/coding/encoders_catalog.py b/src/sage/coding/encoders_catalog.py index 9435f72ee33..e6ac68267fd 100644 --- a/src/sage/coding/encoders_catalog.py +++ b/src/sage/coding/encoders_catalog.py @@ -26,11 +26,9 @@ - :class:`punctured_code.PuncturedCodePuncturedMatrixEncoder ` -.. NOTE:: +To import these names into the global namespace, use:: - To import these names into the global namespace, use: - - sage: from sage.coding.encoders_catalog import * + sage: from sage.coding.encoders_catalog import * """ #***************************************************************************** # Copyright (C) 2009 David Joyner diff --git a/src/sage/coding/extended_code.py b/src/sage/coding/extended_code.py index 6065d4c2c96..a601a0b26b3 100644 --- a/src/sage/coding/extended_code.py +++ b/src/sage/coding/extended_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Extended code @@ -85,7 +86,7 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -98,7 +99,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -111,7 +112,7 @@ def _latex_(self): def original_code(self): r""" - Returns the code which was extended to get ``self``. + Return the code which was extended to get ``self``. EXAMPLES:: @@ -125,7 +126,7 @@ def original_code(self): @cached_method def parity_check_matrix(self): r""" - Returns a parity check matrix of ``self``. + Return a parity check matrix of ``self``. This matrix is computed directly from :func:`original_code`. @@ -156,7 +157,7 @@ def parity_check_matrix(self): def random_element(self): r""" - Returns a random element of ``self``. + Return a random element of ``self``. This random element is computed directly from the original code, and does not compute a generator matrix of ``self`` in the process. @@ -205,7 +206,7 @@ def __init__(self, code): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -219,7 +220,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -252,7 +253,7 @@ def __eq__(self, other): @cached_method def generator_matrix(self): r""" - Returns a generator matrix of the associated code of ``self``. + Return a generator matrix of the associated code of ``self``. EXAMPLES:: @@ -298,7 +299,8 @@ class ExtendedCodeOriginalCodeDecoder(Decoder): sage: Ce = codes.ExtendedCode(C) sage: D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce) sage: D - Decoder of Extension of [15, 7, 9] Reed-Solomon Code over GF(16) through Gao decoder for [15, 7, 9] Reed-Solomon Code over GF(16) + Decoder of Extension of [15, 7, 9] Reed-Solomon Code over GF(16) + through Gao decoder for [15, 7, 9] Reed-Solomon Code over GF(16) """ def __init__(self, code, original_decoder = None, **kwargs): @@ -334,7 +336,7 @@ def __init__(self, code, original_decoder = None, **kwargs): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -348,7 +350,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -362,7 +364,7 @@ def _latex_(self): def original_decoder(self): r""" - Returns the decoder over the original code that will be used to decode words of + Return the decoder over the original code that will be used to decode words of :meth:`sage.coding.decoder.Decoder.code`. EXAMPLES:: @@ -377,7 +379,7 @@ def original_decoder(self): def decode_to_code(self, y, **kwargs): r""" - Decodes ``y`` to an element in :meth:`sage.coding.decoder.Decoder.code`. + Decode ``y`` to an element in :meth:`sage.coding.decoder.Decoder.code`. EXAMPLES:: @@ -385,7 +387,8 @@ def decode_to_code(self, y, **kwargs): sage: Ce = codes.ExtendedCode(C) sage: D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce) sage: c = Ce.random_element() - sage: Chan = channels.StaticErrorRateChannel(Ce.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(Ce.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: y in Ce False @@ -396,10 +399,12 @@ def decode_to_code(self, y, **kwargs): sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) sage: Ce = codes.ExtendedCode(C) - sage: Dgrs = C.decoder('GuruswamiSudan', tau = 4) - sage: D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce, original_decoder = Dgrs) + sage: Dgrs = C.decoder('GuruswamiSudan', tau=4) + sage: D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce, + ....: original_decoder=Dgrs) sage: c = Ce.random_element() - sage: Chan = channels.StaticErrorRateChannel(Ce.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(Ce.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: y in Ce False @@ -433,7 +438,7 @@ def decode_to_code(self, y, **kwargs): def decoding_radius(self, *args, **kwargs): r""" - Returns maximal number of errors that ``self`` can decode. + Return maximal number of errors that ``self`` can decode. INPUT: diff --git a/src/sage/coding/gabidulin_code.py b/src/sage/coding/gabidulin_code.py index b6d2e2bac4d..0ba1d13ec41 100644 --- a/src/sage/coding/gabidulin_code.py +++ b/src/sage/coding/gabidulin_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Gabidulin Code @@ -499,7 +500,8 @@ def generator_matrix(self): sage: Fqm = GF(2^9) sage: Fq = GF(2^3) sage: C = codes.GabidulinCode(Fqm, 3, 3, Fq) - sage: list(C.generator_matrix().row(1)) == [C.evaluation_points()[i]**(2**3) for i in range(3)] + sage: (list(C.generator_matrix().row(1)) + ....: == [C.evaluation_points()[i]**(2**3) for i in range(3)]) True """ from functools import reduce @@ -543,7 +545,8 @@ class GabidulinPolynomialEvaluationEncoder(Encoder): sage: z9 = Fqm.gen() sage: p = (z9^6 + z9^2 + z9 + 1)*x + z9^7 + z9^5 + z9^4 + z9^2 sage: vector(p.multi_point_evaluation(C.evaluation_points())) - doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. + doctest:...: FutureWarning: This class/method/function is marked as experimental. + It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/13215 for details. (z9^7 + z9^6 + z9^5 + z9^4 + z9 + 1, z9^6 + z9^5 + z9^3 + z9) @@ -554,13 +557,15 @@ class GabidulinPolynomialEvaluationEncoder(Encoder): sage: C = codes.GabidulinCode(Fqm, 2, 2, Fq) sage: E = codes.encoders.GabidulinPolynomialEvaluationEncoder(C) sage: E - Polynomial evaluation style encoder for [2, 2, 1] linear Gabidulin code over GF(16)/GF(4) + Polynomial evaluation style encoder for + [2, 2, 1] linear Gabidulin code over GF(16)/GF(4) Alternatively, we can construct the encoder from ``C`` directly:: sage: E = C.encoder("PolynomialEvaluation") sage: E - Polynomial evaluation style encoder for [2, 2, 1] linear Gabidulin code over GF(16)/GF(4) + Polynomial evaluation style encoder for + [2, 2, 1] linear Gabidulin code over GF(16)/GF(4) """ def __init__(self, code): @@ -655,7 +660,8 @@ def message_space(self): sage: C = codes.GabidulinCode(Fqm, 4, 4, Fq) sage: E = codes.encoders.GabidulinPolynomialEvaluationEncoder(C) sage: E.message_space() - Ore Polynomial Ring in x over Finite Field in z20 of size 5^20 twisted by z20 |--> z20^(5^4) + Ore Polynomial Ring in x over Finite Field in z20 of size 5^20 + twisted by z20 |--> z20^(5^4) """ C = self.code() return C.base_field()['x', C.twisting_homomorphism()] diff --git a/src/sage/coding/goppa_code.py b/src/sage/coding/goppa_code.py index fbfa74462c4..fffd3fd080f 100644 --- a/src/sage/coding/goppa_code.py +++ b/src/sage/coding/goppa_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Goppa code diff --git a/src/sage/coding/grs_code.py b/src/sage/coding/grs_code.py index d86c61c254e..b0824a51f62 100644 --- a/src/sage/coding/grs_code.py +++ b/src/sage/coding/grs_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Reed-Solomon codes and Generalized Reed-Solomon codes @@ -7,9 +8,9 @@ .. MATH:: - \{ f(\alpha_1), \ldots, f(\alpha_n) \mid f \in F[x], \deg f < k \} + \{ (f(\alpha_1), \ldots, f(\alpha_n)) \mid f \in F[x], \deg f < k \} -An RS code is often called "classical" if `alpha_i = \alpha^{i-1}` and `\alpha` +An RS code is often called "classical" if `\alpha_i = \alpha^{i-1}` and `\alpha` is a primitive `n`'th root of unity. More generally, given also `n` "column multipliers" `\beta_1, \dots, \beta_n`, @@ -18,7 +19,7 @@ .. MATH:: - \{ (\beta_1 f(\alpha_1), \ldots, \beta_n f(\alpha_n) + \{ (\beta_1 f(\alpha_1), \ldots, \beta_n f(\alpha_n)) \mid f \in F[x], \deg f < k \} Here is a list of all content related to GRS codes: @@ -64,9 +65,6 @@ from sage.misc.functional import symbolic_sum from sage.misc.misc_c import prod -from sage.functions.other import binomial -from sage.symbolic.ring import SR - from .linear_code import AbstractLinearCode from .encoder import Encoder from .decoder import Decoder, DecodingError @@ -516,7 +514,7 @@ def weight_distribution(self): sage: F = GF(11) sage: n, k = 10, 5 sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) - sage: C.weight_distribution() + sage: C.weight_distribution() # optional - sage.symbolic [1, 0, 0, 0, 0, 0, 2100, 6000, 29250, 61500, 62200] TESTS: @@ -525,13 +523,16 @@ def weight_distribution(self): sage: F = GF(7) sage: C = codes.GeneralizedReedSolomonCode(F.list(), 3) - sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time + sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time # optional - sage.symbolic True sage: F = GF(8) sage: C = codes.GeneralizedReedSolomonCode(F.list(), 3) - sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time + sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time # optional - sage.symbolic True """ + from sage.symbolic.ring import SR + from sage.functions.other import binomial + d = self.minimum_distance() n = self.length() q = self.base_ring().order() @@ -576,7 +577,7 @@ def ReedSolomonCode(base_field, length, dimension, primitive_root=None): r""" Construct a classical Reed-Solomon code. - A classical `[n,k]` Reed-Solomon code over `GF(q)` with `1 \le k \le n` and + A classical `[n,k]` Reed-Solomon code over `\GF{q}` with `1 \le k \le n` and `n | (q-1)` is a Reed-Solomon code whose evaluation points are the consecutive powers of a primitive `n`'th root of unity `\alpha`, i.e. `\alpha_i = \alpha^{i-1}`, where `\alpha_1, \ldots, \alpha_n` are the @@ -664,13 +665,13 @@ class GRSEvaluationVectorEncoder(Encoder): .. MATH:: - p = \Sigma_{i=1}^{m} m_i \times x^i. + p = \Sigma_{i=1}^{m} m_i x^i. The encoding of `m` will be the following codeword: .. MATH:: - (\beta_1 \times p(\alpha_1), \dots, \beta_n \times p(\alpha_n)). + (\beta_1 p(\alpha_1), \dots, \beta_n p(\alpha_n)). INPUT: @@ -767,7 +768,7 @@ def generator_matrix(self): .. MATH:: - G = [g_{i,j}], g_{i,j} = \beta_j \times \alpha_{j}^{i}. + G = [g_{i,j}], g_{i,j} = \beta_j \alpha_{j}^{i}. This matrix is a Vandermonde matrix. @@ -806,7 +807,7 @@ class GRSEvaluationPolynomialEncoder(Encoder): .. MATH:: - (\beta_1 \times p(\alpha_1), \dots, \beta_n \times p(\alpha_n)). + (\beta_1 p(\alpha_1), \dots, \beta_n p(\alpha_n)). INPUT: @@ -987,7 +988,8 @@ def encode(self, p): sage: E.encode(p) Traceback (most recent call last): ... - ValueError: The value to encode must be in Univariate Polynomial Ring in x over Finite Field of size 11 + ValueError: The value to encode must be in + Univariate Polynomial Ring in x over Finite Field of size 11 TESTS: @@ -1277,7 +1279,8 @@ def decode_to_message(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) sage: D = codes.decoders.GRSBerlekampWelchDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: D.connected_encoder().unencode(c) == D.decode_to_message(y) True @@ -1338,7 +1341,8 @@ def decode_to_code(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) sage: D = codes.decoders.GRSBerlekampWelchDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: c == D.decode_to_code(y) True @@ -1539,7 +1543,7 @@ def _partial_xgcd(self, a, b, PolRing): Performs an Euclidean algorithm on ``a`` and ``b`` until a remainder has degree less than `\frac{n+k}{2}`, `n` being the dimension of the code, `k` its dimension, and returns `(r, s)` such that in the step - just before termination, `r = a\times s + b\times t`. + just before termination, `r = a s + b t`. INPUT: @@ -1660,7 +1664,8 @@ def decode_to_message(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) sage: D = codes.decoders.GRSGaoDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: D.connected_encoder().unencode(c) == D.decode_to_message(y) True @@ -1721,7 +1726,8 @@ def decode_to_code(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) sage: D = codes.decoders.GRSGaoDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: c == D.decode_to_code(y) True @@ -1893,11 +1899,11 @@ def decode_to_message(self, word_and_erasure_vector): INPUT: - - word_and_erasure_vector -- a tuple whose: + - ``word_and_erasure_vector`` -- a tuple whose: * first element is an element of the ambient space of the code * second element is a vector over `\GF{2}` whose length is the - same as the code's + same as the code's, containing erasure positions .. NOTE:: @@ -1909,12 +1915,6 @@ def decode_to_message(self, word_and_erasure_vector): In either case, if ``r`` is not a codeword, the output is unspecified. - INPUT: - - - ``word_and_erasure_vector`` -- a pair of vectors, where - first element is a codeword of ``self`` and second element - is a vector of GF(2) containing erasure positions - OUTPUT: - a vector of ``self`` message space @@ -1927,7 +1927,8 @@ def decode_to_message(self, word_and_erasure_vector): sage: D = codes.decoders.GRSErrorErasureDecoder(C) sage: c = C.random_element() sage: n_era = randint(0, C.minimum_distance() - 2) - sage: Chan = channels.ErrorErasureChannel(C.ambient_space(), D.decoding_radius(n_era), n_era) + sage: Chan = channels.ErrorErasureChannel(C.ambient_space(), + ....: D.decoding_radius(n_era), n_era) sage: y = Chan(c) sage: D.connected_encoder().unencode(c) == D.decode_to_message(y) True @@ -2133,7 +2134,7 @@ def _partial_xgcd(self, a, b, PolRing): Performs an Euclidean algorithm on ``a`` and ``b`` until a remainder has degree less than `\frac{n+k}{2}`, `n` being the dimension of the code, `k` its dimension, and returns `(r, t)` such that in the step - just before termination, `r = a\times s + b\times t`. + just before termination, `r = a s + b t`. INPUT: @@ -2272,7 +2273,8 @@ def decode_to_code(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k) sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: c == D.decode_to_code(y) True @@ -2346,7 +2348,8 @@ def decode_to_message(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k) sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: D.connected_encoder().unencode(c) == D.decode_to_message(y) True diff --git a/src/sage/coding/guava.py b/src/sage/coding/guava.py index 26d94e068f3..4a529fe762d 100644 --- a/src/sage/coding/guava.py +++ b/src/sage/coding/guava.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.gap sage.modules sage.rings.finite_rings r""" Constructions of generator matrices using the GUAVA package for GAP @@ -45,7 +46,7 @@ def QuasiQuadraticResidueCode(p): Follows the definition of Proposition 2.2 in [BM2003]_. The code has a generator matrix in the block form `G=(Q,N)`. Here `Q` is a `p \times p` circulant matrix whose top row is `(0,x_1,...,x_{p-1})`, where `x_i=1` if and only if - `i` is a quadratic residue `\mod p`, and `N` is a `p \times p` circulant + `i` is a quadratic residue mod `p`, and `N` is a `p \times p` circulant matrix whose top row is `(0,y_1,...,y_{p-1})`, where `x_i+y_i=1` for all `i`. @@ -94,7 +95,7 @@ def RandomLinearCodeGuava(n, k, F): sage: C = codes.RandomLinearCodeGuava(30,15,GF(2)); C # optional - gap_packages (Guava package) [30, 15] linear code over GF(2) - sage: C = codes.RandomLinearCodeGuava(10,5,GF(4,'a')); C # optional - gap_packages (Guava package) + sage: C = codes.RandomLinearCodeGuava(10,5,GF(4,'a')); C # optional - gap_packages (Guava package) [10, 5] linear code over GF(4) AUTHOR: David Joyner (11-2005) diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index 830d49238dc..2497629e0f4 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Guruswami-Sudan decoder for (Generalized) Reed-Solomon codes @@ -36,9 +37,9 @@ def n_k_params(C, n_k): r""" - Internal helper function for the GRSGuruswamiSudanDecoder class for allowing to - specify either a GRS code `C` or the length and dimensions `n, k` directly, - in all the static functions. + Internal helper function for the :class:`GRSGuruswamiSudanDecoder` class for + allowing to specify either a GRS code `C` or the length and dimensions `n, + k` directly, in all the static functions. If neither `C` or `n,k` were specified to those functions, an appropriate error should be raised. Otherwise, `n, k` of the code or the supplied tuple @@ -46,9 +47,10 @@ def n_k_params(C, n_k): INPUT: - - ``C`` -- A GRS code or `None` + - ``C`` -- A GRS code or ``None`` - - ``n_k`` -- A tuple `(n,k)` being length and dimension of a GRS code, or `None`. + - ``n_k`` -- A tuple `(n,k)` being length and dimension of a GRS code, or + ``None``. OUTPUT: @@ -60,13 +62,13 @@ def n_k_params(C, n_k): sage: n_k_params(None, (10, 5)) (10, 5) sage: C = codes.GeneralizedReedSolomonCode(GF(11).list()[:10], 5) - sage: n_k_params(C,None) + sage: n_k_params(C, None) (10, 5) sage: n_k_params(None,None) Traceback (most recent call last): ... ValueError: Please provide either the code or its length and dimension - sage: n_k_params(C,(12, 2)) + sage: n_k_params(C, (12, 2)) Traceback (most recent call last): ... ValueError: Please provide only the code or its length and dimension @@ -85,7 +87,7 @@ def n_k_params(C, n_k): def roth_ruckenstein_root_finder(p, maxd=None, precision=None): """ Wrapper for Roth-Ruckenstein algorithm to compute the roots of a polynomial - with coefficients in ``F[x]``. + with coefficients in `F[x]`. TESTS:: @@ -104,7 +106,7 @@ def roth_ruckenstein_root_finder(p, maxd=None, precision=None): def alekhnovich_root_finder(p, maxd=None, precision=None): """ Wrapper for Alekhnovich's algorithm to compute the roots of a polynomial - with coefficients in ``F[x]``. + with coefficients in `F[x]`. TESTS:: @@ -155,16 +157,18 @@ class GRSGuruswamiSudanDecoder(Decoder): Guruswami-Sudan algorithm to correct. - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter, and - - the second integer is the list size parameter. + + - the first integer is the multiplicity parameter, and + - the second integer is the list size parameter. - ``interpolation_alg`` -- (default: ``None``) the interpolation algorithm that will be used. The following possibilities are currently available: - * ``"LinearAlgebra"`` -- uses a linear system solver. - * ``"LeeOSullivan"`` -- uses Lee O'Sullivan method based on row reduction of a matrix - * ``None`` -- one of the above will be chosen based on the size of the - code and the parameters. + * ``"LinearAlgebra"`` -- uses a linear system solver. + * ``"LeeOSullivan"`` -- uses Lee O'Sullivan method based on row reduction + of a matrix + * ``None`` -- one of the above will be chosen based on the size of the + code and the parameters. You can also supply your own function to perform the interpolation. See NOTE section for details on the signature of this function. @@ -172,12 +176,12 @@ class GRSGuruswamiSudanDecoder(Decoder): - ``root_finder`` -- (default: ``None``) the rootfinding algorithm that will be used. The following possibilities are currently available: - * ``"Alekhnovich"`` -- uses Alekhnovich's algorithm. + * ``"Alekhnovich"`` -- uses Alekhnovich's algorithm. - * ``"RothRuckenstein"`` -- uses Roth-Ruckenstein algorithm. + * ``"RothRuckenstein"`` -- uses Roth-Ruckenstein algorithm. - * ``None`` -- one of the above will be chosen based on the size of the - code and the parameters. + * ``None`` -- one of the above will be chosen based on the size of the + code and the parameters. You can also supply your own function to perform the interpolation. See NOTE section for details on the signature of this function. @@ -201,38 +205,40 @@ class GRSGuruswamiSudanDecoder(Decoder): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 97) - sage: D - Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) + sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau=97); D + Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) + decoding 97 errors with parameters (1, 2) One can specify multiplicity and list size instead of ``tau``:: - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters = (1,2)) - sage: D - Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) + sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters=(1,2)); D + Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) + decoding 97 errors with parameters (1, 2) One can pass a method as ``root_finder`` (works also for ``interpolation_alg``):: sage: from sage.coding.guruswami_sudan.gs_decoder import roth_ruckenstein_root_finder sage: rf = roth_ruckenstein_root_finder - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters = (1,2), root_finder = rf) - sage: D - Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) + sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters=(1,2), + ....: root_finder=rf); D + Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) + decoding 97 errors with parameters (1, 2) If one wants to use the native Sage algorithms for the root finding step, one can directly pass the string given in the ``Input`` block of this class. This works for ``interpolation_alg`` as well:: - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters = (1,2), root_finder="RothRuckenstein") - sage: D - Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) + sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters=(1,2), + ....: root_finder="RothRuckenstein"); D + Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) + decoding 97 errors with parameters (1, 2) Actually, we can construct the decoder from ``C`` directly:: - sage: D = C.decoder("GuruswamiSudan", tau = 97) - sage: D - Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) + sage: D = C.decoder("GuruswamiSudan", tau=97); D + Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) + decoding 97 errors with parameters (1, 2) """ ####################### static methods ############################### @@ -240,7 +246,7 @@ class GRSGuruswamiSudanDecoder(Decoder): @staticmethod def parameters_given_tau(tau, C = None, n_k = None): r""" - Returns the smallest possible multiplicity and list size given the + Return the smallest possible multiplicity and list size given the given parameters of the code and decoding radius. INPUT: @@ -254,8 +260,9 @@ def parameters_given_tau(tau, C = None, n_k = None): OUTPUT: - ``(s, l)`` -- a pair of integers, where: - - ``s`` is the multiplicity parameter, and - - ``l`` is the list size parameter. + + - ``s`` is the multiplicity parameter, and + - ``l`` is the list size parameter. .. NOTE:: @@ -264,23 +271,25 @@ def parameters_given_tau(tau, C = None, n_k = None): EXAMPLES:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: tau, n, k = 97, 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + sage: GSD.parameters_given_tau(tau, n_k=(n, k)) (1, 2) Another example with a bigger decoding radius:: sage: tau, n, k = 118, 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + sage: GSD.parameters_given_tau(tau, n_k=(n, k)) (47, 89) Choosing a decoding radius which is too large results in an errors:: sage: tau = 200 - sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + sage: GSD.parameters_given_tau(tau, n_k=(n, k)) Traceback (most recent call last): ... - ValueError: The decoding radius must be less than the Johnson radius (which is 118.66) + ValueError: The decoding radius must be less than + the Johnson radius (which is 118.66) """ n,k = n_k_params(C, n_k) @@ -309,7 +318,7 @@ def try_l(l): @staticmethod def guruswami_sudan_decoding_radius(C = None, n_k = None, l = None, s = None): r""" - Returns the maximal decoding radius of the Guruswami-Sudan decoder and + Return the maximal decoding radius of the Guruswami-Sudan decoder and the parameter choices needed for this. If ``s`` is set but ``l`` is not it will return the best decoding radius using this ``s`` @@ -332,27 +341,30 @@ def guruswami_sudan_decoding_radius(C = None, n_k = None, l = None, s = None): OUTPUT: - ``(tau, (s, l))`` -- where - - ``tau`` is the obtained decoding radius, and - - ``s, ell`` are the multiplicity parameter, respectively list size - parameter giving this radius. + + - ``tau`` is the obtained decoding radius, and + + - ``s, ell`` are the multiplicity parameter, respectively list size + parameter giving this radius. EXAMPLES:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: n, k = 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k)) + sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k)) (118, (47, 89)) One parameter can be restricted at a time:: sage: n, k = 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), s=3) + sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k), s=3) (109, (3, 5)) - sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), l=7) + sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k), l=7) (111, (4, 7)) The function can also just compute the decoding radius given the parameters:: - sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), s=2, l=6) + sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k), s=2, l=6) (92, (2, 6)) """ n,k = n_k_params(C, n_k) @@ -364,7 +376,7 @@ def get_tau(s,l): return gilt(n - n/2*(s+1)/(l+1) - (k-1)/2*l/s) if l is None and s is None: tau = gilt(johnson_radius(n, n - k + 1)) - return (tau, GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k))) + return (tau, GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k=(n, k))) if l is not None and s is not None: return (get_tau(s,l), (s,l)) @@ -423,8 +435,9 @@ def _suitable_parameters_given_tau(tau, C = None, n_k = None): OUTPUT: - ``(s, l)`` -- a pair of integers, where: - - ``s`` is the multiplicity parameter, and - - ``l`` is the list size parameter. + + - ``s`` is the multiplicity parameter, and + - ``l`` is the list size parameter. .. NOTE:: @@ -436,31 +449,32 @@ def _suitable_parameters_given_tau(tau, C = None, n_k = None): The following is an example where the parameters are optimal:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: tau = 98 sage: n, k = 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder._suitable_parameters_given_tau(tau, n_k = (n, k)) + sage: GSD._suitable_parameters_given_tau(tau, n_k=(n, k)) (2, 3) - sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + sage: GSD.parameters_given_tau(tau, n_k=(n, k)) (2, 3) This is an example where they are not:: sage: tau = 97 sage: n, k = 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder._suitable_parameters_given_tau(tau, n_k = (n, k)) + sage: GSD._suitable_parameters_given_tau(tau, n_k=(n, k)) (2, 3) - sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + sage: GSD.parameters_given_tau(tau, n_k=(n, k)) (1, 2) We can provide a GRS code instead of `n` and `k` directly:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: codes.decoders.GRSGuruswamiSudanDecoder._suitable_parameters_given_tau(tau, C = C) + sage: GSD._suitable_parameters_given_tau(tau, C=C) (2, 3) Another one with a bigger ``tau``:: - sage: codes.decoders.GRSGuruswamiSudanDecoder._suitable_parameters_given_tau(118, C = C) + sage: GSD._suitable_parameters_given_tau(118, C=C) (47, 89) """ n,k = n_k_params(C, n_k) @@ -475,7 +489,7 @@ def _suitable_parameters_given_tau(tau, C = None, n_k = None): @staticmethod def gs_satisfactory(tau, s, l, C = None, n_k = None): r""" - Returns whether input parameters satisfy the governing equation of + Return whether input parameters satisfy the governing equation of Guruswami-Sudan. See [Nie2013]_ page 49, definition 3.3 and proposition 3.4 for details. @@ -497,21 +511,22 @@ def gs_satisfactory(tau, s, l, C = None, n_k = None): EXAMPLES:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: tau, s, l = 97, 1, 2 sage: n, k = 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder.gs_satisfactory(tau, s, l, n_k = (n, k)) + sage: GSD.gs_satisfactory(tau, s, l, n_k=(n, k)) True One can also pass a GRS code:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: codes.decoders.GRSGuruswamiSudanDecoder.gs_satisfactory(tau, s, l, C = C) + sage: GSD.gs_satisfactory(tau, s, l, C=C) True Another example where ``s`` and ``l`` does not satisfy the equation:: sage: tau, s, l = 118, 47, 80 - sage: codes.decoders.GRSGuruswamiSudanDecoder.gs_satisfactory(tau, s, l, n_k = (n, k)) + sage: GSD.gs_satisfactory(tau, s, l, n_k=(n, k)) False If one provides both ``C`` and ``n_k`` an exception is returned:: @@ -519,14 +534,14 @@ def gs_satisfactory(tau, s, l, C = None, n_k = None): sage: tau, s, l = 97, 1, 2 sage: n, k = 250, 70 sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: codes.decoders.GRSGuruswamiSudanDecoder.gs_satisfactory(tau, s, l, C = C, n_k = (n, k)) + sage: GSD.gs_satisfactory(tau, s, l, C=C, n_k=(n, k)) Traceback (most recent call last): ... ValueError: Please provide only the code or its length and dimension Same if one provides none of these:: - sage: codes.decoders.GRSGuruswamiSudanDecoder.gs_satisfactory(tau, s, l) + sage: GSD.gs_satisfactory(tau, s, l) Traceback (most recent call last): ... ValueError: Please provide either the code or its length and dimension @@ -541,8 +556,9 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None If neither ``tau`` nor ``parameters`` is given, an exception is returned:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C) + sage: D = GSD(C) Traceback (most recent call last): ... ValueError: Specify either tau or parameters @@ -551,7 +567,7 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None an exception is returned:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 97, interpolation_alg = 42) + sage: D = GSD(C, tau=97, interpolation_alg=42) Traceback (most recent call last): ... ValueError: Please provide a method or one of the allowed strings for interpolation_alg @@ -559,7 +575,7 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None Same thing for ``root_finder``:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 97, root_finder = "FortyTwo") + sage: D = GSD(C, tau=97, root_finder="FortyTwo") Traceback (most recent call last): ... ValueError: Please provide a method or one of the allowed strings for root_finder @@ -568,7 +584,7 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None error message is returned:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 142, parameters=(1, 2)) + sage: D = GSD(C, tau=142, parameters=(1, 2)) Traceback (most recent call last): ... ValueError: Impossible parameters for the Guruswami-Sudan algorithm @@ -576,7 +592,7 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None If ``code`` is not a GRS code, an error is raised:: sage: C = codes.random_linear_code(GF(11), 10, 4) - sage: codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 2) + sage: GSD(C, tau=2) Traceback (most recent call last): ... ValueError: code has to be a generalized Reed-Solomon code @@ -617,12 +633,12 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) """ @@ -630,12 +646,12 @@ def _repr_(self): def _latex_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: latex(D) \textnormal{Guruswami-Sudan decoder for } [250, 70, 181] \textnormal{ Reed-Solomon Code over } \Bold{F}_{251}\textnormal{ decoding }97\textnormal{ errors with parameters }(1, 2) """ @@ -648,8 +664,8 @@ def __eq__(self, other): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D1 = C.decoder("GuruswamiSudan", tau = 97) - sage: D2 = C.decoder("GuruswamiSudan", tau = 97) + sage: D1 = C.decoder("GuruswamiSudan", tau=97) + sage: D2 = C.decoder("GuruswamiSudan", tau=97) sage: D1.__eq__(D2) True """ @@ -663,7 +679,7 @@ def __eq__(self, other): def interpolation_algorithm(self): r""" - Returns the interpolation algorithm that will be used. + Return the interpolation algorithm that will be used. Remember that its signature has to be: ``my_inter(interpolation_points, tau, s_and_l, wy)``. @@ -673,7 +689,7 @@ def interpolation_algorithm(self): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.interpolation_algorithm() """ @@ -681,7 +697,7 @@ def interpolation_algorithm(self): def rootfinding_algorithm(self): r""" - Returns the rootfinding algorithm that will be used. + Return the rootfinding algorithm that will be used. Remember that its signature has to be: ``my_rootfinder(Q, maxd=default_value, precision=default_value)``. @@ -691,7 +707,7 @@ def rootfinding_algorithm(self): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.rootfinding_algorithm() """ @@ -699,12 +715,12 @@ def rootfinding_algorithm(self): def parameters(self): r""" - Returns the multiplicity and list size parameters of ``self``. + Return the multiplicity and list size parameters of ``self``. EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.parameters() (1, 2) """ @@ -712,12 +728,12 @@ def parameters(self): def multiplicity(self): r""" - Returns the multiplicity parameter of ``self``. + Return the multiplicity parameter of ``self``. EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.multiplicity() 1 """ @@ -725,12 +741,12 @@ def multiplicity(self): def list_size(self): r""" - Returns the list size parameter of ``self``. + Return the list size parameter of ``self``. EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.list_size() 2 """ @@ -749,8 +765,9 @@ def decode_to_message(self, r): EXAMPLES:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: C = codes.GeneralizedReedSolomonCode(GF(17).list()[:15], 6) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau=5) + sage: D = GSD(C, tau=5) sage: F. = GF(17)[] sage: m = 13*x^4 + 7*x^3 + 10*x^2 + 14*x + 3 sage: c = D.connected_encoder().encode(m) @@ -769,7 +786,7 @@ def decode_to_message(self, r): does not fit the allowed signature, an exception will be raised:: sage: C = codes.GeneralizedReedSolomonCode(GF(17).list()[:15], 6) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau=5, root_finder=next_prime) + sage: D = GSD(C, tau=5, root_finder=next_prime) sage: F. = GF(17)[] sage: m = 9*x^5 + 10*x^4 + 9*x^3 + 7*x^2 + 15*x + 2 sage: c = D.connected_encoder().encode(m) @@ -777,7 +794,8 @@ def decode_to_message(self, r): sage: m in D.decode_to_message(r) Traceback (most recent call last): ... - ValueError: The provided root-finding algorithm has a wrong signature. See the documentation of `codes.decoders.GRSGuruswamiSudanDecoder.rootfinding_algorithm()` for details + ValueError: The provided root-finding algorithm has a wrong signature. + See the documentation of `GSD.rootfinding_algorithm()` for details """ return [self.connected_encoder().unencode(c) for c in self.decode_to_code(r)] @@ -792,8 +810,9 @@ def decode_to_code(self, r): EXAMPLES:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: C = codes.GeneralizedReedSolomonCode(GF(17).list()[:15], 6) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau=5) + sage: D = GSD(C, tau=5) sage: c = vector(GF(17), [3,13,12,0,0,7,5,1,8,11,1,9,4,12,14]) sage: c in C True @@ -811,7 +830,7 @@ def decode_to_code(self, r): Check that :trac:`21347` is fixed:: sage: C = codes.GeneralizedReedSolomonCode(GF(13).list()[:10], 3) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 4) + sage: D = GSD(C, tau=4) sage: c = vector(GF(13), [6, 8, 2, 1, 5, 1, 2, 8, 6, 9]) sage: e = vector(GF(13), [1, 0, 0, 1, 1, 0, 0, 1, 0, 1]) sage: D.decode_to_code(c+e) @@ -847,19 +866,19 @@ def decode_to_code(self, r): def decoding_radius(self): r""" - Returns the maximal number of errors that ``self`` is able to correct. + Return the maximal number of errors that ``self`` is able to correct. EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.decoding_radius() 97 An example where tau is not one of the inputs to the constructor:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", parameters = (2,4)) + sage: D = C.decoder("GuruswamiSudan", parameters=(2,4)) sage: D.decoding_radius() 105 """ diff --git a/src/sage/coding/guruswami_sudan/interpolation.py b/src/sage/coding/guruswami_sudan/interpolation.py index af150b460c6..8625bae5b49 100644 --- a/src/sage/coding/guruswami_sudan/interpolation.py +++ b/src/sage/coding/guruswami_sudan/interpolation.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings """ Interpolation algorithms for the Guruswami-Sudan decoder @@ -174,6 +175,7 @@ def _interpolation_matrix_problem(points, tau, parameters, wy): - ``tau`` -- an integer, the number of errors one wants to decode. - ``parameters`` -- (default: ``None``) a pair of integers, where: + - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and - the second integer is the list size parameter. @@ -222,10 +224,10 @@ def _interpolation_matrix_problem(points, tau, parameters, wy): def gs_interpolation_linalg(points, tau, parameters, wy): r""" - Compute an interpolation polynomial Q(x,y) for the Guruswami-Sudan algorithm + Compute an interpolation polynomial `Q(x,y)` for the Guruswami-Sudan algorithm by solving a linear system of equations. - ``Q`` is a bivariate polynomial over the field of the points, such that the + `Q` is a bivariate polynomial over the field of the points, such that the polynomial has a zero of multiplicity at least `s` at each of the points, where `s` is the multiplicity parameter. Furthermore, its ``(1, wy)``-weighted degree should be less than @@ -240,11 +242,13 @@ def gs_interpolation_linalg(points, tau, parameters, wy): - ``tau`` -- an integer, the number of errors one wants to decode. - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and - - the second integer is the list size parameter. - - ``wy`` -- an integer, the `y`-weight, where we seek ``Q`` of low - ``(1,wy)`` weighted degree. + - the first integer is the multiplicity parameter of Guruswami-Sudan + algorithm and + - the second integer is the list size parameter. + + - ``wy`` -- an integer, the `y`-weight, where we seek `Q` of low + ``(1, wy)``-weighted degree. EXAMPLES: @@ -253,12 +257,14 @@ def gs_interpolation_linalg(points, tau, parameters, wy): sage: from sage.coding.guruswami_sudan.interpolation import gs_interpolation_linalg sage: F = GF(11) - sage: points = [(F(x),F(y)) for (x,y) in [(0, 5), (1, 1), (2, 4), (3, 6), (4, 3), (5, 3)]] + sage: points = [(F(x), F(y)) + ....: for (x, y) in [(0, 5), (1, 1), (2, 4), (3, 6), (4, 3), (5, 3)]] sage: tau = 3 sage: params = (2, 4) sage: wy = 1 sage: Q = gs_interpolation_linalg(points, tau, params, wy); Q - 4*x^5 - 4*x^4*y - 2*x^2*y^3 - x*y^4 + 3*x^4 - 4*x^2*y^2 + 5*y^4 - x^3 + x^2*y + 5*x*y^2 - 5*y^3 + 3*x*y - 2*y^2 + x - 4*y + 1 + 4*x^5 - 4*x^4*y - 2*x^2*y^3 - x*y^4 + 3*x^4 - 4*x^2*y^2 + 5*y^4 - x^3 + x^2*y + + 5*x*y^2 - 5*y^3 + 3*x*y - 2*y^2 + x - 4*y + 1 We verify that the interpolation polynomial has a zero of multiplicity at least 2 in each point:: @@ -286,7 +292,7 @@ def gs_interpolation_linalg(points, tau, parameters, wy): def lee_osullivan_module(points, parameters, wy): r""" - Returns the analytically straight-forward basis for the `\GF q[x]` module + Return the analytically straight-forward basis for the `\GF{q}[x]` module containing all interpolation polynomials, as according to Lee and O'Sullivan. @@ -294,7 +300,7 @@ def lee_osullivan_module(points, parameters, wy): interpolation polynomial through the sought interpolation points `(x_i, y_i)`, i.e. `R(x_i) = y_i`. Let `G(x) = \prod_{i=1}^n (x-x_i)`. Then the `i`'th row of the basis matrix of the module is the coefficient-vector of - the following polynomial in `\GF q[x][y]`: + the following polynomial in `\GF{q}[x][y]`: `P_i(x,y) = G(x)^{[i-s]} (y - R(x))^{i - [i-s]} y^{[i-s]}` , @@ -305,22 +311,24 @@ def lee_osullivan_module(points, parameters, wy): INPUT: - - ``points`` -- a list of tuples ``(xi, yi)`` such that we seek ``Q`` with - ``(xi,yi)`` being a root of ``Q`` with multiplicity ``s``. + - ``points`` -- a list of tuples ``(xi, yi)`` such that we seek `Q` with + ``(xi,yi)`` being a root of `Q` with multiplicity `s`. - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter `s` of Guruswami-Sudan algorithm and - - the second integer is the list size parameter. - - ``wy`` -- an integer, the `y`-weight, where we seek ``Q`` of low + - the first integer is the multiplicity parameter `s` of Guruswami-Sudan + algorithm and + - the second integer is the list size parameter. + + - ``wy`` -- an integer, the `y`-weight, where we seek `Q` of low ``(1,wy)`` weighted degree. EXAMPLES:: sage: from sage.coding.guruswami_sudan.interpolation import lee_osullivan_module sage: F = GF(11) - sage: points = [(F(0), F(2)), (F(1), F(5)), (F(2), F(0)), (F(3), F(4)), (F(4), F(9))\ - , (F(5), F(1)), (F(6), F(9)), (F(7), F(10))] + sage: points = [(F(0), F(2)), (F(1), F(5)), (F(2), F(0)), (F(3), F(4)), + ....: (F(4), F(9)), (F(5), F(1)), (F(6), F(9)), (F(7), F(10))] sage: params = (1, 1) sage: wy = 1 sage: lee_osullivan_module(points, params, wy) @@ -363,8 +371,10 @@ def gs_interpolation_lee_osullivan(points, tau, parameters, wy): - ``tau`` -- an integer, the number of errors one wants to decode. - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and - - the second integer is the list size parameter. + + - the first integer is the multiplicity parameter of Guruswami-Sudan + algorithm and + - the second integer is the list size parameter. - ``wy`` -- an integer, the `y`-weight, where we seek ``Q`` of low ``(1,wy)`` weighted degree. @@ -373,13 +383,13 @@ def gs_interpolation_lee_osullivan(points, tau, parameters, wy): sage: from sage.coding.guruswami_sudan.interpolation import gs_interpolation_lee_osullivan sage: F = GF(11) - sage: points = [(F(0), F(2)), (F(1), F(5)), (F(2), F(0)), (F(3), F(4)), (F(4), F(9))\ - , (F(5), F(1)), (F(6), F(9)), (F(7), F(10))] + sage: points = [(F(0), F(2)), (F(1), F(5)), (F(2), F(0)), (F(3), F(4)), + ....: (F(4), F(9)), (F(5), F(1)), (F(6), F(9)), (F(7), F(10))] sage: tau = 1 sage: params = (1, 1) sage: wy = 1 sage: Q = gs_interpolation_lee_osullivan(points, tau, params, wy) - sage: Q / Q.lc() # make monic + sage: Q / Q.lc() # make monic x^3*y + 2*x^3 - x^2*y + 5*x^2 + 5*x*y - 5*x + 2*y - 4 """ from .utils import _degree_of_vector diff --git a/src/sage/coding/guruswami_sudan/utils.py b/src/sage/coding/guruswami_sudan/utils.py index d53637d933f..d899bd0e12e 100644 --- a/src/sage/coding/guruswami_sudan/utils.py +++ b/src/sage/coding/guruswami_sudan/utils.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Guruswami-Sudan utility methods diff --git a/src/sage/coding/hamming_code.py b/src/sage/coding/hamming_code.py index cf355c2431f..5209a0c3754 100644 --- a/src/sage/coding/hamming_code.py +++ b/src/sage/coding/hamming_code.py @@ -1,7 +1,8 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Hamming codes -Given an integer `r` and a field `F`, such that `F=GF(q)`, the `[n, k, d]` code +Given an integer `r` and a field `F`, such that `F=\GF{q}`, the `[n, k, d]` code with length `n=\frac{q^{r}-1}{q-1}`, dimension `k=\frac{q^{r}-1}{q-1} - r` and minimum distance `d=3` is called the Hamming Code of order `r`. diff --git a/src/sage/coding/information_set_decoder.py b/src/sage/coding/information_set_decoder.py index fb4612fa69b..5c1b24d2aec 100644 --- a/src/sage/coding/information_set_decoder.py +++ b/src/sage/coding/information_set_decoder.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Information-set decoding for linear codes @@ -96,7 +96,8 @@ class InformationSetAlgorithm(SageObject): sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: LeeBrickellISDAlgorithm(codes.GolayCode(GF(2)), (0,4)) - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 4 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding up to 4 errors A minimal working example of how to sub-class:: @@ -112,7 +113,8 @@ class InformationSetAlgorithm(SageObject): ....: # decoding algorithm here ....: raise DecodingError("I failed") sage: MinimalISD(codes.GolayCode(GF(2)), (0,4)) - ISD Algorithm (MinimalISD) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 4 errors + ISD Algorithm (MinimalISD) for [24, 12, 8] Extended Golay code over GF(2) + decoding up to 4 errors """ def __init__(self, code, decoding_interval, algorithm_name, parameters = None): @@ -355,7 +357,7 @@ class LeeBrickellISDAlgorithm(InformationSetAlgorithm): This implements the Lee-Brickell variant of ISD, see [LB1988]_ for the original binary case, and [Pet2010]_ for the `q`-ary extension. - Let `C` be a `[n, k]`-linear code over `GF(q)`, and let `r \in GF(q)^{n}` be + Let `C` be a `[n, k]`-linear code over `\GF{q}`, and let `r \in \GF{q}^{n}` be a received word in a transmission. We seek the codeword whose Hamming distance from `r` is minimal. Let `p` and `w` be integers, such that `0\leq p\leq w`, Let `G` be a generator matrix of `C`, and for any set of indices @@ -363,10 +365,10 @@ class LeeBrickellISDAlgorithm(InformationSetAlgorithm): `I`. The Lee-Brickell ISD loops the following until it is successful: 1. Choose an information set `I` of `C`. - 2. Compute `r' = r - r_{I}\times G_I^{-1} \times G` + 2. Compute `r' = r - r_{I} G_I^{-1} G` 3. Consider every size-`p` subset of `I`, `\{a_1, \dots, a_p\}`. - For each `m = (m_1, \dots, m_p) \in GF(q)^{p}`, compute - the error vector `e = r' - \sum_{i=1}^{p} m_i\times g_{a_i}`, + For each `m = (m_1, \dots, m_p) \in \GF{q}^{p}`, compute + the error vector `e = r' - \sum_{i=1}^{p} m_i g_{a_i}`, 4. If `e` has a Hamming weight at most `w`, return `r-e`. INPUT: @@ -388,11 +390,13 @@ class LeeBrickellISDAlgorithm(InformationSetAlgorithm): sage: C = codes.GolayCode(GF(2)) sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: A = LeeBrickellISDAlgorithm(C, (0,4)); A - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 4 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding up to 4 errors sage: C = codes.GolayCode(GF(2)) sage: A = LeeBrickellISDAlgorithm(C, (2,3)); A - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding between 2 and 3 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding between 2 and 3 errors """ def __init__(self, code, decoding_interval, search_size = None): r""" @@ -525,7 +529,8 @@ def calibrate(self): sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: C = codes.GolayCode(GF(2)) sage: A = LeeBrickellISDAlgorithm(C, (0,3)); A - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 3 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding up to 3 errors sage: A.calibrate() sage: A.parameters() #random {'search_size': 1} @@ -535,7 +540,8 @@ def calibrate(self): If we specify the parameter at construction time, calibrate does not override this choice:: sage: A = LeeBrickellISDAlgorithm(C, (0,3), search_size=2); A - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 3 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding up to 3 errors sage: A.parameters() {'search_size': 2} sage: A.calibrate() @@ -693,16 +699,19 @@ class LinearCodeInformationSetDecoder(Decoder): sage: C = codes.GolayCode(GF(3)) sage: D = C.decoder("InformationSet", 2); D - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors You can specify which algorithm you wish to use, and you should do so in order to pass special parameters to it:: sage: C = codes.GolayCode(GF(3)) sage: D2 = C.decoder("InformationSet", 2, algorithm="Lee-Brickell", search_size=2); D2 - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors sage: D2.algorithm() - ISD Algorithm (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + ISD Algorithm (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors sage: D2.algorithm().parameters() {'search_size': 2} @@ -711,7 +720,8 @@ class LinearCodeInformationSetDecoder(Decoder): sage: C.decoder("InformationSet", 2, algorithm="NoSuchThing") Traceback (most recent call last): ... - ValueError: Unknown ISD algorithm 'NoSuchThing'. The known algorithms are ['Lee-Brickell']. + ValueError: Unknown ISD algorithm 'NoSuchThing'. + The known algorithms are ['Lee-Brickell']. You can also construct an ISD algorithm separately and pass that. This is mostly useful if you write your own ISD algorithms:: @@ -719,7 +729,8 @@ class LinearCodeInformationSetDecoder(Decoder): sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: A = LeeBrickellISDAlgorithm(C, (0, 2)) sage: D = C.decoder("InformationSet", 2, algorithm=A); D - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors When passing an already constructed ISD algorithm, you can't also pass parameters to the ISD algorithm when constructing the decoder:: @@ -727,22 +738,26 @@ class LinearCodeInformationSetDecoder(Decoder): sage: C.decoder("InformationSet", 2, algorithm=A, search_size=2) Traceback (most recent call last): ... - ValueError: ISD algorithm arguments are not allowed when supplying a constructed ISD algorithm + ValueError: ISD algorithm arguments are not allowed + when supplying a constructed ISD algorithm We can also information-set decode non-binary codes:: sage: C = codes.GolayCode(GF(3)) sage: D = C.decoder("InformationSet", 2); D - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors There are two other ways to access this class:: sage: D = codes.decoders.LinearCodeInformationSetDecoder(C, 2); D - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors sage: from sage.coding.information_set_decoder import LinearCodeInformationSetDecoder sage: D = LinearCodeInformationSetDecoder(C, 2); D - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors """ def __init__(self, code, number_errors, algorithm=None, **kwargs): r""" @@ -889,7 +904,8 @@ def algorithm(self): sage: C = codes.GolayCode(GF(2)) sage: D = C.decoder("InformationSet", (2,4), "Lee-Brickell") sage: D.algorithm() - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding between 2 and 4 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding between 2 and 4 errors """ return self._algorithm diff --git a/src/sage/coding/kasami_codes.pyx b/src/sage/coding/kasami_codes.pyx index 8212ae29ded..4c35ed34e33 100644 --- a/src/sage/coding/kasami_codes.pyx +++ b/src/sage/coding/kasami_codes.pyx @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Kasami code @@ -9,10 +9,10 @@ The extended Kasami code with parameters `(s,t)` is defined as .. MATH:: - \{ v \in GF(2)^s \mid - \sum_{a \in GF(s)} v_a = - \sum_{a \in GF(s)} a v_a = - \sum_{a \in GF(s)} a^{t+1} v_a = 0 \} + \{ v \in \GF{2}^s \mid + \sum_{a \in \GF{s}} v_a = + \sum_{a \in \GF{s}} a v_a = + \sum_{a \in \GF{s}} a^{t+1} v_a = 0 \} It follows that these are subfield subcodes of the code having those three @@ -73,16 +73,16 @@ class KasamiCode(AbstractLinearCode): .. MATH:: - \{ v \in GF(2)^s \mid - \sum_{a \in GF(s)} v_a = - \sum_{a \in GF(s)} a v_a = - \sum_{a \in GF(s)} a^{t+1} v_a = 0 \} + \{ v \in \GF{2}^s \mid + \sum_{a \in \GF{s}} v_a = + \sum_{a \in \GF{s}} a v_a = + \sum_{a \in \GF{s}} a^{t+1} v_a = 0 \} The only valid parameters `s,t` are given by the below, where `q` is a power of 2: - * `s = q^{2j+1}`, `t = q^m` with `m \leq j` and `\gcd(m,2j+1) = 1` - * `s = q^2`, `t=q` + * `s = q^{2j+1}`, `t = q^m` with `m \leq j` and `\gcd(m,2j+1) = 1` + * `s = q^2`, `t=q` The Kasami code `(s,t)` is obtained from the extended Kasami code `(s,t)`, via truncation of all words. @@ -294,7 +294,7 @@ class KasamiCode(AbstractLinearCode): We build the parity check matrix given by the three equations that the codewords must satisfy. Then we generate the parity check matrix - over `GF(2)` and from this the obtain the generator matrix for the + over `\GF{2}` and from this the obtain the generator matrix for the extended Kasami codes. For the Kasami codes, we truncate the last column. diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index b03ef5116ba..ae80ec10894 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Generic structures for linear codes over the Hamming metric @@ -217,12 +217,10 @@ class should inherit from this class. Also ``AbstractLinearCode`` should never from sage.combinat.subset import Subsets from sage.cpython.string import bytes_to_str from sage.features.gap import GapPackage -from sage.groups.perm_gps.permgroup_named import SymmetricGroup -from sage.groups.perm_gps.permgroup import PermutationGroup -from sage.interfaces.gap import gap from sage.matrix.matrix_space import MatrixSpace from sage.misc.cachefunc import cached_method from sage.misc.functional import is_even +from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod from sage.misc.randstate import current_randstate from sage.modules.free_module import VectorSpace @@ -233,6 +231,11 @@ class should inherit from this class. Also ``AbstractLinearCode`` should never from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import QQ +lazy_import('sage.groups.perm_gps.permgroup_named', 'SymmetricGroup') +lazy_import('sage.groups.perm_gps.permgroup', 'PermutationGroup') +lazy_import('sage.interfaces.gap', 'gap') + + # ***************************************************************************** # coding theory functions # ***************************************************************************** @@ -295,9 +298,9 @@ class AbstractLinearCode(AbstractLinearCodeNoMetric): To implement a linear code, you need to: - - inherit from AbstractLinearCode + - inherit from :class:`AbstractLinearCode` - - call AbstractLinearCode ``__init__`` method in the subclass constructor. Example: + - call :class:`AbstractLinearCode` ``__init__`` method in the subclass constructor. Example: ``super().__init__(base_field, length, "EncoderName", "DecoderName")``. By doing that, your subclass will have its ``length`` parameter initialized and will be properly set as a member of the category framework. @@ -325,7 +328,7 @@ class AbstractLinearCode(AbstractLinearCodeNoMetric): ``MyNewCodeClass`` will be able to use instances of ``MyDecoderClass``. - As AbstractLinearCode is not designed to be implemented, it does not have any representation + As the class :class:`AbstractLinearCode` is not designed to be instantiated, it does not have any representation methods. You should implement ``_repr_`` and ``_latex_`` methods in the subclass. .. NOTE:: @@ -374,7 +377,8 @@ def __init__(self, base_field, length, default_encoder_name, default_decoder_nam sage: class MyCodeFamily(sage.coding.linear_code.AbstractLinearCode): ....: def __init__(self, field, length, dimension, generator_matrix): - ....: sage.coding.linear_code.AbstractLinearCode.__init__(self,field, length, "GeneratorMatrix", "Syndrome") + ....: super().__init__(field, length, + ....: "GeneratorMatrix", "Syndrome") ....: self._dimension = dimension ....: self._generator_matrix = generator_matrix ....: def generator_matrix(self): @@ -445,11 +449,11 @@ def automorphism_group_gens(self, equivalence="semilinear"): - ``equivalence`` (optional) -- which defines the acting group, either - * ``permutational`` + * ``"permutational"`` - * ``linear`` + * ``"linear"`` - * ``semilinear`` + * ``"semilinear"`` OUTPUT: @@ -462,34 +466,59 @@ def automorphism_group_gens(self, equivalence="semilinear"): depends on which packages are loaded, so we must re-seed GAP to ensure a consistent result for this example:: - sage: libgap.set_seed(0) + sage: libgap.set_seed(0) # optional - sage.libs.gap 0 sage: C = codes.HammingCode(GF(4, 'z'), 3) sage: C.automorphism_group_gens() - ([((1, 1, 1, z, z + 1, 1, 1, 1, 1, z + 1, z, z, z + 1, z + 1, z + 1, 1, z + 1, z, z, 1, z); (1,13,14,20)(2,21,8,18,7,16,19,15)(3,10,5,12,17,9,6,4), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z + 1), - ((z, 1, z, z, z, z + 1, z, z, z, z, z, z, z + 1, z, z, z, z, z + 1, z, z, z); (1,11,5,12,3,19)(2,8)(6,18,13)(7,17,15)(9,10,14,16,20,21), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z + 1), - ((z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z); (), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z)], + ([((1, 1, 1, z, z + 1, 1, 1, 1, 1, z + 1, z, z, z + 1, z + 1, + z + 1, 1, z + 1, z, z, 1, z); + (1,13,14,20)(2,21,8,18,7,16,19,15)(3,10,5,12,17,9,6,4), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z + 1), + ((z, 1, z, z, z, z + 1, z, z, z, z, z, z, z + 1, z, z, z, + z, z + 1, z, z, z); + (1,11,5,12,3,19)(2,8)(6,18,13)(7,17,15)(9,10,14,16,20,21), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z + 1), + ((z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z); + (), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z)], 362880) sage: C.automorphism_group_gens(equivalence="linear") - ([((z, 1, z + 1, z + 1, 1, z + 1, z, 1, z + 1, z + 1, 1, z, 1, z + 1, z, 1, z, 1, z + 1, 1, 1); (1,12,11,10,6,8,9,20,13,21,5,14,3,16,17,19,7,4,2,15,18), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z), - ((z + 1, z + 1, z + 1, z, 1, 1, z, z, 1, z + 1, z, 1, 1, z, 1, z + 1, z, z + 1, z + 1, 1, z); (1,3,18,2,17,6,19)(4,15,13,20,7,14,16)(5,11,8,21,12,9,10), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z), - ((z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1); (), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z)], + ([((z, 1, z + 1, z + 1, 1, z + 1, z, 1, z + 1, z + 1, 1, z, 1, z + 1, + z, 1, z, 1, z + 1, 1, 1); + (1,12,11,10,6,8,9,20,13,21,5,14,3,16,17,19,7,4,2,15,18), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z), + ((z + 1, z + 1, z + 1, z, 1, 1, z, z, 1, z + 1, z, 1, 1, z, 1, z + 1, + z, z + 1, z + 1, 1, z); + (1,3,18,2,17,6,19)(4,15,13,20,7,14,16)(5,11,8,21,12,9,10), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z), + ((z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, + z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1); + (), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z)], 181440) sage: C.automorphism_group_gens(equivalence="permutational") - ([((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (1,11)(3,10)(4,9)(5,7)(12,21)(14,20)(15,19)(16,17), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z), - ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (2,18)(3,19)(4,10)(5,16)(8,13)(9,14)(11,21)(15,20), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z), - ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (1,19)(3,17)(4,21)(5,20)(7,14)(9,12)(10,16)(11,15), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z), - ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (2,13)(3,14)(4,20)(5,11)(8,18)(9,19)(10,15)(16,21), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z)], + ([((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + (1,11)(3,10)(4,9)(5,7)(12,21)(14,20)(15,19)(16,17), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z), + ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + (2,18)(3,19)(4,10)(5,16)(8,13)(9,14)(11,21)(15,20), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z), + ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + (1,19)(3,17)(4,21)(5,20)(7,14)(9,12)(10,16)(11,15), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z), + ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + (2,13)(3,14)(4,20)(5,11)(8,18)(9,19)(10,15)(16,21), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z)], 64) """ aut_group_can_label = self._canonize(equivalence) @@ -549,7 +578,7 @@ def assmus_mattson_designs(self, t, mode=None): `C=C^*` in this case, so this info is extraneous). The test fails to produce 6-designs (ie, the hypotheses of the theorem fail to hold, not that the 6-designs definitely don't exist). The command - assmus_mattson_designs(C,5,mode="verbose") returns the same value + ``assmus_mattson_designs(C,5,mode="verbose")`` returns the same value but prints out more detailed information. The second example below illustrates the blocks of the 5-(24, 8, 1) @@ -559,17 +588,14 @@ def assmus_mattson_designs(self, t, mode=None): sage: C = codes.GolayCode(GF(2)) # example 1 sage: C.assmus_mattson_designs(5) - ['weights from C: ', - [8, 12, 16, 24], - 'designs from C: ', - [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)], [5, (24, 24, 1)]], - 'weights from C*: ', - [8, 12, 16], - 'designs from C*: ', - [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)]]] + ['weights from C: ', [8, 12, 16, 24], + 'designs from C: ', [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)], + [5, (24, 24, 1)]], + 'weights from C*: ', [8, 12, 16], + 'designs from C*: ', [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)]]] sage: C.assmus_mattson_designs(6) 0 - sage: X = range(24) # example 2 + sage: X = range(24) # example 2 sage: blocks = [c.support() for c in C if c.hamming_weight()==8]; len(blocks) # long time computation 759 """ @@ -619,7 +645,7 @@ def binomial_moment(self, i): where `k_S` is the dimension of the shortened code `C_{J-S}`, `J=[1,2,...,n]`. (The normalized binomial moment is - `b_i(C) = \binom(n,d+i)^{-1}B_{d+i}(C)`.) In other words, `C_{J-S}` + `b_i(C) = \binom{n}{d+i})^{-1}B_{d+i}(C)`.) In other words, `C_{J-S}` is isomorphic to the subcode of C of codewords supported on S. EXAMPLES:: @@ -717,11 +743,11 @@ def canonical_representative(self, equivalence="semilinear"): - ``equivalence`` (optional) -- which defines the acting group, either - * ``permutational`` + * ``"permutational"`` - * ``linear`` + * ``"linear"`` - * ``semilinear`` + * ``"semilinear"`` OUTPUT: @@ -892,7 +918,8 @@ def covering_radius(self): sage: C.covering_radius() # optional - gap_packages (Guava package) Traceback (most recent call last): ... - NotImplementedError: the GAP algorithm that Sage is using is limited to computing with fields of size at most 256 + NotImplementedError: the GAP algorithm that Sage is using + is limited to computing with fields of size at most 256 """ from sage.libs.gap.libgap import libgap GapPackage("guava", spkg="gap_packages").require() @@ -919,7 +946,7 @@ def divisor(self): sage: C = codes.GolayCode(GF(2)) sage: C.divisor() # Type II self-dual 4 - sage: C = codes.QuadraticResidueCodeEvenPair(17,GF(2))[0] + sage: C = codes.QuadraticResidueCodeEvenPair(17, GF(2))[0] sage: C.divisor() 2 """ @@ -952,7 +979,7 @@ def is_projective(self): A non-projective code:: - sage: C = codes.LinearCode(matrix(GF(2),[[1,0,1],[1,1,1]])) + sage: C = codes.LinearCode(matrix(GF(2), [[1,0,1],[1,1,1]])) sage: C.is_projective() False """ @@ -1065,23 +1092,23 @@ def product_code(self, other): Note that the two codes have to be over the same field. - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C - [7, 4] Hamming Code over GF(2) - sage: D = codes.ReedMullerCode(GF(2), 2, 2) - sage: D - Binary Reed-Muller Code of order 2 and number of variables 2 - sage: A = C.product_code(D) - sage: A - [28, 16] linear code over GF(2) - sage: A.length() == C.length()*D.length() - True - sage: A.dimension() == C.dimension()*D.dimension() - True - sage: A.minimum_distance() == C.minimum_distance()*D.minimum_distance() - True + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C + [7, 4] Hamming Code over GF(2) + sage: D = codes.ReedMullerCode(GF(2), 2, 2) + sage: D + Binary Reed-Muller Code of order 2 and number of variables 2 + sage: A = C.product_code(D) + sage: A + [28, 16] linear code over GF(2) + sage: A.length() == C.length()*D.length() + True + sage: A.dimension() == C.dimension()*D.dimension() + True + sage: A.minimum_distance() == C.minimum_distance()*D.minimum_distance() + True """ G1 = self.generator_matrix() @@ -1102,29 +1129,29 @@ def construction_x(self, other, aux): The method will then return a `[n+n_a, k_1, d_a+d_1]` linear code. - EXAMPLES:: - - sage: C = codes.BCHCode(GF(2),15,7) - sage: C - [15, 5] BCH Code over GF(2) with designed distance 7 - sage: D = codes.BCHCode(GF(2),15,5) - sage: D - [15, 7] BCH Code over GF(2) with designed distance 5 - sage: C.is_subcode(D) - True - sage: C.minimum_distance() - 7 - sage: D.minimum_distance() - 5 - sage: aux = codes.HammingCode(GF(2),2) - sage: aux = aux.dual_code() - sage: aux.minimum_distance() - 2 - sage: Cx = D.construction_x(C,aux) - sage: Cx - [18, 7] linear code over GF(2) - sage: Cx.minimum_distance() - 7 + EXAMPLES:: + + sage: C = codes.BCHCode(GF(2),15,7) + sage: C + [15, 5] BCH Code over GF(2) with designed distance 7 + sage: D = codes.BCHCode(GF(2),15,5) + sage: D + [15, 7] BCH Code over GF(2) with designed distance 5 + sage: C.is_subcode(D) + True + sage: C.minimum_distance() + 7 + sage: D.minimum_distance() + 5 + sage: aux = codes.HammingCode(GF(2),2) + sage: aux = aux.dual_code() + sage: aux.minimum_distance() + 2 + sage: Cx = D.construction_x(C,aux) + sage: Cx + [18, 7] linear code over GF(2) + sage: Cx.minimum_distance() + 7 """ if not other.is_subcode(self): raise ValueError("%s is not a subcode of %s" % (self, other)) @@ -1150,12 +1177,12 @@ def construction_x(self, other, aux): def extended_code(self): r""" - Return `self` as an extended code. + Return ``self`` as an extended code. See documentation of :class:`sage.coding.extended_code.ExtendedCode` for details. - EXAMPLES:: + EXAMPLES:: sage: C = codes.HammingCode(GF(4,'a'), 3) sage: C @@ -1245,14 +1272,14 @@ def is_permutation_equivalent(self,other,algorithm=None): EXAMPLES:: sage: P. = PolynomialRing(GF(2),"x") - sage: g = x^3+x+1 - sage: C1 = codes.CyclicCode(length = 7, generator_pol = g); C1 + sage: g = x^3 + x + 1 + sage: C1 = codes.CyclicCode(length=7, generator_pol=g); C1 [7, 4] Cyclic Code over GF(2) sage: C2 = codes.HammingCode(GF(2), 3); C2 [7, 4] Hamming Code over GF(2) sage: C1.is_permutation_equivalent(C2) True - sage: C1.is_permutation_equivalent(C2,algorithm="verbose") + sage: C1.is_permutation_equivalent(C2, algorithm="verbose") (True, (3,4)(5,7,6)) sage: C1 = codes.random_linear_code(GF(2), 10, 5) sage: C2 = codes.random_linear_code(GF(3), 10, 5) @@ -1323,9 +1350,11 @@ def minimum_distance(self, algorithm=None): INPUT: - ``algorithm`` -- (default: ``None``) the name of the algorithm to use - to perform minimum distance computation. If set to ``None``, - GAP methods will be used. ``algorithm`` can be: - - ``"Guava"``, which will use optional GAP package Guava + to perform minimum distance computation. ``algorithm`` can be: + + - ``None``, to use GAP methods (but not Guava) + + - ``"Guava"``, to use the optional GAP package Guava OUTPUT: @@ -1342,9 +1371,9 @@ def minimum_distance(self, algorithm=None): If ``algorithm`` is provided, then the minimum distance will be recomputed even if there is a stored value from a previous run.:: - sage: C.minimum_distance(algorithm="gap") + sage: C.minimum_distance(algorithm="gap") # optional - sage.libs.gap 3 - sage: libgap.SetAllInfoLevels(0) # to suppress extra info messages + sage: libgap.SetAllInfoLevels(0) # to suppress extra info messages # optional - sage.libs.gap sage: C.minimum_distance(algorithm="guava") # optional - gap_packages (Guava package) ... 3 @@ -1474,10 +1503,11 @@ def module_composition_factors(self, gp): EXAMPLES:: sage: MS = MatrixSpace(GF(2),4,8) - sage: G = MS([[1,0,0,0,1,1,1,0],[0,1,1,1,0,0,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,1,0,0]]) + sage: G = MS([[1,0,0,0,1,1,1,0], [0,1,1,1,0,0,0,0], + ....: [0,0,0,0,0,0,0,1], [0,0,0,0,0,1,0,0]]) sage: C = LinearCode(G) sage: gp = C.permutation_automorphism_group() - sage: C.module_composition_factors(gp) + sage: C.module_composition_factors(gp) # optional - sage.libs.gap [ rec( IsIrreducible := true, IsOverFiniteField := true, @@ -1535,15 +1565,16 @@ def permutation_automorphism_group(self, algorithm="partition"): EXAMPLES:: sage: MS = MatrixSpace(GF(2),4,8) - sage: G = MS([[1,0,0,0,1,1,1,0],[0,1,1,1,0,0,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,1,0,0]]) + sage: G = MS([[1,0,0,0,1,1,1,0], [0,1,1,1,0,0,0,0], + ....: [0,0,0,0,0,0,0,1], [0,0,0,0,0,1,0,0]]) sage: C = LinearCode(G) sage: C [8, 4] linear code over GF(2) - sage: G = C.permutation_automorphism_group() - sage: G.order() + sage: G = C.permutation_automorphism_group() # optional - sage.groups + sage: G.order() # optional - sage.groups 144 - sage: GG = C.permutation_automorphism_group("codecan") - sage: GG == G + sage: GG = C.permutation_automorphism_group("codecan") # optional - sage.groups + sage: GG == G # optional - sage.groups True A less easy example involves showing that the permutation @@ -1553,42 +1584,44 @@ def permutation_automorphism_group(self, algorithm="partition"): :: sage: C = codes.GolayCode(GF(3)) - sage: M11 = MathieuGroup(11) - sage: M11.order() + sage: M11 = MathieuGroup(11) # optional - sage.groups + sage: M11.order() # optional - sage.groups 7920 - sage: G = C.permutation_automorphism_group() # long time (6s on sage.math, 2011) - sage: G.is_isomorphic(M11) # long time + sage: G = C.permutation_automorphism_group() # long time (6s on sage.math, 2011) # optional - sage.groups + sage: G.is_isomorphic(M11) # long time # optional - sage.groups True - sage: GG = C.permutation_automorphism_group("codecan") # long time - sage: GG == G # long time + sage: GG = C.permutation_automorphism_group("codecan") # long time # optional - sage.groups + sage: GG == G # long time # optional - sage.groups True Other examples:: sage: C = codes.GolayCode(GF(2)) - sage: G = C.permutation_automorphism_group() - sage: G.order() + sage: G = C.permutation_automorphism_group() # optional - sage.groups + sage: G.order() # optional - sage.groups 244823040 sage: C = codes.HammingCode(GF(2), 5) - sage: G = C.permutation_automorphism_group() - sage: G.order() + sage: G = C.permutation_automorphism_group() # optional - sage.groups + sage: G.order() # optional - sage.groups 9999360 sage: C = codes.HammingCode(GF(3), 2); C [4, 2] Hamming Code over GF(3) - sage: C.permutation_automorphism_group(algorithm="partition") + sage: C.permutation_automorphism_group(algorithm="partition") # optional - sage.groups Permutation Group with generators [(1,3,4)] sage: C = codes.HammingCode(GF(4,"z"), 2); C [5, 3] Hamming Code over GF(4) - sage: G = C.permutation_automorphism_group(algorithm="partition"); G + sage: G = C.permutation_automorphism_group(algorithm="partition"); G # optional - sage.groups Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)] - sage: GG = C.permutation_automorphism_group(algorithm="codecan") # long time - sage: GG == G # long time + sage: GG = C.permutation_automorphism_group(algorithm="codecan") # long time, optional - sage.groups + sage: GG == G # long time, optional - sage.groups True - sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_packages (Guava package) + sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_packages (Guava package) sage.groups Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)] sage: C = codes.GolayCode(GF(3), True) - sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_packages (Guava package) - Permutation Group with generators [(5,7)(6,11)(8,9)(10,12), (4,6,11)(5,8,12)(7,10,9), (3,4)(6,8)(9,11)(10,12), (2,3)(6,11)(8,12)(9,10), (1,2)(5,10)(7,12)(8,9)] + sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_packages (Guava package) sage.groups + Permutation Group with generators + [(5,7)(6,11)(8,9)(10,12), (4,6,11)(5,8,12)(7,10,9), (3,4)(6,8)(9,11)(10,12), + (2,3)(6,11)(8,12)(9,10), (1,2)(5,10)(7,12)(8,9)] However, the option ``algorithm="gap+verbose"``, will print out:: @@ -1683,7 +1716,7 @@ def punctured(self, L): INPUT: - - ``L`` - List of positions to puncture + - ``L`` -- List of positions to puncture OUTPUT: @@ -1748,7 +1781,7 @@ def shortened(self, L): INPUT: - - ``L`` - Subset of `\{1,...,n\}`, where `n` is the length of this code + - ``L`` -- Subset of `\{1,...,n\}`, where `n` is the length of this code OUTPUT: @@ -1774,8 +1807,8 @@ def weight_distribution(self, algorithm=None): INPUT: - - ``algorithm`` - (optional, default: ``None``) If set to ``"gap"``, - call GAP. If set to `"leon"`, call the option GAP package GUAVA and + - ``algorithm`` -- (optional, default: ``None``) If set to ``"gap"``, + call GAP. If set to ``"leon"``, call the option GAP package GUAVA and call a function therein by Jeffrey Leon (see warning below). If set to ``"binary"``, use an algorithm optimized for binary codes. The default is to use ``"binary"`` for binary codes and ``"gap"`` otherwise. @@ -1786,7 +1819,7 @@ def weight_distribution(self, algorithm=None): .. WARNING:: - Specifying ``algorithm = "leon"`` sometimes prints a traceback + Specifying ``algorithm="leon"`` sometimes prints a traceback related to a stack smashing error in the C library. The result appears to be computed correctly, however. It appears to run much faster than the GAP algorithm in small examples and much slower than @@ -1808,17 +1841,17 @@ def weight_distribution(self, algorithm=None): [7, 4] Hamming Code over GF(2) sage: C.weight_distribution(algorithm="leon") # optional - gap_packages (Guava package) [1, 0, 0, 7, 7, 0, 0, 1] - sage: C.weight_distribution(algorithm="gap") + sage: C.weight_distribution(algorithm="gap") # optional - sage.libs.gap [1, 0, 0, 7, 7, 0, 0, 1] sage: C.weight_distribution(algorithm="binary") [1, 0, 0, 7, 7, 0, 0, 1] sage: C = codes.HammingCode(GF(3), 3); C [13, 10] Hamming Code over GF(3) - sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") # optional - gap_packages (Guava package) + sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") # optional - gap_packages (Guava package) True sage: C = codes.HammingCode(GF(5), 2); C [6, 4] Hamming Code over GF(5) - sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") # optional - gap_packages (Guava package) + sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") # optional - gap_packages (Guava package) True sage: C = codes.HammingCode(GF(7), 2); C [8, 6] Hamming Code over GF(7) @@ -1826,7 +1859,6 @@ def weight_distribution(self, algorithm=None): True """ - from sage.libs.gap.libgap import libgap if algorithm is None: if self.base_ring().order() == 2: algorithm = "binary" @@ -1835,6 +1867,7 @@ def weight_distribution(self, algorithm=None): F = self.base_ring() n = self.length() if algorithm=="gap": + from sage.libs.gap.libgap import libgap Gmat = self.generator_matrix() q = self.base_ring().order() z = 0*libgap.Z(q)*([0]*self.length()) # GAP zero vector @@ -1848,6 +1881,7 @@ def weight_distribution(self, algorithm=None): raise NotImplementedError("The algorithm 'leon' is only implemented for q = 2,3,5,7.") # The GAP command DirectoriesPackageLibrary tells the location of the latest # version of the Guava libraries, so gives us the location of the Guava binaries too. + from sage.libs.gap.libgap import libgap guava_bin_dir = libgap.DirectoriesPackagePrograms("guava")[0].Filename("").sage() input = _dump_code_in_leon_format(self) + "::code" lines = subprocess.check_output([os.path.join(guava_bin_dir, 'wtdist'), input]) @@ -1869,7 +1903,7 @@ def weight_distribution(self, algorithm=None): def support(self): r""" Return the set of indices `j` where `A_j` is nonzero, where - `A_j` is the number of codewords in `self` of Hamming weight `j`. + `A_j` is the number of codewords in ``self`` of Hamming weight `j`. OUTPUT: @@ -1893,16 +1927,16 @@ def weight_enumerator(self, names=None, bivariate=True): Return the weight enumerator polynomial of ``self``. This is the bivariate, homogeneous polynomial in `x` and `y` whose - coefficient to `x^i y^{n-i}` is the number of codewords of `self` of - Hamming weight `i`. Here, `n` is the length of `self`. + coefficient to `x^i y^{n-i}` is the number of codewords of ``self`` of + Hamming weight `i`. Here, `n` is the length of ``self``. INPUT: - - ``names`` - (default: ``"xy"``) The names of the variables in the + - ``names`` -- (default: ``"xy"``) The names of the variables in the homogeneous polynomial. Can be given as a single string of length 2, or a single string with a comma, or as a tuple or list of two strings. - - ``bivariate`` - (default: `True`) Whether to return a bivariate, + - ``bivariate`` -- (default: ``True``) Whether to return a bivariate, homogeneous polynomial or just a univariate polynomial. If set to ``False``, then ``names`` will be interpreted as a single variable name and default to ``"x"``. @@ -1956,7 +1990,7 @@ def zeta_polynomial(self, name="T"): INPUT: - - ``name`` - String, variable name (default: ``"T"``) + - ``name`` -- String, variable name (default: ``"T"``) OUTPUT: @@ -1968,9 +2002,9 @@ def zeta_polynomial(self, name="T"): sage: C.zeta_polynomial() 2/5*T^2 + 2/5*T + 1/5 sage: C = codes.databases.best_linear_code_in_guava(6,3,GF(2)) # optional - gap_packages (Guava package) - sage: C.minimum_distance() # optional - gap_packages (Guava package) + sage: C.minimum_distance() # optional - gap_packages (Guava package) 3 - sage: C.zeta_polynomial() # optional - gap_packages (Guava package) + sage: C.zeta_polynomial() # optional - gap_packages (Guava package) 2/5*T^2 + 2/5*T + 1/5 sage: C = codes.HammingCode(GF(2), 4) sage: C.zeta_polynomial() @@ -2163,7 +2197,7 @@ class LinearCode(AbstractLinearCode): minimum distance, will use generic, slow algorithms. If you are looking for constructing a code from a more specific family, see - if the family has been implemented by investigating `codes.`. These + if the family has been implemented by investigating ``codes.``. These more specific classes use properties particular to that family to allow faster algorithms, and could also have family-specific methods. @@ -2467,7 +2501,8 @@ def generator_matrix(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C) sage: E.generator_matrix() @@ -2527,7 +2562,9 @@ class LinearCodeSyndromeDecoder(Decoder): EXAMPLES:: - sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2],[0,1,0,2,2,0,1,1,0],[0,0,1,0,2,2,2,1,2]]) + sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2], + ....: [0,1,0,2,2,0,1,1,0], + ....: [0,0,1,0,2,2,2,1,2]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C) sage: D @@ -2831,7 +2868,7 @@ def _build_lookup_table(self): def decode_to_code(self, r): r""" - Corrects the errors in ``word`` and returns a codeword. + Correct the errors in ``word`` and return a codeword. INPUT: @@ -2872,11 +2909,13 @@ def maximum_error_weight(self): Return the maximal number of errors a received word can have and for which ``self`` is guaranteed to return a most likely codeword. - Same as ``self.decoding_radius``. + Same as :meth:`decoding_radius`. EXAMPLES:: - sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2],[0,1,0,2,2,0,1,1,0],[0,0,1,0,2,2,2,1,2]]) + sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2], + ....: [0,1,0,2,2,0,1,1,0], + ....: [0,0,1,0,2,2,2,1,2]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C) sage: D.maximum_error_weight() @@ -2891,7 +2930,9 @@ def decoding_radius(self): EXAMPLES:: - sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2],[0,1,0,2,2,0,1,1,0],[0,0,1,0,2,2,2,1,2]]) + sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2], + ....: [0,1,0,2,2,0,1,1,0], + ....: [0,0,1,0,2,2,2,1,2]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C) sage: D.decoding_radius() @@ -2905,7 +2946,8 @@ def syndrome_table(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C) sage: D.syndrome_table() @@ -3000,7 +3042,8 @@ def decode_to_code(self, r): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeNearestNeighborDecoder(C) sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) @@ -3023,7 +3066,8 @@ def decoding_radius(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeNearestNeighborDecoder(C) sage: D.decoding_radius() diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index bb70d6a74c5..0cb08292699 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Generic structures for linear codes of any metric @@ -76,9 +77,9 @@ class AbstractLinearCodeNoMetric(AbstractCode, Module): :class:`sage.coding.linear_code.LinearCode`. - As AbstractLinearCodeNoMetric is not designed to be implemented, it does not - have any representation methods. You should implement ``_repr_`` and ``_latex_`` - methods in the subclass. + As the class :class:`AbstractLinearCodeNoMetric` is not designed to be + instantiated, it does not have any representation methods. You should + implement ``_repr_`` and ``_latex_`` methods in the subclass. .. WARNING:: @@ -199,7 +200,8 @@ def base_field(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], + ....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) sage: C.base_field() Finite Field of size 2 @@ -233,7 +235,7 @@ def generator_matrix(self, encoder_name=None, **kwargs): EXAMPLES:: - sage: G = matrix(GF(3),2,[1,-1,1,-1,1,1]) + sage: G = matrix(GF(3), 2, [1,-1,1,-1,1,1]) sage: code = LinearCode(G) sage: code.generator_matrix() [1 2 1] @@ -304,7 +306,7 @@ def dimension(self): EXAMPLES:: - sage: G = matrix(GF(2),[[1,0,0],[1,1,0]]) + sage: G = matrix(GF(2), [[1,0,0], [1,1,0]]) sage: C = LinearCode(G) sage: C.dimension() 2 @@ -379,7 +381,8 @@ def gens(self): sage: C = codes.HammingCode(GF(2), 3) sage: C.gens() - [(1, 0, 0, 0, 0, 1, 1), (0, 1, 0, 0, 1, 0, 1), (0, 0, 1, 0, 1, 1, 0), (0, 0, 0, 1, 1, 1, 1)] + [(1, 0, 0, 0, 0, 1, 1), (0, 1, 0, 0, 1, 0, 1), + (0, 0, 1, 0, 1, 1, 0), (0, 0, 0, 1, 1, 1, 1)] """ return self.generator_matrix().rows() @@ -659,8 +662,8 @@ def information_set(self): EXAMPLES:: - sage: G = matrix(GF(3),2,[1,2,0,\ - 2,1,1]) + sage: G = matrix(GF(3),2,[1,2,0, + ....: 2,1,1]) sage: code = LinearCode(G) sage: code.systematic_generator_matrix() [1 2 0] @@ -677,7 +680,7 @@ def is_information_set(self, positions): INPUT: - A list of positions, i.e. integers in the range 0 to `n-1` where `n` - is the length of `self`. + is the length of ``self``. OUTPUT: @@ -686,8 +689,8 @@ def is_information_set(self, positions): EXAMPLES:: - sage: G = matrix(GF(3),2,[1,2,0,\ - 2,1,1]) + sage: G = matrix(GF(3),2,[1,2,0, + ....: 2,1,1]) sage: code = LinearCode(G) sage: code.is_information_set([0,1]) False @@ -895,8 +898,8 @@ def is_subcode(self, other): def is_permutation_automorphism(self,g): r""" - Return `1` if `g` is an element of `S_n` (`n` = length of self) and - if `g` is an automorphism of self. + Return `1` if `g` is an element of `S_n` (`n` = length of ``self``) and + if `g` is an automorphism of ``self``. EXAMPLES:: @@ -905,7 +908,8 @@ def is_permutation_automorphism(self,g): sage: C.is_permutation_automorphism(g) 0 sage: MS = MatrixSpace(GF(2),4,8) - sage: G = MS([[1,0,0,0,1,1,1,0],[0,1,1,1,0,0,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,1,0,0]]) + sage: G = MS([[1,0,0,0,1,1,1,0], [0,1,1,1,0,0,0,0], + ....: [0,0,0,0,0,0,0,1], [0,0,0,0,0,1,0,0]]) sage: C = LinearCode(G) sage: S8 = SymmetricGroup(8) sage: g = S8("(2,3)") @@ -933,7 +937,8 @@ def permuted_code(self, p): sage: C = codes.HammingCode(GF(2), 3) sage: G = C.permutation_automorphism_group(); G - Permutation Group with generators [(4,5)(6,7), (4,6)(5,7), (2,3)(6,7), (2,4)(3,5), (1,2)(5,6)] + Permutation Group with generators + [(4,5)(6,7), (4,6)(5,7), (2,3)(6,7), (2,4)(3,5), (1,2)(5,6)] sage: g = G("(2,3)(6,7)") sage: Cg = C.permuted_code(g) sage: Cg @@ -1000,7 +1005,7 @@ def is_self_orthogonal(self): sage: C.is_self_orthogonal() False sage: C = codes.QuasiQuadraticResidueCode(11) # optional - gap_packages (Guava package) - sage: C.is_self_orthogonal() # optional - gap_packages (Guava package) + sage: C.is_self_orthogonal() # optional - gap_packages (Guava package) True """ return self.is_subcode(self.dual_code()) @@ -1053,38 +1058,39 @@ class LinearCodeSystematicEncoder(Encoder): the range 0 to `n-1` where `n` is the length of the code and `k` its dimension. The 0th symbol of a message will then be at position ``systematic_positions[0]``, the 1st index at position - ``systematic_positions[1]``, etc. A ``ValueError`` is raised at + ``systematic_positions[1]``, etc. A :class:`ValueError` is raised at construction time if the supplied indices do not form an information set. EXAMPLES: The following demonstrates the basic usage of :class:`LinearCodeSystematicEncoder`:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0,0],\ - [1,0,0,1,1,0,0,0],\ - [0,1,0,1,0,1,0,0],\ - [1,1,0,1,0,0,1,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: E.generator_matrix() - [1 0 0 0 0 1 1 1] - [0 1 0 0 1 0 1 1] - [0 0 1 0 1 1 0 0] - [0 0 0 1 1 1 1 1] - sage: E2 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[5,4,3,2]) - sage: E2.generator_matrix() - [1 0 0 0 0 1 1 1] - [0 1 0 0 1 0 1 1] - [1 1 0 1 0 0 1 1] - [1 1 1 0 0 0 0 0] + sage: LCSE = codes.encoders.LinearCodeSystematicEncoder + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0,0],\ + [1,0,0,1,1,0,0,0],\ + [0,1,0,1,0,1,0,0],\ + [1,1,0,1,0,0,1,1]]) + sage: C = LinearCode(G) + sage: E = LCSE(C) + sage: E.generator_matrix() + [1 0 0 0 0 1 1 1] + [0 1 0 0 1 0 1 1] + [0 0 1 0 1 1 0 0] + [0 0 0 1 1 1 1 1] + sage: E2 = LCSE(C, systematic_positions=[5,4,3,2]) + sage: E2.generator_matrix() + [1 0 0 0 0 1 1 1] + [0 1 0 0 1 0 1 1] + [1 1 0 1 0 0 1 1] + [1 1 1 0 0 0 0 0] An error is raised if one specifies systematic positions which do not form an information set:: - sage: E3 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[0,1,6,7]) - Traceback (most recent call last): - ... - ValueError: systematic_positions are not an information set + sage: E3 = LCSE(C, systematic_positions=[0,1,6,7]) + Traceback (most recent call last): + ... + ValueError: systematic_positions are not an information set We exemplify how to use :class:`LinearCodeSystematicEncoder` as the default @@ -1092,7 +1098,7 @@ class LinearCodeSystematicEncoder(Encoder): sage: class DualRepetitionCode(sage.coding.linear_code.AbstractLinearCode): ....: def __init__(self, field, length): - ....: sage.coding.linear_code.AbstractLinearCode.__init__(self,field, length, "Systematic", "Syndrome") + ....: super().__init__(field, length, "Systematic", "Syndrome") ....: ....: def parity_check_matrix(self): ....: return Matrix(self.base_field(), [1]*self.length()) @@ -1112,7 +1118,7 @@ class LinearCodeSystematicEncoder(Encoder): sage: class BadCodeFamily(sage.coding.linear_code.AbstractLinearCode): ....: def __init__(self, field, length): - ....: sage.coding.linear_code.AbstractLinearCode.__init__(self, field, length, "Systematic", "Syndrome") + ....: super().__init__(field, length, "Systematic", "Syndrome") ....: ....: def _repr_(self): ....: return "I am a badly defined code" @@ -1120,7 +1126,8 @@ class LinearCodeSystematicEncoder(Encoder): sage: BadCodeFamily(GF(3), 5).generator_matrix() Traceback (most recent call last): ... - ValueError: a parity check matrix must be specified if LinearCodeSystematicEncoder is the default encoder + ValueError: a parity check matrix must be specified + if LinearCodeSystematicEncoder is the default encoder """ def __init__(self, code, systematic_positions=None): @@ -1212,12 +1219,13 @@ def generator_matrix(self): EXAMPLES:: + sage: LCSE = codes.encoders.LinearCodeSystematicEncoder sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],\ [1,0,0,1,1,0,0],\ [0,1,0,1,0,1,0],\ [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E = LCSE(C) sage: E.generator_matrix() [1 0 0 0 0 1 1] [0 1 0 0 1 0 1] @@ -1226,7 +1234,7 @@ def generator_matrix(self): We can ask for different systematic positions:: - sage: E2 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[5,4,3,2]) + sage: E2 = LCSE(C, systematic_positions=[5,4,3,2]) sage: E2.generator_matrix() [1 0 0 0 0 1 1] [0 1 0 0 1 0 1] @@ -1240,7 +1248,7 @@ def generator_matrix(self): [0,0,1,0,0,1,0],\ [0,0,1,0,1,0,1]]) sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E = LCSE(C) sage: E.generator_matrix() [1 1 0 0 0 1 0] [0 0 1 0 0 1 0] @@ -1313,12 +1321,13 @@ def systematic_positions(self): EXAMPLES:: + sage: LCSE = codes.encoders.LinearCodeSystematicEncoder sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],\ [1,0,0,1,1,0,0],\ [0,1,0,1,0,1,0],\ [1,1,0,1,0,0,1]]) sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E = LCSE(C) sage: E.systematic_positions() (0, 1, 2, 3) @@ -1329,7 +1338,7 @@ def systematic_positions(self): [0,0,1,0,0,1,0],\ [0,0,1,0,1,0,1]]) sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E = LCSE(C) sage: E.systematic_positions() (0, 2, 4, 6) @@ -1351,7 +1360,7 @@ def systematic_positions(self): [0,1,0,0],\ [0,0,1,1]]) sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[0,1,3]) + sage: E = LCSE(C, systematic_positions=[0,1,3]) sage: E.systematic_positions() (0, 1, 3) """ diff --git a/src/sage/coding/linear_rank_metric.py b/src/sage/coding/linear_rank_metric.py index 78db1b8c602..01e1b9bb4f8 100644 --- a/src/sage/coding/linear_rank_metric.py +++ b/src/sage/coding/linear_rank_metric.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Generic structures for linear codes over the rank metric @@ -7,10 +7,10 @@ In coding theory, the most common metric is the Hamming metric, where distance between two codewords is given by the number of positions in which they differ. -An alternative to this is the rank metric. Take two fields, `F_q` and `F_{q^m}`, +An alternative to this is the rank metric. Take two fields, `\GF{q}` and `\GF{q^m}`, and define a code `C` to be a set of vectors of length `n` with entries from -`F_{q^m}`. Let `c` be a codeword. We can represent it as an `m \times n` matrix -`M` over `F_q`. +`\GF{q^m}`. Let `c` be a codeword. We can represent it as an `m \times n` matrix +`M` over `\GF{q}`. A detailed description on the relationship between the two representations can be found in :meth:`sage.coding.linear_rank_metric.to_matrix_representation` @@ -22,9 +22,9 @@ representation of `c`. This module allows representing rank metric codes which are linear over the -big field `F_{q^m}`, i.e. the usual linearity condition when the codewords are +big field `\GF{q^m}`, i.e. the usual linearity condition when the codewords are considered in vector form. One can also consider rank metric codes which are -only linear over `F_q`, but these are not currently supported in SageMath. +only linear over `\GF{q}`, but these are not currently supported in SageMath. Note that linear rank metric codes per the definition of this file are mathematically just linear block codes, and so could be considered as a @@ -127,28 +127,28 @@ def to_matrix_representation(v, sub_field=None, basis=None): Return a matrix representation of ``v`` over ``sub_field`` in terms of ``basis``. - Let `(b_1, b_2, \ldots, b_m)`, `b_i \in GF(q^m)`, be a basis of `GF(q^m)` as - a vector space over `GF(q)`. Take an element `x \in GF(q^m)`. We can write + Let `(b_1, b_2, \ldots, b_m)`, `b_i \in GF(q^m)`, be a basis of `\GF{q^m}` as + a vector space over `\GF{q}`. Take an element `x \in \GF{q^m}`. We can write `x` as `x = u_1 b_1 + u_2 b_2 + \ldots u_m b_m`, where `u_i \in GF(q)`. This - way we can represent an element from `GF(q^m)` as a vector of length `m` - over `GF(q)`. + way we can represent an element from `\GF{q^m}` as a vector of length `m` + over `\GF{q}`. - Given a vector ``v`` of length `n` over some field `F_{q^m}`, we can + Given a vector ``v`` of length `n` over some field `\GF{q^m}`, we can represent each entry as a vector of length `m`, yielding an `m \times n` matrix over ``sub_field``. In case ``sub_field`` is not given, we take the - prime subfield `F_p` of `F_{q^m}`. + prime subfield `\GF{p}` of `\GF{q^m}`. INPUT: - - ``v`` -- a vector over some field `F_{q^m}` + - ``v`` -- a vector over some field `\GF{q^m}` - - ``sub_field`` -- (default: ``None``) a sub field of `F_{q^m}`. If not - specified, it is the prime subfield `F_p` of `F_{q^m}`. + - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`. If not + specified, it is the prime subfield `\GF{p}` of `\GF{q^m}`. - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES:: @@ -181,25 +181,25 @@ def from_matrix_representation(w, base_field=None, basis=None): Return a vector representation of a matrix ``w`` over ``base_field`` in terms of ``basis``. - Given an `m \times n` matrix over `F_q` and some ``basis`` of `F_{q^m}` - over `F_q`, we can represent each of its columns as an element of `F_{q^m}`, - yielding a vector of length `n` over `F_q`. + Given an `m \times n` matrix over `\GF{q}` and some ``basis`` of `\GF{q^m}` + over `\GF{q}`, we can represent each of its columns as an element of `\GF{q^m}`, + yielding a vector of length `n` over `\GF{q}`. - In case ``base_field`` is not given, we take `F_{q^m}`, the field extension of - `F_q` of degree `m`, the number of rows of ``w``. + In case ``base_field`` is not given, we take `\GF{q^m}`, the field extension of + `\GF{q}` of degree `m`, the number of rows of ``w``. INPUT: - - ``w`` -- a matrix over some field `F_q` + - ``w`` -- a matrix over some field `\GF{q}` - - ``base_field`` -- (default: ``None``) an extension field of `F_q`. If not - specified, it is the field `F_{q^m}`, where `m` is the number of rows of + - ``base_field`` -- (default: ``None``) an extension field of `\GF{q}`. If not + specified, it is the field `\GF{q^m}`, where `m` is the number of rows of ``w``. - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over - ``F_q``. If not specified, given that `q = p^s`, let + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over + `\GF{q}`. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES:: @@ -229,20 +229,20 @@ def rank_weight(c, sub_field=None, basis=None): r""" Return the rank of ``c`` as a matrix over ``sub_field``. - If ``c`` is a vector over some field `F_{q^m}`, the function converts it - into a matrix over `F_q`. + If ``c`` is a vector over some field `\GF{q^m}`, the function converts it + into a matrix over `\GF{q}`. INPUT: - - ``c`` -- a vector over some field `F_{q^m}`; or a matrix over `F_q` + - ``c`` -- a vector over some field `\GF{q^m}`; or a matrix over `\GF{q}` - - ``sub_field`` -- (default: ``None``) a sub field of `F_{q^m}`. If not - specified, it is the prime subfield `F_p` of `F_{q^m}`. + - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`. If not + specified, it is the prime subfield `\GF{p}` of `\GF{q^m}`. - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES:: @@ -260,26 +260,26 @@ def rank_distance(a, b, sub_field=None, basis=None): r""" Return the rank of ``a`` - ``b`` as a matrix over ``sub_field``. - Take two vectors ``a``, ``b`` over some field `F_{q^m}`. This function - converts them to matrices over `F_q` and calculates the rank of their + Take two vectors ``a``, ``b`` over some field `\GF{q^m}`. This function + converts them to matrices over `\GF{q}` and calculates the rank of their difference. - If ``sub_field`` is not specified, we take the prime subfield `F_q` of - `F_{q^m}`. + If ``sub_field`` is not specified, we take the prime subfield `\GF{q}` of + `\GF{q^m}`. INPUT: - - ``a`` -- a vector over some field `F_{q^m}` + - ``a`` -- a vector over some field `\GF{q^m}` - - ``b`` -- a vector over some field `F_{q^m}` + - ``b`` -- a vector over some field `\GF{q^m}` - - ``sub_field`` -- (default: ``None``) a sub field of `F_{q^m}`. If not - specified, it is the prime subfield `F_p` of `F_{q^m}`. + - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`. If not + specified, it is the prime subfield `\GF{p}` of `\GF{q^m}`. - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES:: @@ -331,8 +331,8 @@ class AbstractLinearRankMetricCode(AbstractLinearCodeNoMetric): This class is intended for codes which are linear over the ``base_field``. Codewords of rank metric codes have two representations. They can either be - written as a vector of length `n` over `GF(q^m)`, or an `m \times n` matrix - over `GF(q)`. This implementation principally uses the vector representation. + written as a vector of length `n` over `\GF{q^m}`, or an `m \times n` matrix + over `\GF{q}`. This implementation principally uses the vector representation. However, one can always get the matrix representation using the :meth:`sage.coding.linear_rank_metric.AbstractLinearRankMetricCode.to_matrix` method. To go back to a vector, use the @@ -377,10 +377,10 @@ def __init__(self, base_field, sub_field, length, default_encoder_name, - ``default_decoder_name`` -- the name of the default decoder of ``self`` - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES: @@ -391,9 +391,11 @@ def __init__(self, base_field, sub_field, length, default_encoder_name, sage: from sage.coding.linear_rank_metric import AbstractLinearRankMetricCode sage: class RankRepetitionCode(AbstractLinearRankMetricCode): ....: def __init__(self, base_field, sub_field, length): - ....: sage.coding.linear_rank_metric.AbstractLinearRankMetricCode.__init__(self, base_field, sub_field, length, "GeneratorMatrix", "NearestNeighbor") + ....: super().__init__(self, base_field, sub_field, length, + ....: "GeneratorMatrix", "NearestNeighbor") ....: beta = base_field.gen() - ....: self._generator_matrix = matrix(base_field, [[ beta^i for i in range(length) ]]) + ....: self._generator_matrix = matrix(base_field, + ....: [[beta^i for i in range(length)]]) ....: def generator_matrix(self): ....: return self._generator_matrix ....: def _repr_(self): @@ -436,7 +438,8 @@ def __init__(self, base_field, sub_field, length, default_encoder_name, sage: C.parent() sage: C.category() - Category of facade finite dimensional vector spaces with basis over Finite Field in z3 of size 2^3 + Category of facade finite dimensional vector spaces with basis + over Finite Field in z3 of size 2^3 And any method that works on rank metric linear codes works for our new dummy code:: @@ -492,7 +495,7 @@ def extension_degree(self): r""" Return `m`, the degree of the field extension of ``self``. - Let ``base_field`` be `GF(q^m)` and ``sub_field`` be `GF(q)`. Then this + Let ``base_field`` be `\GF{q^m}` and ``sub_field`` be `\GF{q}`. Then this function returns `m`. EXAMPLES:: @@ -509,8 +512,8 @@ def field_extension(self): r""" Return the field extension of ``self``. - Let ``base_field`` be some field `F_{q^m}` and ``sub_field`` `F_{q}`. - This function returns the vector space of dimension `m` over `F_{q}`. + Let ``base_field`` be some field `\GF{q^m}` and ``sub_field`` `\GF{q}`. + This function returns the vector space of dimension `m` over `\GF{q}`. EXAMPLES:: @@ -674,10 +677,10 @@ def __init__(self, generator, sub_field=None, basis=None): - ``sub_field`` -- (default: ``None``) the sub field of ``self``, if not specified, it is the prime field of ``base_field`` - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES:: diff --git a/src/sage/coding/parity_check_code.py b/src/sage/coding/parity_check_code.py index 880de2c00fd..03f23bcc17f 100644 --- a/src/sage/coding/parity_check_code.py +++ b/src/sage/coding/parity_check_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Parity-check code @@ -5,8 +6,8 @@ parity check to ensure that the sum of the digits in a transmitted word is even. -A parity-check code of dimension `k` over `F_q` is the set: -`\{(m_1, m_2, \dots, m_k, - \Sigma_{i=1}^k m_i) \mid (m_1, m_2, \dots, m_k) \in F_q^k\}` +A parity-check code of dimension `k` over `\GF{q}` is the set: +`\{(m_1, m_2, \dots, m_k, - \Sigma_{i=1}^k m_i) \mid (m_1, m_2, \dots, m_k) \in \GF{q}^k\}` REFERENCE: diff --git a/src/sage/coding/punctured_code.py b/src/sage/coding/punctured_code.py index 0c85dddbd77..dbb1de87cca 100644 --- a/src/sage/coding/punctured_code.py +++ b/src/sage/coding/punctured_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Punctured code @@ -28,7 +29,7 @@ def _puncture(v, points): r""" - Returns v punctured as the positions listed in ``points``. + Return v punctured as the positions listed in ``points``. INPUT: @@ -59,7 +60,7 @@ def _puncture(v, points): def _insert_punctured_positions(l, punctured_points, value = None): r""" - Returns ``l`` with ``value`` inserted in the corresponding + Return ``l`` with ``value`` inserted in the corresponding position from ``punctured_points``. INPUT: @@ -68,8 +69,9 @@ def _insert_punctured_positions(l, punctured_points, value = None): - ``punctured_points`` -- a set of integers - - ``value`` -- (default: ``None``) an element to insert in every position given in``punctured_points``. - If it is let to ``None``, a random value will be chosen for each insertion. + - ``value`` -- (default: ``None``) an element to insert in every position + given in``punctured_points``. If it is let to ``None``, a random value + will be chosen for each insertion. EXAMPLES:: @@ -120,13 +122,15 @@ def __init__(self, C, positions): r""" TESTS: - If one of the positions to puncture is bigger than the length of ``C``, an exception will be raised:: + If one of the positions to puncture is bigger than the length of ``C``, + an exception will be raised:: sage: C = codes.random_linear_code(GF(7), 11, 5) sage: Cp = codes.PuncturedCode(C, {4,8,15}) Traceback (most recent call last): ... - ValueError: Positions to puncture must be positive integers smaller than the length of the provided code + ValueError: Positions to puncture must be positive integers smaller + than the length of the provided code """ if not isinstance(positions, (Integer, int, set, list)): raise TypeError("positions must be either a Sage Integer, a Python int, a set or a list") @@ -163,7 +167,7 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -177,7 +181,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -191,7 +195,7 @@ def _latex_(self): def punctured_positions(self): r""" - Returns the list of positions which were punctured on the original code. + Return the list of positions which were punctured on the original code. EXAMPLES:: @@ -204,7 +208,7 @@ def punctured_positions(self): def original_code(self): r""" - Returns the linear code which was punctured to get ``self``. + Return the linear code which was punctured to get ``self``. EXAMPLES:: @@ -217,7 +221,7 @@ def original_code(self): def dimension(self): r""" - Returns the dimension of ``self``. + Return the dimension of ``self``. EXAMPLES:: @@ -234,7 +238,7 @@ def dimension(self): def random_element(self, *args, **kwds): r""" - Returns a random codeword of ``self``. + Return a random codeword of ``self``. This method does not trigger the computation of ``self``'s :meth:`sage.coding.linear_code_no_metric.generator_matrix`. @@ -278,7 +282,9 @@ def encode(self, m, original_encode=False, encoder_name=None, **kwargs): EXAMPLES:: - sage: M = matrix(GF(7), [[1, 0, 0, 0, 3, 4, 6], [0, 1, 0, 6, 1, 6, 4], [0, 0, 1, 5, 2, 2, 4]]) + sage: M = matrix(GF(7), [[1, 0, 0, 0, 3, 4, 6], + ....: [0, 1, 0, 6, 1, 6, 4], + ....: [0, 0, 1, 5, 2, 2, 4]]) sage: C_original = LinearCode(M) sage: Cp = codes.PuncturedCode(C_original, 2) sage: m = vector(GF(7), [1, 3, 5]) @@ -293,7 +299,7 @@ def encode(self, m, original_encode=False, encoder_name=None, **kwargs): @cached_method def structured_representation(self): r""" - Returns ``self`` as a structured code object. + Return ``self`` as a structured code object. If ``self`` has a specific structured representation (e.g. a punctured GRS code is a GRS code too), it will return this representation, else it returns a @@ -348,7 +354,8 @@ class PuncturedCodePuncturedMatrixEncoder(Encoder): sage: Cp = codes.PuncturedCode(C, 3) sage: E = codes.encoders.PuncturedCodePuncturedMatrixEncoder(Cp) sage: E - Punctured matrix-based encoder for the Puncturing of [11, 5] linear code over GF(7) on position(s) [3] + Punctured matrix-based encoder for the + Puncturing of [11, 5] linear code over GF(7) on position(s) [3] """ def __init__(self, code): @@ -369,7 +376,7 @@ def __init__(self, code): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -383,7 +390,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -398,7 +405,7 @@ def _latex_(self): @cached_method def generator_matrix(self): r""" - Returns a generator matrix of the associated code of ``self``. + Return a generator matrix of the associated code of ``self``. EXAMPLES:: @@ -435,18 +442,19 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): - ``strategy`` -- (default: ``None``) the strategy used to decode. The available strategies are: - * ``'error-erasure'`` -- uses an error-erasure decoder over the original code if available, - fails otherwise. + * ``'error-erasure'`` -- uses an error-erasure decoder over the original + code if available, fails otherwise. - * ``'random-values'`` -- fills the punctured positions with random elements - in ``code``'s base field and tries to decode using - the default decoder of the original code + * ``'random-values'`` -- fills the punctured positions with random elements + in ``code``'s base field and tries to decode using + the default decoder of the original code - * ``'try-all'`` -- fills the punctured positions with every possible combination of - symbols until decoding succeeds, or until every combination have been tried + * ``'try-all'`` -- fills the punctured positions with every possible + combination of symbols until decoding succeeds, or until every + combination have been tried - * ``None`` -- uses ``error-erasure`` if an error-erasure decoder is available, - switch to ``random-values`` behaviour otherwise + * ``None`` -- uses ``error-erasure`` if an error-erasure decoder is + available, switch to ``random-values`` behaviour otherwise - ``original_decoder`` -- (default: ``None``) the decoder that will be used over the original code. It has to be a decoder object over the original code. @@ -456,33 +464,36 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): - ``**kwargs`` -- all extra arguments are forwarded to original code's decoder - EXAMPLES:: + EXAMPLES:: - sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) - sage: Cp = codes.PuncturedCode(C, 3) - sage: codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp) - Decoder of Puncturing of [15, 7, 9] Reed-Solomon Code over GF(16) on position(s) [3] through Error-Erasure decoder for [15, 7, 9] Reed-Solomon Code over GF(16) + sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) + sage: Cp = codes.PuncturedCode(C, 3) + sage: codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp) + Decoder of Puncturing of [15, 7, 9] Reed-Solomon Code over GF(16) on position(s) [3] + through Error-Erasure decoder for [15, 7, 9] Reed-Solomon Code over GF(16) - As seen above, if all optional are left blank, and if an error-erasure decoder is - available, it will be chosen as the original decoder. - Now, if one forces ``strategy `` to ``'try-all'`` or ``'random-values'``, the - default decoder of the original code will be chosen, even if an error-erasure is available:: + As seen above, if all optional are left blank, and if an error-erasure + decoder is available, it will be chosen as the original decoder. Now, if + one forces ``strategy`` to ``'try-all'`` or ``'random-values'``, the default + decoder of the original code will be chosen, even if an error-erasure is + available:: - sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) - sage: Cp = codes.PuncturedCode(C, 3) - sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, strategy="try-all") - sage: "error-erasure" in D.decoder_type() - False + sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) + sage: Cp = codes.PuncturedCode(C, 3) + sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, strategy="try-all") + sage: "error-erasure" in D.decoder_type() + False - And if one fills ``original_decoder`` and ``strategy`` fields with contradictory - elements, the ``original_decoder`` takes precedence:: + And if one fills ``original_decoder`` and ``strategy`` fields with + contradictory elements, the ``original_decoder`` takes precedence:: - sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) - sage: Cp = codes.PuncturedCode(C, 3) - sage: Dor = C.decoder("Gao") - sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, original_decoder = Dor, strategy="error-erasure") - sage: D.original_decoder() == Dor - True + sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) + sage: Cp = codes.PuncturedCode(C, 3) + sage: Dor = C.decoder("Gao") + sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, original_decoder=Dor, + ....: strategy="error-erasure") + sage: D.original_decoder() == Dor + True """ def __init__(self, code, strategy = None, original_decoder = None, **kwargs): @@ -559,7 +570,7 @@ def __init__(self, code, strategy = None, original_decoder = None, **kwargs): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -574,7 +585,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -588,7 +599,7 @@ def _latex_(self): def original_decoder(self): r""" - Returns the decoder over the original code that will be used to decode words of + Return the decoder over the original code that will be used to decode words of :meth:`sage.coding.decoder.Decoder.code`. EXAMPLES:: @@ -603,7 +614,7 @@ def original_decoder(self): def decode_to_code(self, y): r""" - Decodes ``y`` to an element in :meth:`sage.coding.decoder.Decoder.code`. + Decode ``y`` to an element in :meth:`sage.coding.decoder.Decoder.code`. EXAMPLES:: @@ -673,7 +684,7 @@ def decode_to_code(self, y): def decoding_radius(self, number_erasures = None): r""" - Returns maximal number of errors that ``self`` can decode. + Return the maximal number of errors that ``self`` can decode. EXAMPLES:: diff --git a/src/sage/coding/reed_muller_code.py b/src/sage/coding/reed_muller_code.py index 457f90bdab9..6885532757b 100644 --- a/src/sage/coding/reed_muller_code.py +++ b/src/sage/coding/reed_muller_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Reed-Muller code @@ -44,7 +45,7 @@ def _binomial_sum(n, k): r""" - Returns the sum of all binomials `\binom{n}{i}`, + Return the sum of all binomials `\binom{n}{i}`, with `i` ranging from `0` to `k` and including `k`. INPUT: @@ -67,7 +68,7 @@ def _binomial_sum(n, k): def _multivariate_polynomial_interpolation(evaluation, order, polynomial_ring): r""" - Returns `f \in \GF{q}[X_1,...,X_m]` such that `f(\mathbf a) = v[i(\mathbf a)]` + Return `f \in \GF{q}[X_1,...,X_m]` such that `f(\mathbf a) = v[i(\mathbf a)]` for all `\mathbf a \in \GF{q^m}`, where `v \in \GF{q}^{q^m}` is a given vector of evaluations, and `i(a)` is a specific ordering of `\GF{q^m}` (see below for details) @@ -132,7 +133,7 @@ def _interpolate(evaluation, num_of_var, order): def ReedMullerCode(base_field, order, num_of_var): r""" - Returns a Reed-Muller code. + Return a Reed-Muller code. A Reed-Muller Code of order `r` and number of variables `m` over a finite field `F` is the set: @@ -145,7 +146,7 @@ def ReedMullerCode(base_field, order, num_of_var): - ``base_field`` -- The finite field `F` over which the code is built. - ``order`` -- The order of the Reed-Muller Code, which is the maximum - degree of the polynomial to be used in the code. + degree of the polynomial to be used in the code. - ``num_of_var`` -- The number of variables used in polynomial. @@ -191,28 +192,30 @@ def ReedMullerCode(base_field, order, num_of_var): class QAryReedMullerCode(AbstractLinearCode): r""" - Representation of a q-ary Reed-Muller code. + Representation of a `q`-ary Reed-Muller code. For details on the definition of Reed-Muller codes, refer to :meth:`ReedMullerCode`. .. NOTE:: - It is better to use the aforementioned method rather than calling - this class directly, as :meth:`ReedMullerCode` creates either - a binary or a q-ary Reed-Muller code according to the arguments it receives. + It is better to use the aforementioned method rather than calling this + class directly, as :meth:`ReedMullerCode` creates either a binary or a + `q`-ary Reed-Muller code according to the arguments it receives. INPUT: - ``base_field`` -- A finite field, which is the base field of the code. - - ``order`` -- The order of the Reed-Muller Code, i.e., the maximum degree of the polynomial to be used in the code. + - ``order`` -- The order of the Reed-Muller Code, i.e., the maximum degree + of the polynomial to be used in the code. - ``num_of_var`` -- The number of variables used in polynomial. .. WARNING:: - For now, this implementation only supports Reed-Muller codes whose order is less than q. + For now, this implementation only supports Reed-Muller codes whose order + is less than q. EXAMPLES:: @@ -271,7 +274,7 @@ def __init__(self, base_field, order, num_of_var): def order(self): r""" - Returns the order of ``self``. + Return the order of ``self``. Order is the maximum degree of the polynomial used in the Reed-Muller code. @@ -287,7 +290,7 @@ def order(self): def number_of_variables(self): r""" - Returns the number of variables of the polynomial ring used in ``self``. + Return the number of variables of the polynomial ring used in ``self``. EXAMPLES:: @@ -301,9 +304,10 @@ def number_of_variables(self): def minimum_distance(self): r""" - Returns the minimum distance between two words in ``self``. + Return the minimum distance between two words in ``self``. - The minimum distance of a q-ary Reed-Muller code with order `d` and number of variables `m` is `(q-d)q^{m-1}` + The minimum distance of a `q`-ary Reed-Muller code with order `d` and + number of variables `m` is `(q-d)q^{m-1}` EXAMPLES:: @@ -320,7 +324,7 @@ def minimum_distance(self): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -335,7 +339,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -378,14 +382,15 @@ class BinaryReedMullerCode(AbstractLinearCode): .. NOTE:: - It is better to use the aforementioned method rather than calling - this class directly, as :meth:`ReedMullerCode` creates either - a binary or a q-ary Reed-Muller code according to the arguments it receives. + It is better to use the aforementioned method rather than calling this + class directly, as :meth:`ReedMullerCode` creates either a binary or a + `q`-ary Reed-Muller code according to the arguments it receives. INPUT: - - ``order`` -- The order of the Reed-Muller Code, i.e., the maximum degree of the polynomial to be used in the code. + - ``order`` -- The order of the Reed-Muller Code, i.e., the maximum degree + of the polynomial to be used in the code. - ``num_of_var`` -- The number of variables used in the polynomial. @@ -436,7 +441,9 @@ def __init__(self, order, num_of_var): def order(self): r""" - Returns the order of ``self``. Order is the maximum degree of the polynomial used in the Reed-Muller code. + Return the order of ``self``. + + Order is the maximum degree of the polynomial used in the Reed-Muller code. EXAMPLES:: @@ -448,7 +455,7 @@ def order(self): def number_of_variables(self): r""" - Returns the number of variables of the polynomial ring used in ``self``. + Return the number of variables of the polynomial ring used in ``self``. EXAMPLES:: @@ -460,8 +467,10 @@ def number_of_variables(self): def minimum_distance(self): r""" - Returns the minimum distance of ``self``. - The minimum distance of a binary Reed-Muller code of order `d` and number of variables `m` is `q^{m-d}` + Return the minimum distance of ``self``. + + The minimum distance of a binary Reed-Muller code of order `d` and + number of variables `m` is `q^{m-d}` EXAMPLES:: @@ -473,7 +482,7 @@ def minimum_distance(self): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -486,7 +495,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -520,12 +529,12 @@ class ReedMullerVectorEncoder(Encoder): Consider a Reed-Muller code of order `r`, number of variables `m`, length `n`, dimension `k` over some finite field `F`. Let those variables be `(x_1, x_2, \dots, x_m)`. - We order the monomials by lowest power on lowest index variables. If we have three monomials - `x_1 \times x_2`, `x_1 \times x_2^2` and `x_1^2 \times x_2`, the ordering is: - `x_1 \times x_2 < x_1 \times x_2^2 < x_1^2 \times x_2` + We order the monomials by lowest power on lowest index variables. If we have + three monomials `x_1 x_2`, `x_1 x_2^2` and `x_1^2 x_2`, the ordering is: + `x_1 x_2 < x_1 x_2^2 < x_1^2 x_2` Let now `(v_1,v_2,\ldots,v_k)` be a vector of `F`, which corresponds to the polynomial - `f = \Sigma^{k}_{i=1} v_i \times x_i`. + `f = \Sigma^{k}_{i=1} v_i x_i`. Let `(\beta_1, \beta_2, \ldots, \beta_q)` be the elements of `F` ordered as they are returned by Sage when calling ``F.list()``. @@ -533,8 +542,9 @@ class ReedMullerVectorEncoder(Encoder): The aforementioned polynomial `f` is encoded as: `(f(\alpha_{11},\alpha_{12},\ldots,\alpha_{1m}),f(\alpha_{21},\alpha_{22},\ldots, - \alpha_{2m}),\ldots,f(\alpha_{q^m1},\alpha_{q^m2},\ldots,\alpha_{q^mm}`, with - `\alpha_{ij}=\beta_{i \ mod \ q^j} \forall (i,j)` + \alpha_{2m}),\ldots,f(\alpha_{q^m1},\alpha_{q^m2},\ldots,\alpha_{q^mm}))` + + with `\alpha_{ij}=\beta_{i \bmod{q^j}}` for all `i`, `j)`. INPUT: @@ -542,21 +552,24 @@ class ReedMullerVectorEncoder(Encoder): EXAMPLES:: - sage: C1=codes.ReedMullerCode(GF(2), 2, 4) - sage: E1=codes.encoders.ReedMullerVectorEncoder(C1) + sage: C1 = codes.ReedMullerCode(GF(2), 2, 4) + sage: E1 = codes.encoders.ReedMullerVectorEncoder(C1) sage: E1 - Evaluation vector-style encoder for Binary Reed-Muller Code of order 2 and number of variables 4 - sage: C2=codes.ReedMullerCode(GF(3), 2, 2) - sage: E2=codes.encoders.ReedMullerVectorEncoder(C2) + Evaluation vector-style encoder for + Binary Reed-Muller Code of order 2 and number of variables 4 + sage: C2 = codes.ReedMullerCode(GF(3), 2, 2) + sage: E2 = codes.encoders.ReedMullerVectorEncoder(C2) sage: E2 - Evaluation vector-style encoder for Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 + Evaluation vector-style encoder for + Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 Actually, we can construct the encoder from ``C`` directly:: sage: C=codes.ReedMullerCode(GF(2), 2, 4) sage: E = C.encoder("EvaluationVector") sage: E - Evaluation vector-style encoder for Binary Reed-Muller Code of order 2 and number of variables 4 + Evaluation vector-style encoder for + Binary Reed-Muller Code of order 2 and number of variables 4 """ def __init__(self, code): @@ -582,7 +595,7 @@ def __init__(self, code): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -596,7 +609,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -629,7 +642,7 @@ def __eq__(self, other): @cached_method def generator_matrix(self): r""" - Returns a generator matrix of ``self`` + Return a generator matrix of ``self`` EXAMPLES:: @@ -663,7 +676,8 @@ def generator_matrix(self): def points(self): r""" - Returns the points of `F^m`, where `F` is base field and `m` is the number of variables, in order of which polynomials are evaluated on. + Return the points of `F^m`, where `F` is the base field and `m` is the + number of variables, in order of which polynomials are evaluated on. EXAMPLES:: @@ -686,8 +700,8 @@ class ReedMullerPolynomialEncoder(Encoder): dimension `k` over some finite field `F`. Let those variables be `(x_1, x_2, \dots, x_m)`. We order the monomials by lowest power on lowest index variables. If we have three monomials - `x_1 \times x_2`, `x_1 \times x_2^2` and `x_1^2 \times x_2`, the ordering is: - `x_1 \times x_2 < x_1 \times x_2^2 < x_1^2 \times x_2` + `x_1 x_2`, `x_1 x_2^2` and `x_1^2 x_2`, the ordering is: + `x_1 x_2 < x_1 x_2^2 < x_1^2 x_2` Let now `f` be a polynomial of the multivariate polynomial ring `F[x_1, \dots, x_m]`. @@ -697,42 +711,46 @@ class ReedMullerPolynomialEncoder(Encoder): The aforementioned polynomial `f` is encoded as: `(f(\alpha_{11},\alpha_{12},\ldots,\alpha_{1m}),f(\alpha_{21},\alpha_{22},\ldots, - \alpha_{2m}),\ldots,f(\alpha_{q^m1},\alpha_{q^m2},\ldots,\alpha_{q^mm}`, with - `\alpha_{ij}=\beta_{i \ mod \ q^j} \forall (i,j)` + \alpha_{2m}),\ldots,f(\alpha_{q^m1},\alpha_{q^m2},\ldots,\alpha_{q^mm}))` + with `\alpha_{ij}=\beta_{i \bmod{q^j}}` for all `i`, `j`. INPUT: - ``code`` -- The associated code of this encoder. - -``polynomial_ring`` -- (default:``None``) The polynomial ring from which the message is chosen. - If this is set to ``None``, a polynomial ring in `x` will be built - from the code parameters. + - ``polynomial_ring`` -- (default:``None``) The polynomial ring from which + the message is chosen. If this is set to ``None``, a polynomial ring in + `x` will be built from the code parameters. EXAMPLES:: - sage: C1=codes.ReedMullerCode(GF(2), 2, 4) - sage: E1=codes.encoders.ReedMullerPolynomialEncoder(C1) + sage: C1 = codes.ReedMullerCode(GF(2), 2, 4) + sage: E1 = codes.encoders.ReedMullerPolynomialEncoder(C1) sage: E1 - Evaluation polynomial-style encoder for Binary Reed-Muller Code of order 2 and number of variables 4 - sage: C2=codes.ReedMullerCode(GF(3), 2, 2) - sage: E2=codes.encoders.ReedMullerPolynomialEncoder(C2) + Evaluation polynomial-style encoder for + Binary Reed-Muller Code of order 2 and number of variables 4 + sage: C2 = codes.ReedMullerCode(GF(3), 2, 2) + sage: E2 = codes.encoders.ReedMullerPolynomialEncoder(C2) sage: E2 - Evaluation polynomial-style encoder for Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 + Evaluation polynomial-style encoder for + Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 We can also pass a predefined polynomial ring:: - sage: R=PolynomialRing(GF(3), 2, 'y') - sage: C=codes.ReedMullerCode(GF(3), 2, 2) - sage: E=codes.encoders.ReedMullerPolynomialEncoder(C, R) + sage: R = PolynomialRing(GF(3), 2, 'y') + sage: C = codes.ReedMullerCode(GF(3), 2, 2) + sage: E = codes.encoders.ReedMullerPolynomialEncoder(C, R) sage: E - Evaluation polynomial-style encoder for Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 + Evaluation polynomial-style encoder for + Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 Actually, we can construct the encoder from ``C`` directly:: sage: E = C1.encoder("EvaluationPolynomial") sage: E - Evaluation polynomial-style encoder for Binary Reed-Muller Code of order 2 and number of variables 4 + Evaluation polynomial-style encoder for + Binary Reed-Muller Code of order 2 and number of variables 4 """ def __init__(self, code, polynomial_ring=None): @@ -776,7 +794,7 @@ def __init__(self, code, polynomial_ring=None): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -790,7 +808,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -846,7 +864,7 @@ def encode(self, p): True If a polynomial with good monomial degree but wrong monomial - degree is given,an error is raised:: + degree is given, an error is raised:: sage: p = x0^2*x1 sage: E.encode(p) @@ -861,7 +879,8 @@ def encode(self, p): sage: E.encode(p) Traceback (most recent call last): ... - ValueError: The value to encode must be in Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3 + ValueError: The value to encode must be in + Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3 """ M = self.message_space() if p not in M: @@ -875,7 +894,7 @@ def encode(self, p): def unencode_nocheck(self, c): r""" - Returns the message corresponding to the codeword ``c``. + Return the message corresponding to the codeword ``c``. Use this method with caution: it does not check if ``c`` belongs to the code, and if this is not the case, the output is @@ -921,7 +940,7 @@ def unencode_nocheck(self, c): def message_space(self): r""" - Returns the message space of ``self`` + Return the message space of ``self`` EXAMPLES:: @@ -935,7 +954,7 @@ def message_space(self): def polynomial_ring(self): r""" - Returns the polynomial ring associated with ``self`` + Return the polynomial ring associated with ``self`` EXAMPLES:: @@ -949,7 +968,7 @@ def polynomial_ring(self): def points(self): r""" - Returns the evaluation points in the appropriate order as used by ``self`` when + Return the evaluation points in the appropriate order as used by ``self`` when encoding a message. EXAMPLES:: diff --git a/src/sage/coding/self_dual_codes.py b/src/sage/coding/self_dual_codes.py index 4fa7960e4df..67f90226ccb 100644 --- a/src/sage/coding/self_dual_codes.py +++ b/src/sage/coding/self_dual_codes.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups sage.modules r""" Enumerating binary self-dual codes @@ -5,68 +6,67 @@ The main function is ``self_dual_binary_codes``, which is a case-by-case list of entries, each represented by a Python dictionary. -Format of each entry: a Python dictionary with keys "order autgp", "spectrum", -"code", "Comment", "Type", where +Format of each entry: a Python dictionary with keys ``"order autgp"``, ``"spectrum"``, +``"code"``, ``"Comment"``, ``"Type"``, where -- "code" - a sd code C of length n, dim n/2, over GF(2) +- ``"code"`` -- a sd code `C` of length `n`, dim `n/2`, over `\GF{2}` -- "order autgp" - order of the permutation automorphism group of C +- ``"order autgp"`` -- order of the permutation automorphism group of `C` -- "Type" - the type of C (which can be "I" or "II", in the binary case) +- ``"Type"`` -- the type of `C` (which can be ``"I"`` or ``"II"``, in the binary case) -- "spectrum" - the spectrum [A0,A1,...,An] +- ``"spectrum"`` -- the spectrum `[A_0,A_1,...,A_n]` -- "Comment" - possibly an empty string. +- ``"Comment"`` -- possibly an empty string. Python dictionaries were used since they seemed to be both human-readable and allow others to update the database easiest. -- The following double for loop can be time-consuming but should - be run once in awhile for testing purposes. It should only print - True and have no trace-back errors:: +- The following double ``for`` loop can be time-consuming but should + be run once in a while for testing purposes. It should only print + ``True`` and have no trace-back errors:: - for n in [4,6,8,10,12,14,16,18,20,22]: - C = self_dual_binary_codes(n); m = len(C.keys()) - for i in range(m): - C0 = C["%s"%n]["%s"%i]["code"] - print([n,i,C["%s"%n]["%s"%i]["spectrum"] == C0.spectrum()]) - print(C0 == C0.dual_code()) - G = C0.automorphism_group_binary_code() - print(C["%s" % n]["%s" % i]["order autgp"] == G.order()) + sage: for n in [4,6,8,10,12,14,16,18,20,22]: # not tested + ....: C = self_dual_binary_codes(n); m = len(C.keys()) + ....: for i in range(m): + ....: C0 = C["%s"%n]["%s"%i]["code"] + ....: print([n,i,C["%s"%n]["%s"%i]["spectrum"] == C0.spectrum()]) + ....: print(C0 == C0.dual_code()) + ....: G = C0.automorphism_group_binary_code() + ....: print(C["%s" % n]["%s" % i]["order autgp"] == G.order()) - To check if the "Riemann hypothesis" holds, run the following code:: - R = PolynomialRing(CC,"T") - T = R.gen() - for n in [4,6,8,10,12,14,16,18,20,22]: - C = self_dual_binary_codes(n); m = len(C["%s"%n].keys()) - for i in range(m): - C0 = C["%s"%n]["%s"%i]["code"] - if C0.minimum_distance()>2: - f = R(C0.sd_zeta_polynomial()) - print([n,i,[z[0].abs() for z in f.roots()]]) - + sage: R = PolynomialRing(CC,"T") # not tested + sage: T = R.gen() # not tested + sage: for n in [4,6,8,10,12,14,16,18,20,22]: # not tested + ....: C = self_dual_binary_codes(n); m = len(C["%s"%n].keys()) + ....: for i in range(m): + ....: C0 = C["%s"%n]["%s"%i]["code"] + ....: if C0.minimum_distance()>2: + ....: f = R(C0.sd_zeta_polynomial()) + ....: print([n,i,[z[0].abs() for z in f.roots()]]) You should get lists of numbers equal to 0.707106781186548. Here's a rather naive construction of self-dual codes in the binary case: -For even m, let A_m denote the mxm matrix over GF(2) given by adding -the all 1's matrix to the identity matrix (in -``MatrixSpace(GF(2),m,m)`` of course). If M_1, ..., M_r are square -matrices, let `diag(M_1,M_2,...,M_r)` denote the"block diagonal" -matrix with the `M_i` 's on the diagonal and 0's elsewhere. Let +For even `m`, let `A_m` denote the `m\times m` matrix over `\GF{2}` +given by adding the all 1's matrix to the identity matrix (in +``MatrixSpace(GF(2),m,m)`` of course). If `M_1, ..., M_r` are square +matrices, let `diag(M_1,M_2,...,M_r)` denote the "block diagonal" +matrix with the matrices `M_i` on the diagonal and 0's elsewhere. Let `C(m_1,...,m_r,s)` denote the linear code with generator matrix having block form `G = (I, A)`, where `A = diag(A_{m_1},A_{m_2},...,A_{m_r},I_s)`, for some -(even) `m_i` 's and `s`, where +(even) `m_i`'s and `s`, where `m_1+m_2+...+m_r+s=n/2`. Note: Such codes `C(m_1,...,m_r,s)` are SD. SD codes not of this form will be called (for the purpose of -documenting the code below) "exceptional". Except when n is +documenting the code below) "exceptional". Except when `n` is "small", most sd codes are exceptional (based on a counting argument and table 9.1 in the Huffman+Pless [HP2003]_, page 347). @@ -255,25 +255,25 @@ def _H8(): def self_dual_binary_codes(n): r""" - Returns the dictionary of inequivalent binary self dual codes of length n. + Return the dictionary of inequivalent binary self dual codes of length `n`. - For n=4 even, returns the sd codes of a given length, up to (perm) + For `n=4` even, returns the sd codes of a given length, up to (perm) equivalence, the (perm) aut gp, and the type. - The number of inequiv "diagonal" sd binary codes in the database of + The number of inequivalent "diagonal" sd binary codes in the database of length n is ("diagonal" is defined by the conjecture above) is the - same as the restricted partition number of n, where only integers - from the set 1,4,6,8,... are allowed. This is the coefficient of + same as the restricted partition number of `n`, where only integers + from the set 1, 4, 6, 8, ... are allowed. This is the coefficient of `x^n` in the series expansion `(1-x)^{-1}\prod_{2^\infty (1-x^{2j})^{-1}}`. Typing the - command f = (1-x)(-1)\*prod([(1-x(2\*j))(-1) for j in range(2,18)]) + command ``f = (1-x)(-1)\*prod([(1-x(2\*j))(-1) for j in range(2,18)])`` into Sage, we obtain for the coeffs of `x^4`, `x^6`, ... [1, 1, 2, 2, 3, 3, 5, 5, 7, 7, 11, 11, 15, 15, 22, 22, 30, 30, 42, 42, 56, 56, 77, 77, 101, 101, 135, 135, 176, 176, 231] These numbers grow too slowly to account for all the sd codes (see Huffman+Pless' Table 9.1, referenced above). In fact, in - Table 9.10 of [HP2003]_, the number B_n of inequivalent sd binary codes - of length n is given:: + Table 9.10 of [HP2003]_, the number `B_n` of inequivalent sd binary codes + of length `n` is given:: n 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 B_n 1 1 1 2 2 3 4 7 9 16 25 55 103 261 731 @@ -288,7 +288,7 @@ def self_dual_binary_codes(n): True sage: C["10"]["1"]["code"] == C["10"]["1"]["code"].dual_code() True - sage: len(C["10"].keys()) # number of inequiv sd codes of length 10 + sage: len(C["10"].keys()) # number of inequiv sd codes of length 10 2 sage: C = codes.databases.self_dual_binary_codes(12) sage: C["12"]["0"]["code"] == C["12"]["0"]["code"].dual_code() diff --git a/src/sage/coding/source_coding/huffman.py b/src/sage/coding/source_coding/huffman.py index 59f16555e3a..eb138738f2f 100644 --- a/src/sage/coding/source_coding/huffman.py +++ b/src/sage/coding/source_coding/huffman.py @@ -102,15 +102,15 @@ class Huffman(SageObject): - ``source`` -- can be either - - A string from which the Huffman encoding should be created. + - A string from which the Huffman encoding should be created. - - A dictionary that associates to each symbol of an alphabet a numeric - value. If we consider the frequency of each alphabetic symbol, then - ``source`` is considered as the frequency table of the alphabet with - each numeric (non-negative integer) value being the number of - occurrences of a symbol. The numeric values can also represent weights - of the symbols. In that case, the numeric values are not necessarily - integers, but can be real numbers. + - A dictionary that associates to each symbol of an alphabet a numeric + value. If we consider the frequency of each alphabetic symbol, then + ``source`` is considered as the frequency table of the alphabet with + each numeric (non-negative integer) value being the number of + occurrences of a symbol. The numeric values can also represent weights + of the symbols. In that case, the numeric values are not necessarily + integers, but can be real numbers. In order to construct a Huffman code for an alphabet, we use exactly one of the following methods: @@ -235,7 +235,7 @@ def __init__(self, source): Feeding anything else than a string or a dictionary:: - sage: Huffman(Graph()) + sage: Huffman(Graph()) # optional - sage.graphs Traceback (most recent call last): ... ValueError: Input must be either a string or a dictionary. @@ -510,9 +510,9 @@ def tree(self): sage: from sage.coding.source_coding.huffman import Huffman sage: str = "Sage is my most favorite general purpose computer algebra system" sage: h = Huffman(str) - sage: T = h.tree(); T + sage: T = h.tree(); T # optional - sage.graphs Digraph on 39 vertices - sage: T.show(figsize=[20,20]) + sage: T.show(figsize=[20,20]) # optional - sage.graphs sage.plot """ from sage.graphs.digraph import DiGraph @@ -543,8 +543,8 @@ def _generate_edges(self, tree, parent="", bit=""): sage: from sage.coding.source_coding.huffman import Huffman sage: H = Huffman("Sage") - sage: T = H.tree() - sage: T.edges(sort=True, labels=None) # indirect doctest + sage: T = H.tree() # optional - sage.graphs + sage: T.edges(sort=True, labels=None) # indirect doctest # optional - sage.graphs [('0', 'S: 00'), ('0', 'a: 01'), ('1', 'e: 10'), ('1', 'g: 11'), ('root', '0'), ('root', '1')] """ if parent == "": diff --git a/src/sage/coding/subfield_subcode.py b/src/sage/coding/subfield_subcode.py index b3861707d6b..c4f8b984941 100644 --- a/src/sage/coding/subfield_subcode.py +++ b/src/sage/coding/subfield_subcode.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Subfield subcode @@ -113,7 +114,7 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -127,7 +128,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -141,7 +142,7 @@ def _latex_(self): def dimension(self): r""" - Returns the dimension of ``self``. + Return the dimension of ``self``. EXAMPLES:: @@ -154,7 +155,7 @@ def dimension(self): def dimension_upper_bound(self): r""" - Returns an upper bound for the dimension of ``self``. + Return an upper bound for the dimension of ``self``. EXAMPLES:: @@ -167,7 +168,7 @@ def dimension_upper_bound(self): def dimension_lower_bound(self): r""" - Returns a lower bound for the dimension of ``self``. + Return a lower bound for the dimension of ``self``. EXAMPLES:: @@ -184,7 +185,7 @@ def dimension_lower_bound(self): def original_code(self): r""" - Returns the original code of ``self``. + Return the original code of ``self``. EXAMPLES:: @@ -197,7 +198,7 @@ def original_code(self): def embedding(self): r""" - Returns the field embedding between the base field of ``self`` and + Return the field embedding between the base field of ``self`` and the base field of its original code. EXAMPLES:: @@ -215,7 +216,7 @@ def embedding(self): @cached_method def parity_check_matrix(self): r""" - Returns a parity check matrix of ``self``. + Return a parity check matrix of ``self``. EXAMPLES:: @@ -282,7 +283,8 @@ class SubfieldSubcodeOriginalCodeDecoder(Decoder): sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'aa').list()[:13], 5) sage: Cs = codes.SubfieldSubcode(C, GF(4, 'a')) sage: codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs) - Decoder of Subfield subcode of [13, 5, 9] Reed-Solomon Code over GF(16) down to GF(4) through Gao decoder for [13, 5, 9] Reed-Solomon Code over GF(16) + Decoder of Subfield subcode of [13, 5, 9] Reed-Solomon Code over GF(16) down to GF(4) + through Gao decoder for [13, 5, 9] Reed-Solomon Code over GF(16) """ def __init__(self, code, original_decoder = None, **kwargs): @@ -296,7 +298,7 @@ def __init__(self, code, original_decoder = None, **kwargs): sage: Cs = codes.SubfieldSubcode(C, GF(4, 'a')) sage: Cbis = codes.GeneralizedReedSolomonCode(GF(16, 'aa').list()[:9], 5) sage: D = Cbis.decoder() - sage: codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs, original_decoder = D) + sage: codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs, original_decoder=D) Traceback (most recent call last): ... ValueError: original_decoder must have the original code as associated code @@ -318,7 +320,7 @@ def __init__(self, code, original_decoder = None, **kwargs): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -332,7 +334,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -346,7 +348,7 @@ def _latex_(self): def original_decoder(self): r""" - Returns the decoder over the original code that will be used to decode words of + Return the decoder over the original code that will be used to decode words of :meth:`sage.coding.decoder.Decoder.code`. EXAMPLES:: @@ -368,7 +370,8 @@ def decode_to_code(self, y): sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'aa').list()[:13], 5) sage: Cs = codes.SubfieldSubcode(C, GF(4, 'a')) sage: D = codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs) - sage: Chan = channels.StaticErrorRateChannel(Cs.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(Cs.ambient_space(), + ....: D.decoding_radius()) sage: c = Cs.random_element() sage: y = Chan(c) sage: c == D.decode_to_code(y) @@ -399,7 +402,7 @@ def decode_to_code(self, y): def decoding_radius(self, **kwargs): r""" - Returns maximal number of errors ``self`` can decode. + Return the maximal number of errors ``self`` can decode. INPUT: diff --git a/src/sage/coding/two_weight_db.py b/src/sage/coding/two_weight_db.py index 1fb1f90ad84..44695300f33 100644 --- a/src/sage/coding/two_weight_db.py +++ b/src/sage/coding/two_weight_db.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Database of two-weight codes