Coding Theory
Release 10.4

The Sage Development TeamJul 23, 2024

CONTENTS

1

Codes

3

2

Channels

19

3

Encoders

31

4

Decoders

37

5

Index of channels

43

6

Index of code constructions

45

7

Index of decoders

47

8

Index of encoders

49

9

Index of bounds on the parameters of codes

51

10 Linear Codes

53

11 Families of Linear Codes

127

12 Derived Code Constructions

263

13 Decoding

281

14 Automorphism Groups of Linear Codes313

15 Bounds for Parameters of Linear Codes

325

16 Databases for Coding Theory343

17 Miscellaneous Modules

351

18 Indices and Tables

361

Python Module Index

363

Index

365

i

ii

Coding Theory, Release 10.4

Coding theory is the mathematical theory for algebraic and combinatorial codes used for forward error correction incommunications theory. Sage provides an extensive library of objects and algorithms in coding theory.
Basic objects in coding theory are codes, channels, encoders, and decoders. The following modules provide the baseclasses defining them.

CONTENTS

1

Coding Theory, Release 10.4

2

CONTENTSCHAPTER

ONE

CODES

Class supporting methods available for any type of code (linear, non-linear) and over any metric (Hamming, rank).
There are further abstract classes representing certain types of codes. For linear codes, AbstractLinearCodeNoMetric contains all the methods that any linear code can use regardless of its metric. Inheriting from this class are baseclasses for linear codes over specific metrics. For example, AbstractLinearCode is a base class for all linear codes
over the Hamming metric.
Take the class HammingCode. This class inherits from AbstractLinearCode, since it is a linear code over theHamming metric. AbstractLinearCode then inherits from AbstractLinearCodeNoMetric, since it is alinear code. Finally, this class inherits from AbstractCode, since it is a code.
The following diagram shows the inheritance relationship in the coding module:
AbstractCode+ AbstractLinearCodeNoMetric| + AbstractLinearCode| | + ParityCheckCode| | + HammingCode| | + CyclicCode| | + BCHCode| | + GolayCode| | + ReedMullerCode| | + GeneralizedReedSolomonCode| | + GoppaCode| + AbstractLinearRankMetricCodeAny class inheriting from AbstractCode can use the encode/decode framework.
The encoder/decoder framework within the coding module offers the creation and use of encoders/decoders independentlyof codes. An encoder encodes a message into a codeword. A decoder decodes a word into a codeword or a message,
possibly with error-correction.
Instead of creating specific encoders/decoders for every code family, some encoders/decoders can be used by multiple
code families. The encoder/decoder framework enables just that. For example, LinearCodeGeneratorMatrixEncoder can be used by any code that has a generator matrix. Similarly, LinearCodeNearestNeighborDecoder can be used for any linear code with Hamming metric.
When creating a new code family, investigate the encoder/decoder catalogs, codes.encoders and codes.
decoders, to see if there are suitable encoders/decoders for your code family already implemented. If this is thecase, follow the instructions in AbstractCode to set these up.
A new encoder must have the following methods:• encode – method encoding a message into a codeword• unencode – method decoding a codeword into a message

3

Coding Theory, Release 10.4

• message_space – ambient space of messages that can be encoded• code – code of the encoder
For more information about the Encoder class, see Encoder
A new decoder must have the following methods:• decode_to_code or decode_to_message – method decoding a word from the input space into either acodeword or a message• input_space – ambient space of words that can be decoded• code – code of the decoder
For more information about the Decoder class, see Decoderclass sage.coding.abstract_code.AbstractCode(length, default_encoder_name=None,default_decoder_name=None, metric='Hamming')
Bases: Parent
Abstract class for codes.
This class contains all the methods that can be used on any code and on any code family. As opposed to sage.
coding.linear_code.AbstractLinearCode, this class makes no assumptions about linearity, metric,
finiteness or the number of alphabets.
The abstract notion of “code” that is implicitly used for this class is any enumerable subset of a cartesian product𝐴1 × 𝐴2 × . . . × 𝐴𝑛 for some sets 𝐴𝑖 . Note that this class makes no attempt to directly represent the code inthis fashion, allowing subclasses to make the appropriate choices. The notion of metric is also not mathematicallyenforced in any way, and is simply stored as a string value.
Every code-related class should inherit from this abstract class.
To implement a code, you need to:• inherit from AbstractCode• call 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 not necessarily
have to have general encoders/decoders. However, if you want to use the encoding/decoding methods, youhave to add these.
• since this class does not specify any category, it is highly recommended to set up the category framework in the subclass. To do this, use the Parent.__init__(self, base, facade, category) function in the subclass constructor. A good example is in sage.coding.linear_code.
AbstractLinearCode.
• it is also recommended to override the ambient_space method, which is required by __call__• to use the encoder/decoder framework, one has to set up the category and related functions __iter__ and__contains__. A good example is in sage.coding.linear_code.AbstractLinearCode.
• add the following two lines on the class level:_registered_encoders = {}_registered_decoders = {}• fill the dictionary of its encoders in sage.coding.__init__.py file.
Example: I wantto link the encoder MyEncoderClass to MyNewCodeClass under the name MyEncoderName. All I need to do is to write this line in the __init__.py file: MyNewCodeClass.
_registered_encoders["NameOfMyEncoder"] = MyEncoderClass and all instances of
MyNewCodeClass will be able to use instances of MyEncoderClass.
4

Chapter 1. CodesCoding Theory, Release 10.4

• fill the dictionary of its decoders in sage.coding.__init__ file.
Example: I want tolink the encoder MyDecoderClass to MyNewCodeClass under the name MyDecoderName. All I need to do is to write this line in the __init__.py file: MyNewCodeClass.
_registered_decoders["NameOfMyDecoder"] = MyDecoderClass and all instances of
MyNewCodeClass will be able to use instances of MyDecoderClass.
As the 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.
add_decoder(name, decoder)
Adds an decoder to the list of registered decoders of self.
Note: This method only adds decoder to self, and not to any member of the class of self. To know
how to add an sage.coding.decoder.Decoder, please refer to the documentation of AbstractCode.
INPUT:• name – the string name for the decoder• decoder – the class name of the decoder
EXAMPLES:First of all, we create a (very basic) new decoder:sage: class MyDecoder(sage.coding.decoder.Decoder):....:def __init__(self, code):....:
super().__init__(code)....:
def _repr_(self):....:
return "MyDecoder decoder with associated code %s" % self.code()>>> from sage.all import *>>> class MyDecoder(sage.coding.decoder.Decoder):...
def __init__(self, code):...
super().__init__(code)...
def _repr_(self):...
return "MyDecoder decoder with associated code %s" % self.code()

We now create a new code:
sage: C = codes.HammingCode(GF(2), 3)>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))

We can add our new decoder to the list of available decoders of C:
sage: C.add_decoder("MyDecoder", MyDecoder)sage: sorted(C.decoders_available())[ InformationSet , MyDecoder , NearestNeighbor ,Syndrome ]>>> from sage.all import *>>> C.add_decoder("MyDecoder", MyDecoder)>>> sorted(C.decoders_available())[ InformationSet , MyDecoder , NearestNeighbor ,Syndrome ]5

Coding Theory, Release 10.4

We can verify that any new code will not know MyDecoder:sage: C2 = codes.HammingCode(GF(2), 3)
sage: sorted(C2.decoders_available())[ InformationSet , NearestNeighbor , Syndrome ]>>> from sage.all import *>>> C2 = codes.HammingCode(GF(Integer(2)), Integer(3))>>> sorted(C2.decoders_available())[ InformationSet , NearestNeighbor , Syndrome ]add_encoder(name, encoder)
Adds an encoder to the list of registered encoders of self.
Note: This method only adds encoder to self, and not to any member of the class of self. To know
how to add an sage.coding.encoder.Encoder, please refer to the documentation of AbstractCode.
INPUT:• name – the string name for the encoder• encoder – the class name of the encoder
EXAMPLES:First of all, we create a (very basic) new encoder:sage: class MyEncoder(sage.coding.encoder.Encoder):....:def __init__(self, code):....:
super().__init__(code)....:
def _repr_(self):....:
return "MyEncoder encoder with associated code %s" % self.code()>>> from sage.all import *>>> class MyEncoder(sage.coding.encoder.Encoder):...
def __init__(self, code):...
super().__init__(code)...
def _repr_(self):...
return "MyEncoder encoder with associated code %s" % self.code()

We now create a new code:
sage: C = codes.HammingCode(GF(2), 3)>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))

We can add our new encoder to the list of available encoders of C:
sage: C.add_encoder("MyEncoder", MyEncoder)sage: sorted(C.encoders_available())[ MyEncoder , Systematic ]>>> from sage.all import *>>> C.add_encoder("MyEncoder", MyEncoder)(continues on next page)

6

Chapter 1. CodesCoding Theory, Release 10.4

(continued from previous page)>>> sorted(C.encoders_available())[ MyEncoder , Systematic ]We can verify that any new code will not know MyEncoder:sage: C2 = codes.HammingCode(GF(2), 3)
sage: sorted(C2.encoders_available())[ Systematic ]>>> from sage.all import *>>> C2 = codes.HammingCode(GF(Integer(2)), Integer(3))>>> sorted(C2.encoders_available())[ Systematic ]ambient_space()
Return an error stating ambient_space of self is not implemented.
This method is required by __call__().
EXAMPLES:
sage: from sage.coding.abstract_code import AbstractCodesage: class MyCode(AbstractCode):....:
def __init__(self, length):....:
super().__init__(length)
sage: C = MyCode(3)sage: C.ambient_space()
Traceback (most recent call last):...
NotImplementedError: No ambient space implemented for this code.
>>> from sage.all import *>>> from sage.coding.abstract_code import AbstractCode>>> class MyCode(AbstractCode):...
def __init__(self, length):...
super().__init__(length)>>> C = MyCode(Integer(3))>>> C.ambient_space()
Traceback (most recent call last):...
NotImplementedError: No ambient space implemented for this code.

decode_to_code(word, decoder_name=None, *args, **kwargs)
Correct the errors in word and returns a codeword.
INPUT:• word – an element in the ambient space as self
• decoder_name – (default: None) Name of the decoder which will be used to decode word. The
default decoder of self will be used if default value is kept.
• args, kwargs – all additional arguments are forwarded to decoder()OUTPUT:• A vector of self.
EXAMPLES:
7

Coding Theory, Release 10.4

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))
sage: C.decode_to_code(w_err)(1, 1, 0, 0, 1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> word = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(1), Integer(1), Integer(0)))>>> w_err = word + vector(GF(Integer(2)), (Integer(1), Integer(0), Integer(0),˓→ Integer(0), Integer(0), Integer(0), Integer(0)))>>> C.decode_to_code(w_err)(1, 1, 0, 0, 1, 1, 0)

It is possible to manually choose the decoder amongst the list of the available ones:sage: sorted(C.decoders_available())[ InformationSet , NearestNeighbor , Syndrome ]sage: C.decode_to_code(w_err, NearestNeighbor )(1, 1, 0, 0, 1, 1, 0)>>> from sage.all import *>>> sorted(C.decoders_available())[ InformationSet , NearestNeighbor , Syndrome ]>>> C.decode_to_code(w_err, NearestNeighbor )(1, 1, 0, 0, 1, 1, 0)

decode_to_message(word, decoder_name=None, *args, **kwargs)
Correct the errors in word and decodes it to the message space.
INPUT:• word – an element in the ambient space as self
• decoder_name – (default: None) Name of the decoder which will be used to decode word. The
default decoder of self will be used if default value is kept.
• args, kwargs – all additional arguments are forwarded to decoder()OUTPUT:• A vector of the message space of 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: C = LinearCode(G)sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0))(continues on next page)

8

Chapter 1. CodesCoding Theory, Release 10.4

(continued from previous page)

sage: C.decode_to_message(word)(0, 1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> word = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(1), Integer(1), Integer(0)))>>> C.decode_to_message(word)(0, 1, 1, 0)

It is possible to manually choose the decoder amongst the list of the available ones:sage: sorted(C.decoders_available())[ InformationSet , NearestNeighbor , Syndrome ]sage: C.decode_to_message(word, NearestNeighbor )(0, 1, 1, 0)>>> from sage.all import *>>> sorted(C.decoders_available())[ InformationSet , NearestNeighbor , Syndrome ]>>> C.decode_to_message(word, NearestNeighbor )(0, 1, 1, 0)

decoder(decoder_name=None, *args, **kwargs)
Return a decoder of self.
INPUT:• decoder_name – (default: None) name of the decoder which will be returned. The default decoderof self will be used if default value is kept.
• args, kwargs – all additional arguments will be forwarded to the constructor of the decoder that will
be returned by this method
OUTPUT:• a decoder object
Besides creating the decoder and returning it, this method also stores the decoder in a cache. With thisbehaviour, each decoder will be created at most one time for 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: C = LinearCode(G)sage: C.decoder()Syndrome decoder for [7, 4] linear code over GF(2) handling errors of weight␣˓→up to 1

9

Coding Theory, Release 10.4>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> C.decoder()Syndrome decoder for [7, 4] linear code over GF(2) handling errors of weight␣˓→up to 1

If there is no decoder for the code, we return an error:
sage: from sage.coding.abstract_code import AbstractCodesage: class MyCodeFamily(AbstractCode):....:
def __init__(self, length, field):....:sage.coding.abstract_code.AbstractCode.__init__(self, length)....:
Parent.__init__(self, base=field, facade=False, category=Sets())....:
self._field = field....:def field(self):....:
return self._field....:
def _repr_(self):....:
return "%d dummy code over GF(%s)" % (self.length(), self.field().
˓→cardinality())
sage: D = MyCodeFamily(5, GF(2))
sage: D.decoder()Traceback (most recent call last):...
NotImplementedError: No decoder implemented for this code.
>>> from sage.all import *>>> from sage.coding.abstract_code import AbstractCode>>> class MyCodeFamily(AbstractCode):...
def __init__(self, length, field):...
sage.coding.abstract_code.AbstractCode.__init__(self, length)...
Parent.__init__(self, base=field, facade=False, category=Sets())...
self._field = field...
def field(self):...
return self._field...
def _repr_(self):...
return "%d dummy code over GF(%s)" % (self.length(), self.field().
˓→cardinality())>>> D = MyCodeFamily(Integer(5), GF(Integer(2)))>>> D.decoder()Traceback (most recent call last):...
NotImplementedError: No decoder implemented for this code.

If the name of a decoder which is not known by self is passed, an exception will be raised:sage: sorted(C.decoders_available())[ InformationSet , NearestNeighbor ,sage: C.decoder( Try )Traceback (most recent call last):...
ValueError: There is no Decoder named

Syndrome ]Try .
(continues on next page)10

Chapter 1. CodesCoding Theory, Release 10.4

(continued from previous page)The known Decoders are: [ InformationSet ,NearestNeighbor ,Syndrome ]>>> from sage.all import *>>> sorted(C.decoders_available())[ InformationSet , NearestNeighbor , Syndrome ]>>> C.decoder( Try )Traceback (most recent call last):...
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:sage: C.decoder( InformationSet )Traceback (most recent call last):...
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.
>>> from sage.all import *>>> C.decoder( InformationSet )Traceback (most recent call last):...
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.

decoders_available(classes=False)
Returns a list of the available decoders’ names for self.
INPUT:• classes – (default: False) if classes is set to True, return instead a dict mapping available
decoder name to the associated decoder class.
OUTPUT: a list of strings, or a 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: C = LinearCode(G)sage: C.decoders_available()[ InformationSet , NearestNeighbor , Syndrome ]sage: dictionary = C.decoders_available(True)
sage: sorted(dictionary.keys())(continues on next page)11

Coding Theory, Release 10.4

(continued from previous page)[ InformationSet , NearestNeighbor , Syndrome ]sage: dictionary[ NearestNeighbor ]<class sage.coding.linear_code.LinearCodeNearestNeighborDecoder >>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> C.decoders_available()[ InformationSet , NearestNeighbor , Syndrome ]>>> dictionary = C.decoders_available(True)>>> sorted(dictionary.keys())[ InformationSet , NearestNeighbor , Syndrome ]>>> dictionary[ NearestNeighbor ]<class sage.coding.linear_code.LinearCodeNearestNeighborDecoder >encode(word, encoder_name=None, *args, **kwargs)
Transforms an element of a message space into a codeword.
INPUT:• word – an element of a message space of the code
• encoder_name – (default: None) Name of the encoder which will be used to encode word. The
default encoder of self will be used if default value is kept.
• args, kwargs – all additional arguments are forwarded to the construction of the encoder that is used..
One can use the following shortcut to encode a word
C(word)OUTPUT:• a vector of 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: C = LinearCode(G)sage: word = vector((0, 1, 1, 0))
sage: C.encode(word)(1, 1, 0, 0, 1, 1, 0)
sage: C(word)(1, 1, 0, 0, 1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),(continues on next page)

12

Chapter 1. CodesCoding Theory, Release 10.4

(continued from previous page)

Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> word = vector((Integer(0), Integer(1), Integer(1), Integer(0)))>>> C.encode(word)(1, 1, 0, 0, 1, 1, 0)>>> C(word)(1, 1, 0, 0, 1, 1, 0)˓→It is possible to manually choose the encoder amongst the list of the available ones:sage: sorted(C.encoders_available())[ GeneratorMatrix , Systematic ]sage: word = vector((0, 1, 1, 0))
sage: C.encode(word, GeneratorMatrix )(1, 1, 0, 0, 1, 1, 0)>>> from sage.all import *>>> sorted(C.encoders_available())[ GeneratorMatrix , Systematic ]>>> word = vector((Integer(0), Integer(1), Integer(1), Integer(0)))>>> C.encode(word, GeneratorMatrix )(1, 1, 0, 0, 1, 1, 0)

encoder(encoder_name=None, *args, **kwargs)
Returns an encoder of self.
The returned encoder provided by this method is cached.
This methods creates a new instance of the encoder subclass designated by encoder_name. While it is also
possible to do the same by directly calling the subclass’ constructor, it is strongly advised to use this method
to take advantage of the caching mechanism.
INPUT:• encoder_name – (default: None) name of the encoder which will be returned. The default encoderof self will be used if default value is kept.
• args, kwargs – all additional arguments are forwarded to the constructor of the encoder this method
will return.
OUTPUT:• an Encoder object.
Note: The default encoder always has 𝐹 𝑘 as message space, with 𝑘 the dimension of self and 𝐹 the basering of 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: C = LinearCode(G)sage: C.encoder()Generator matrix-based encoder for [7, 4] linear code over GF(2)13

Coding Theory, Release 10.4>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> C.encoder()Generator matrix-based encoder for [7, 4] linear code over GF(2)If there is no encoder for the code, we return an error:
sage: from sage.coding.abstract_code import AbstractCodesage: class MyCodeFamily(AbstractCode):....:
def __init__(self, length, field):....:sage.coding.abstract_code.AbstractCode.__init__(self, length)....:
Parent.__init__(self, base=field, facade=False, category=Sets())....:
self._field = field....:def field(self):....:
return self._field....:
def _repr_(self):....:
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):...
NotImplementedError: No encoder implemented for this code.
>>> from sage.all import *>>> from sage.coding.abstract_code import AbstractCode>>> class MyCodeFamily(AbstractCode):...
def __init__(self, length, field):...
sage.coding.abstract_code.AbstractCode.__init__(self, length)...
Parent.__init__(self, base=field, facade=False, category=Sets())...
self._field = field...
def field(self):...
return self._field...
def _repr_(self):...
return "%d dummy code over GF(%s)" % (self.length(),...
self.field().cardinality())>>> D = MyCodeFamily(Integer(5), GF(Integer(2)))>>> D.encoder()Traceback (most recent call last):...
NotImplementedError: No encoder implemented for this code.

We check that the returned encoder is cached:sage: C.encoder.is_in_cache()True>>> from sage.all import *>>> C.encoder.is_in_cache()
True

14

Chapter 1. CodesCoding Theory, Release 10.4

If the name of an encoder which is not known by self is passed, an exception will be raised:sage: sorted(C.encoders_available())[ GeneratorMatrix , Systematic ]sage: C.encoder( NonExistingEncoder )Traceback (most recent call last):...
ValueError: There is no Encoder named NonExistingEncoder .
The known Encoders are: [ GeneratorMatrix , Systematic ]>>> from sage.all import *>>> sorted(C.encoders_available())[ GeneratorMatrix , Systematic ]>>> C.encoder( NonExistingEncoder )Traceback (most recent call last):...
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: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.
>>> from sage.all import *>>> 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.

encoders_available(classes=False)
Returns a list of the available encoders’ names for self.
INPUT:• classes – (default: False) if classes is set to True, return instead a dict mapping available
encoder name to the associated encoder class.
OUTPUT: a list of strings, or a 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: C = LinearCode(G)(continues on next page)

15

Coding Theory, Release 10.4

(continued from previous page)

sage: C.encoders_available()[ GeneratorMatrix , Systematic ]sage: dictionary = C.encoders_available(True)
sage: sorted(dictionary.items())[( GeneratorMatrix , <class sage.coding.linear_code.
˓→LinearCodeGeneratorMatrixEncoder >),( Systematic , <class sage.coding.linear_code_no_metric.
˓→LinearCodeSystematicEncoder >)]>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> C.encoders_available()[ GeneratorMatrix , Systematic ]>>> dictionary = C.encoders_available(True)>>> sorted(dictionary.items())[( GeneratorMatrix , <class sage.coding.linear_code.
˓→LinearCodeGeneratorMatrixEncoder >),( Systematic , <class sage.coding.linear_code_no_metric.
˓→LinearCodeSystematicEncoder >)]length()Returns the length of this code.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.length()
7>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.length()7list()
Return a list of all elements of this code.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: Clist = C.list()
sage: Clist[5]; Clist[5] in C
(1, 0, 1, 0, 1, 0, 1)
True>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> Clist = C.list()>>> Clist[Integer(5)]; Clist[Integer(5)] in C
(continues on next page)

16

Chapter 1. CodesCoding Theory, Release 10.4

(continued from previous page)(1, 0, 1, 0, 1, 0, 1)
True

metric()Return the metric of self.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.metric()
Hamming>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.metric()
Hamming

random_element(*args, **kwds)
Returns a random codeword; passes other positional and keyword arguments to random_element()
method of vector space.
OUTPUT:• Random element of the vector space of this code
EXAMPLES:
sage: C = codes.HammingCode(GF(4, a ), 3)
sage: C.random_element() # random test
(1, 0, 0, a + 1, 1, a, a, a + 1, a + 1, 1, 1, 0, a + 1, a, 0, a, a, 0, a, a,␣
˓→1)>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(4), a ), Integer(3))>>> C.random_element() # random test
(1, 0, 0, a + 1, 1, a, a, a + 1, a + 1, 1, 1, 0, a + 1, a, 0, a, a, 0, a, a,␣˓→1)Passes extra positional or keyword arguments through:sage: C.random_element(prob=.5, distribution= 1/n ) # random test
(1, 0, a, 0, 0, 0, 0, a + 1, 0, 0, 0, 0, 0, 0, 0, 0, a + 1, a + 1, 1, 0, 0)>>> from sage.all import *>>> C.random_element(prob=RealNumber( .5 ), distribution= 1/n ) # random test
(1, 0, a, 0, 0, 0, 0, a + 1, 0, 0, 0, 0, 0, 0, 0, 0, a + 1, a + 1, 1, 0, 0)

unencode(c, encoder_name=None, nocheck=False, **kwargs)
Returns the message corresponding to c.
This is the inverse of encode().
INPUT:• c – a codeword of self.
• encoder_name – (default: None) name of the decoder which will be used to decode word. The
default decoder of self will be used if default value is kept.
17

Coding Theory, Release 10.4

• nocheck – (default: False) checks if c is in self. You might set this to True to disable the checkfor saving computation. Note that if c is not in self and nocheck = True, then the output of
unencode() is not defined (except that it will be in the message space of self).
• kwargs – all additional arguments are forwarded to the construction of the encoder that is used.
OUTPUT:• an element of the message space of encoder_name of 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: C = LinearCode(G)sage: c = vector(GF(2), (1, 1, 0, 0, 1, 1, 0))
sage: C.unencode(c)(0, 1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> c = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(1), Integer(1), Integer(0)))>>> C.unencode(c)(0, 1, 1, 0)

18

Chapter 1. Codes

CHAPTERTWO

CHANNELS

Given an input space and an output space, a channel takes element from the input space (the message) and transforms it
into an element of the output space (the transmitted message).
In Sage, Channels simulate error-prone transmission over communication channels, and we borrow the nomenclature from
communication theory, such as “transmission” and “positions” as the elements of transmitted vectors. Transmission canbe achieved with two methods:• Channel.transmit(). Considering a channel Chan and a message msg, transmitting msg with Chan canbe done this way:
Chan.transmit(msg)

It can also be written in a more convenient way:
Chan(msg)• transmit_unsafe(). This does the exact same thing as transmit() except that it does not check if msg
belongs to the input space of Chan:
Chan.transmit_unsafe(msg)This is useful in e.g. an inner-loop of a long simulation as a lighter-weight alternative to Channel.transmit().
This file contains the following elements:• Channel, the abstract class for Channels• StaticErrorRateChannel, which creates a specific number of errors in each transmitted message• ErrorErasureChannel, which creates a specific number of errors and a specific number of erasures in eachtransmitted message
class sage.coding.channel.Channel(input_space, output_space)
Bases: SageObject
Abstract top-class for Channel objects.
All channel objects must inherit from this class. To implement a channel subclass, one should do the following:• inherit from this class,• call the super constructor,• override transmit_unsafe().
While not being mandatory, it might be useful to reimplement representation methods (_repr_ and _latex_).
This abstract class provides the following parameters:

19

Coding Theory, Release 10.4

• input_space – the space of the words to transmit• output_space – the space of the transmitted words
input_space()
Return the input space of self.
EXAMPLES:
sage: n_err = 2
sage: Chan = channels.StaticErrorRateChannel(GF(59)^6, n_err)
sage: Chan.input_space()
Vector space of dimension 6 over Finite Field of size 59>>> from sage.all import *>>> n_err = Integer(2)>>> Chan = channels.StaticErrorRateChannel(GF(Integer(59))**Integer(6), n_err)>>> Chan.input_space()
Vector space of dimension 6 over Finite Field of size 59

output_space()
Return the output space of self.
EXAMPLES:
sage: n_err = 2
sage: Chan = channels.StaticErrorRateChannel(GF(59)^6, n_err)
sage: Chan.output_space()
Vector space of dimension 6 over Finite Field of size 59>>> from sage.all import *>>> n_err = Integer(2)>>> Chan = channels.StaticErrorRateChannel(GF(Integer(59))**Integer(6), n_err)>>> Chan.output_space()
Vector space of dimension 6 over Finite Field of size 59

transmit(message)
Return message, modified accordingly with the algorithm of the channel it was transmitted through.
Checks if message belongs to the input space, and returns an exception if not. Note that message itself
is never modified by the channel.
INPUT:• message – a vector
OUTPUT:• a vector of the output space of self
EXAMPLES:
sage: F = GF(59)^6
sage: n_err = 2
sage: Chan = channels.StaticErrorRateChannel(F, n_err)
sage: msg = F((4, 8, 15, 16, 23, 42))
sage: set_random_seed(10)sage: Chan.transmit(msg)(4, 8, 4, 16, 23, 53)

20

Chapter 2. Channels

Coding Theory, Release 10.4>>> from sage.all import *>>> F = GF(Integer(59))**Integer(6)>>> n_err = Integer(2)>>> Chan = channels.StaticErrorRateChannel(F, n_err)>>> msg = F((Integer(4), Integer(8), Integer(15), Integer(16), Integer(23),␣
˓→Integer(42)))>>> set_random_seed(Integer(10))>>> Chan.transmit(msg)(4, 8, 4, 16, 23, 53)

We can check that the input msg is not modified:sage: msg
(4, 8, 15, 16, 23, 42)>>> from sage.all import *>>> msg(4, 8, 15, 16, 23, 42)

If we transmit a vector which is not in the input space of self:
sage: n_err = 2
sage: Chan = channels.StaticErrorRateChannel(GF(59)^6, n_err)
sage: msg = (4, 8, 15, 16, 23, 42)
sage: Chan.transmit(msg)
Traceback (most recent call last):...
TypeError: Message must be an element of the input space for the given channel>>> from sage.all import *>>> n_err = Integer(2)>>> Chan = channels.StaticErrorRateChannel(GF(Integer(59))**Integer(6), n_err)>>> msg = (Integer(4), Integer(8), Integer(15), Integer(16), Integer(23),␣
˓→Integer(42))>>> Chan.transmit(msg)
Traceback (most recent call last):...
TypeError: Message must be an element of the input space for the given channel

Note:
One can also call directly Chan(message), which does the same as Chan.
transmit(message)transmit_unsafe(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 is an abstract method which should be reimplemented in all the subclasses of Channel.
EXAMPLES:
sage: n_err = 2
sage: Chan = channels.StaticErrorRateChannel(GF(59)^6, n_err)
sage: v = Chan.input_space().random_element()
sage: Chan.transmit_unsafe(v) # random(1, 33, 46, 18, 20, 49)

21

Coding Theory, Release 10.4>>> from sage.all import *>>> n_err = Integer(2)>>> Chan = channels.StaticErrorRateChannel(GF(Integer(59))**Integer(6), n_err)>>> v = Chan.input_space().random_element()>>> Chan.transmit_unsafe(v) # random(1, 33, 46, 18, 20, 49)class sage.coding.channel.ErrorErasureChannel(space, number_errors, number_erasures)
Bases: Channel
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 F2 .
INPUT:• space – the input and output space• number_errors – the number of errors created in each transmitted message. It can be either an integerof a tuple. If a tuple is passed as an argument, the number of errors will be a random integer between the twobounds of this tuple.
• number_erasures – the number of erasures created in each transmitted message. It can be either an
integer of a tuple. If a tuple is passed as an argument, the number of erasures will be a random integer
between the two bounds of this tuple.
EXAMPLES:
We construct a ErrorErasureChannel which adds 2 errors and 2 erasures to any transmitted message:
sage: n_err, n_era = 2, 2
sage: Chan = channels.ErrorErasureChannel(GF(59)^40, n_err, n_era)
sage: Chan
Error-and-erasure channel creating 2 errors and 2 erasuresof input space Vector space of dimension 40 over Finite Field of size 59
and output space The Cartesian product of (Vector space of dimension 40
over Finite Field of size 59, Vector space of dimension 40 over Finite Field of␣˓→size 2)>>> from sage.all import *>>> n_err, n_era = Integer(2), Integer(2)>>> Chan = channels.ErrorErasureChannel(GF(Integer(59))**Integer(40), n_err, n_
˓→era)>>> ChanError-and-erasure channel creating 2 errors and 2 erasuresof input space Vector space of dimension 40 over Finite Field of size 59
and output space The Cartesian product of (Vector space of dimension 40
over Finite Field of size 59, Vector space of dimension 40 over Finite Field of␣˓→size 2)

We can also pass the number of errors and erasures as a couple of integers:
sage: n_err, n_era = (1, 10), (1, 10)
sage: Chan = channels.ErrorErasureChannel(GF(59)^40, n_err, n_era)
sage: Chan
Error-and-erasure channel creating between 1 and 10 errors andbetween 1 and 10 erasures of input space Vector space of dimension 40
over Finite Field of size 59 and output space The Cartesian product of(continues on next page)

22

Chapter 2. Channels

Coding Theory, Release 10.4

(continued from previous page)(Vector space of dimension 40 over Finite Field of size 59,
Vector space of dimension 40 over Finite Field of size 2)>>> from sage.all import *>>> n_err, n_era = (Integer(1), Integer(10)), (Integer(1), Integer(10))>>> Chan = channels.ErrorErasureChannel(GF(Integer(59))**Integer(40), n_err, n_
˓→era)>>> ChanError-and-erasure channel creating between 1 and 10 errors andbetween 1 and 10 erasures of input space Vector space of dimension 40
over Finite Field of size 59 and output space The Cartesian product of(Vector space of dimension 40 over Finite Field of size 59,
Vector space of dimension 40 over Finite Field of size 2)

number_erasures()
Return the number of erasures created by self.
EXAMPLES:
sage: n_err, n_era = 0, 3
sage: Chan = channels.ErrorErasureChannel(GF(59)^6, n_err, n_era)
sage: Chan.number_erasures()(3, 3)>>> from sage.all import *>>> n_err, n_era = Integer(0), Integer(3)>>> Chan = channels.ErrorErasureChannel(GF(Integer(59))**Integer(6), n_err, n_
˓→era)>>> Chan.number_erasures()(3, 3)

number_errors()
Return the number of errors created by self.
EXAMPLES:
sage: n_err, n_era = 3, 0
sage: Chan = channels.ErrorErasureChannel(GF(59)^6, n_err, n_era)
sage: Chan.number_errors()(3, 3)>>> from sage.all import *>>> n_err, n_era = Integer(3), Integer(0)>>> Chan = channels.ErrorErasureChannel(GF(Integer(59))**Integer(6), n_err, n_
˓→era)>>> Chan.number_errors()(3, 3)

transmit_unsafe(message)
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 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. It does the same with self.
_number_erasures.

23

Coding Theory, Release 10.4

All erased positions are set to 0 in the transmitted message. It is guaranteed that the erasures and the errors
will never overlap: 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.
INPUT:• message – a vector
OUTPUT:• 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 and 0 elsewhere.
EXAMPLES:
sage: F = GF(59)^11
sage: n_err, n_era = 2, 2
sage: Chan = channels.ErrorErasureChannel(F, n_err, n_era)
sage: msg = F((3, 14, 15, 9, 26, 53, 58, 9, 7, 9, 3))
sage: set_random_seed(10)sage: Chan.transmit_unsafe(msg)((31, 0, 15, 9, 38, 53, 58, 9, 0, 9, 3), (0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0))>>> from sage.all import *>>> F = GF(Integer(59))**Integer(11)>>> n_err, n_era = Integer(2), Integer(2)>>> Chan = channels.ErrorErasureChannel(F, n_err, n_era)>>> msg = F((Integer(3), Integer(14), Integer(15), Integer(9), Integer(26),␣
˓→Integer(53), Integer(58), Integer(9), Integer(7), Integer(9), Integer(3)))>>> set_random_seed(Integer(10))>>> Chan.transmit_unsafe(msg)((31, 0, 15, 9, 38, 53, 58, 9, 0, 9, 3), (0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0))class sage.coding.channel.QarySymmetricChannel(space, epsilon)
Bases: Channel
The 𝑞-ary symmetric, memoryless communication channel.
Given an alphabet Σ with |Σ| = 𝑞 and an error probability 𝜖, a 𝑞-ary symmetric channel sends an element of Σ𝜖into the same element with probability 1 − 𝜖, and any one of the other 𝑞 − 1 elements with probability 𝑞−1. This𝑛
implementation operates over vectors in Σ , and “transmits” each element of the vector independently in the above
manner.
Though Σ is usually taken to be a finite field, this implementation allows any structure for which Sage can represent
Σ𝑛 and for which Σ has a random_element() method. However, beware that if Σ is infinite, errors will not
be uniformly distributed (since random_element() does not draw uniformly at random).
The input space and the output space of this channel are the same: Σ𝑛 .
INPUT:• space – the input and output space of the channel. It has to be F𝑛𝑞 for some finite field F𝑞 .
• epsilon – the transmission error probability of the individual elements.
EXAMPLES:
We construct a QarySymmetricChannel which corrupts 30% of all transmitted symbols:

24

Chapter 2. Channels

Coding Theory, Release 10.4

sage: epsilon = 0.3
sage: Chan = channels.QarySymmetricChannel(GF(59)^50, epsilon)
sage: Chanq-ary symmetric channel with error probability 0.300000000000000,
of input and output space
Vector space of dimension 50 over Finite Field of size 59>>> from sage.all import *>>> epsilon = RealNumber( 0.3 )>>> Chan = channels.QarySymmetricChannel(GF(Integer(59))**Integer(50), epsilon)>>> Chanq-ary symmetric channel with error probability 0.300000000000000,
of input and output space
Vector space of dimension 50 over Finite Field of size 59

error_probability()
Return the error probability of a single symbol transmission of self.
EXAMPLES:
sage: epsilon = 0.3
sage: Chan = channels.QarySymmetricChannel(GF(59)^50, epsilon)
sage: Chan.error_probability()
0.300000000000000>>> from sage.all import *>>> epsilon = RealNumber( 0.3 )>>> Chan = channels.QarySymmetricChannel(GF(Integer(59))**Integer(50),␣
˓→epsilon)>>> Chan.error_probability()
0.300000000000000

probability_of_at_most_t_errors(t)Return the probability self has to return at most t errors.
INPUT:• t – an integer
EXAMPLES:
sage: epsilon = 0.3
sage: Chan = channels.QarySymmetricChannel(GF(59)^50, epsilon)
sage: Chan.probability_of_at_most_t_errors(20)0.952236164579467>>> from sage.all import *>>> epsilon = RealNumber( 0.3 )>>> Chan = channels.QarySymmetricChannel(GF(Integer(59))**Integer(50),␣
˓→epsilon)>>> Chan.probability_of_at_most_t_errors(Integer(20))
0.952236164579467

probability_of_exactly_t_errors(t)Return the probability self has to return exactly t errors.
INPUT:

25

Coding Theory, Release 10.4

• t – an integer
EXAMPLES:
sage: epsilon = 0.3
sage: Chan = channels.QarySymmetricChannel(GF(59)^50, epsilon)
sage: Chan.probability_of_exactly_t_errors(15)0.122346861835401>>> from sage.all import *>>> epsilon = RealNumber( 0.3 )>>> Chan = channels.QarySymmetricChannel(GF(Integer(59))**Integer(50),␣
˓→epsilon)>>> Chan.probability_of_exactly_t_errors(Integer(15))
0.122346861835401

transmit_unsafe(message)
Return message where each of the symbols has been changed to another from the alphabet with probability
error_probability().
This method does not check if message belongs to the input space of self.
INPUT:• message – a vector
EXAMPLES:
sage: F = GF(59)^11
sage: epsilon = 0.3
sage: Chan = channels.QarySymmetricChannel(F, epsilon)
sage: msg = F((3, 14, 15, 9, 26, 53, 58, 9, 7, 9, 3))
sage: set_random_seed(10)sage: Chan.transmit_unsafe(msg)(3, 14, 15, 53, 12, 53, 58, 9, 55, 9, 3)>>> from sage.all import *>>> F = GF(Integer(59))**Integer(11)>>> epsilon = RealNumber( 0.3 )>>> Chan = channels.QarySymmetricChannel(F, epsilon)>>> msg = F((Integer(3), Integer(14), Integer(15), Integer(9), Integer(26),␣
˓→Integer(53), Integer(58), Integer(9), Integer(7), Integer(9), Integer(3)))>>> set_random_seed(Integer(10))>>> Chan.transmit_unsafe(msg)(3, 14, 15, 53, 12, 53, 58, 9, 55, 9, 3)class sage.coding.channel.StaticErrorRateChannel(space, number_errors)
Bases: Channel
Channel which adds a static number of errors to each message it transmits.
The input space and the output space of this channel are the same.
INPUT:• space – the space of both input and output• number_errors – the number of errors added to each transmitted message It can be either an integer of atuple. If a tuple is passed as argument, the number of errors will be a random integer between the two boundsof the tuple.

26

Chapter 2. Channels

Coding Theory, Release 10.4

EXAMPLES:
We construct a StaticErrorRateChannel which adds 2 errors to any transmitted message:
sage: n_err = 2
sage: Chan = channels.StaticErrorRateChannel(GF(59)^40, n_err)
sage: Chan
Static error rate channel creating 2 errors, of input and output space
Vector space of dimension 40 over Finite Field of size 59>>> from sage.all import *>>> n_err = Integer(2)>>> Chan = channels.StaticErrorRateChannel(GF(Integer(59))**Integer(40), n_err)>>> ChanStatic error rate channel creating 2 errors, of input and output space
Vector space of dimension 40 over Finite Field of size 59

We can also pass a tuple for the number of errors:
sage: n_err = (1, 10)
sage: Chan = channels.StaticErrorRateChannel(GF(59)^40, n_err)
sage: Chan
Static error rate channel creating between 1 and 10 errors,of input and output space Vector space of dimension 40 over Finite Field of size␣
˓→59>>> from sage.all import *>>> n_err = (Integer(1), Integer(10))>>> Chan = channels.StaticErrorRateChannel(GF(Integer(59))**Integer(40), n_err)>>> ChanStatic error rate channel creating between 1 and 10 errors,of input and output space Vector space of dimension 40 over Finite Field of size␣
˓→59

number_errors()
Return the number of errors created by self.
EXAMPLES:
sage: n_err = 3
sage: Chan = channels.StaticErrorRateChannel(GF(59)^6, n_err)
sage: Chan.number_errors()(3, 3)>>> from sage.all import *>>> n_err = Integer(3)>>> Chan = channels.StaticErrorRateChannel(GF(Integer(59))**Integer(6), n_err)>>> Chan.number_errors()(3, 3)

transmit_unsafe(message)
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.
INPUT:
27

Coding Theory, Release 10.4

• message – a vector
OUTPUT:• a vector of the output space
EXAMPLES:
sage: F = GF(59)^6
sage: n_err = 2
sage: Chan = channels.StaticErrorRateChannel(F, n_err)
sage: msg = F((4, 8, 15, 16, 23, 42))
sage: set_random_seed(10)sage: Chan.transmit_unsafe(msg)(4, 8, 4, 16, 23, 53)>>> from sage.all import *>>> F = GF(Integer(59))**Integer(6)>>> n_err = Integer(2)>>> Chan = channels.StaticErrorRateChannel(F, n_err)>>> msg = F((Integer(4), Integer(8), Integer(15), Integer(16), Integer(23),␣
˓→Integer(42)))>>> set_random_seed(Integer(10))>>> Chan.transmit_unsafe(msg)(4, 8, 4, 16, 23, 53)

This checks that Issue #19863 is fixed:
sage: V = VectorSpace(GF(2), 1000)
sage: Chan = channels.StaticErrorRateChannel(V, 367)
sage: c = V.random_element()
sage: (c - Chan(c)).hamming_weight()
367>>> from sage.all import *>>> V = VectorSpace(GF(Integer(2)), Integer(1000))>>> Chan = channels.StaticErrorRateChannel(V, Integer(367))>>> c = V.random_element()>>> (c - Chan(c)).hamming_weight()
367

sage.coding.channel.format_interval(t)Return a formatted string representation of t.
This method should be called by any representation function in Channel classes.
Note: This is a helper function, which should only be used when implementing new channels.
INPUT:• t – a list or a tuple
OUTPUT:• a string
sage.coding.channel.random_error_vector(n, F, error_positions)
Return a vector of length n over F filled with random non-zero coefficients at the positions given by error_positions.
28

Chapter 2. Channels

Coding Theory, Release 10.4

Note: This is a helper function, which should only be used when implementing new channels.
INPUT:• n – the length of the vector• F – the field over which the vector is defined• error_positions – the non-zero positions of the vector
OUTPUT:• a vector of F
AUTHORS:This function is taken from codinglib (https://bitbucket.org/jsrn/codinglib/) and was written by Johan Nielsen.
EXAMPLES:
sage: from sage.coding.channel import random_error_vector
sage: random_error_vector(5, GF(2), [1,3])(0, 1, 0, 1, 0)>>> from sage.all import *>>> from sage.coding.channel import random_error_vector>>> random_error_vector(Integer(5), GF(Integer(2)), [Integer(1),Integer(3)])(0, 1, 0, 1, 0)

29

Coding Theory, Release 10.4

30

Chapter 2. Channels

CHAPTER

THREE

ENCODERS

Representation of a bijection between a message space and a code.
AUTHORS:• David Lucas (2015): initial version
class sage.coding.encoder.Encoder(code)
Bases: SageObject
Abstract top-class for Encoder objects.
Every encoder class for linear codes (of any metric) should inherit from this abstract class.
To implement an encoder, you need to:• inherit from Encoder,• call Encoder.__init__ in the subclass constructor. Example: super().__init__(code). By
doing that, your subclass will have its code parameter initialized.
• Then, if the message space is a vector space, default implementations of encode() and unencode_nocheck() methods are provided. These implementations rely on generator_matrix()
which you need to override to use the default implementations.
• If the message space is not of the form 𝐹 𝑘 , where 𝐹 is a finite field, you cannot have a generator matrix. In
that case, you need to override encode(), unencode_nocheck() and message_space().
• By default, comparison of Encoder (using methods __eq__ and __ne__ ) are by memory reference:
if you build the same encoder twice, they will be different. If you need something more clever, override__eq__ and __ne__ in your subclass.
• As Encoder is not designed to be instantiated, it does not have any representation methods. You should
implement _repr_ and _latex_ methods in the subclass.
REFERENCES:• [Nie]code()
Returns the code for this Encoder.
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: C = LinearCode(G)sage: E = C.encoder()sage: E.code() == C
True

31

Coding Theory, Release 10.4>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> E = C.encoder()>>> E.code() == C
True

encode(word)
Transforms an element of the message space into a codeword.
This is a default implementation which assumes that the message space of the encoder is 𝐹 𝑘 , where𝐹issage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric.
base_field()and𝑘issage.coding.linear_code_no_metric.
AbstractLinearCodeNoMetric.dimension(). If this is not the case, this method shouldbe overwritten by the subclass.
Note: encode() might be a partial function over self’s message_space(). One should use theexception EncodingError to catch attempts to encode words that are outside of the message space.
One can use the following shortcut to encode a word with an encoder E:E(word)INPUT:• word – a vector of the message space of the self.
OUTPUT:• a vector of code().
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: C = LinearCode(G)sage: word = vector(GF(2), (0, 1, 1, 0))
sage: E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)sage: E.encode(word)(1, 1, 0, 0, 1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> word = vector(GF(Integer(2)), (Integer(0), Integer(1), Integer(1),␣
˓→Integer(0)))(continues on next page)

32

Chapter 3. Encoders

Coding Theory, Release 10.4

(continued from previous page)>>> E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)>>> E.encode(word)(1, 1, 0, 0, 1, 1, 0)

If word is not in the message space of self, it will return an exception:
sage: word = random_vector(GF(7), 4)
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>>> from sage.all import *>>> word = random_vector(GF(Integer(7)), Integer(4))>>> 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

generator_matrix()
Returns a generator matrix of the associated code of self.
This is an abstract method and it should be implemented separately. Reimplementing this for each subclassof Encoder is not mandatory (as a generator matrix only makes sense when the message space is of the 𝐹 𝑘 ,where 𝐹 is the base field of code().)
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: C = LinearCode(G)sage: E = C.encoder()sage: E.generator_matrix()[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]>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> E = C.encoder()>>> E.generator_matrix()[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]

message_space()

33

Coding Theory, Release 10.4

Returns the ambient space of allowed input to encode(). Note that encode() is possibly a partial function over the ambient space.
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: C = LinearCode(G)sage: E = C.encoder()sage: E.message_space()
Vector space of dimension 4 over Finite Field of size 2>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> E = C.encoder()>>> E.message_space()
Vector space of dimension 4 over Finite Field of size 2

unencode(c, nocheck=False)
Return the message corresponding to the codeword c.
This is the inverse of encode().
INPUT:• c – a codeword of code().
• nocheck – (default: False) checks if c is in code(). You might set this to True to disable thecheck for saving computation. Note that if c is not in self() and nocheck = True, then the
output of unencode() is not defined (except that it will be in the message space of self).
OUTPUT:• an element of the message space of 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: C = LinearCode(G)sage: c = vector(GF(2), (1, 1, 0, 0, 1, 1, 0))
sage: c in C
True
sage: E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)sage: E.unencode(c)(0, 1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),(continues on next page)

34

Chapter 3. Encoders

Coding Theory, Release 10.4

(continued from previous page)

Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> c = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(1), Integer(1), Integer(0)))>>> c in C
True>>> E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)>>> E.unencode(c)(0, 1, 1, 0)
˓→unencode_nocheck(c)Returns the message corresponding to c.
When c is not a codeword, the output is unspecified.
AUTHORS:This function is taken from codinglib [Nie]INPUT:• c – a codeword of code().
OUTPUT:• an element of the message space of 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: C = LinearCode(G)sage: c = vector(GF(2), (1, 1, 0, 0, 1, 1, 0))
sage: c in C
True
sage: E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)sage: E.unencode_nocheck(c)(0, 1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> c = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(1), Integer(1), Integer(0)))>>> c in C
True>>> E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)>>> E.unencode_nocheck(c)(0, 1, 1, 0)

Taking a vector that does not belong to C will not raise an error but probably just give a non-sensical result:35

Coding Theory, Release 10.4

sage: c = vector(GF(2), (1, 1, 0, 0, 1, 1, 1))
sage: c in C
False
sage: E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)sage: E.unencode_nocheck(c)(0, 1, 1, 0)
sage: m = vector(GF(2), (0, 1, 1, 0))
sage: c1 = E.encode(m)sage: c == c1
False>>> from sage.all import *>>> c = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(1), Integer(1), Integer(1)))>>> c in C
False>>> E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)>>> E.unencode_nocheck(c)(0, 1, 1, 0)>>> m = vector(GF(Integer(2)), (Integer(0), Integer(1), Integer(1),␣
˓→Integer(0)))>>> c1 = E.encode(m)>>> c == c1
False

exception sage.coding.encoder.EncodingError
Bases: Exception
Special exception class to indicate an error during encoding or unencoding.

36

Chapter 3. Encoders

CHAPTERFOURDECODERS

Representation of an error-correction algorithm for a code.
AUTHORS:• David Joyner (2009-02-01): initial version• David Lucas (2015-06-29): abstract class version
class sage.coding.decoder.Decoder(code, input_space, connected_encoder_name)
Bases: SageObject
Abstract top-class for Decoder objects.
Every decoder class for linear codes (of any metric) should inherit from this abstract class.
To implement a decoder, you need to:• inherit from Decoder• call Decoder.__init__ in the subclass constructor. Example: super().__init__(code,
input_space, connected_encoder_name). By doing that, your subclass will have all the parameters described above initialized.
• Then, you need to override one of decoding methods, either decode_to_code() or decode_to_message(). You can also override the optional method decoding_radius().
• By default, comparison of Decoder (using methods __eq__ and __ne__ ) are by memory reference:
if you build the same decoder twice, they will be different. If you need something more clever, override__eq__ and __ne__ in your subclass.
• As Decoder is not designed to be instantiated, it does not have any representation methods. You should
implement _repr_ and _latex_ methods in the subclass.
code()
Return the code for this Decoder.
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: C = LinearCode(G)sage: D = C.decoder()sage: D.code()[7, 4] linear code over GF(2)37

Coding Theory, Release 10.4>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> D = C.decoder()>>> D.code()[7, 4] linear code over GF(2)connected_encoder()Return the connected encoder of 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: C = LinearCode(G)sage: D = C.decoder()sage: D.connected_encoder()Generator matrix-based encoder for [7, 4] linear code over GF(2)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> D = C.decoder()>>> D.connected_encoder()Generator matrix-based encoder for [7, 4] linear code over GF(2)decode_to_code(r)Correct the errors in r and return a codeword.
This is a default implementation which assumes that the method decode_to_message() has been implemented, else it returns an exception.
INPUT:• r – a element of the input space of self.
OUTPUT:• a vector of code().
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: C = LinearCode(G)sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0))
sage: word in C
True
sage: w_err = word + vector(GF(2), (1, 0, 0, 0, 0, 0, 0))(continues on next page)

38

Chapter 4. Decoders

Coding Theory, Release 10.4

(continued from previous page)

sage: w_err in C
False
sage: D = C.decoder()sage: D.decode_to_code(w_err)(1, 1, 0, 0, 1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> word = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(1), Integer(1), Integer(0)))>>> word in C
True>>> w_err = word + vector(GF(Integer(2)), (Integer(1), Integer(0), Integer(0),˓→ Integer(0), Integer(0), Integer(0), Integer(0)))>>> w_err in C
False>>> D = C.decoder()>>> D.decode_to_code(w_err)(1, 1, 0, 0, 1, 1, 0)

decode_to_message(r)Decode r to the message space of connected_encoder().
This is a default implementation, which assumes that the method decode_to_code() has been implemented, else it returns an exception.
INPUT:• r – a element of the input space of self.
OUTPUT:• a vector of message_space().
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: 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))
sage: D = C.decoder()sage: D.decode_to_message(w_err)(0, 1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])(continues on next page)39

Coding Theory, Release 10.4

(continued from previous page)>>> C = LinearCode(G)>>> word = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(1), Integer(1), Integer(0)))>>> w_err = word + vector(GF(Integer(2)), (Integer(1), Integer(0), Integer(0),˓→ Integer(0), Integer(0), Integer(0), Integer(0)))>>> D = C.decoder()>>> D.decode_to_message(w_err)(0, 1, 1, 0)classmethod decoder_type()
Returns the set of types of self.
This method can be called on both an uninstantiated decoder class, or on an instance of a decoder class.
The types of a decoder are a set of labels commonly associated with decoders which describe the nature andbehaviour of the decoding algorithm. It should be considered as an informal descriptor but can be coarsely
relied upon for e.g. program logic.
The following are the most common types and a brief definition:
Decodertype

Definition

always-succeed
The decoder always returns a closest codeword if the number of errors is up to the decoding
radius.
bounded-distanceAny vector with Hamming distance at most decoding_radius() to a codeword is decodable to some codeword. If might-fail is also a type, then this is not a guarantee but
an expectancy.
complete
The decoder decodes every word in the ambient space of the code.
dynamic
Some of the decoder’s types will only be determined at construction time (depends on theparameters).
half-minimum-distanceThe decoder corrects up to half the minimum distance, or a specific lower bound thereof.
hard-decision The decoder uses no information on which positions are more likely to be in error or not.
list-decoder The decoder outputs a list of likely codewords, instead of just a single codeword.
might-failThe decoder can fail at decoding even within its usual promises, e.g. bounded distance.
not-always-closest
The decoder does not guarantee to always return a closest codeword.
probabilis- The decoder has internal randomness which can affect running time and the decoding result.
tic
soft-decision As part of the input, the decoder takes reliability information on which positions are more
likely to be in error. Such a decoder only works for specific channels.
EXAMPLES:
We call it on a class:sage: codes.decoders.LinearCodeSyndromeDecoder.decoder_type(){ dynamic , hard-decision }>>> from sage.all import *>>> codes.decoders.LinearCodeSyndromeDecoder.decoder_type(){ dynamic , hard-decision }We can also call it on a instance of a Decoder class:

40

Chapter 4. Decoders

Coding Theory, Release 10.4

sage: G = Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 1, 1]])
sage: C = LinearCode(G)sage: D = C.decoder()sage: D.decoder_type(){ complete , hard-decision , might-error }>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1), Integer(0), Integer(0),␣
˓→Integer(1)], [Integer(0), Integer(1), Integer(1), Integer(1)]])>>> C = LinearCode(G)>>> D = C.decoder()>>> D.decoder_type(){ complete , hard-decision , might-error }decoding_radius(**kwargs)
Return the maximal number of errors that self is able to correct.
This is an abstract method and it should be implemented in subclasses.
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: C = LinearCode(G)sage: D = codes.decoders.LinearCodeSyndromeDecoder(C)sage: D.decoding_radius()
1>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> D = codes.decoders.LinearCodeSyndromeDecoder(C)>>> D.decoding_radius()
1

input_space()
Return the input space of 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: C = LinearCode(G)sage: D = C.decoder()sage: D.input_space()
Vector space of dimension 7 over Finite Field of size 2>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],(continues on next page)41

Coding Theory, Release 10.4

(continued from previous page)...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> D = C.decoder()>>> D.input_space()
Vector space of dimension 7 over Finite Field of size 2

message_space()
Return the message space of self’s connected_encoder().
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: C = LinearCode(G)sage: D = C.decoder()sage: D.message_space()
Vector space of dimension 4 over Finite Field of size 2>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> D = C.decoder()>>> D.message_space()
Vector space of dimension 4 over Finite Field of size 2

exception sage.coding.decoder.DecodingError
Bases: Exception
Special exception class to indicate an error during decoding.
Catalogs for available constructions of the basic objects and for bounds on the parameters of linear codes are provided.

42

Chapter 4. Decoders

CHAPTERFIVE

INDEX OF CHANNELS

Channels in Sage implement the information theoretic notion of transmission of messages.
The channels object may be used to access the codes that Sage can build.
• channel.ErrorErasureChannel• channel.QarySymmetricChannel• channel.StaticErrorRateChannel
To import these names into the global namespace, use:
sage: from sage.coding.channels_catalog import *>>> from sage.all import *>>> from sage.coding.channels_catalog import *43

Coding Theory, Release 10.4

44

Chapter 5. Index of channels

CHAPTERSIXINDEX OF CODE CONSTRUCTIONS

The codes object may be used to access the codes that Sage can build.

6.1 Families of Codes (Rich representation)
ParityCheckCode()
CyclicCode()
BCHCode()GeneralizedReedSolomonCode()
ReedSolomonCode()
BinaryReedMullerCode()
ReedMullerCode()
HammingCode()
GolayCode()GoppaCode()
KasamiCode()

Parity check codes
Cyclic codes
BCH Codes
Generalized Reed-Solomon codes
Reed-Solomon codes
Binary Reed-Muller codes
q-ary Reed-Muller codes
Hamming codes
Golay codes
Goppa codes
Kasami codes45

Coding Theory, Release 10.4

6.2 Families of Codes (Generator matrix representation)
DuadicCodeEvenPair()
DuadicCodeOddPair()QuadraticResidueCode()
ExtendedQuadraticResidueCode()
QuadraticResidueCodeEvenPair()QuadraticResidueCodeOddPair()
QuasiQuadraticResidueCode()
ToricCode()
WalshCode()
from_parity_check_matrix()
random_linear_code()
RandomLinearCodeGuava()

Duadic codes, even pair
Duadic codes, odd pair
Quadratic residue codes
Extended quadratic residue codes
Even-like quadratic residue codes
Odd-like quadratic residue codes
Quasi quadratic residue codes (Requires GAP/Guava)
Toric codes
Walsh codes
Construct a code from a parity check matrix
Construct a random linear code
Construct a random linear code through Guava (Requires GAP/Guava)

6.3 Derived Codes
SubfieldSubcode()
ExtendedCode()
PuncturedCode()

Subfield subcodes
Extended codes
Puncturedcodes

To import these names into the global namespace, use:
sage: from sage.coding.codes_catalog import *>>> from sage.all import *>>> from sage.coding.codes_catalog import *46

Chapter 6. Index of code constructions

CHAPTERSEVEN

INDEX OF DECODERSThe codes.decoders object may be used to access the decoders that Sage can build.
It is usually not necessary to access these directly: rather, the decoder method directly on a code allows you to construct
all compatible decoders for that code (sage.coding.linear_code.AbstractLinearCode.decoder()).
Extended code decoder• extended_code.ExtendedCodeOriginalCodeDecoder
Subfield subcode decoder• subfield_subcode.SubfieldSubcodeOriginalCodeDecoder
Generalized Reed-Solomon code decoders• grs_code.GRSBerlekampWelchDecoder• grs_code.GRSErrorErasureDecoder• grs_code.GRSGaoDecoder• grs_code.GRSKeyEquationSyndromeDecoder• guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder
Generic decoders• linear_code.LinearCodeNearestNeighborDecoder• linear_code.LinearCodeSyndromeDecoder• information_set_decoder.LinearCodeInformationSetDecoder
Cyclic code decoder• cyclic_code.CyclicCodeSurroundingBCHDecoder
BCH code decoder• bch_code.BCHUnderlyingGRSDecoder
Punctured code decoder• punctured_code.PuncturedCodeOriginalCodeDecoder
Evaluation and differential AG code decoders• ag_code_decoders.EvaluationAGCodeUniqueDecoder• ag_code_decoders.DifferentialAGCodeUniqueDecoder
To import these names into the global namespace, use:47

Coding Theory, Release 10.4

sage: from sage.coding.decoders_catalog import *>>> from sage.all import *>>> from sage.coding.decoders_catalog import *48

Chapter 7. Index of decoders

CHAPTEREIGHTINDEX OF ENCODERSThe codes.encoders object may be used to access the encoders that Sage can build.
Cyclic code encoders• cyclic_code.CyclicCodePolynomialEncoder• cyclic_code.CyclicCodeVectorEncoder
Extended code encoder• extended_code.ExtendedCodeExtendedMatrixEncoder
Generic encoders• linear_code.LinearCodeGeneratorMatrixEncoder• linear_code_no_metric.LinearCodeSystematicEncoder
Generalized Reed-Solomon code encoders• grs_code.GRSEvaluationVectorEncoder• grs_code.GRSEvaluationPolynomialEncoder
Punctured code encoder• punctured_code.PuncturedCodePuncturedMatrixEncoder
To import these names into the global namespace, use:
sage: from sage.coding.encoders_catalog import *>>> from sage.all import *>>> from sage.coding.encoders_catalog import *49

Coding Theory, Release 10.4

50

Chapter 8. Index of encoders

CHAPTERNINE

INDEX OF BOUNDS ON THE PARAMETERS OF CODES

The codes.bounds object may be used to access the bounds that Sage can compute.
codesize_upper_bound()delsarte_bound_Q_matrix()
delsarte_bound_additive_hamming_space()delsarte_bound_constant_weight_code()delsarte_bound_hamming_space()dimension_upper_bound()eberlein()elias_bound_asymp()
elias_upper_bound()entropy()gilbert_lower_bound()griesmer_upper_bound()gv_bound_asymp()
gv_info_rate()hamming_bound_asymp()
hamming_upper_bound()krawtchouk()mrrw1_bound_asymp()
plotkin_bound_asymp()
plotkin_upper_bound()singleton_bound_asymp()
singleton_upper_bound()volume_hamming()

Return an upper bound on the number of codewords in a (possibly non-linear)code.
Delsarte bound on a code with Q matrix q and lower bound on min. dist. d.
Find a modified Delsarte bound on additive codes in Hamming space 𝐻𝑞𝑛 of minimal distance 𝑑.
Find the Delsarte bound on a constant weight code.
Find the Delsarte bound on codes in H_q^n of minimal distance d
Return an upper bound for the dimension of a linear code.
Compute 𝐸𝑘𝑤,𝑛 (𝑥), the Eberlein polynomial.
The asymptotic Elias bound for the information rate.
Return the Elias upper bound.
Compute the entropy at 𝑥 on the 𝑞-ary symmetric channel.
Return the Gilbert-Varshamov lower bound.
Return the Griesmer upper bound.
The asymptotic Gilbert-Varshamov bound for the information rate, R.
The Gilbert-Varshamov lower bound for information rate.
The asymptotic Hamming bound for the information rate.
Return the Hamming upper bound.
Compute 𝐾𝑙𝑛,𝑞 (𝑥), the Krawtchouk (a.k.a. Kravchuk) polynomial.
The first asymptotic McEliese-Rumsey-Rodemich-Welsh bound.
The asymptotic Plotkin bound for the information rate.
Return the Plotkin upper bound.
The asymptotic Singleton bound for the information rate.
Return the Singleton upper bound.
Return the number of elements in a Hamming ball.

To import these names into the global namespace, use:
sage: from sage.coding.bounds_catalog import *51

Coding Theory, Release 10.4>>> from sage.all import *>>> from sage.coding.bounds_catalog import *52

Chapter 9. Index of bounds on the parameters of codes

CHAPTERTENLINEAR CODES

The following module is a base class for linear code objects regardless their metric.

10.1 Generic structures for linear codes of any metricClass supporting methods available for linear codes over any metric (Hamming, rank).
class sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric(base_field,
length,default_encoder_name,default_decoder_name,metric='Hamming')
Bases: AbstractCode, Module
Abstract class for linear codes of any metric.
This class contains all the methods that can be used on any linear code of any metric. Every abstract class of
linear codes over some metric (e.g. abstract class for linear codes over the Hamming metric, sage.coding.
linear_code.AbstractLinearCode) should inherit from this class.
To create a new class of linear codes over some metrics, you need to:• inherit from AbstractLinearCodeNoMetric• call AbstractCode __init__ method in the subclass constructor.
Example:__init__(length, "EncoderName", "DecoderName", "metric").

super().

• add the following two lines on the class level:_registered_encoders = {}_registered_decoders = {}• fill the dictionary of its encoders in sage.coding.__init__.py file.
Example: I wantto link the encoder MyEncoderClass to MyNewCodeClass under the name MyEncoderName. All I need to do is to write this line in the __init__.py file: MyNewCodeClass.
_registered_encoders["NameOfMyEncoder"] = MyEncoderClass and all instances of
MyNewCodeClass will be able to use instances of MyEncoderClass.
• fill the dictionary of its decoders in sage.coding.__init__ file.
Example: I want tolink the encoder MyDecoderClass to MyNewCodeClass under the name MyDecoderName. All I need to do is to write this line in the __init__.py file: MyNewCodeClass.

53

Coding Theory, Release 10.4

_registered_decoders["NameOfMyDecoder"] = MyDecoderClass and all instances of
MyNewCodeClass will be able to use instances of MyDecoderClass.
• create a generic constructor representative of you abstract class. This generic constructor is a class for unstructured linear codes given by some generator and considered over the given metric. A good example of thisis sage.coding.linear_code.LinearCode, which is a generic constructor for sage.coding.
linear_code.AbstractLinearCode, an abstract class for linear codes over the Hamming metric.
• set a private field in the __init__ method specifying the generic constructor, (e.g. MyAbstractCode.
_generic_constructor = MyCode)
It is assumed that the subclass codes are linear over base_field. To test this, it is recommended to add a test
suite test to the generic constructor. To do this, create a representative of your code 𝐶 and run TestSuite(C).
run(). A good example of this is in sage.coding.linear_code.LinearCode.
As the 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: A lot of methods of the abstract class rely on the knowledge of a generator matrix. It is thus strongly
recommended to set an encoder with a generator matrix implemented as a default encoder.
ambient_space()
Return the ambient vector space of self.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.ambient_space()
Vector space of dimension 7 over Finite Field of size 2>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.ambient_space()
Vector space of dimension 7 over Finite Field of size 2

base_field()
Return the base field of 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: C = LinearCode(G)sage: C.base_field()
Finite Field of size 2>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> C.base_field()
Finite Field of size 2

54

Chapter 10. Linear CodesCoding Theory, Release 10.4

basis()
Return a basis of self.
OUTPUT:• Sequence – an immutable sequence whose universe is ambient space of self.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.basis()[(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)]
sage: C.basis().universe()
Vector space of dimension 7 over Finite Field of size 2>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.basis()[(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)]>>> C.basis().universe()
Vector space of dimension 7 over Finite Field of size 2

cardinality()
Return the size of this code.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.cardinality()
16
sage: len(C)16>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.cardinality()
16>>> len(C)16dimension()
Return the dimension of this code.
EXAMPLES:
sage: G = matrix(GF(2), [[1,0,0], [1,1,0]])
sage: C = LinearCode(G)sage: C.dimension()2

10.1. Generic structures for linear codes of any metric55

Coding Theory, Release 10.4>>> from sage.all import *>>> G = matrix(GF(Integer(2)), [[Integer(1),Integer(0),Integer(0)],␣
˓→[Integer(1),Integer(1),Integer(0)]])>>> C = LinearCode(G)>>> C.dimension()2dual_code()
Return the dual code 𝐶 ⊥ of the code 𝐶,𝐶 ⊥ = {𝑣 ∈ 𝑉 | 𝑣 · 𝑐 = 0, ∀𝑐 ∈ 𝐶}.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.dual_code()[7, 3] linear code over GF(2)sage: C = codes.HammingCode(GF(4, a ), 3)
sage: C.dual_code()[21, 3] linear code over GF(4)>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.dual_code()[7, 3] linear code over GF(2)>>> C = codes.HammingCode(GF(Integer(4), a ), Integer(3))>>> C.dual_code()[21, 3] linear code over GF(4)generator_matrix(encoder_name=None, **kwargs)
Return a generator matrix of self.
INPUT:• encoder_name – (default: None) name of the encoder which will be used to compute the generator
matrix. The default encoder of self will be used if default value is kept.
• kwargs – all additional arguments are forwarded to the construction of the encoder that is used.
EXAMPLES:
sage: G = matrix(GF(3), 2, [1,-1,1,-1,1,1])
sage: code = LinearCode(G)sage: code.generator_matrix()[1 2 1][2 1 1]>>> from sage.all import *>>> G = matrix(GF(Integer(3)), Integer(2), [Integer(1),-Integer(1),Integer(1),˓→-Integer(1),Integer(1),Integer(1)])>>> code = LinearCode(G)>>> code.generator_matrix()[1 2 1][2 1 1]gens()
Return the generators of this code as a list of vectors.
EXAMPLES:
56

Chapter 10. Linear CodesCoding Theory, Release 10.4

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)]>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> 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)]

information_set()
Return an information set of the code.
Return value of this method is cached.
A set of column positions of a generator matrix of a code is called an information set if the corresponding
columns form a square matrix of full rank.
OUTPUT:• Information set of a systematic generator matrix of the code.
EXAMPLES:
sage: G = matrix(GF(3),2,[1,2,0,....:
2,1,1])
sage: code = LinearCode(G)sage: code.systematic_generator_matrix()[1 2 0][0 0 1]
sage: code.information_set()(0, 2)>>> from sage.all import *>>> G = matrix(GF(Integer(3)),Integer(2),[Integer(1),Integer(2),Integer(0),...
Integer(2),Integer(1),Integer(1)])>>> code = LinearCode(G)>>> code.systematic_generator_matrix()[1 2 0][0 0 1]>>> code.information_set()(0, 2)

is_information_set(positions)
Return whether the given positions form an information set.
INPUT:• A list of positions, i.e. integers in the range 0 to 𝑛 − 1 where 𝑛 is the length of self.
OUTPUT:• A boolean indicating whether the positions form an information set.
EXAMPLES:
sage: G = matrix(GF(3),2,[1,2,0,....:
2,1,1])(continues on next page)

10.1. Generic structures for linear codes of any metric57

Coding Theory, Release 10.4

(continued from previous page)

sage: code = LinearCode(G)sage: code.is_information_set([0,1])
False
sage: code.is_information_set([0,2])
True>>> from sage.all import *>>> G = matrix(GF(Integer(3)),Integer(2),[Integer(1),Integer(2),Integer(0),...
Integer(2),Integer(1),Integer(1)])>>> code = LinearCode(G)>>> code.is_information_set([Integer(0),Integer(1)])
False>>> code.is_information_set([Integer(0),Integer(2)])
True

is_permutation_automorphism(g)Return 1 if 𝑔 is an element of 𝑆𝑛 (𝑛 = length of self) and if 𝑔 is an automorphism of self.
EXAMPLES:
sage: # needs sage.groups
sage: C = codes.HammingCode(GF(3), 3)
sage: g = SymmetricGroup(13).random_element()
sage: C.is_permutation_automorphism(g)0sage: 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: C = LinearCode(G)sage: S8 = SymmetricGroup(8)sage: g = S8("(2,3)")
sage: C.is_permutation_automorphism(g)1sage: g = S8("(1,2,3,4)")
sage: C.is_permutation_automorphism(g)0>>> from sage.all import *>>> # needs sage.groups>>> C = codes.HammingCode(GF(Integer(3)), Integer(3))>>> g = SymmetricGroup(Integer(13)).random_element()>>> C.is_permutation_automorphism(g)0>>> MS = MatrixSpace(GF(Integer(2)),Integer(4),Integer(8))>>> G = MS([[Integer(1),Integer(0),Integer(0),Integer(0),Integer(1),˓→Integer(1),Integer(1),Integer(0)], [Integer(0),Integer(1),Integer(1),˓→Integer(1),Integer(0),Integer(0),Integer(0),Integer(0)],...
[Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(1)], [Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(1),Integer(0),Integer(0)]])>>> C = LinearCode(G)>>> S8 = SymmetricGroup(Integer(8))>>> g = S8("(2,3)")>>> C.is_permutation_automorphism(g)1>>> g = S8("(1,2,3,4)")(continues on next page)

58

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> C.is_permutation_automorphism(g)0is_self_dual()
Return True if the code is self-dual (in the usual Hamming inner product) and False otherwise.
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: C.is_self_dual()
Truesage: C = codes.HammingCode(GF(2), 3)
sage: C.is_self_dual()
False>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> C.is_self_dual()
True>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.is_self_dual()
False

is_self_orthogonal()
Return True if this code is self-orthogonal and False otherwise.
A code is self-orthogonal if it is a subcode of its dual.
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: C.is_self_orthogonal()
True
sage: C = codes.HammingCode(GF(2), 3)
sage: C.is_self_orthogonal()
False
sage: C = codes.QuasiQuadraticResidueCode(11)sage: C.is_self_orthogonal()
True# optional - gap_package_guava# optional - gap_package_guava>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> C.is_self_orthogonal()
True>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.is_self_orthogonal()
False>>> C = codes.QuasiQuadraticResidueCode(Integer(11)) # optional - gap_
˓→package_guava>>> C.is_self_orthogonal()# optional - gap_package_guava
True

is_subcode(other)
Return True if self is a subcode of other.
EXAMPLES:

10.1. Generic structures for linear codes of any metric59

Coding Theory, Release 10.4

sage: C1 = codes.HammingCode(GF(2), 3)
sage: G1 = C1.generator_matrix()
sage: G2 = G1.matrix_from_rows([0,1,2])
sage: C2 = LinearCode(G2)sage: C2.is_subcode(C1)True
sage: C1.is_subcode(C2)False
sage: C3 = C1.extended_code()sage: C1.is_subcode(C3)False
sage: C4 = C1.punctured([1])
sage: C4.is_subcode(C1)False
sage: C5 = C1.shortened([1])
sage: C5.is_subcode(C1)False
sage: C1 = codes.HammingCode(GF(9,"z"), 3)
sage: G1 = C1.generator_matrix()
sage: G2 = G1.matrix_from_rows([0,1,2])
sage: C2 = LinearCode(G2)sage: C2.is_subcode(C1)True>>> from sage.all import *>>> C1 = codes.HammingCode(GF(Integer(2)), Integer(3))>>> G1 = C1.generator_matrix()>>> G2 = G1.matrix_from_rows([Integer(0),Integer(1),Integer(2)])>>> C2 = LinearCode(G2)>>> C2.is_subcode(C1)
True>>> C1.is_subcode(C2)
False>>> C3 = C1.extended_code()>>> C1.is_subcode(C3)
False>>> C4 = C1.punctured([Integer(1)])>>> C4.is_subcode(C1)
False>>> C5 = C1.shortened([Integer(1)])>>> C5.is_subcode(C1)
False>>> C1 = codes.HammingCode(GF(Integer(9),"z"), Integer(3))>>> G1 = C1.generator_matrix()>>> G2 = G1.matrix_from_rows([Integer(0),Integer(1),Integer(2)])>>> C2 = LinearCode(G2)>>> C2.is_subcode(C1)Trueparity_check_matrix()
Return the parity check matrix of self.
The parity check matrix of a linear code 𝐶 corresponds to the generator matrix of the dual code of 𝐶.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)(continues on next page)

60

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: Cperp = C.dual_code()sage: C; Cperp[7, 4] Hamming Code over GF(2)[7, 3] linear code over GF(2)sage: C.generator_matrix()[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]
sage: C.parity_check_matrix()[1 0 1 0 1 0 1]
[0 1 1 0 0 1 1]
[0 0 0 1 1 1 1]
sage: Cperp.parity_check_matrix()[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]
sage: Cperp.generator_matrix()[1 0 1 0 1 0 1]
[0 1 1 0 0 1 1]
[0 0 0 1 1 1 1]>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> Cperp = C.dual_code()>>> C; Cperp[7, 4] Hamming Code over GF(2)[7, 3] linear code over GF(2)>>> C.generator_matrix()[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]>>> C.parity_check_matrix()[1 0 1 0 1 0 1]
[0 1 1 0 0 1 1]
[0 0 0 1 1 1 1]>>> Cperp.parity_check_matrix()[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]>>> Cperp.generator_matrix()[1 0 1 0 1 0 1]
[0 1 1 0 0 1 1]
[0 0 0 1 1 1 1]

permuted_code(p)Return the permuted code, which is equivalent to self via the column permutation p.
EXAMPLES:
sage: # needs sage.groups
sage: C = codes.HammingCode(GF(2), 3)
sage: G = C.permutation_automorphism_group(); G(continues on next page)

10.1. Generic structures for linear codes of any metric61

Coding Theory, Release 10.4

(continued from previous page)

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
[7, 4] linear code over GF(2)sage: C.generator_matrix() == Cg.systematic_generator_matrix()True>>> from sage.all import *>>> # needs sage.groups>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> 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)]>>> g = G("(2,3)(6,7)")>>> Cg = C.permuted_code(g)>>> Cg[7, 4] linear code over GF(2)>>> C.generator_matrix() == Cg.systematic_generator_matrix()Truerate()
Return the ratio of the number of information symbols to the code length.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.rate()
4/7>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.rate()
4/7

redundancy_matrix()
Return the non-identity columns of a systematic generator matrix for self.
A systematic generator matrix is a generator matrix such that a subset of its columns forms the identity matrix.
This method returns the remaining part of the matrix.
For any given code, there can be many systematic generator matrices (depending on which positions
should form the identity). This method will use the matrix returned by AbstractLinearCode.
systematic_generator_matrix().
OUTPUT:• An 𝑘 × (𝑛 − 𝑘) matrix.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.generator_matrix()[1 0 0 0 0 1 1]
[0 1 0 0 1 0 1]
[0 0 1 0 1 1 0]
(continues on next page)

62

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)[0 0 0 1 1 1 1]
sage: C.redundancy_matrix()[0 1 1][1 0 1][1 1 0][1 1 1]
sage: C = LinearCode(matrix(GF(3),2,[1,2,0,\
2,1,1]))
sage: C.systematic_generator_matrix()[1 2 0][0 0 1]
sage: C.redundancy_matrix()[2][0]>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.generator_matrix()[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]>>> C.redundancy_matrix()[0 1 1][1 0 1][1 1 0][1 1 1]>>> C = LinearCode(matrix(GF(Integer(3)),Integer(2),[Integer(1),Integer(2),˓→Integer(0),\2,1,1]))>>> C.systematic_generator_matrix()[1 2 0][0 0 1]>>> C.redundancy_matrix()[2][0]

standard_form(return_permutation=True)
Return a linear code which is permutation-equivalent to self and admits a generator matrix in standardform.
A generator matrix is in standard form if it is of the form [𝐼|𝐴], where 𝐼 is the 𝑘 ×𝑘 identity matrix. Any code
admits a generator matrix in systematic form, i.e. where a subset of the columns form the identity matrix,
but one might need to permute columns to allow the identity matrix to be leading.
INPUT:• return_permutation – (default: True) if True, the column permutation which brings self
into the returned code is also returned.
OUTPUT:• A LinearCode whose systematic_generator_matrix() is guaranteed to be of the form
[𝐼|𝐴].
EXAMPLES:

10.1. Generic structures for linear codes of any metric63

Coding Theory, Release 10.4

sage: C = codes.HammingCode(GF(2), 3)
sage: C.generator_matrix()[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]
sage: Cs,p = C.standard_form()
sage: p[]sage: Cs is C
True
sage: C = LinearCode(matrix(GF(2), [[1,0,0,0,1,1,0],\[0,1,0,1,0,1,0],\[0,0,0,0,0,0,1]]))
sage: Cs, p = C.standard_form()
sage: p[1, 2, 7, 3, 4, 5, 6]
sage: Cs.generator_matrix()[1 0 0 0 0 1 1]
[0 1 0 0 1 0 1]
[0 0 1 0 0 0 0]>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.generator_matrix()[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]>>> Cs,p = C.standard_form()>>> p[]>>> Cs is C
True>>> C = LinearCode(matrix(GF(Integer(2)), [[Integer(1),Integer(0),Integer(0),˓→Integer(0),Integer(1),Integer(1),Integer(0)],\[0,1,0,1,0,1,0],\[0,0,0,0,0,0,1]]))>>> Cs, p = C.standard_form()>>> p[1, 2, 7, 3, 4, 5, 6]>>> Cs.generator_matrix()[1 0 0 0 0 1 1]
[0 1 0 0 1 0 1]
[0 0 1 0 0 0 0]

syndrome(r)Return the syndrome of r.
The syndrome of r is the result of 𝐻 × 𝑟 where 𝐻 is the parity check matrix of self. If r belongs to self,
its syndrome equals to the zero vector.
INPUT:• r – a vector of the same length as self
OUTPUT:• a column vector
64

Chapter 10. Linear CodesCoding Theory, Release 10.4

EXAMPLES:
sage: MS = MatrixSpace(GF(2),4,7)
sage: G = MS([[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: r = vector(GF(2), (1,0,1,0,1,0,1))
sage: r in C
True
sage: C.syndrome(r)(0, 0, 0)>>> from sage.all import *>>> MS = MatrixSpace(GF(Integer(2)),Integer(4),Integer(7))>>> G = MS([[Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),˓→Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),Integer(1),˓→Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),˓→Integer(0),Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> r = vector(GF(Integer(2)), (Integer(1),Integer(0),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(1)))>>> r in C
True>>> C.syndrome(r)(0, 0, 0)

If r is not a codeword, its syndrome is not equal to zero:sage: r = vector(GF(2), (1,0,1,0,1,1,1))
sage: r in C
False
sage: C.syndrome(r)(0, 1, 1)>>> from sage.all import *>>> r = vector(GF(Integer(2)), (Integer(1),Integer(0),Integer(1),Integer(0),˓→Integer(1),Integer(1),Integer(1)))>>> r in C
False>>> C.syndrome(r)(0, 1, 1)

Syndrome computation works fine on bigger fields:
sage: C = codes.random_linear_code(GF(59), 12, 4)
sage: c = C.random_element()
sage: C.syndrome(c)(0, 0, 0, 0, 0, 0, 0, 0)>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(59)), Integer(12), Integer(4))>>> c = C.random_element()>>> C.syndrome(c)(0, 0, 0, 0, 0, 0, 0, 0)

systematic_generator_matrix(systematic_positions=None)

10.1. Generic structures for linear codes of any metric65

Coding Theory, Release 10.4

Return a systematic generator matrix of the code.
A generator matrix of a code is called systematic if it contains a set of columns forming an identity matrix.
INPUT:• systematic_positions – (default: None) if supplied, the set of systematic positions in the systematic generator matrix. See the documentation for LinearCodeSystematicEncoder details.
EXAMPLES:
sage: G = matrix(GF(3), [[ 1, 2, 1, 0],
˓→2, 1, 1, 1]])
sage: C = LinearCode(G)sage: C.generator_matrix()[1 2 1 0][2 1 1 1]
sage: C.systematic_generator_matrix()[1 2 0 1][0 0 1 2][␣>>> from sage.all import *>>> G = matrix(GF(Integer(3)), [[ Integer(1), Integer(2), Integer(1),␣
˓→Integer(0)],[ Integer(2), Integer(1),␣
˓→Integer(1), Integer(1)]])>>> C = LinearCode(G)>>> C.generator_matrix()[1 2 1 0][2 1 1 1]>>> C.systematic_generator_matrix()[1 2 0 1][0 0 1 2]Specific systematic positions can also be requested:sage: C.systematic_generator_matrix(systematic_positions=[3,2])[1 2 0 1][1 2 1 0]>>> from sage.all import *>>> C.systematic_generator_matrix(systematic_positions=[Integer(3),˓→Integer(2)])[1 2 0 1][1 2 1 0]zero()
Return the zero vector of self.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.zero()(0, 0, 0, 0, 0, 0, 0)
sage: C.sum(()) # indirect doctest(0, 0, 0, 0, 0, 0, 0)
sage: C.sum((C.gens())) # indirect doctest(1, 1, 1, 1, 1, 1, 1)

66

Chapter 10. Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.zero()(0, 0, 0, 0, 0, 0, 0)>>> C.sum(()) # indirect doctest(0, 0, 0, 0, 0, 0, 0)>>> C.sum((C.gens())) # indirect doctest(1, 1, 1, 1, 1, 1, 1)class sage.coding.linear_code_no_metric.LinearCodeSystematicEncoder(code,
systematic_positions=None)
Bases: Encoder
Encoder based on a generator matrix in systematic form for Linear codes.
To encode an element of its message space, this encoder first builds a generator matrix in systematic form. Whatis called systematic form here is the reduced row echelon form of a matrix, which is not necessarily [𝐼|𝐻],
where 𝐼 is the identity block and 𝐻 the parity block. One can refer to LinearCodeSystematicEncoder.
generator_matrix() for a concrete example. Once such a matrix has been computed, it is used to encode
any message into a codeword.
This encoder can also serve as the default encoder of a code defined by a parity check matrix: if the LinearCodeSystematicEncoder detects that it is the default encoder, it computes a generator matrix as the
reduced row echelon form of the right kernel of the parity check matrix.
INPUT:• code – The associated code of this encoder.
• systematic_positions – (default: None) the positions in codewords that should correspond to themessage symbols. A list of 𝑘 distinct integers in the range 0 to 𝑛 − 1 where 𝑛 is the length of the code and 𝑘
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 construction time
if the supplied indices do not form an information set.
EXAMPLES:
The following demonstrates the basic usage of LinearCodeSystematicEncoder: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]

10.1. Generic structures for linear codes of any metric67

Coding Theory, Release 10.4>>> from sage.all import *>>> LCSE = codes.encoders.LinearCodeSystematicEncoder>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0),Integer(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]])>>> C = LinearCode(G)>>> E = LCSE(C)>>> 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]>>> E2 = LCSE(C, systematic_positions=[Integer(5),Integer(4),Integer(3),˓→Integer(2)])>>> 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 = LCSE(C, systematic_positions=[0,1,6,7])
Traceback (most recent call last):...
ValueError: systematic_positions are not an information set>>> from sage.all import *>>> E3 = LCSE(C, systematic_positions=[Integer(0),Integer(1),Integer(6),˓→Integer(7)])
Traceback (most recent call last):...
ValueError: systematic_positions are not an information set

We exemplify how to use LinearCodeSystematicEncoder as the default encoder. The following class isthe dual of the repetition code:
sage: class DualRepetitionCode(sage.coding.linear_code.AbstractLinearCode):....:
def __init__(self, field, length):....:
super().__init__(field, length, "Systematic", "Syndrome")
....:
....:
def parity_check_matrix(self):....:
return Matrix(self.base_field(), [1]*self.length())
....:
....:
def _repr_(self):....:
return "Dual of the [%d, 1] Repetition Code over GF(%s)" % (self.
˓→length(), self.base_field().cardinality())....:
sage: DualRepetitionCode(GF(3), 5).generator_matrix()[1 0 0 0 2]
[0 1 0 0 2]
[0 0 1 0 2]
[0 0 0 1 2]

68

Chapter 10. Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> class DualRepetitionCode(sage.coding.linear_code.AbstractLinearCode):...
def __init__(self, field, length):...
super().__init__(field, length, "Systematic", "Syndrome")
....:
>>>
def parity_check_matrix(self):...
return Matrix(self.base_field(), [Integer(1)]*self.length())
....:
>>>
def _repr_(self):...
return "Dual of the [%d, 1] Repetition Code over GF(%s)" % (self.
˓→length(), self.base_field().cardinality())....:>>> DualRepetitionCode(GF(Integer(3)), Integer(5)).generator_matrix()[1 0 0 0 2]
[0 1 0 0 2]
[0 0 1 0 2]
[0 0 0 1 2]

An exception is thrown if LinearCodeSystematicEncoder is the default encoder but no parity checkmatrix has been specified for the code:
sage: class BadCodeFamily(sage.coding.linear_code.AbstractLinearCode):....:
def __init__(self, field, length):....:
super().__init__(field, length, "Systematic", "Syndrome")
....:
....:
def _repr_(self):....:
return "I am a badly defined code"....:
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>>> from sage.all import *>>> class BadCodeFamily(sage.coding.linear_code.AbstractLinearCode):...
def __init__(self, field, length):...
super().__init__(field, length, "Systematic", "Syndrome")
....:
>>>
def _repr_(self):...
return "I am a badly defined code"....:>>> BadCodeFamily(GF(Integer(3)), Integer(5)).generator_matrix()
Traceback (most recent call last):...
ValueError: a parity check matrix must be specified
if LinearCodeSystematicEncoder is the default encoder

generator_matrix()
Return a generator matrix in systematic form of the associated code of self.
Systematic form here means that a subsets of the columns of the matrix forms the identity matrix.
Note: The matrix returned by this method will not necessarily be [𝐼|𝐻], where 𝐼 is the identity block and
𝐻 the parity block. If one wants to know which columns create the identity block, one can call systematic_positions()

10.1. Generic structures for linear codes of any metric69

Coding Theory, Release 10.4

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 = LCSE(C)sage: E.generator_matrix()[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]>>> from sage.all import *>>> LCSE = codes.encoders.LinearCodeSystematicEncoder>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)],\[1,0,0,1,1,0,0],\[0,1,0,1,0,1,0],\[1,1,0,1,0,0,1]])>>> C = LinearCode(G)>>> E = LCSE(C)>>> E.generator_matrix()[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]

We can ask for different systematic positions: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]
[1 1 0 1 0 0 1]
[1 1 1 0 0 0 0]>>> from sage.all import *>>> E2 = LCSE(C, systematic_positions=[Integer(5),Integer(4),Integer(3),˓→Integer(2)])>>> E2.generator_matrix()[1 0 0 0 0 1 1]
[0 1 0 0 1 0 1]
[1 1 0 1 0 0 1]
[1 1 1 0 0 0 0]

Another example where there is no generator matrix of the form [𝐼|𝐻]:
sage: G = Matrix(GF(2), [[1,1,0,0,1,0,1],\[1,1,0,0,1,0,0],\[0,0,1,0,0,1,0],\[0,0,1,0,1,0,1]])
sage: C = LinearCode(G)sage: E = LCSE(C)sage: E.generator_matrix()(continues on next page)

70

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)[1 1 0 0 0 1 0]
[0 0 1 0 0 1 0]
[0 0 0 0 1 1 0]
[0 0 0 0 0 0 1]>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(0),Integer(1)],\[1,1,0,0,1,0,0],\[0,0,1,0,0,1,0],\[0,0,1,0,1,0,1]])>>> C = LinearCode(G)>>> E = LCSE(C)>>> E.generator_matrix()[1 1 0 0 0 1 0]
[0 0 1 0 0 1 0]
[0 0 0 0 1 1 0]
[0 0 0 0 0 0 1]

systematic_permutation()
Return a permutation which would take the systematic positions into [0,..,k-1]
EXAMPLES:
sage: C = LinearCode(matrix(GF(2), [[1,0,0,0,1,1,0],\[0,1,0,1,0,1,0],\[0,0,0,0,0,0,1]]))
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)sage: E.systematic_positions()(0, 1, 6)
sage: E.systematic_permutation()[1, 2, 7, 3, 4, 5, 6]>>> from sage.all import *>>> C = LinearCode(matrix(GF(Integer(2)), [[Integer(1),Integer(0),Integer(0),˓→Integer(0),Integer(1),Integer(1),Integer(0)],\[0,1,0,1,0,1,0],\[0,0,0,0,0,0,1]]))>>> E = codes.encoders.LinearCodeSystematicEncoder(C)>>> E.systematic_positions()(0, 1, 6)>>> E.systematic_permutation()[1, 2, 7, 3, 4, 5, 6]

systematic_positions()
Return a tuple containing the indices of the columns which form an identity matrix when the generator matrix
is in systematic form.
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)(continues on next page)

10.1. Generic structures for linear codes of any metric71

Coding Theory, Release 10.4

(continued from previous page)

sage: E = LCSE(C)sage: E.systematic_positions()(0, 1, 2, 3)>>> from sage.all import *>>> LCSE = codes.encoders.LinearCodeSystematicEncoder>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)],\[1,0,0,1,1,0,0],\[0,1,0,1,0,1,0],\[1,1,0,1,0,0,1]])>>> C = LinearCode(G)>>> E = LCSE(C)>>> E.systematic_positions()(0, 1, 2, 3)

We take another matrix with a less nice shape:
sage: G = Matrix(GF(2), [[1,1,0,0,1,0,1],\[1,1,0,0,1,0,0],\[0,0,1,0,0,1,0],\[0,0,1,0,1,0,1]])
sage: C = LinearCode(G)sage: E = LCSE(C)sage: E.systematic_positions()(0, 2, 4, 6)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(0),Integer(1)],\[1,1,0,0,1,0,0],\[0,0,1,0,0,1,0],\[0,0,1,0,1,0,1]])>>> C = LinearCode(G)>>> E = LCSE(C)>>> E.systematic_positions()(0, 2, 4, 6)

The systematic positions correspond to the positions which carry information in a codeword:
sage: MS = E.message_space()sage: m = MS.random_element()
sage: c = m * E.generator_matrix()
sage: pos = E.systematic_positions()
sage: info = MS([c[i] for i in pos])sage: m == info
True>>> from sage.all import *>>> MS = E.message_space()>>> m = MS.random_element()>>> c = m * E.generator_matrix()>>> pos = E.systematic_positions()>>> info = MS([c[i] for i in pos])>>> m == info
True

72

Chapter 10. Linear CodesCoding Theory, Release 10.4

When constructing a systematic encoder with specific systematic positions, then it is guaranteed that thismethod returns exactly those positions (even if another choice might also be systematic):
sage: G = Matrix(GF(2), [[1,0,0,0],\[0,1,0,0],\[0,0,1,1]])
sage: C = LinearCode(G)sage: E = LCSE(C, systematic_positions=[0,1,3])
sage: E.systematic_positions()(0, 1, 3)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(0),Integer(0),Integer(0)],˓→\[0,1,0,0],\[0,0,1,1]])>>> C = LinearCode(G)>>> E = LCSE(C, systematic_positions=[Integer(0),Integer(1),Integer(3)])>>> E.systematic_positions()(0, 1, 3)There is a number of representatives of linear codes over a specific metric.

10.2 Generic structures for linear codes over the Hamming metric10.2.1 Linear Codes
Let 𝐹 = F𝑞 be a finite field. A rank 𝑘 linear subspace of the vector space 𝐹 𝑛 is called an [𝑛, 𝑘]-linear code, 𝑛 being thelength of the code and 𝑘 its dimension. Elements of a code 𝐶 are called codewords.
A linear map from 𝐹 𝑘 to an [𝑛, 𝑘] code 𝐶 is called an “encoding”, and it can be represented as a 𝑘 × 𝑛 matrix, called agenerator matrix. Alternatively, 𝐶 can be represented by its orthogonal complement in 𝐹 𝑛 , i.e. the (𝑛 − 𝑘)-dimensional
vector space 𝐶 ⊥ such that the inner product of any element from 𝐶 and any element from 𝐶 ⊥ is zero. 𝐶 ⊥ is called thedual code of 𝐶, and any generator matrix for 𝐶 ⊥ is called a parity check matrix for 𝐶.
We commonly endow 𝐹 𝑛 with the Hamming metric, i.e. the weight of a vector is the number of non-zero elements in it.
The central operation of a linear code is then “decoding”: given a linear code 𝐶 ⊂ 𝐹 𝑛 and a “received word” 𝑟 ∈ 𝐹 𝑛 ,retrieve the codeword 𝑐 ∈ 𝐶 such that the Hamming distance between 𝑟 and 𝑐 is minimal.

10.2.2 Families or Generic codes
Linear codes are either studied as generic vector spaces without any known structure, or as particular sub-families withspecial properties.
The class sage.coding.linear_code.LinearCode is used to represent the former.
For the latter, these will be represented by specialised classes; for instance, the family of Hamming codes are represented
by the class sage.coding.hamming_code.HammingCode. Type codes.<tab> for a list of all code families
known to Sage. Such code family classes should inherit from the abstract base class sage.coding.linear_code.
AbstractLinearCode.

10.2. Generic structures for linear codes over the Hamming metric73

Coding Theory, Release 10.4

AbstractLinearCode
This is a base class designed to contain methods, features and parameters shared by every linear code. For instance,
generic algorithms for computing the minimum distance, the covering radius, etc. Many of these algorithms are slow,
e.g. exponential in the code length. For specific subfamilies, better algorithms or even closed formulas might be known,in which case the respective method should be overridden.
AbstractLinearCode is an abstract class for linear codes, so any linear code class should inherit from this class.
Also AbstractLinearCode should never itself be instantiated.
See sage.coding.linear_code.AbstractLinearCode for details and examples.
LinearCode
This class is used to represent arbitrary and unstructured linear codes. It mostly rely directly on generic methods provided by AbstractLinearCode, which means that basic operations on the code (e.g. computation of the minimum
distance) will use slow algorithms.
A LinearCode is instantiated by providing a generator matrix:
sage: M = matrix(GF(2), [[1, 0, 0, 1, 0],\[0, 1, 0, 1, 1],\[0, 0, 1, 1, 1]])
sage: C = codes.LinearCode(M)sage: C[5, 3] linear code over GF(2)sage: C.generator_matrix()[1 0 0 1 0]
[0 1 0 1 1]
[0 0 1 1 1]
sage: MS = MatrixSpace(GF(2),4,7)
sage: G = MS([[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.basis()[(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 = C.basis()[1]sage: c in C
True
sage: c.nonzero_positions()[0, 3, 4]
sage: c.support()[0, 3, 4]
sage: c.parent()
Vector space of dimension 7 over Finite Field of size 2>>> from sage.all import *>>> M = matrix(GF(Integer(2)), [[Integer(1), Integer(0), Integer(0), Integer(1),␣
˓→Integer(0)],\[0, 1, 0, 1, 1],\[0, 0, 1, 1, 1]])>>> C = codes.LinearCode(M)(continues on next page)

74

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> C[5, 3] linear code over GF(2)>>> C.generator_matrix()[1 0 0 1 0]
[0 1 0 1 1]
[0 0 1 1 1]>>> MS = MatrixSpace(GF(Integer(2)),Integer(4),Integer(7))>>> G = MS([[Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),Integer(0),˓→Integer(0)], [Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),˓→Integer(0)], [Integer(0),Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0)], [Integer(1),Integer(1),Integer(0),Integer(1),Integer(0),Integer(0),˓→Integer(1)]])>>> C = LinearCode(G)>>> C.basis()[(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)]>>> c = C.basis()[Integer(1)]>>> c in C
True>>> c.nonzero_positions()[0, 3, 4]>>> c.support()[0, 3, 4]>>> c.parent()
Vector space of dimension 7 over Finite Field of size 2

Further references
If you want to get started on Sage’s linear codes library, see https://doc.sagemath.org/html/en/thematic_tutorials/coding_theory.html
If you want to learn more on the design of this library, see https://doc.sagemath.org/html/en/thematic_tutorials/
structures_in_coding_theory.html
REFERENCES:• [HP2003]• [Gu]AUTHORS:• David Joyner (2005-11-22, 2006-12-03): initial version• William Stein (2006-01-23): Inclusion in Sage
• David Joyner (2006-01-30, 2006-04): small fixes• David Joyner (2006-07): added documentation, group-theoretical methods, ToricCode• David Joyner (2006-08): hopeful latex fixes to documentation, added list and __iter__ methods to LinearCode andexamples, added hamming_weight function, fixed random method to return a vector, TrivialCode, fixed subtle bugin dual_code, added galois_closure method, fixed mysterious bug in permutation_automorphism_group (GAP wasover-using “G” somehow?)
10.2. Generic structures for linear codes over the Hamming metric75

Coding Theory, Release 10.4

• David Joyner (2006-08): hopeful latex fixes to documentation, added CyclicCode, best_known_linear_code,
bounds_minimum_distance, assmus_mattson_designs (implementing Assmus-Mattson Theorem).
• David Joyner (2006-09): modified decode syntax, fixed bug in is_galois_closed, added LinearCode_from_vectorspace, extended_code, zeta_function• Nick Alexander (2006-12-10): factor GUAVA code to guava.py• David Joyner (2007-05): added methods punctured, shortened, divisor, characteristic_polynomial, binomial_moment, support for LinearCode. Completely rewritten zeta_function (old version is now zeta_function2) and a new
function, LinearCodeFromVectorSpace.
• David Joyner (2007-11): added zeta_polynomial, weight_enumerator, chinen_polynomial;
best_known_code; made some pythonic revisions; added is_equivalent (for binary codes)

improved• David Joyner (2008-01): fixed bug in decode reported by Harald Schilly, (with Mike Hansen) added some doctests.
• David Joyner (2008-02): translated standard_form, dual_code to Python.
• David Joyner (2008-03): translated punctured, shortened, extended_code, random (and renamed random torandom_element), deleted zeta_function2, zeta_function3, added wrapper automorphism_group_binary_code toRobert Miller’s code), added direct_sum_code, is_subcode, is_self_dual, is_self_orthogonal, redundancy_matrix, did some alphabetical reorganizing to make the file more readable. Fixed a bug in permutation_automorphism_group which caused it to crash.
• David Joyner (2008-03): fixed bugs in spectrum and zeta_polynomial, which misbehaved over non-prime baserings.
• David Joyner (2008-10): use CJ Tjhal’s MinimumWeight if char = 2 or 3 for min_dist; add is_permutation_equivalent and improve permutation_automorphism_group using an interface with Robert Miller’s code; added interface
with Leon’s code for the spectrum method.
• David Joyner (2009-02): added native decoding methods (see module_decoder.py)• David Joyner (2009-05): removed dependence on Guava, allowing it to be an option. Fixed errors in some docstrings.
• Kwankyu Lee (2010-01): added methods generator_matrix_systematic, information_set, and magma interface forlinear codes.
• Niles Johnson (2010-08): Issue #3893: random_element() should pass on *args and **kwds.
• Thomas Feulner (2012-11): Issue #13723: deprecation of hamming_weight()• Thomas Feulner (2013-10): added methods to compute a canonical representative and the automorphism groupclass sage.coding.linear_code.AbstractLinearCode(base_field, length, default_encoder_name,default_decoder_name)
Bases: AbstractLinearCodeNoMetric
Abstract base class for linear codes.
This class contains all methods that can be used on Linear Codes and on Linear Codes families. So, every Linear
Code-related class should inherit from this abstract class.
To implement a linear code, you need to:• inherit from AbstractLinearCode• call 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. You need of course to complete the constructor by adding any additional parameter needed
to describe properly the code defined in the subclass.

76

Chapter 10. Linear CodesCoding Theory, Release 10.4

• Add the following two lines on the class level:_registered_encoders = {}_registered_decoders = {}• fill the dictionary of its encoders in sage.coding.__init__.py file.
Example: I wantto link the encoder MyEncoderClass to MyNewCodeClass under the name MyEncoderName. All I need to do is to write this line in the __init__.py file: MyNewCodeClass.
_registered_encoders["NameOfMyEncoder"] = MyEncoderClass and all instances of
MyNewCodeClass will be able to use instances of MyEncoderClass.
• fill the dictionary of its decoders in sage.coding.__init__ file.
Example: I want tolink the encoder MyDecoderClass to MyNewCodeClass under the name MyDecoderName. All I need to do is to write this line in the __init__.py file: MyNewCodeClass.
_registered_decoders["NameOfMyDecoder"] = MyDecoderClass and all instances of
MyNewCodeClass will be able to use instances of MyDecoderClass.
As the 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: AbstractLinearCode has a generic implementation of the method __eq__ which uses the generator
matrix and is quite slow. In subclasses you are encouraged to override __eq__ and __hash__.

Warning: The default encoder should always have 𝐹 𝑘 as message space, with 𝑘 the dimension of the code
and 𝐹 is the base ring of the code.
A lot of methods of the abstract class rely on the knowledge of a generator matrix. It is thus strongly recommended to set an encoder with a generator matrix implemented as a default encoder.
assmus_mattson_designs(t, mode=None)
Assmus and Mattson Theorem (section 8.4, page 303 of [HP2003]): Let 𝐴0 , 𝐴1 , ..., 𝐴𝑛 be the weights ofthe codewords in a binary linear [𝑛, 𝑘, 𝑑] code 𝐶, and let 𝐴*0 , 𝐴*1 , ..., 𝐴*𝑛 be the weights of the codewords in
its dual [𝑛, 𝑛 − 𝑘, 𝑑* ] code 𝐶 * . Fix a 𝑡, 0 < 𝑡 < 𝑑, and let
𝑠 = |{𝑖 | 𝐴*𝑖 ̸= 0, 0 < 𝑖 ≤ 𝑛 − 𝑡}|.
Assume 𝑠 ≤ 𝑑 − 𝑡.
1. If 𝐴𝑖 ̸= 0 and 𝑑 ≤ 𝑖 ≤ 𝑛 then 𝐶𝑖 = {𝑐 ∈ 𝐶 | 𝑤𝑡(𝑐) = 𝑖} holds a simple t-design.
2. If 𝐴*𝑖 ̸= 0 and 𝑑* ≤ 𝑖 ≤ 𝑛 − 𝑡 then 𝐶𝑖* = {𝑐 ∈ 𝐶 * | 𝑤𝑡(𝑐) = 𝑖} holds a simple t-design.
A block design is a pair (𝑋, 𝐵), where 𝑋 is a non-empty finite set of 𝑣 > 0 elements called points, and 𝐵 isa non-empty finite multiset of size b whose elements are called blocks, such that each block is a non-empty
finite multiset of 𝑘 points. 𝐴 design without repeated blocks is called a simple block design. If every subset
of points of size 𝑡 is contained in exactly 𝜆 blocks the block design is called a 𝑡 − (𝑣, 𝑘, 𝜆) design (or simply
a 𝑡-design when the parameters are not specified). When 𝜆 = 1 then the block design is called a 𝑆(𝑡, 𝑘, 𝑣)
Steiner system.
In the Assmus and Mattson Theorem (1), 𝑋 is the set {1, 2, ..., 𝑛} of coordinate locations and 𝐵 ={𝑠𝑢𝑝𝑝(𝑐) | 𝑐 ∈ 𝐶𝑖 } is the set of supports of the codewords of 𝐶 of weight 𝑖. Therefore, the parametersof the 𝑡-design for 𝐶𝑖 are

10.2. Generic structures for linear codes over the Hamming metric77

Coding Theory, Release 10.4

t =
given
v =
n
k =
i
(k not to be confused with dim(C))
b =Ai
lambda = b*binomial(k,t)/binomial(v,t) (by Theorem 8.1.6,
p 294, in [HP2003]_)

Setting the mode="verbose" option prints out the values of the parameters.
The first example below means that the binary [24,12,8]-code C has the property that the (support of the)codewords of weight 8 (resp., 12, 16) form a 5-design. Similarly for its dual code 𝐶 * (of course 𝐶 = 𝐶 * inthis case, so this info is extraneous). The test fails to produce 6-designs (ie, the hypotheses of the theorem failto hold, not that the 6-designs definitely don’t exist). The command 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) design (i.e., the S(5,8,24) Steiner system).
EXAMPLES:
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)]]]sage: C.assmus_mattson_designs(6)0sage: X = range(24)# example 2
sage: blocks = [c.support() # long time....:
for c in C if c.hamming_weight()==8]; len(blocks)
759>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))# example 1>>> C.assmus_mattson_designs(Integer(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)]]]>>> C.assmus_mattson_designs(Integer(6))
0>>> X = range(Integer(24))# example 2>>> blocks = [c.support() # long time...
for c in C if c.hamming_weight()==Integer(8)]; len(blocks)
759

automorphism_group_gens(equivalence='semilinear')
Return generators of the automorphism group of self.
INPUT:• equivalence (optional) – which defines the acting group, either– "permutational"– "linear"– "semilinear"
78

Chapter 10. Linear CodesCoding Theory, Release 10.4

OUTPUT:• generators of the automorphism group of self
• the order of the automorphism group of self
EXAMPLES:
Note, this result can depend on the PRNG state in libgap in a way that depends on which packages are loaded,so we must re-seed GAP to ensure a consistent result for this example:
sage: # needs sage.libs.gap
sage: libgap.set_seed(0)0sage: 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)],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)],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);(continues on next page)10.2. Generic structures for linear codes over the Hamming metric79

Coding Theory, Release 10.4

(continued from previous page)(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)>>> from sage.all import *>>> # needs sage.libs.gap>>> libgap.set_seed(Integer(0))
0>>> C = codes.HammingCode(GF(Integer(4), z ), Integer(3))>>> 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)],362880)>>> 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)],181440)>>> 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(continues on next page)

80

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)

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)

binomial_moment(i)Return the i-th binomial moment of the [𝑛, 𝑘, 𝑑]𝑞 -code 𝐶:
𝐵𝑖 (𝐶) =∑︁ 𝑞 𝑘𝑆 − 1
𝑞−1

𝑆,|𝑆|=𝑖where 𝑘𝑆 is theof the shortened code 𝐶𝐽−𝑆 , 𝐽 = [1, 2, ..., 𝑛]. (The normalized binomial moment(︀ 𝑛dimension)︀ −1
is 𝑏𝑖 (𝐶) = 𝑑+𝑖) 𝐵𝑑+𝑖 (𝐶).) In other words, 𝐶𝐽−𝑆 is isomorphic to the subcode of C of codewords
supported on S.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.binomial_moment(2)˓→needs sage.libs.gap
0
sage: C.binomial_moment(4)# long time
˓→needs sage.libs.gap
35>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.binomial_moment(Integer(2))˓→# needs sage.libs.gap
0>>> C.binomial_moment(Integer(4))# long time˓→# needs sage.libs.gap
35

#␣

#␣

␣

␣

Warning: This is slow.
REFERENCE:• [Du2004]
canonical_representative(equivalence='semilinear')
Compute a canonical orbit representative under the action of the semimonomial transformation group.
See sage.coding.codecan.autgroup_can_label for more details, for example if you would
like to compute a canonical form under some more restrictive notion of equivalence, i.e. if you would like torestrict the permutation group to a Young subgroup.
INPUT:• equivalence (optional) – which defines the acting group, either
10.2. Generic structures for linear codes over the Hamming metric81

Coding Theory, Release 10.4

– "permutational"– "linear"– "semilinear"
OUTPUT:• a canonical representative of self
• a semimonomial transformation mapping self onto its representative
EXAMPLES:
sage: F.<z> = GF(4)sage: C = codes.HammingCode(F, 3)
sage: CanRep, transp = C.canonical_representative()
˓→needs sage.libs.gap#␣>>> from sage.all import *>>> F = GF(Integer(4), names=( z ,)); (z,) = F._first_ngens(1)>>> C = codes.HammingCode(F, Integer(3))>>> CanRep, transp = C.canonical_representative()
˓→needs sage.libs.gap#␣Check that the transporter element is correct:
sage: LinearCode(transp*C.generator_matrix()) == CanRep
˓→needs sage.libs.gap
True

#␣

>>> from sage.all import *>>> LinearCode(transp*C.generator_matrix()) == CanRep
˓→needs sage.libs.gap
True

#␣

Check if an equivalent code has the same canonical representative:
sage: f = F.hom([z**2])
sage: C_iso = LinearCode(C.generator_matrix().apply_map(f))
sage: CanRep_iso, _ = C_iso.canonical_representative()
˓→needs sage.libs.gap
sage: CanRep_iso == CanRep
˓→needs sage.libs.gap
True>>> from sage.all import *>>> f = F.hom([z**Integer(2)])>>> C_iso = LinearCode(C.generator_matrix().apply_map(f))>>> CanRep_iso, _ = C_iso.canonical_representative()
˓→needs sage.libs.gap>>> CanRep_iso == CanRep
˓→needs sage.libs.gap
True

#␣
#␣

#␣
#␣

Since applying the Frobenius automorphism could be extended to an automorphism of 𝐶, the following mustalso yield True:

82

Chapter 10. Linear CodesCoding Theory, Release 10.4

sage: CanRep1, _ = C.canonical_representative("linear")
˓→needs sage.libs.gap
sage: CanRep2, _ = C_iso.canonical_representative("linear")
˓→needs sage.libs.gap
sage: CanRep2 == CanRep1
˓→needs sage.libs.gap
True>>> from sage.all import *>>> CanRep1, _ = C.canonical_representative("linear")
˓→needs sage.libs.gap>>> CanRep2, _ = C_iso.canonical_representative("linear")
˓→needs sage.libs.gap>>> CanRep2 == CanRep1
˓→needs sage.libs.gap
True

#␣
#␣
#␣

#␣
#␣
#␣

characteristic()
Return the characteristic of the base ring of self.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.characteristic()
2>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.characteristic()
2

characteristic_polynomial()
Return the characteristic polynomial of a linear code, as defined in [Lin1999].
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: C.characteristic_polynomial()-4/3*x^3 + 64*x^2 - 2816/3*x + 4096>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> C.characteristic_polynomial()-4/3*x^3 + 64*x^2 - 2816/3*x + 4096

chinen_polynomial()
Return the Chinen zeta polynomial of the code.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.chinen_polynomial()# long time
1/5*(2*sqrt(2)*t^3 + 2*sqrt(2)*t^2 + 2*t^2 + sqrt(2)*t + 2*t + 1)/(sqrt(2) +␣˓→1)
sage: C = codes.GolayCode(GF(3), False)
sage: C.chinen_polynomial()# long time(continues on next page)10.2. Generic structures for linear codes over the Hamming metric83

Coding Theory, Release 10.4

(continued from previous page)

1/7*(3*sqrt(3)*t^3 + 3*sqrt(3)*t^2 + 3*t^2 + sqrt(3)*t + 3*t + 1)/(sqrt(3) +␣˓→1)>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.chinen_polynomial()# long time
1/5*(2*sqrt(2)*t^3 + 2*sqrt(2)*t^2 + 2*t^2 + sqrt(2)*t + 2*t + 1)/(sqrt(2) +␣˓→1)>>> C = codes.GolayCode(GF(Integer(3)), False)>>> C.chinen_polynomial()# long time
1/7*(3*sqrt(3)*t^3 + 3*sqrt(3)*t^2 + 3*t^2 + sqrt(3)*t + 3*t + 1)/(sqrt(3) +␣˓→1)This last output agrees with the corresponding example given in Chinen’s paper below.
REFERENCES:• Chinen, K. “An abundance of invariant polynomials satisfying the Riemann hypothesis”, April 2007
preprint.
construction_x(other, aux)
Construction X applied to self=C_1, other=C_2 and aux=C_a.
other must be a subcode of self.
If 𝐶1 is a [𝑛, 𝑘1 , 𝑑1 ] linear code and 𝐶2 is a [𝑛, 𝑘2 , 𝑑2 ] linear code, then 𝑘1 > 𝑘2 and 𝑑1 < 𝑑2 . 𝐶𝑎 must bea [𝑛𝑎 , 𝑘𝑎 , 𝑑𝑎 ] linear code, such that 𝑘𝑎 + 𝑘2 = 𝑘1 and 𝑑𝑎 + 𝑑1 ≤ 𝑑2 .
The method will then return a [𝑛 + 𝑛𝑎 , 𝑘1 , 𝑑𝑎 + 𝑑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: # needs sage.libs.gap
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>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(2)),Integer(15),Integer(7))(continues on next page)

84

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> C[15, 5] BCH Code over GF(2) with designed distance 7>>> D = codes.BCHCode(GF(Integer(2)),Integer(15),Integer(5))>>> D[15, 7] BCH Code over GF(2) with designed distance 5>>> C.is_subcode(D)True>>> # needs sage.libs.gap>>> C.minimum_distance()
7>>> D.minimum_distance()
5>>> aux = codes.HammingCode(GF(Integer(2)),Integer(2))>>> aux = aux.dual_code()>>> aux.minimum_distance()2>>> Cx = D.construction_x(C,aux)>>> Cx[18, 7] linear code over GF(2)>>> Cx.minimum_distance()
7

cosetGraph()
Return the coset graph of this linear code.
The coset graph of a linear code 𝐶 is the graph whose vertices are the cosets of 𝐶, considered as a subgroupof the additive group of the ambient vector space, and two cosets are adjacent if they have representatives
that differ in exactly one coordinate.
EXAMPLES:
sage: # needs sage.graphs
sage: C = codes.GolayCode(GF(3))
sage: G = C.cosetGraph()
sage: G.is_distance_regular()True
sage: C = codes.KasamiCode(8,2)
sage: G = C.cosetGraph()
sage: G.is_distance_regular()True>>> from sage.all import *>>> # needs sage.graphs>>> C = codes.GolayCode(GF(Integer(3)))>>> G = C.cosetGraph()>>> G.is_distance_regular()
True>>> C = codes.KasamiCode(Integer(8),Integer(2))>>> G = C.cosetGraph()>>> G.is_distance_regular()
True

ALGORITHM:
Instead of working with cosets we compute a (direct sum) complement of 𝐶. Let 𝑃 be the projection of thecosets to the newly found subspace. Then two vectors are adjacent if they differ by 𝜆𝑃 (𝑒𝑖 ) for some 𝑖.

10.2. Generic structures for linear codes over the Hamming metric85

Coding Theory, Release 10.4

covering_radius()
Return the minimal integer 𝑟 such that any element in the ambient space of self has distance at most 𝑟 toa codeword of self.
This method requires the optional GAP package Guava.
If the covering radius of a code equals its minimum distance, then the code is called perfect.
Note: This method is currently not implemented on codes over base fields of cardinality greater than 256
due to limitations in the underlying algorithm of GAP.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 5)
sage: C.covering_radius()
˓→guava...1# optional - gap_package_

sage: C = codes.random_linear_code(GF(263), 5, 1)
sage: C.covering_radius()# optional - gap_package_
˓→guava
Traceback (most recent call last):...
NotImplementedError: the GAP algorithm that Sage is using
is limited to computing with fields of size at most 256>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(5))>>> C.covering_radius()# optional - gap_package_
˓→guava...1>>> C = codes.random_linear_code(GF(Integer(263)), Integer(5), Integer(1))>>> C.covering_radius()# optional - gap_package_
˓→guava
Traceback (most recent call last):...
NotImplementedError: the GAP algorithm that Sage is using
is limited to computing with fields of size at most 256

direct_sum(other)
Return the direct sum of the codes self and other.
This returns the code given by the direct sum of the codes self and other, which must be linear codes
defined over the same base ring.
EXAMPLES:
sage: C1 = codes.HammingCode(GF(2), 3)
sage: C2 = C1.direct_sum(C1); C2[14, 8] linear code over GF(2)sage: C3 = C1.direct_sum(C2); C3[21, 12] linear code over GF(2)>>> from sage.all import *>>> C1 = codes.HammingCode(GF(Integer(2)), Integer(3))(continues on next page)

86

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> C2 = C1.direct_sum(C1); C2[14, 8] linear code over GF(2)>>> C3 = C1.direct_sum(C2); C3[21, 12] linear code over GF(2)divisor()Return the greatest common divisor of the weights of the nonzero codewords.
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: C.divisor()# Type II self-dual
4
sage: C = codes.QuadraticResidueCodeEvenPair(17, GF(2))[0]sage: C.divisor()2>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> C.divisor()# Type II self-dual
4>>> C = codes.QuadraticResidueCodeEvenPair(Integer(17),␣
˓→GF(Integer(2)))[Integer(0)]>>> C.divisor()
2extended_code()
Return self as an extended code.
See documentation of sage.coding.extended_code.ExtendedCode for details.
EXAMPLES:
sage: C = codes.HammingCode(GF(4, a ), 3)
sage: C
[21, 18] Hamming Code over GF(4)sage: Cx = C.extended_code()sage: Cx
Extension of [21, 18] Hamming Code over GF(4)>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(4), a ), Integer(3))>>> C[21, 18] Hamming Code over GF(4)>>> Cx = C.extended_code()>>> CxExtension of [21, 18] Hamming Code over GF(4)galois_closure(F0)
If self is a linear code defined over 𝐹 and 𝐹0 is a subfield with Galois group 𝐺 = 𝐺𝑎𝑙(𝐹 /𝐹0 ) then thisreturns the 𝐺-module 𝐶 − containing 𝐶.
EXAMPLES:
sage: C = codes.HammingCode(GF(4, a ), 3)
sage: Cc = C.galois_closure(GF(2))(continues on next page)10.2. Generic structures for linear codes over the Hamming metric87

Coding Theory, Release 10.4

(continued from previous page)

sage: C; Cc[21, 18] Hamming Code over GF(4)[21, 20] linear code over GF(4)sage: c = C.basis()[2]sage: V = VectorSpace(GF(4, a ),21)
sage: c2 = V([x^2 for x in c.list()])
sage: c2 in C
False
sage: c2 in Cc
True>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(4), a ), Integer(3))>>> Cc = C.galois_closure(GF(Integer(2)))>>> C; Cc[21, 18] Hamming Code over GF(4)[21, 20] linear code over GF(4)>>> c = C.basis()[Integer(2)]>>> V = VectorSpace(GF(Integer(4), a ),Integer(21))>>> c2 = V([x**Integer(2) for x in c.list()])>>> c2 in C
False>>> c2 in Cc
Truegenus()
Return the “Duursma genus” of the code, 𝛾𝐶 = 𝑛 + 1 − 𝑘 − 𝑑.
EXAMPLES:
sage: C1 = codes.HammingCode(GF(2), 3); C1[7, 4] Hamming Code over GF(2)sage: C1.genus()
1sage: C2 = codes.HammingCode(GF(4,"a"), 2); C2[5, 3] Hamming Code over GF(4)sage: C2.genus()0>>> from sage.all import *>>> C1 = codes.HammingCode(GF(Integer(2)), Integer(3)); C1[7, 4] Hamming Code over GF(2)>>> C1.genus()
1>>> C2 = codes.HammingCode(GF(Integer(4),"a"), Integer(2)); C2[5, 3] Hamming Code over GF(4)>>> C2.genus()
0

Since all Hamming codes have minimum distance 3, these computations agree with the definition, 𝑛+1−𝑘−𝑑.
is_galois_closed()
Checks if self is equal to its Galois closure.
EXAMPLES:

88

Chapter 10. Linear CodesCoding Theory, Release 10.4

sage: C = codes.HammingCode(GF(4,"a"), 3)
sage: C.is_galois_closed()
False>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(4),"a"), Integer(3))>>> C.is_galois_closed()False

is_permutation_equivalent(other, algorithm=None)
Return True if self and other are permutation equivalent codes and False otherwise.
The algorithm="verbose" option also returns a permutation (if True) sending self to other.
Uses Robert Miller’s double coset partition refinement work.
EXAMPLES:
sage: P.<x> = PolynomialRing(GF(2),"x")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")
˓→needs sage.groups(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)
sage: C1.is_permutation_equivalent(C2)
False

#␣

>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(2)),"x", names=( x ,)); (x,) = P._first_
˓→ngens(1)>>> g = x**Integer(3) + x + Integer(1)>>> C1 = codes.CyclicCode(length=Integer(7), generator_pol=g); C1[7, 4] Cyclic Code over GF(2)>>> C2 = codes.HammingCode(GF(Integer(2)), Integer(3)); C2[7, 4] Hamming Code over GF(2)>>> C1.is_permutation_equivalent(C2)
True>>> C1.is_permutation_equivalent(C2, algorithm="verbose")#␣˓→needs sage.groups(True, (3,4)(5,7,6))>>> C1 = codes.random_linear_code(GF(Integer(2)), Integer(10), Integer(5))>>> C2 = codes.random_linear_code(GF(Integer(3)), Integer(10), Integer(5))>>> C1.is_permutation_equivalent(C2)False

is_projective()
Test whether the code is projective.
A linear code 𝐶 over a field is called projective when its dual 𝐶𝑑 has minimum weight ≥ 3, i.e. when no two
coordinate positions of 𝐶 are linearly independent (cf. definition 3 from [BS2011] or 9.8.1 from [BH2012]).
EXAMPLES:
10.2. Generic structures for linear codes over the Hamming metric89

Coding Theory, Release 10.4

sage: C = codes.GolayCode(GF(2), False)
sage: C.is_projective()
True
sage: C.dual_code().minimum_distance()
˓→needs sage.libs.gap
8#␣>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)), False)>>> C.is_projective()
True>>> C.dual_code().minimum_distance()
˓→needs sage.libs.gap
8#␣

A non-projective code:
sage: C = codes.LinearCode(matrix(GF(2), [[1,0,1],[1,1,1]]))
sage: C.is_projective()
False>>> from sage.all import *>>> C = codes.LinearCode(matrix(GF(Integer(2)), [[Integer(1),Integer(0),˓→Integer(1)],[Integer(1),Integer(1),Integer(1)]]))>>> C.is_projective()
False

juxtapose(other)
Juxtaposition of self and other
The two codes must have equal dimension.
EXAMPLES:
sage: C1 = codes.HammingCode(GF(2), 3)
sage: C2 = C1.juxtapose(C1)sage: C2
[14, 4] linear code over GF(2)>>> from sage.all import *>>> C1 = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C2 = C1.juxtapose(C1)>>> C2[14, 4] linear code over GF(2)minimum_distance(algorithm=None)
Return the minimum distance of self.
Note: When using GAP, this raises a NotImplementedError if the base field of the code has size
greater than 256 due to limitations in GAP.
INPUT:• algorithm – (default: None) the name of the algorithm to use to perform minimum distance computation. algorithm can be:

90

Chapter 10. Linear CodesCoding Theory, Release 10.4

– None, to use GAP methods (but not Guava)– "Guava", to use the optional GAP package Guava
OUTPUT:• Integer, minimum distance of this code
EXAMPLES:
sage: MS = MatrixSpace(GF(3),4,7)
sage: G = MS([[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.minimum_distance()#␣˓→needs sage.libs.gap
3>>> from sage.all import *>>> MS = MatrixSpace(GF(Integer(3)),Integer(4),Integer(7))>>> G = MS([[Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),˓→Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),Integer(1),˓→Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),˓→Integer(0),Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> C.minimum_distance()
˓→needs sage.libs.gap
3#␣

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")#␣˓→needs sage.libs.gap
3
sage: libgap.SetAllInfoLevels(0)# to suppress extra info messages #␣˓→needs sage.libs.gap
sage: C.minimum_distance(algorithm="guava")# optional - gap_package_
˓→guava...3>>> from sage.all import *>>> C.minimum_distance(algorithm="gap")
˓→needs sage.libs.gap
3>>> libgap.SetAllInfoLevels(Integer(0))˓→messages# needs sage.libs.gap>>> C.minimum_distance(algorithm="guava")
˓→guava...3#␣# to suppress extra info␣
# optional - gap_package_

module_composition_factors(gp)Print the GAP record of the Meataxe composition factors module.
This is displayed in Meataxe notation.
This uses GAP but not Guava.
EXAMPLES:
10.2. Generic structures for linear codes over the Hamming metric91

Coding Theory, Release 10.4

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: C = LinearCode(G)sage: gp = C.permutation_automorphism_group()
˓→needs sage.libs.gap
sage: C.module_composition_factors(gp)˓→needs sage.libs.gap[ rec(
IsIrreducible := true,
IsOverFiniteField := true,...) ]#␣#␣>>> from sage.all import *>>> MS = MatrixSpace(GF(Integer(2)),Integer(4),Integer(8))>>> G = MS([[Integer(1),Integer(0),Integer(0),Integer(0),Integer(1),˓→Integer(1),Integer(1),Integer(0)], [Integer(0),Integer(1),Integer(1),˓→Integer(1),Integer(0),Integer(0),Integer(0),Integer(0)],...
[Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(1)], [Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(1),Integer(0),Integer(0)]])>>> C = LinearCode(G)>>> gp = C.permutation_automorphism_group()
˓→needs sage.libs.gap>>> C.module_composition_factors(gp)˓→needs sage.libs.gap[ rec(
IsIrreducible := true,
IsOverFiniteField := true,...) ]#␣#␣

permutation_automorphism_group(algorithm='partition')
If 𝐶 is an [𝑛, 𝑘, 𝑑] code over 𝐹 , this function computes the subgroup 𝐴𝑢𝑡(𝐶) ⊂ 𝑆𝑛 of all permutation
automorphisms of 𝐶. The binary case always uses the (default) partition refinement algorithm of Robert
Miller.
Note that if the base ring of 𝐶 is 𝐺𝐹 (2) then this is the full automorphism group. Otherwise, you could use
automorphism_group_gens() to compute generators of the full automorphism group.
INPUT:• algorithm – If "gap" then GAP’s MatrixAutomorphism function (written by Thomas Breuer) isused. The implementation combines an idea of mine with an improvement suggested by Cary Huffman.
If "gap+verbose" then code-theoretic data is printed out at several stages of the computation. If"partition" then the (default) partition refinement algorithm of Robert Miller is used. Finally, if"codecan" then the partition refinement algorithm of Thomas Feulner is used, which also computes
a canonical representative of self (call canonical_representative() to access it).
OUTPUT:• Permutation automorphism group
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: C = LinearCode(G); C(continues on next page)

92

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)[8, 4] linear code over GF(2)sage: # needs sage.groups
sage: G = C.permutation_automorphism_group()
sage: G.order()144
sage: GG = C.permutation_automorphism_group("codecan")sage: GG == G
True>>> from sage.all import *>>> MS = MatrixSpace(GF(Integer(2)),Integer(4),Integer(8))>>> G = MS([[Integer(1),Integer(0),Integer(0),Integer(0),Integer(1),˓→Integer(1),Integer(1),Integer(0)], [Integer(0),Integer(1),Integer(1),˓→Integer(1),Integer(0),Integer(0),Integer(0),Integer(0)],...
[Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(1)], [Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(1),Integer(0),Integer(0)]])>>> C = LinearCode(G); C[8, 4] linear code over GF(2)>>> # needs sage.groups>>> G = C.permutation_automorphism_group()>>> G.order()144>>> GG = C.permutation_automorphism_group("codecan")>>> GG == GTrue

A less easy example involves showing that the permutation automorphism group of the extended ternary Golay
code is the Mathieu group 𝑀11 .
sage: # needs sage.groups
sage: C = codes.GolayCode(GF(3))
sage: M11 = MathieuGroup(11)sage: M11.order()7920
sage: G = C.permutation_automorphism_group()
˓→on sage.math, 2011)
sage: G.is_isomorphic(M11)True
sage: GG = C.permutation_automorphism_group("codecan")sage: GG == G
True>>> from sage.all import *>>> # needs sage.groups>>> C = codes.GolayCode(GF(Integer(3)))>>> M11 = MathieuGroup(Integer(11))>>> M11.order()7920>>> G = C.permutation_automorphism_group()
˓→sage.math, 2011)>>> G.is_isomorphic(M11)
True>>> GG = C.permutation_automorphism_group("codecan")# long time (6s␣
# long time
# long time
# long time

# long time (6s on␣# long time
# long time(continues on next page)10.2. Generic structures for linear codes over the Hamming metric93

Coding Theory, Release 10.4

(continued from previous page)>>> GG == G
True

# long time

Other examples:sage: # needs sage.groups
sage: C = codes.GolayCode(GF(2))
sage: G = C.permutation_automorphism_group()
sage: G.order()244823040
sage: C = codes.HammingCode(GF(2), 5)
sage: G = C.permutation_automorphism_group()
sage: G.order()9999360
sage: C = codes.HammingCode(GF(3), 2); C[4, 2] Hamming Code over GF(3)sage: C.permutation_automorphism_group(algorithm="partition")
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
Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)]
sage: GG = C.permutation_automorphism_group(algorithm="codecan")# long␣˓→timesage: GG == G
# long␣˓→timeTruesage: C.permutation_automorphism_group(algorithm="gap")# optional - gap_
˓→package_guava
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_
˓→package_guava
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)]>>> from sage.all import *>>> # needs sage.groups>>> C = codes.GolayCode(GF(Integer(2)))>>> G = C.permutation_automorphism_group()>>> G.order()244823040>>> C = codes.HammingCode(GF(Integer(2)), Integer(5))>>> G = C.permutation_automorphism_group()>>> G.order()9999360>>> C = codes.HammingCode(GF(Integer(3)), Integer(2)); C[4, 2] Hamming Code over GF(3)>>> C.permutation_automorphism_group(algorithm="partition")
Permutation Group with generators [(1,3,4)]>>> C = codes.HammingCode(GF(Integer(4),"z"), Integer(2)); C[5, 3] Hamming Code over GF(4)>>> G = C.permutation_automorphism_group(algorithm="partition"); G
Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)]>>> GG = C.permutation_automorphism_group(algorithm="codecan")# long time(continues on next page)

94

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> GG == G
# long time
True>>> C.permutation_automorphism_group(algorithm="gap")# optional - gap_
˓→package_guava
Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)]>>> C = codes.GolayCode(GF(Integer(3)), True)>>> C.permutation_automorphism_group(algorithm="gap")# optional - gap_
˓→package_guava
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:
Minimum distance: 5 Weight distribution: [1, 0, 0, 0, 0, 132, 132,
0, 330, 110, 0, 24]
Using the 132 codewords of weight 5 Supergroup size: 39916800

in addition to the output of C.permutation_automorphism_group(algorithm="gap").
product_code(other)
Combines self with other to give the tensor product code.
If self is a [𝑛1 , 𝑘1 , 𝑑1 ]-code and other is a [𝑛2 , 𝑘2 , 𝑑2 ]-code, the product is a [𝑛1 𝑛2 , 𝑘1 𝑘2 , 𝑑1 𝑑2 ]-code.
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()Truesage: A.minimum_distance() == C.minimum_distance()*D.minimum_distance()
˓→needs sage.libs.gap
True

#␣

>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C[7, 4] Hamming Code over GF(2)>>> D = codes.ReedMullerCode(GF(Integer(2)), Integer(2), Integer(2))>>> D
Binary Reed-Muller Code of order 2 and number of variables 2>>> A = C.product_code(D)>>> A[28, 16] linear code over GF(2)(continues on next page)10.2. Generic structures for linear codes over the Hamming metric95

Coding Theory, Release 10.4

(continued from previous page)>>> A.length() == C.length()*D.length()
True>>> A.dimension() == C.dimension()*D.dimension()
True>>> A.minimum_distance() == C.minimum_distance()*D.minimum_distance()
˓→needs sage.libs.gap
True

#␣

punctured(L)Return a sage.coding.punctured_code object from L.
INPUT:• L – List of positions to puncture
OUTPUT:• an instance of sage.coding.punctured_code
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.punctured([1,2])
Puncturing of [7, 4] Hamming Code over GF(2) on position(s) [1, 2]>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.punctured([Integer(1),Integer(2)])
Puncturing of [7, 4] Hamming Code over GF(2) on position(s) [1, 2]

relative_distance()
Return the ratio of the minimum distance to the code length.
EXAMPLES:
sage: C = codes.HammingCode(GF(2),3)
sage: C.relative_distance()
3/7>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)),Integer(3))>>> C.relative_distance()
3/7

shortened(L)Return the code shortened at the positions L, where 𝐿 ⊂ {1, 2, ..., 𝑛}.
Consider the subcode 𝐶(𝐿) consisting of all codewords 𝑐 ∈ 𝐶 which satisfy 𝑐𝑖 = 0 for all 𝑖 ∈ 𝐿. The
punctured code 𝐶(𝐿)𝐿 is called the shortened code on 𝐿 and is denoted 𝐶𝐿 . The code constructed is actually
only isomorphic to the shortened code defined in this way.
By Theorem 1.5.7 in [HP2003], 𝐶𝐿 is ((𝐶 ⊥ )𝐿 )⊥ . This is used in the construction below.
INPUT:• L – Subset of {1, ..., 𝑛}, where 𝑛 is the length of this code
OUTPUT:• Linear code, the shortened code described above
96

Chapter 10. Linear CodesCoding Theory, Release 10.4

EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.shortened([1,2])[5, 2] linear code over GF(2)>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.shortened([Integer(1),Integer(2)])[5, 2] linear code over GF(2)spectrum(algorithm=None)
Return the weight distribution, or spectrum, of self as a list.
The weight distribution a code of length 𝑛 is the sequence 𝐴0 , 𝐴1 , ..., 𝐴𝑛 where 𝐴𝑖 is the number of codewords of weight 𝑖.
INPUT:• algorithm – (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.
OUTPUT:• A list of non-negative integers: the weight distribution.
Warning: Specifying algorithm="leon" sometimes prints a traceback related to a stack smashingerror in the C library. The result appears to be computed correctly, however. It appears to run much fasterthan the GAP algorithm in small examples and much slower than the GAP algorithm in larger examples.
EXAMPLES:
sage: MS = MatrixSpace(GF(2),4,7)
sage: G = MS([[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.weight_distribution()[1, 0, 0, 7, 7, 0, 0, 1]
sage: F.<z> = GF(2^2,"z")sage: C = codes.HammingCode(F, 2); C[5, 3] Hamming Code over GF(4)sage: C.weight_distribution()#␣˓→needs sage.libs.gap[1, 0, 0, 30, 15, 18]
sage: C = codes.HammingCode(GF(2), 3); C[7, 4] Hamming Code over GF(2)sage: C.weight_distribution(algorithm="leon")# optional - gap_package_guava[1, 0, 0, 7, 7, 0, 0, 1]
sage: C.weight_distribution(algorithm="gap")#␣˓→needs 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: # optional - gap_package_guava(continues on next page)10.2. Generic structures for linear codes over the Hamming metric97

Coding Theory, Release 10.4

(continued from previous page)

sage: C = codes.HammingCode(GF(3), 3); C[13, 10] Hamming Code over GF(3)sage: C.weight_distribution() == C.weight_distribution(algorithm="leon")Truesage: C = codes.HammingCode(GF(5), 2); C[6, 4] Hamming Code over GF(5)sage: C.weight_distribution() == C.weight_distribution(algorithm="leon")Truesage: C = codes.HammingCode(GF(7), 2); C[8, 6] Hamming Code over GF(7)sage: C.weight_distribution() == C.weight_distribution(algorithm="leon")
True>>> from sage.all import *>>> MS = MatrixSpace(GF(Integer(2)),Integer(4),Integer(7))>>> G = MS([[Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),˓→Integer(0),Integer(0)],[Integer(1),Integer(0),Integer(0),Integer(1),˓→Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(1),Integer(0)],[Integer(1),Integer(1),˓→Integer(0),Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> C.weight_distribution()[1, 0, 0, 7, 7, 0, 0, 1]>>> F = GF(Integer(2)**Integer(2),"z", names=( z ,)); (z,) = F._first_ngens(1)>>> C = codes.HammingCode(F, Integer(2)); C[5, 3] Hamming Code over GF(4)>>> C.weight_distribution()#␣˓→needs sage.libs.gap[1, 0, 0, 30, 15, 18]>>> C = codes.HammingCode(GF(Integer(2)), Integer(3)); C[7, 4] Hamming Code over GF(2)>>> C.weight_distribution(algorithm="leon")# optional - gap_package_guava[1, 0, 0, 7, 7, 0, 0, 1]>>> C.weight_distribution(algorithm="gap")#␣˓→needs sage.libs.gap[1, 0, 0, 7, 7, 0, 0, 1]>>> C.weight_distribution(algorithm="binary")[1, 0, 0, 7, 7, 0, 0, 1]>>> # optional - gap_package_guava>>> C = codes.HammingCode(GF(Integer(3)), Integer(3)); C[13, 10] Hamming Code over GF(3)>>> C.weight_distribution() == C.weight_distribution(algorithm="leon")
True>>> C = codes.HammingCode(GF(Integer(5)), Integer(2)); C[6, 4] Hamming Code over GF(5)>>> C.weight_distribution() == C.weight_distribution(algorithm="leon")
True>>> C = codes.HammingCode(GF(Integer(7)), Integer(2)); C[8, 6] Hamming Code over GF(7)>>> C.weight_distribution() == C.weight_distribution(algorithm="leon")
Truesupport()Return the set of indices 𝑗 where 𝐴𝑗 is nonzero, where 𝐴𝑗 is the number of codewords in self of Hamming
weight 𝑗.

98

Chapter 10. Linear CodesCoding Theory, Release 10.4

OUTPUT:• List of integers
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.weight_distribution()[1, 0, 0, 7, 7, 0, 0, 1]
sage: C.support()[0, 3, 4, 7]>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.weight_distribution()[1, 0, 0, 7, 7, 0, 0, 1]>>> C.support()[0, 3, 4, 7]

u_u_plus_v_code(other)
Return the (𝑢|𝑢 + 𝑣)-construction with self=u and other=v.
This returns the code obtained through (𝑢|𝑢 + 𝑣)-construction with self as 𝑢 and other as 𝑣. Note that𝑢 and 𝑣 must have equal lengths. For 𝑢 a [𝑛, 𝑘1 , 𝑑1 ]-code and 𝑣 a [𝑛, 𝑘2 , 𝑑2 ]-code this returns a [2𝑛, 𝑘1 +𝑘2 , 𝑑]-code, where 𝑑 = min(2𝑑1 , 𝑑2 ).
EXAMPLES:
sage: C1 = codes.HammingCode(GF(2), 3)
sage: C2 = codes.HammingCode(GF(2), 3)
sage: D = C1.u_u_plus_v_code(C2)sage: D
[14, 8] linear code over GF(2)>>> from sage.all import *>>> C1 = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C2 = codes.HammingCode(GF(Integer(2)), Integer(3))>>> D = C1.u_u_plus_v_code(C2)>>> D[14, 8] linear code over GF(2)weight_distribution(algorithm=None)
Return the weight distribution, or spectrum, of self as a list.
The weight distribution a code of length 𝑛 is the sequence 𝐴0 , 𝐴1 , ..., 𝐴𝑛 where 𝐴𝑖 is the number of codewords of weight 𝑖.
INPUT:• algorithm – (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.
OUTPUT:• A list of non-negative integers: the weight distribution.

10.2. Generic structures for linear codes over the Hamming metric99

Coding Theory, Release 10.4

Warning: Specifying algorithm="leon" sometimes prints a traceback related to a stack smashingerror in the C library. The result appears to be computed correctly, however. It appears to run much fasterthan the GAP algorithm in small examples and much slower than the GAP algorithm in larger examples.
EXAMPLES:
sage: MS = MatrixSpace(GF(2),4,7)
sage: G = MS([[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.weight_distribution()[1, 0, 0, 7, 7, 0, 0, 1]
sage: F.<z> = GF(2^2,"z")sage: C = codes.HammingCode(F, 2); C[5, 3] Hamming Code over GF(4)sage: C.weight_distribution()#␣˓→needs sage.libs.gap[1, 0, 0, 30, 15, 18]
sage: C = codes.HammingCode(GF(2), 3); C[7, 4] Hamming Code over GF(2)sage: C.weight_distribution(algorithm="leon")# optional - gap_package_guava[1, 0, 0, 7, 7, 0, 0, 1]
sage: C.weight_distribution(algorithm="gap")#␣˓→needs 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: # optional - gap_package_guava
sage: C = codes.HammingCode(GF(3), 3); C[13, 10] Hamming Code over GF(3)sage: C.weight_distribution() == C.weight_distribution(algorithm="leon")Truesage: C = codes.HammingCode(GF(5), 2); C[6, 4] Hamming Code over GF(5)sage: C.weight_distribution() == C.weight_distribution(algorithm="leon")Truesage: C = codes.HammingCode(GF(7), 2); C[8, 6] Hamming Code over GF(7)sage: C.weight_distribution() == C.weight_distribution(algorithm="leon")
True>>> from sage.all import *>>> MS = MatrixSpace(GF(Integer(2)),Integer(4),Integer(7))>>> G = MS([[Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),˓→Integer(0),Integer(0)],[Integer(1),Integer(0),Integer(0),Integer(1),˓→Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(1),Integer(0)],[Integer(1),Integer(1),˓→Integer(0),Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> C.weight_distribution()[1, 0, 0, 7, 7, 0, 0, 1]>>> F = GF(Integer(2)**Integer(2),"z", names=( z ,)); (z,) = F._first_ngens(1)>>> C = codes.HammingCode(F, Integer(2)); C[5, 3] Hamming Code over GF(4)>>> C.weight_distribution()#␣(continues on next page)

100

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)needs sage.libs.gap[1, 0, 0, 30, 15, 18]>>> C = codes.HammingCode(GF(Integer(2)), Integer(3)); C[7, 4] Hamming Code over GF(2)>>> C.weight_distribution(algorithm="leon")# optional - gap_package_guava[1, 0, 0, 7, 7, 0, 0, 1]>>> C.weight_distribution(algorithm="gap")#␣˓→needs sage.libs.gap[1, 0, 0, 7, 7, 0, 0, 1]>>> C.weight_distribution(algorithm="binary")[1, 0, 0, 7, 7, 0, 0, 1]
˓→>>> # optional - gap_package_guava>>> C = codes.HammingCode(GF(Integer(3)), Integer(3)); C[13, 10] Hamming Code over GF(3)>>> C.weight_distribution() == C.weight_distribution(algorithm="leon")
True>>> C = codes.HammingCode(GF(Integer(5)), Integer(2)); C[6, 4] Hamming Code over GF(5)>>> C.weight_distribution() == C.weight_distribution(algorithm="leon")
True>>> C = codes.HammingCode(GF(Integer(7)), Integer(2)); C[8, 6] Hamming Code over GF(7)>>> C.weight_distribution() == C.weight_distribution(algorithm="leon")Trueweight_enumerator(names=None, bivariate=True)
Return the weight enumerator polynomial of self.
This is the bivariate, homogeneous polynomial in 𝑥 and 𝑦 whose coefficient to 𝑥𝑖 𝑦 𝑛−𝑖 is the number ofcodewords of self of Hamming weight 𝑖. Here, 𝑛 is the length of self.
INPUT:• names – (default: "xy") The names of the variables in the homogeneous polynomial. Can be given asa 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, homogeneous polynomial or just a univariate polynomial. If set to False, then names will be interpreted as a single variable name anddefault to "x".
OUTPUT:• The weight enumerator polynomial over .
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.weight_enumerator()x^7 + 7*x^4*y^3 + 7*x^3*y^4 + y^7
sage: C.weight_enumerator(names="st")s^7 + 7*s^4*t^3 + 7*s^3*t^4 + t^7
sage: C.weight_enumerator(names="var1, var2")
var1^7 + 7*var1^4*var2^3 + 7*var1^3*var2^4 + var2^7
sage: C.weight_enumerator(names=( var1 , var2 ))var1^7 + 7*var1^4*var2^3 + 7*var1^3*var2^4 + var2^7
sage: C.weight_enumerator(bivariate=False)x^7 + 7*x^4 + 7*x^3 + 1

10.2. Generic structures for linear codes over the Hamming metric101

Coding Theory, Release 10.4>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.weight_enumerator()x^7 + 7*x^4*y^3 + 7*x^3*y^4 + y^7>>> C.weight_enumerator(names="st")s^7 + 7*s^4*t^3 + 7*s^3*t^4 + t^7>>> C.weight_enumerator(names="var1, var2")
var1^7 + 7*var1^4*var2^3 + 7*var1^3*var2^4 + var2^7>>> C.weight_enumerator(names=( var1 , var2 ))var1^7 + 7*var1^4*var2^3 + 7*var1^3*var2^4 + var2^7>>> C.weight_enumerator(bivariate=False)x^7 + 7*x^4 + 7*x^3 + 1

An example of a code with a non-symmetrical weight enumerator:
sage: C = codes.GolayCode(GF(3), extended=False)
sage: C.weight_enumerator()
24*x^11 + 110*x^9*y^2 + 330*x^8*y^3 + 132*x^6*y^5 + 132*x^5*y^6 + y^11>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(3)), extended=False)>>> C.weight_enumerator()
24*x^11 + 110*x^9*y^2 + 330*x^8*y^3 + 132*x^6*y^5 + 132*x^5*y^6 + y^11zeta_function(name='T')
Return the Duursma zeta function of the code.
INPUT:• name – String, variable name (default: "T")OUTPUT:
Element of(𝑇 )EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.zeta_function()
˓→needs sage.libs.gap(1/5*T^2 + 1/5*T + 1/10)/(T^2 - 3/2*T + 1/2)>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.zeta_function()
˓→needs sage.libs.gap(1/5*T^2 + 1/5*T + 1/10)/(T^2 - 3/2*T + 1/2)#␣#␣

zeta_polynomial(name='T')
Return the Duursma zeta polynomial of this code.
Assumes that the minimum distances of this code and its dual are greater than 1. Prints a warning to stdout
otherwise.
INPUT:• name – String, variable name (default: "T")OUTPUT:

102

Chapter 10. Linear CodesCoding Theory, Release 10.4

• Polynomial over
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3)
sage: C.zeta_polynomial()
˓→needs sage.libs.gap
2/5*T^2 + 2/5*T + 1/5
sage: C = codes.databases.best_linear_code_in_guava(6, 3, GF(2))˓→optional - gap_package_guava
sage: C.minimum_distance()
˓→optional - gap_package_guava
3
sage: C.zeta_polynomial()
˓→optional - gap_package_guava
2/5*T^2 + 2/5*T + 1/5

#␣

#␣
#␣

#␣

sage: C = codes.HammingCode(GF(2), 4)
sage: C.zeta_polynomial()#␣˓→needs sage.libs.gap
16/429*T^6 + 16/143*T^5 + 80/429*T^4 + 32/143*T^3 + 30/143*T^2 + 2/13*T + 1/13
sage: F.<z> = GF(4,"z")sage: MS = MatrixSpace(F, 3, 6)
sage: G = MS([[1,0,0,1,z,z],[0,1,0,z,1,z],[0,0,1,z,z,1]])
sage: C = LinearCode(G) # the "hexacode"
sage: C.zeta_polynomial()
˓→needs sage.libs.gap
1>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3))>>> C.zeta_polynomial()
˓→needs sage.libs.gap
2/5*T^2 + 2/5*T + 1/5#␣#␣>>> C = codes.databases.best_linear_code_in_guava(Integer(6), Integer(3),␣
˓→GF(Integer(2)))# optional - gap_package_guava>>> C.minimum_distance()# optional ˓→ gap_package_guava
3>>> C.zeta_polynomial()# optional ˓→ gap_package_guava
2/5*T^2 + 2/5*T + 1/5>>> C = codes.HammingCode(GF(Integer(2)), Integer(4))>>> C.zeta_polynomial()#␣˓→needs sage.libs.gap
16/429*T^6 + 16/143*T^5 + 80/429*T^4 + 32/143*T^3 + 30/143*T^2 + 2/13*T + 1/13>>> F = GF(Integer(4),"z", names=( z ,)); (z,) = F._first_ngens(1)>>> MS = MatrixSpace(F, Integer(3), Integer(6))>>> G = MS([[Integer(1),Integer(0),Integer(0),Integer(1),z,z],[Integer(0),˓→Integer(1),Integer(0),z,Integer(1),z],[Integer(0),Integer(0),Integer(1),z,z,
˓→Integer(1)]])>>> C = LinearCode(G) # the "hexacode">>> C.zeta_polynomial()#␣(continues on next page)10.2. Generic structures for linear codes over the Hamming metric103

Coding Theory, Release 10.4

(continued from previous page)needs sage.libs.gap

˓→

1

REFERENCES:• [Du2001]
class sage.coding.linear_code.LinearCode(generator, d=None)
Bases: AbstractLinearCode
Linear codes over a finite field or finite ring, represented using a generator matrix.
This class should be used for arbitrary and unstructured linear codes. This means that basic operations on the code,such as the computation of the 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 byinvestigating codes.<tab>. These more specific classes use properties particular to that family to allow faster
algorithms, and could also have family-specific methods.
See Wikipedia article Linear_code for more information on unstructured linear codes.
INPUT:• generator – a generator matrix over a finite field (G can be defined over a finite ring but the matrices overthat ring must have certain attributes, such as rank); or a code over a finite field• d – (default: None) the minimum distance of the code
Note: The veracity of the minimum distance d, if provided, is not checked.
EXAMPLES:
sage: MS = MatrixSpace(GF(2),4,7)
sage: G = MS([[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[7, 4] linear code over GF(2)sage: C.base_ring()
Finite Field of size 2
sage: C.dimension()4
sage: C.length()
7
sage: C.minimum_distance()#␣˓→needs sage.libs.gap
3
sage: C.spectrum()[1, 0, 0, 7, 7, 0, 0, 1]
sage: C.weight_distribution()[1, 0, 0, 7, 7, 0, 0, 1]>>> from sage.all import *>>> MS = MatrixSpace(GF(Integer(2)),Integer(4),Integer(7))>>> G = MS([[Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),Integer(0),˓→Integer(0)], [Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),˓→Integer(0)], [Integer(0),Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),(continues on next page)

104

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)

Integer(0)], [Integer(1),Integer(1),Integer(0),Integer(1),Integer(0),Integer(0),˓→Integer(1)]])>>> C = LinearCode(G)>>> C[7, 4] linear code over GF(2)>>> C.base_ring()
Finite Field of size 2>>> C.dimension()
4>>> C.length()
7>>> C.minimum_distance()#␣˓→needs sage.libs.gap
3>>> C.spectrum()[1, 0, 0, 7, 7, 0, 0, 1]>>> C.weight_distribution()[1, 0, 0, 7, 7, 0, 0, 1]
˓→The minimum distance of the code, if known, can be provided as an optional parameter.:sage: C = LinearCode(G, d=3)
sage: C.minimum_distance()
˓→needs sage.libs.gap
3>>> from sage.all import *>>> C = LinearCode(G, d=Integer(3))>>> C.minimum_distance()
˓→needs sage.libs.gap
3

#␣

#␣

Another example.:sage: MS = MatrixSpace(GF(5),4,7)
sage: G = MS([[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); C[7, 4] linear code over GF(5)>>> from sage.all import *>>> MS = MatrixSpace(GF(Integer(5)),Integer(4),Integer(7))>>> G = MS([[Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),Integer(0),˓→Integer(0)], [Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),˓→Integer(0)], [Integer(0),Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0)], [Integer(1),Integer(1),Integer(0),Integer(1),Integer(0),Integer(0),˓→Integer(1)]])>>> C = LinearCode(G); C[7, 4] linear code over GF(5)Providing a code as the parameter in order to “forget” its structure (see Issue #20198):
sage: C = codes.GeneralizedReedSolomonCode(GF(23).list(), 12)
sage: LinearCode(C)[23, 12] linear code over GF(23)10.2. Generic structures for linear codes over the Hamming metric105

Coding Theory, Release 10.4>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(23)).list(), Integer(12))>>> LinearCode(C)[23, 12] linear code over GF(23)Another example:
sage: C = codes.HammingCode(GF(7), 3)
sage: C[57, 54] Hamming Code over GF(7)sage: LinearCode(C)[57, 54] linear code over GF(7)>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(7)), Integer(3))>>> C[57, 54] Hamming Code over GF(7)>>> LinearCode(C)[57, 54] linear code over GF(7)AUTHORS:• David Joyner (11-2005)• Charles Prior (03-2016): Issue #20198, LinearCode from a code
generator_matrix(encoder_name=None, **kwargs)
Return a generator matrix of self.
INPUT:• encoder_name – (default: None) name of the encoder which will be used to compute the generator
matrix. self._generator_matrix will be returned if default value is kept.
• kwargs – all additional arguments are forwarded to the construction of the encoder that is used.
EXAMPLES:
sage: G = matrix(GF(3),2,[1,-1,1,-1,1,1])
sage: code = LinearCode(G)sage: code.generator_matrix()[1 2 1][2 1 1]>>> from sage.all import *>>> G = matrix(GF(Integer(3)),Integer(2),[Integer(1),-Integer(1),Integer(1),˓→Integer(1),Integer(1),Integer(1)])>>> code = LinearCode(G)>>> code.generator_matrix()[1 2 1][2 1 1]class sage.coding.linear_code.LinearCodeGeneratorMatrixEncoder(code)
Bases: Encoder
Encoder based on generator_matrix for Linear codes.
This is the default encoder of a generic linear code, and should never be used for other codes than LinearCode.
INPUT:
106

Chapter 10. Linear CodesCoding Theory, Release 10.4

• code – The associated LinearCode of this encoder.
generator_matrix()
Return a generator matrix of the associated code of 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: C = LinearCode(G)sage: E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)sage: E.generator_matrix()[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]>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)>>> E.generator_matrix()[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]

class sage.coding.linear_code.LinearCodeNearestNeighborDecoder(code)
Bases: Decoder
Construct a decoder for Linear Codes. This decoder will decode to the nearest codeword found.
INPUT:• code – A code associated to this decoder
decode_to_code(r)Corrects the errors in word and returns a codeword.
INPUT:• r – a codeword of self
OUTPUT:• a vector of self’s message space
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: C = LinearCode(G)sage: D = codes.decoders.LinearCodeNearestNeighborDecoder(C)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))(continues on next page)10.2. Generic structures for linear codes over the Hamming metric107

Coding Theory, Release 10.4

(continued from previous page)

sage: D.decode_to_code(w_err)(1, 1, 0, 0, 1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> D = codes.decoders.LinearCodeNearestNeighborDecoder(C)>>> word = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(1), Integer(1), Integer(0)))>>> w_err = word + vector(GF(Integer(2)), (Integer(1), Integer(0), Integer(0),˓→ Integer(0), Integer(0), Integer(0), Integer(0)))>>> D.decode_to_code(w_err)(1, 1, 0, 0, 1, 1, 0)

decoding_radius()
Return maximal number of errors self can decode.
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: C = LinearCode(G)sage: D = codes.decoders.LinearCodeNearestNeighborDecoder(C)sage: D.decoding_radius()
˓→needs sage.libs.gap
1#␣>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> D = codes.decoders.LinearCodeNearestNeighborDecoder(C)>>> D.decoding_radius()#␣˓→needs sage.libs.gap
1class sage.coding.linear_code.LinearCodeSyndromeDecoder(code,
maximum_error_weight=None)
Bases: Decoder
Constructs a decoder for Linear Codes based on syndrome lookup table.
The decoding algorithm works as follows:• First, a lookup table is built by computing the syndrome of every error pattern of weight up to maximum_error_weight.
• Then, whenever one tries to decode a word r, the syndrome of r is computed. The corresponding error
pattern is recovered from the pre-computed lookup table.
108

Chapter 10. Linear CodesCoding Theory, Release 10.4

• Finally, the recovered error pattern is subtracted from r to recover the original word.
maximum_error_weight need never exceed the covering radius of the code, since there are then always
lower-weight errors with the same syndrome. If one sets maximum_error_weight to a value greater than the
covering radius, then the covering radius will be determined while building the lookup-table. This lower value isthen returned if you query decoding_radius after construction.
If maximum_error_weight is left unspecified or set to a number at least the covering radius of the code, thisdecoder is complete, i.e. it decodes every vector in the ambient space.
Note: Constructing the lookup table takes time exponential in the length of the code and the size of the code’sbase field. Afterwards, the individual decodings are fast.
INPUT:• code – A code associated to this decoder• maximum_error_weight – (default: None) the maximum number of errors to look for when building
the table. An error is raised if it is set greater than 𝑛 − 𝑘, since this is an upper bound on the covering radius
on any linear code. If maximum_error_weight is kept unspecified, it will be set to 𝑛 − 𝑘, where 𝑛 is
the length of code and 𝑘 its dimension.
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: C = LinearCode(G)sage: D = codes.decoders.LinearCodeSyndromeDecoder(C)sage: D
Syndrome decoder for [9, 3] linear code over GF(3) handling errors of weight up␣
˓→to 4>>> from sage.all import *>>> G = Matrix(GF(Integer(3)), [[Integer(1),Integer(0),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0),Integer(1),Integer(2)],...
[Integer(0),Integer(1),Integer(0),Integer(2),Integer(2),˓→Integer(0),Integer(1),Integer(1),Integer(0)],...
[Integer(0),Integer(0),Integer(1),Integer(0),Integer(2),˓→Integer(2),Integer(2),Integer(1),Integer(2)]])>>> C = LinearCode(G)>>> D = codes.decoders.LinearCodeSyndromeDecoder(C)>>> D
Syndrome decoder for [9, 3] linear code over GF(3) handling errors of weight up␣
˓→to 4

If one wants to correct up to a lower number of errors, one can do as follows:
sage: D = codes.decoders.LinearCodeSyndromeDecoder(C, maximum_error_weight=2)
sage: D
Syndrome decoder for [9, 3] linear code over GF(3) handling errors of weight up␣
˓→to 2>>> from sage.all import *>>> D = codes.decoders.LinearCodeSyndromeDecoder(C, maximum_error_
˓→weight=Integer(2))>>> D(continues on next page)10.2. Generic structures for linear codes over the Hamming metric109

Coding Theory, Release 10.4

(continued from previous page)

Syndrome decoder for [9, 3] linear code over GF(3) handling errors of weight up␣
˓→to 2

If one checks the list of types of this decoder before constructing it, one will notice it contains the keyword dynamic. Indeed, the behaviour of the syndrome decoder depends on the maximum error weight one wants to handle,
and how it compares to the minimum distance and the covering radius of code. In the following examples, we
illustrate this property by computing different instances of syndrome decoder for the same code.
We choose the following linear code, whose covering radius equals to 4 and minimum distance to 5 (half theminimum distance is 2):
sage: G = matrix(GF(5), [[1, 0, 0, 0, 0, 4, 3, 0, 3, 1, 0],....:[0, 1, 0, 0, 0, 3, 2, 2, 3, 2, 1],....:[0, 0, 1, 0, 0, 1, 3, 0, 1, 4, 1],....:[0, 0, 0, 1, 0, 3, 4, 2, 2, 3, 3],....:[0, 0, 0, 0, 1, 4, 2, 3, 2, 2, 1]])
sage: C = LinearCode(G)>>> from sage.all import *>>> G = matrix(GF(Integer(5)), [[Integer(1), Integer(0), Integer(0), Integer(0),␣
˓→Integer(0), Integer(4), Integer(3), Integer(0), Integer(3), Integer(1),␣
˓→Integer(0)],...
[Integer(0), Integer(1), Integer(0), Integer(0),␣
˓→Integer(0), Integer(3), Integer(2), Integer(2), Integer(3), Integer(2),␣
˓→Integer(1)],...
[Integer(0), Integer(0), Integer(1), Integer(0),␣
˓→Integer(0), Integer(1), Integer(3), Integer(0), Integer(1), Integer(4),␣
˓→Integer(1)],...
[Integer(0), Integer(0), Integer(0), Integer(1),␣
˓→Integer(0), Integer(3), Integer(4), Integer(2), Integer(2), Integer(3),␣
˓→Integer(3)],...
[Integer(0), Integer(0), Integer(0), Integer(0),␣
˓→Integer(1), Integer(4), Integer(2), Integer(3), Integer(2), Integer(2),␣
˓→Integer(1)]])>>> C = LinearCode(G)In the following examples, we illustrate how the choice of maximum_error_weight influences the types of
the instance of syndrome decoder, alongside with its decoding radius.
We build a first syndrome decoder, and pick a maximum_error_weight smaller than both the covering radiusand half the minimum distance:
sage: D = C.decoder("Syndrome", maximum_error_weight=1)
sage: D.decoder_type(){ always-succeed , bounded_distance , hard-decision }sage: D.decoding_radius()
1>>> from sage.all import *>>> D = C.decoder("Syndrome", maximum_error_weight=Integer(1))>>> D.decoder_type(){ always-succeed , bounded_distance , hard-decision }>>> D.decoding_radius()
1

In that case, we are sure the decoder will always succeed. It is also a bounded distance decoder.

110

Chapter 10. Linear CodesCoding Theory, Release 10.4

We now build another syndrome decoder, and this time, maximum_error_weight is chosen to be bigger thanhalf the minimum distance, but lower than the covering radius:
sage: D = C.decoder("Syndrome", maximum_error_weight=3)
sage: D.decoder_type(){ bounded_distance , hard-decision , might-error }sage: D.decoding_radius()
3>>> from sage.all import *>>> D = C.decoder("Syndrome", maximum_error_weight=Integer(3))>>> D.decoder_type(){ bounded_distance , hard-decision , might-error }>>> D.decoding_radius()
3

Here, we still get a bounded distance decoder. But because we have a maximum error weight bigger than half theminimum distance, we know it might return a codeword which was not the original codeword.
And now, we build a third syndrome decoder, whose maximum_error_weight is bigger than both the coveringradius and half the minimum distance:
sage: D = C.decoder("Syndrome", maximum_error_weight=5)
sage: D.decoder_type(){ complete , hard-decision , might-error }sage: D.decoding_radius()
4# long time
# long time
# long time>>> from sage.all import *>>> D = C.decoder("Syndrome", maximum_error_weight=Integer(5))# long time>>> D.decoder_type()# long time
{ complete , hard-decision , might-error }>>> D.decoding_radius()# long time
4

In that case, the decoder might still return an unexpected codeword, but it is now complete. Note the decoding
radius is equal to 4: it was determined while building the syndrome lookup table that any error with weight morethan 4 will be decoded incorrectly. That is because the covering radius for the code is 4.
The minimum distance and the covering radius are both determined while computing the syndrome lookup table.
They user did not explicitly ask to compute these on the code C. The dynamic typing of the syndrome decoder
might therefore seem slightly surprising, but in the end is quite informative.
decode_to_code(r)Correct the errors in word and return a codeword.
INPUT:• r – a codeword of self
OUTPUT:• a vector of self’s message space
EXAMPLES:
sage: G = Matrix(GF(3), [[1, 0, 0, 0, 2, 2, 1, 1],....:[0, 1, 0, 0, 0, 0, 1, 1],....:[0, 0, 1, 0, 2, 0, 0, 2],(continues on next page)10.2. Generic structures for linear codes over the Hamming metric111

Coding Theory, Release 10.4

(continued from previous page)....:[0, 0, 0, 1, 0, 2, 0, 1]])
sage: C = LinearCode(G)sage: D = codes.decoders.LinearCodeSyndromeDecoder(C, maximum_error_weight =␣
˓→1)
sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), 1)
sage: c = C.random_element()
sage: r = Chan(c)sage: c == D.decode_to_code(r)True>>> from sage.all import *>>> G = Matrix(GF(Integer(3)), [[Integer(1), Integer(0), Integer(0),␣
˓→Integer(0), Integer(2), Integer(2), Integer(1), Integer(1)],...
[Integer(0), Integer(1), Integer(0), Integer(0),␣
˓→Integer(0), Integer(0), Integer(1), Integer(1)],...
[Integer(0), Integer(0), Integer(1), Integer(0),␣
˓→Integer(2), Integer(0), Integer(0), Integer(2)],...
[Integer(0), Integer(0), Integer(0), Integer(1),␣
˓→Integer(0), Integer(2), Integer(0), Integer(1)]])>>> C = LinearCode(G)>>> D = codes.decoders.LinearCodeSyndromeDecoder(C, maximum_error_weight =␣˓→Integer(1))>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(), Integer(1))>>> c = C.random_element()>>> r = Chan(c)>>> c == D.decode_to_code(r)True

decoding_radius()
Return the maximal number of errors a received word can have and for which self is guaranteed to returna most likely codeword.
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: C = LinearCode(G)sage: D = codes.decoders.LinearCodeSyndromeDecoder(C)sage: D.decoding_radius()
4>>> from sage.all import *>>> G = Matrix(GF(Integer(3)), [[Integer(1),Integer(0),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0),Integer(1),Integer(2)],...
[Integer(0),Integer(1),Integer(0),Integer(2),˓→Integer(2),Integer(0),Integer(1),Integer(1),Integer(0)],...
[Integer(0),Integer(0),Integer(1),Integer(0),˓→Integer(2),Integer(2),Integer(2),Integer(1),Integer(2)]])>>> C = LinearCode(G)>>> D = codes.decoders.LinearCodeSyndromeDecoder(C)>>> D.decoding_radius()
4

maximum_error_weight()
Return the maximal number of errors a received word can have and for which self is guaranteed to return
112

Chapter 10. Linear CodesCoding Theory, Release 10.4

a most likely codeword.
Same as 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: C = LinearCode(G)sage: D = codes.decoders.LinearCodeSyndromeDecoder(C)sage: D.maximum_error_weight()
4>>> from sage.all import *>>> G = Matrix(GF(Integer(3)), [[Integer(1),Integer(0),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0),Integer(1),Integer(2)],...
[Integer(0),Integer(1),Integer(0),Integer(2),˓→Integer(2),Integer(0),Integer(1),Integer(1),Integer(0)],...
[Integer(0),Integer(0),Integer(1),Integer(0),˓→Integer(2),Integer(2),Integer(2),Integer(1),Integer(2)]])>>> C = LinearCode(G)>>> D = codes.decoders.LinearCodeSyndromeDecoder(C)>>> D.maximum_error_weight()
4syndrome_table()
Return the syndrome lookup table of 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: C = LinearCode(G)sage: D = codes.decoders.LinearCodeSyndromeDecoder(C)sage: D.syndrome_table(){(0, 0, 0): (0, 0, 0, 0, 0, 0, 0),(1, 0, 0): (1, 0, 0, 0, 0, 0, 0),(0, 1, 0): (0, 1, 0, 0, 0, 0, 0),(1, 1, 0): (0, 0, 1, 0, 0, 0, 0),(0, 0, 1): (0, 0, 0, 1, 0, 0, 0),(1, 0, 1): (0, 0, 0, 0, 1, 0, 0),(0, 1, 1): (0, 0, 0, 0, 0, 1, 0),(1, 1, 1): (0, 0, 0, 0, 0, 0, 1)}>>> from sage.all import *>>> G = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)], [Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0)], [Integer(1),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> C = LinearCode(G)>>> D = codes.decoders.LinearCodeSyndromeDecoder(C)>>> D.syndrome_table(){(0, 0, 0): (0, 0, 0, 0, 0, 0, 0),(1, 0, 0): (1, 0, 0, 0, 0, 0, 0),(0, 1, 0): (0, 1, 0, 0, 0, 0, 0),(continues on next page)10.2. Generic structures for linear codes over the Hamming metric113

Coding Theory, Release 10.4

(continued from previous page)(1, 1, 0): (0, 0, 1, 0, 0, 0, 0),(0, 0, 1): (0, 0, 0, 1, 0, 0, 0),(1, 0, 1): (0, 0, 0, 0, 1, 0, 0),(0, 1, 1): (0, 0, 0, 0, 0, 1, 0),(1, 1, 1): (0, 0, 0, 0, 0, 0, 1)}

10.3 Generic structures for linear codes over the rank metric10.3.1 Rank Metric
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𝑞 and F𝑞𝑚 , anddefine a code 𝐶 to be a set of vectors of length 𝑛 with entries from F𝑞𝑚 . Let 𝑐 be a codeword. We can represent it as an𝑚 × 𝑛 matrix 𝑀 over F𝑞 .
A detailed description on the relationship between the two representations can be found in sage.
coding.linear_rank_metric.to_matrix_representation()andsage.coding.
linear_rank_metric.from_matrix_representation().
We can define a metric using the rank of the matrix representation of the codewords. A distance between two codewords
𝑎, 𝑏 is the rank of the matrix representation of 𝑎 − 𝑏. A weight of a codeword 𝑐 is the rank of the matrix representationof 𝑐.
This module allows representing rank metric codes which are linear over the big field F𝑞𝑚 , 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 overF𝑞 , 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 sage.coding.linear_code.LinearCode. However, since most of the functionality of thatclass is specific to the Hamming metric, the two notions are implemented as entirely different in SageMath. If you wish
to investigate Hamming-metric properties of a linear rank metric code C, you can easily convert it by calling C_hamm =LinearCode(C).

114

Chapter 10. Linear CodesCoding Theory, Release 10.4

10.3.2 Linear Rank Metric Code and Gabidulin Codes
The class sage.coding.linear_rank_metric.LinearRankMetricCode is the analog of sage.
coding.linear_code.LinearCode, i.e. it is a generator matrix-based representation of a linear rank metriccode without specific knowledge on the structure of the code.
Gabidulin codes are the main family of structured linear rank metric codes. These codes are the rank-metric analog ofReed-Solomon codes.
AbstractLinearRankMetricCode
This is a base class designed to contain methods, features and parameters shared by every linear rank metric code. For instance, generic algorithms for computing the minimum distance, etc. Many of these algorithms are slow, e.g. exponential
in the code length. It also contains methods for swapping between vector and matrix representation of elements.
AbstractLinearCodeNoMetric is an abstract class for linear rank metric codes, so any linear rank metric codeclass should inherit from this class. Also AbstractLinearCodeNoMetric should never itself be instantiated.
See sage.coding.linear_rank_metric.AbstractLinearRankMetricCode for details and examples.
LinearRankMetricCode
This class is used to represent arbitrary and unstructured linear rank metric codes. It mostly relies directly on genericmethods provided by AbstractLinearRankMetricCode, which means that basic operations on the code (e.g.
computation of the minimum distance) will use slow algorithms.
A LinearRankMetricCode is instantiated by providing a generator:
sage: G = Matrix(GF(64), [[1,1,0], [0,0,1]])
sage: C = codes.LinearRankMetricCode(G, GF(4))
sage: C[3, 2] linear rank metric code over GF(64)/GF(4)sage: C.generator_matrix()[1 1 0][0 0 1]
sage: c = vector(GF(64), (1, 1, 1))
sage: c in C
True>>> from sage.all import *>>> G = Matrix(GF(Integer(64)), [[Integer(1),Integer(1),Integer(0)], [Integer(0),˓→Integer(0),Integer(1)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(4)))>>> C[3, 2] linear rank metric code over GF(64)/GF(4)>>> C.generator_matrix()[1 1 0][0 0 1]>>> c = vector(GF(Integer(64)), (Integer(1), Integer(1), Integer(1)))>>> c in C
True

10.3. Generic structures for linear codes over the rank metric115

Coding Theory, Release 10.4

Further references
Read more about rank metric and Gabidulin codes
AUTHORS:• Marketa Slukova (2019-08-16): initial version
class sage.coding.linear_rank_metric.AbstractLinearRankMetricCode(base_field,
sub_field, length,default_encoder_name,default_decoder_name,basis=None)
Bases: AbstractLinearCodeNoMetric
Abstract class for linear rank metric codes.
This class contains methods that can be used on families of linear rank metric codes. Every linear rank metric codeclass should inherit from this abstract class.
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𝑛 over F𝑞𝑚 , or an 𝑚 × 𝑛 matrix over F𝑞 . This implementation principally uses the vector representation.
However, one can always get the matrix representation using the sage.coding.linear_rank_metric.
AbstractLinearRankMetricCode.to_matrix() method. To go back to a vector, use the sage.
coding.linear_rank_metric.AbstractLinearRankMetricCode.from_matrix() method.
Instructions on how to make a new family of rank metric codes is analogous to making a new family of
linear codes over the Hamming metric, instructions for which are in sage.coding.linear_code.
AbstractLinearCode.
For an example on, see sage.coding.linear_rank_metric.
AbstractLinearRankMetricCode.__init__()Warning: A lot of methods of the abstract class rely on the knowledge of a generator matrix. It is thus strongly
recommended to set an encoder with a generator matrix implemented as a default encoder.
extension_degree()Return 𝑚, the degree of the field extension of self.
Let base_field be F𝑞𝑚 and sub_field be F𝑞 . Then this function returns 𝑚.
EXAMPLES:
sage: G = Matrix(GF(64), [[1,1,0], [0,0,1]])
sage: C = codes.LinearRankMetricCode(G, GF(4))
sage: C.extension_degree()3>>> from sage.all import *>>> G = Matrix(GF(Integer(64)), [[Integer(1),Integer(1),Integer(0)],␣
˓→[Integer(0),Integer(0),Integer(1)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(4)))>>> C.extension_degree()3116

Chapter 10. Linear CodesCoding Theory, Release 10.4

field_extension()
Return the field extension of self.
Let base_field be some field F𝑞𝑚 and sub_field F𝑞 . This function returns the vector space of dimension 𝑚 over F𝑞 .
EXAMPLES:
sage: G = Matrix(GF(64), [[1,1,0], [0,0,1]])
sage: C = codes.LinearRankMetricCode(G, GF(4))
sage: C.field_extension()
Vector space of dimension 3 over Finite Field in z2 of size 2^2>>> from sage.all import *>>> G = Matrix(GF(Integer(64)), [[Integer(1),Integer(1),Integer(0)],␣
˓→[Integer(0),Integer(0),Integer(1)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(4)))>>> C.field_extension()
Vector space of dimension 3 over Finite Field in z2 of size 2^2matrix_form_of_vector(word)
Return the matrix representation of a word.
INPUT:• word – a vector over the base_field of self
EXAMPLES:
sage: G = Matrix(GF(64), [[1,1,0], [0,0,1]])
sage: C = codes.LinearRankMetricCode(G, GF(4))
sage: x = GF(64).gen()sage: a = vector(GF(64), (x + 1, x + 1, 1))
sage: C.matrix_form_of_vector(a)[1 1 1][1 1 0][0 0 0]>>> from sage.all import *>>> G = Matrix(GF(Integer(64)), [[Integer(1),Integer(1),Integer(0)],␣
˓→[Integer(0),Integer(0),Integer(1)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(4)))>>> x = GF(Integer(64)).gen()>>> a = vector(GF(Integer(64)), (x + Integer(1), x + Integer(1), Integer(1)))>>> C.matrix_form_of_vector(a)[1 1 1][1 1 0][0 0 0]minimum_distance()
Return the minimum distance of self.
This algorithm simply iterates over all the elements of the code and returns the minimum weight.
EXAMPLES:
sage: F.<a> = GF(8)sage: G = Matrix(F, [[1,a,a^2,0]])
sage: C = codes.LinearRankMetricCode(G, GF(2))(continues on next page)

10.3. Generic structures for linear codes over the rank metric117

Coding Theory, Release 10.4

(continued from previous page)

sage: C.minimum_distance()3>>> from sage.all import *>>> F = GF(Integer(8), names=( a ,)); (a,) = F._first_ngens(1)>>> G = Matrix(F, [[Integer(1),a,a**Integer(2),Integer(0)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(2)))>>> C.minimum_distance()3

rank_distance_between_vectors(left, right)
Return the rank of the matrix of left - right.
INPUT:• left – a vector over the base_field of self
• right – a vector over the base_field of self
EXAMPLES:
sage: G = Matrix(GF(64), [[1,1,0], [0,0,1]])
sage: C = codes.LinearRankMetricCode(G, GF(4))
sage: x = GF(64).gen()sage: a = vector(GF(64), (x + 1, x + 1, 1))
sage: b = vector(GF(64), (1, 0, 0))
sage: C.rank_distance_between_vectors(a, b)
2>>> from sage.all import *>>> G = Matrix(GF(Integer(64)), [[Integer(1),Integer(1),Integer(0)],␣
˓→[Integer(0),Integer(0),Integer(1)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(4)))>>> x = GF(Integer(64)).gen()>>> a = vector(GF(Integer(64)), (x + Integer(1), x + Integer(1), Integer(1)))>>> b = vector(GF(Integer(64)), (Integer(1), Integer(0), Integer(0)))>>> C.rank_distance_between_vectors(a, b)2

rank_weight_of_vector(word)
Return the weight of the word, i.e. its rank.
INPUT:• word – a vector over the base_field of self
EXAMPLES:
sage: G = Matrix(GF(64), [[1,1,0], [0,0,1]])
sage: C = codes.LinearRankMetricCode(G, GF(4))
sage: x = GF(64).gen()sage: a = vector(GF(64), (x + 1, x + 1, 1))
sage: C.rank_weight_of_vector(a)2>>> from sage.all import *>>> G = Matrix(GF(Integer(64)), [[Integer(1),Integer(1),Integer(0)],␣
(continues on next page)

118

Chapter 10. Linear CodesCoding Theory, Release 10.4

(continued from previous page)[Integer(0),Integer(0),Integer(1)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(4)))>>> x = GF(Integer(64)).gen()>>> a = vector(GF(Integer(64)), (x + Integer(1), x + Integer(1), Integer(1)))>>> C.rank_weight_of_vector(a)2˓→sub_field()
Return the sub field of self.
EXAMPLES:
sage: G = Matrix(GF(64), [[1,1,0], [0,0,1]])
sage: C = codes.LinearRankMetricCode(G, GF(4))
sage: C.sub_field()
Finite Field in z2 of size 2^2>>> from sage.all import *>>> G = Matrix(GF(Integer(64)), [[Integer(1),Integer(1),Integer(0)],␣
˓→[Integer(0),Integer(0),Integer(1)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(4)))>>> C.sub_field()
Finite Field in z2 of size 2^2vector_form_of_matrix(word)
Return the vector representation of a word.
INPUT:• word – a matrix over the sub_field of self
EXAMPLES:
sage: G = Matrix(GF(64), [[1,1,0], [0,0,1]])
sage: C = codes.LinearRankMetricCode(G, GF(4))
sage: x = GF(64).gen()sage: m = Matrix(GF(4), [[1, 1, 1], [1, 1, 0], [0, 0, 0]])sage: C.vector_form_of_matrix(m)(z6 + 1, z6 + 1, 1)>>> from sage.all import *>>> G = Matrix(GF(Integer(64)), [[Integer(1),Integer(1),Integer(0)],␣
˓→[Integer(0),Integer(0),Integer(1)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(4)))>>> x = GF(Integer(64)).gen()>>> m = Matrix(GF(Integer(4)), [[Integer(1), Integer(1), Integer(1)],␣
˓→[Integer(1), Integer(1), Integer(0)], [Integer(0), Integer(0), Integer(0)]])>>> C.vector_form_of_matrix(m)(z6 + 1, z6 + 1, 1)class sage.coding.linear_rank_metric.LinearRankMetricCode(generator, sub_field=None,
basis=None)
Bases: AbstractLinearRankMetricCode
Linear rank metric codes over a finite field, represented using a generator matrix.
This class should be used for arbitrary and unstructured linear rank metric codes. This means that basic operations
on the code, such as the computation of the minimum distance, will use generic, slow algorithms.
10.3. Generic structures for linear codes over the rank metric

119

Coding Theory, Release 10.4

If you are looking for constructing a code from a more specific family, see if the family has been implemented byinvestigating codes.<tab>. These more specific classes use properties particular to that family to allow faster
algorithms, and could also have family-specific methods.
EXAMPLES:
sage: G = Matrix(GF(64), [[1,1,0], [0,0,1]])
sage: C = codes.LinearRankMetricCode(G, GF(4))
sage: C[3, 2] linear rank metric code over GF(64)/GF(4)sage: C.base_field()
Finite Field in z6 of size 2^6sage: C.sub_field()
Finite Field in z2 of size 2^2
sage: C.length()3
sage: C.dimension()2
sage: C[2](z6, z6, 0)
sage: E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)sage: word = vector(C.base_field(), [1, 0])
sage: E(word)(1, 1, 0)>>> from sage.all import *>>> G = Matrix(GF(Integer(64)), [[Integer(1),Integer(1),Integer(0)], [Integer(0),˓→Integer(0),Integer(1)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(4)))>>> C[3, 2] linear rank metric code over GF(64)/GF(4)>>> C.base_field()
Finite Field in z6 of size 2^6>>> C.sub_field()
Finite Field in z2 of size 2^2>>> C.length()
3>>> C.dimension()
2>>> C[Integer(2)](z6, z6, 0)>>> E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C)>>> word = vector(C.base_field(), [Integer(1), Integer(0)])>>> E(word)(1, 1, 0)

generator_matrix(encoder_name=None, **kwargs)
Return a generator matrix of self.
INPUT:• encoder_name – (default: None) name of the encoder which will be used to compute the generator
matrix. self._generator_matrix will be returned if default value is kept.
• kwargs – all additional arguments are forwarded to the construction of the encoder that is used.
EXAMPLES:

120

Chapter 10. Linear CodesCoding Theory, Release 10.4

sage: G = Matrix(GF(64), [[1,1,0], [0,0,1]])
sage: C = codes.LinearRankMetricCode(G, GF(4))
sage: C.generator_matrix()[1 1 0][0 0 1]>>> from sage.all import *>>> G = Matrix(GF(Integer(64)), [[Integer(1),Integer(1),Integer(0)],␣
˓→[Integer(0),Integer(0),Integer(1)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(4)))>>> C.generator_matrix()[1 1 0][0 0 1]class sage.coding.linear_rank_metric.LinearRankMetricCodeNearestNeighborDecoder(code)
Bases: Decoder
Construct a decoder for Linear Rank Metric Codes.
This decoder will decode to the nearest codeword found.
decode_to_code(r)Corrects the errors in word and returns a codeword.
INPUT:• r – a codeword of self
OUTPUT:• a vector of self’s message space
EXAMPLES:
sage: F.<a> = GF(4)sage: G = Matrix(F, [[1,1,0]])
sage: C = codes.LinearRankMetricCode(G, GF(2))
sage: D = codes.decoders.LinearRankMetricCodeNearestNeighborDecoder(C)sage: D.decode_to_code(vector(F, [a, a, 1]))(a, a, 0)>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> G = Matrix(F, [[Integer(1),Integer(1),Integer(0)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(2)))>>> D = codes.decoders.LinearRankMetricCodeNearestNeighborDecoder(C)>>> D.decode_to_code(vector(F, [a, a, Integer(1)]))(a, a, 0)

decoding_radius()
Return maximal number of errors self can decode.
EXAMPLES:
sage: F.<a> = GF(8)sage: G = Matrix(F, [[1,a,a^2,0]])
sage: C = codes.LinearRankMetricCode(G, GF(2))
sage: D = codes.decoders.LinearRankMetricCodeNearestNeighborDecoder(C)(continues on next page)

10.3. Generic structures for linear codes over the rank metric121

Coding Theory, Release 10.4

(continued from previous page)

sage: D.decoding_radius()
1>>> from sage.all import *>>> F = GF(Integer(8), names=( a ,)); (a,) = F._first_ngens(1)>>> G = Matrix(F, [[Integer(1),a,a**Integer(2),Integer(0)]])>>> C = codes.LinearRankMetricCode(G, GF(Integer(2)))>>> D = codes.decoders.LinearRankMetricCodeNearestNeighborDecoder(C)>>> D.decoding_radius()
1

sage.coding.linear_rank_metric.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 𝑚 × 𝑛 matrix over F𝑞 and some basis of F𝑞𝑚 over F𝑞 , we can represent each of its columns as anelement of F𝑞𝑚 , yielding a vector of length 𝑛 over F𝑞 .
In case base_field is not given, we take F𝑞𝑚 , the field extension of F𝑞 of degree 𝑚, the number of rows of w.
INPUT:• w – a matrix over some field F𝑞• base_field – (default: None) an extension field of F𝑞 . If not specified, it is the field F𝑞𝑚 , where 𝑚 isthe number of rows of w.
• basis – (default: None) a basis of F𝑞𝑚 as a vector space over F𝑞 . If not specified, given that 𝑞 = 𝑝𝑠 ,let 1, 𝛽, . . . , 𝛽 𝑠𝑚 be the power basis that SageMath uses to represent F𝑞𝑚 . The default basis is then1, 𝛽, . . . , 𝛽 𝑚−1 .
EXAMPLES:
sage: from sage.coding.linear_rank_metric import from_matrix_representation
sage: m = Matrix(GF(4), [[1, 1, 1], [1, 1, 0], [0, 0, 0]])sage: from_matrix_representation(m)(z6 + 1, z6 + 1, 1)
sage: v = vector(GF(4), (1, 0, 0))
sage: from_matrix_representation(v)Traceback (most recent call last):...
TypeError: Input must be a matrix>>> from sage.all import *>>> from sage.coding.linear_rank_metric import from_matrix_representation>>> m = Matrix(GF(Integer(4)), [[Integer(1), Integer(1), Integer(1)], [Integer(1),˓→ Integer(1), Integer(0)], [Integer(0), Integer(0), Integer(0)]])>>> from_matrix_representation(m)(z6 + 1, z6 + 1, 1)>>> v = vector(GF(Integer(4)), (Integer(1), Integer(0), Integer(0)))>>> from_matrix_representation(v)Traceback (most recent call last):...
TypeError: Input must be a matrix

122

Chapter 10. Linear CodesCoding Theory, Release 10.4

sage.coding.linear_rank_metric.rank_distance(a, b, sub_field=None, basis=None)
Return the rank of a - b as a matrix over sub_field.
Take two vectors a, b over some field F𝑞𝑚 . This function converts them to matrices over F𝑞 and calculates therank of their difference.
If sub_field is not specified, we take the prime subfield F𝑞 of F𝑞𝑚 .
INPUT:• a – a vector over some field F𝑞𝑚• b – a vector over some field F𝑞𝑚• sub_field – (default: None) a sub field of F𝑞𝑚 . If not specified, it is the prime subfield F𝑝 of F𝑞𝑚 .
• basis – (default: None) a basis of F𝑞𝑚 as a vector space over sub_field. If not specified, given that𝑞 = 𝑝𝑠 , let 1, 𝛽, . . . , 𝛽 𝑠𝑚 be the power basis that SageMath uses to represent F𝑞𝑚 . The default basis is then1, 𝛽, . . . , 𝛽 𝑚−1 .
EXAMPLES:
sage: from sage.coding.linear_rank_metric import rank_distancesage: x = GF(64).gen()sage: a = vector(GF(64), (x + 1, x + 1, 1))
sage: b = vector(GF(64), (1, 0, 0))
sage: rank_distance(a, b, GF(4))
2sage: c = vector(GF(4), (1, 0, 0))
sage: rank_distance(a, c, GF(4))
Traceback (most recent call last):...
ValueError: The base field of (z6 + 1, z6 + 1, 1) and (1, 0, 0) has to be the same
sage: d = Matrix(GF(64), (1, 0, 0))
sage: rank_distance(a, d, GF(64))
Traceback (most recent call last):...
TypeError: Both inputs have to be vectors
sage: e = vector(GF(64), (1, 0))
sage: rank_distance(a, e, GF(64))
Traceback (most recent call last):...
ValueError: The length of (z6 + 1, z6 + 1, 1) and (1, 0) has to be the same>>> from sage.all import *>>> from sage.coding.linear_rank_metric import rank_distance>>> x = GF(Integer(64)).gen()>>> a = vector(GF(Integer(64)), (x + Integer(1), x + Integer(1), Integer(1)))>>> b = vector(GF(Integer(64)), (Integer(1), Integer(0), Integer(0)))>>> rank_distance(a, b, GF(Integer(4)))
2>>> c = vector(GF(Integer(4)), (Integer(1), Integer(0), Integer(0)))>>> rank_distance(a, c, GF(Integer(4)))
Traceback (most recent call last):...
ValueError: The base field of (z6 + 1, z6 + 1, 1) and (1, 0, 0) has to be the same(continues on next page)

10.3. Generic structures for linear codes over the rank metric123

Coding Theory, Release 10.4

(continued from previous page)>>> d = Matrix(GF(Integer(64)), (Integer(1), Integer(0), Integer(0)))>>> rank_distance(a, d, GF(Integer(64)))
Traceback (most recent call last):...
TypeError: Both inputs have to be vectors>>> e = vector(GF(Integer(64)), (Integer(1), Integer(0)))>>> rank_distance(a, e, GF(Integer(64)))
Traceback (most recent call last):...
ValueError: The length of (z6 + 1, z6 + 1, 1) and (1, 0) has to be the same

sage.coding.linear_rank_metric.rank_weight(c, sub_field=None, basis=None)
Return the rank of c as a matrix over sub_field.
If c is a vector over some field F𝑞𝑚 , the function converts it into a matrix over F𝑞 .
INPUT:• c – a vector over some field F𝑞𝑚 ; or a matrix over F𝑞• sub_field – (default: None) a sub field of F𝑞𝑚 . If not specified, it is the prime subfield F𝑝 of F𝑞𝑚 .
• basis – (default: None) a basis of F𝑞𝑚 as a vector space over sub_field. If not specified, given that𝑞 = 𝑝𝑠 , let 1, 𝛽, . . . , 𝛽 𝑠𝑚 be the power basis that SageMath uses to represent F𝑞𝑚 . The default basis is then1, 𝛽, . . . , 𝛽 𝑚−1 .
EXAMPLES:
sage: from sage.coding.linear_rank_metric import rank_weight
sage: x = GF(64).gen()sage: a = vector(GF(64), (x + 1, x + 1, 1))
sage: rank_weight(a, GF(4))
2>>> from sage.all import *>>> from sage.coding.linear_rank_metric import rank_weight>>> x = GF(Integer(64)).gen()>>> a = vector(GF(Integer(64)), (x + Integer(1), x + Integer(1), Integer(1)))>>> rank_weight(a, GF(Integer(4)))
2sage.coding.linear_rank_metric.to_matrix_representation(v, sub_field=None, basis=None)
Return a matrix representation of v over sub_field in terms of basis.
Let (𝑏1 , 𝑏2 , . . . , 𝑏𝑚 ), 𝑏𝑖 ∈ 𝐺𝐹 (𝑞 𝑚 ), be a basis of F𝑞𝑚 as a vector space over F𝑞 . Take an element 𝑥 ∈ F𝑞𝑚 . We
can write 𝑥 as 𝑥 = 𝑢1 𝑏1 + 𝑢2 𝑏2 + . . . 𝑢𝑚 𝑏𝑚 , where 𝑢𝑖 ∈ 𝐺𝐹 (𝑞). This way we can represent an element fromF𝑞𝑚 as a vector of length 𝑚 over F𝑞 .
Given a vector v of length 𝑛 over some field F𝑞𝑚 , we can represent each entry as a vector of length 𝑚, yielding an
𝑚 × 𝑛 matrix over sub_field. In case sub_field is not given, we take the prime subfield F𝑝 of F𝑞𝑚 .
INPUT:• v – a vector over some field F𝑞𝑚• sub_field – (default: None) a sub field of F𝑞𝑚 . If not specified, it is the prime subfield F𝑝 of F𝑞𝑚 .

124

Chapter 10. Linear CodesCoding Theory, Release 10.4

• basis – (default: None) a basis of F𝑞𝑚 as a vector space over sub_field. If not specified, given that𝑞 = 𝑝𝑠 , let 1, 𝛽, . . . , 𝛽 𝑠𝑚 be the power basis that SageMath uses to represent F𝑞𝑚 . The default basis is then1, 𝛽, . . . , 𝛽 𝑚−1 .
EXAMPLES:
sage: from sage.coding.linear_rank_metric import to_matrix_representation
sage: x = GF(64).gen()sage: a = vector(GF(64), (x + 1, x + 1, 1))
sage: to_matrix_representation(a, GF(4))[1 1 1][1 1 0][0 0 0]sage: m = Matrix(GF(4), [[1, 1, 1], [1, 1, 0], [0, 0, 0]])sage: to_matrix_representation(m)Traceback (most recent call last):...
TypeError: Input must be a vector>>> from sage.all import *>>> from sage.coding.linear_rank_metric import to_matrix_representation>>> x = GF(Integer(64)).gen()>>> a = vector(GF(Integer(64)), (x + Integer(1), x + Integer(1), Integer(1)))>>> to_matrix_representation(a, GF(Integer(4)))[1 1 1][1 1 0][0 0 0]>>> m = Matrix(GF(Integer(4)), [[Integer(1), Integer(1), Integer(1)], [Integer(1),˓→ Integer(1), Integer(0)], [Integer(0), Integer(0), Integer(0)]])>>> to_matrix_representation(m)Traceback (most recent call last):...
TypeError: Input must be a vector

10.3. Generic structures for linear codes over the rank metric125

Coding Theory, Release 10.4

126

Chapter 10. Linear Codes

CHAPTERELEVENFAMILIES OF LINEAR CODES

Famous families of codes, listed below, are represented in Sage by their own classes. For some of them, implementationsof special decoding algorithms or computations for structural invariants are available.

11.1 Parity-check code
A simple way of detecting up to one error is to use the device of adding a parity check to ensure that the sum of the digits
in a transmitted word is even.
A parity-check code of dimension 𝑘 over F𝑞 is the set: {(𝑚1 , 𝑚2 , . . . , 𝑚𝑘 , −Σ𝑘𝑖=1 𝑚𝑖 ) | (𝑚1 , 𝑚2 , . . . , 𝑚𝑘 ) ∈ F𝑘𝑞 }REFERENCE:• [Wel1988]
class sage.coding.parity_check_code.ParityCheckCode(base_field=Finite Field of size 2,
dimension=7)
Bases: AbstractLinearCode
Representation of a parity-check code.
INPUT:• base_field – the base field over which self is defined.
• dimension – the dimension of self.
EXAMPLES:
sage: C = codes.ParityCheckCode(GF(5), 7)
sage: C[8, 7] parity-check code over GF(5)>>> from sage.all import *>>> C = codes.ParityCheckCode(GF(Integer(5)), Integer(7))>>> C[8, 7] parity-check code over GF(5)minimum_distance()
Return the minimum distance of self.
It is always 2 as self is a parity-check code.
EXAMPLES:

127

Coding Theory, Release 10.4

sage: C = codes.ParityCheckCode(GF(5), 7)
sage: C.minimum_distance()2>>> from sage.all import *>>> C = codes.ParityCheckCode(GF(Integer(5)), Integer(7))>>> C.minimum_distance()
2class sage.coding.parity_check_code.ParityCheckCodeGeneratorMatrixEncoder(code)
Bases: LinearCodeGeneratorMatrixEncoder
Encoder for parity-check codes which uses a generator matrix to obtain codewords.
INPUT:• code – the associated code of this encoder.
EXAMPLES:
sage: C = codes.ParityCheckCode(GF(5), 7)
sage: E = codes.encoders.ParityCheckCodeGeneratorMatrixEncoder(C)sage: E
Generator matrix-based encoder for [8, 7] parity-check code over GF(5)>>> from sage.all import *>>> C = codes.ParityCheckCode(GF(Integer(5)), Integer(7))>>> E = codes.encoders.ParityCheckCodeGeneratorMatrixEncoder(C)>>> E
Generator matrix-based encoder for [8, 7] parity-check code over GF(5)Actually, we can construct the encoder from C directly:
sage: E = C.encoder("ParityCheckCodeGeneratorMatrixEncoder")sage: E
Generator matrix-based encoder for [8, 7] parity-check code over GF(5)>>> from sage.all import *>>> E = C.encoder("ParityCheckCodeGeneratorMatrixEncoder")>>> E
Generator matrix-based encoder for [8, 7] parity-check code over GF(5)generator_matrix()
Return a generator matrix of self.
EXAMPLES:
sage: C = codes.ParityCheckCode(GF(5),7)
sage: E = codes.encoders.ParityCheckCodeGeneratorMatrixEncoder(C)sage: E.generator_matrix()[1 0 0 0 0 0 0 4]
[0 1 0 0 0 0 0 4]
[0 0 1 0 0 0 0 4]
[0 0 0 1 0 0 0 4]
[0 0 0 0 1 0 0 4]
[0 0 0 0 0 1 0 4]
[0 0 0 0 0 0 1 4]

128

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> C = codes.ParityCheckCode(GF(Integer(5)),Integer(7))>>> E = codes.encoders.ParityCheckCodeGeneratorMatrixEncoder(C)>>> E.generator_matrix()[1 0 0 0 0 0 0 4]
[0 1 0 0 0 0 0 4]
[0 0 1 0 0 0 0 4]
[0 0 0 1 0 0 0 4]
[0 0 0 0 1 0 0 4]
[0 0 0 0 0 1 0 4]
[0 0 0 0 0 0 1 4]class sage.coding.parity_check_code.ParityCheckCodeStraightforwardEncoder(code)
Bases: Encoder
Encoder for parity-check codes which computes the sum of message symbols and appends its opposite to themessage to obtain codewords.
INPUT:• code – the associated code of this encoder.
EXAMPLES:
sage: C = codes.ParityCheckCode(GF(5), 7)
sage: E = codes.encoders.ParityCheckCodeStraightforwardEncoder(C)sage: E
Parity-check encoder for the [8, 7] parity-check code over GF(5)>>> from sage.all import *>>> C = codes.ParityCheckCode(GF(Integer(5)), Integer(7))>>> E = codes.encoders.ParityCheckCodeStraightforwardEncoder(C)>>> E
Parity-check encoder for the [8, 7] parity-check code over GF(5)Actually, we can construct the encoder from C directly:
sage: E = C.encoder("ParityCheckCodeStraightforwardEncoder")sage: E
Parity-check encoder for the [8, 7] parity-check code over GF(5)>>> from sage.all import *>>> E = C.encoder("ParityCheckCodeStraightforwardEncoder")>>> E
Parity-check encoder for the [8, 7] parity-check code over GF(5)encode(message)
Transform the vector message into a codeword of code().
INPUT:• message – A self.code().dimension()-vector from the message space of self.
OUTPUT:• A codeword in associated code of self.
EXAMPLES:

11.1. Parity-check code129

Coding Theory, Release 10.4

sage: C = codes.ParityCheckCode(GF(5),7)
sage: message = vector(C.base_field(),[1,0,4,2,0,3,2])
sage: C.encode(message)(1, 0, 4, 2, 0, 3, 2, 3)>>> from sage.all import *>>> C = codes.ParityCheckCode(GF(Integer(5)),Integer(7))>>> message = vector(C.base_field(),[Integer(1),Integer(0),Integer(4),˓→Integer(2),Integer(0),Integer(3),Integer(2)])>>> C.encode(message)(1, 0, 4, 2, 0, 3, 2, 3)

message_space()
Return the message space of self.
EXAMPLES:
sage: C = codes.ParityCheckCode(GF(5),7)
sage: E = codes.encoders.ParityCheckCodeStraightforwardEncoder(C)sage: E.message_space()
Vector space of dimension 7 over Finite Field of size 5>>> from sage.all import *>>> C = codes.ParityCheckCode(GF(Integer(5)),Integer(7))>>> E = codes.encoders.ParityCheckCodeStraightforwardEncoder(C)>>> E.message_space()
Vector space of dimension 7 over Finite Field of size 5

unencode_nocheck(word)
Return the message corresponding to the vector word.
Use this method with caution: it does not check if word belongs to the code.
INPUT:• word – A self.code().length()-vector from the ambiant space of self.
OUTPUT:• A vector corresponding to the self.code().dimension()-first symbols in word.
EXAMPLES:
sage: C = codes.ParityCheckCode(GF(5), 7)
sage: word = vector(C.base_field(), [1, 0, 4, 2, 0, 3, 2, 3])
sage: E = codes.encoders.ParityCheckCodeStraightforwardEncoder(C)sage: E.unencode_nocheck(word)(1, 0, 4, 2, 0, 3, 2)>>> from sage.all import *>>> C = codes.ParityCheckCode(GF(Integer(5)), Integer(7))>>> word = vector(C.base_field(), [Integer(1), Integer(0), Integer(4),␣
˓→Integer(2), Integer(0), Integer(3), Integer(2), Integer(3)])>>> E = codes.encoders.ParityCheckCodeStraightforwardEncoder(C)>>> E.unencode_nocheck(word)(1, 0, 4, 2, 0, 3, 2)

130

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

11.2 Hamming codes
𝑟

𝑟

−1
−1
Given an integer 𝑟 and a field 𝐹 , such that 𝐹 = F𝑞 , the [𝑛, 𝑘, 𝑑] code with length 𝑛 = 𝑞𝑞−1
, dimension 𝑘 = 𝑞𝑞−1−𝑟
and minimum distance 𝑑 = 3 is called the Hamming Code of order 𝑟.

REFERENCES:• [Rot2006]
class sage.coding.hamming_code.HammingCode(base_field, order)
Bases: AbstractLinearCode
Representation of a Hamming code.
INPUT:• base_field – the base field over which self is defined.
• order – the order of self.
EXAMPLES:
sage: C = codes.HammingCode(GF(7), 3)
sage: C[57, 54] Hamming Code over GF(7)>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(7)), Integer(3))>>> C[57, 54] Hamming Code over GF(7)minimum_distance()
Return the minimum distance of self.
It is always 3 as self is a Hamming Code.
EXAMPLES:
sage: C = codes.HammingCode(GF(7), 3)
sage: C.minimum_distance()3>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(7)), Integer(3))>>> C.minimum_distance()
3

parity_check_matrix()
Return a parity check matrix of self.
The construction of the parity check matrix in case self is not a binary code is not really well documented.
Regarding the choice of projective geometry, one might check:• the note over section 2.3 in [Rot2006], pages 47-48• the dedicated paragraph in [HP2003], page 30
EXAMPLES:

11.2. Hamming codes131

Coding Theory, Release 10.4

sage: C = codes.HammingCode(GF(3), 3)
sage: C.parity_check_matrix()[1 0 1 1 0 1 0 1 1 1 0 1 1]
[0 1 1 2 0 0 1 1 2 0 1 1 2]
[0 0 0 0 1 1 1 1 1 2 2 2 2]>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(3)), Integer(3))>>> C.parity_check_matrix()[1 0 1 1 0 1 0 1 1 1 0 1 1]
[0 1 1 2 0 0 1 1 2 0 1 1 2]
[0 0 0 0 1 1 1 1 1 2 2 2 2]

11.3 Cyclic code
Let 𝐹 be a field. A [𝑛, 𝑘] code 𝐶 over 𝐹 is called cyclic if every cyclic shift of a codeword is also a codeword [Rot2006]:∀𝑐 ∈ 𝐶, 𝑐 = (𝑐0 , 𝑐1 , . . . , 𝑐𝑛−1 ) ∈ 𝐶 ⇒ (𝑐𝑛−1 , 𝑐0 , . . . , 𝑐𝑛−2 ) ∈ 𝐶
Let 𝑐 = (𝑐0 , 𝑐1 , . . . , 𝑐𝑛−1 ) be a codeword of 𝐶. This codeword can be seen as a polynomial over 𝐹𝑞 [𝑥] as follows:𝑖Σ𝑛−1
𝑖=0 𝑐𝑖 𝑥 . There is a unique monic polynomial 𝑔(𝑥) such that for every 𝑐(𝑥) ∈ 𝐹𝑞 [𝑥] of degree less than 𝑛 − 1, we have𝑐(𝑥) ∈ 𝐶 ⇔ 𝑔(𝑥)|𝑐(𝑥). This polynomial is called the generator polynomial of 𝐶.
For now, only single-root cyclic codes (i.e. whose length 𝑛 and field order 𝑞 are coprimes) are implemented.
class sage.coding.cyclic_code.CyclicCode(generator_pol=None, length=None, code=None,check=True, D=None, field=None,
primitive_root=None)
Bases: AbstractLinearCode
Representation of a cyclic code.
We propose three different ways to create a new CyclicCode, either by providing:• the generator polynomial and the length (1)• an existing linear code. In that case, a generator polynomial will be computed from the provided linear code’s
parameters (2)• (a subset of) the defining set of the cyclic code (3)For now, only single-root cyclic codes are implemented. That is, only cyclic codes such that its length 𝑛 and fieldorder 𝑞 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.
INPUT:• generator_pol – (default: None) the generator polynomial of self. That is, the highest-degree monicpolynomial which divides every polynomial representation of a codeword in self.
• length – (default: None) the length of self. It has to be bigger than the degree of generator_pol.
• code – (default: None) a linear code.

132

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

• check – (default: False) a boolean representing whether the cyclicity of self must be checked whilefinding the generator polynomial. See find_generator_polynomial() for details.
• D – (default: None) a list of integers between 0 and length-1, corresponding to (a subset of) the defining
set of the code. Will be modified if it is not cyclotomic-closed.
• field – (default: None) the base field of self.
• primitive_root – (default: None) the primitive root of the splitting field which contains the roots ofthe generator polynomial. It has to be of multiplicative order length over this field. If the splitting field is
not field, it also have to be a polynomial in zx, where x is the degree of the extension over the prime field.
For instance, over GF(16), it must be a polynomial in z4.
EXAMPLES:
We can construct a CyclicCode object using three different methods. First (1), we provide a generator polynomial and a code length:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
sage: C = codes.CyclicCode(generator_pol=g, length=n)sage: C[7, 4] Cyclic Code over GF(2)>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> C[7, 4] Cyclic Code over GF(2)

We can also provide a code (2). In that case, the program will try to extract a generator polynomial (seefind_generator_polynomial() for details):
sage: C = codes.GeneralizedReedSolomonCode(GF(8,sage: Cc = codes.CyclicCode(code = C)sage: Cc
[7, 4] Cyclic Code over GF(8)a ).list()[1:], 4)>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(8),˓→Integer(4))>>> Cc = codes.CyclicCode(code = C)>>> Cc[7, 4] Cyclic Code over GF(8)a ).list()[Integer(1):],␣

Finally, we can give (a subset of) a defining set for the code (3). In this case, the generator polynomial will becomputed:sage: F = GF(16, a )sage: n = 15
sage: Cc = codes.CyclicCode(length=n, field=F, D = [1,2])
sage: Cc
[15, 13] Cyclic Code over GF(16)11.3. Cyclic code133

Coding Theory, Release 10.4>>> from sage.all import *>>> F = GF(Integer(16), a )>>> n = Integer(15)>>> Cc = codes.CyclicCode(length=n, field=F, D = [Integer(1),Integer(2)])>>> Cc[15, 13] Cyclic Code over GF(16)bch_bound(arithmetic=False)
Return the BCH bound of self which is a bound on self minimum distance.
See sage.coding.cyclic_code.bch_bound() for details.
INPUT:• arithmetic – (default: False), if it is set to True, then it computes the BCH bound using thelongest arithmetic sequence definition
OUTPUT:• (delta + 1, (l, c)) – such that delta + 1 is the BCH bound, and l, c are the parametersof the largest arithmetic sequence
EXAMPLES:
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.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.bch_bound(True)(4, (2, 12))>>> from sage.all import *>>> F = GF(Integer(16), a )>>> n = Integer(15)>>> D = [Integer(14),Integer(1),Integer(2),Integer(11),Integer(12)]>>> C = codes.CyclicCode(field=F, length=n, D = D)>>> C.bch_bound()(3, (1, 1))>>> F = GF(Integer(16), a )>>> n = Integer(15)>>> D = [Integer(14),Integer(1),Integer(2),Integer(11),Integer(12)]>>> C = codes.CyclicCode(field=F, length=n, D = D)>>> C.bch_bound(True)(4, (2, 12))check_polynomial()
Return the check polynomial of self.
𝑛−1
Let 𝐶 be a cyclic code of length 𝑛 and 𝑔 its generator polynomial. The following: ℎ = 𝑥𝑔(𝑥)is called 𝐶’s
check polynomial.

EXAMPLES:
134

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
sage: C = codes.CyclicCode(generator_pol=g, length=n)sage: h = C.check_polynomial()
sage: h == (x**n - 1)/C.generator_polynomial()
True>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> h = C.check_polynomial()>>> h == (x**n - Integer(1))/C.generator_polynomial()
Truedefining_set(primitive_root=None)
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.
INPUT:• primitive_root (optional) – a primitive root of the extension field
EXAMPLES:
We provide a defining set at construction time:
sage: F = GF(16, a )sage: n = 15
sage: C = codes.CyclicCode(length=n, field=F, D=[1,2])
sage: C.defining_set()[1, 2]>>> from sage.all import *>>> F = GF(Integer(16), a )>>> n = Integer(15)>>> C = codes.CyclicCode(length=n, field=F, D=[Integer(1),Integer(2)])>>> C.defining_set()[1, 2]

If the defining set was provided by the user, it might have been expanded at construction time. In this case,the expanded defining set will be returned:
sage: C = codes.CyclicCode(length=13, field=F, D=[1, 2])
sage: C.defining_set()[1, 2, 3, 5, 6, 9]>>> from sage.all import *>>> C = codes.CyclicCode(length=Integer(13), field=F, D=[Integer(1),␣
˓→Integer(2)])>>> C.defining_set()[1, 2, 3, 5, 6, 9]

If a generator polynomial was passed at construction time, the defining set is computed using this polynomial:

11.3. Cyclic code135

Coding Theory, Release 10.4

sage: R.<x> = F[]sage: n = 7
sage: g = x ** 3 + x + 1
sage: C = codes.CyclicCode(generator_pol=g, length=n)sage: C.defining_set()[1, 2, 4]>>> from sage.all import *>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> C.defining_set()[1, 2, 4]

Both operations give the same result:
sage: C1 = codes.CyclicCode(length=n, field=F, D=[1, 2, 4])
sage: C1.generator_polynomial() == g
True>>> from sage.all import *>>> C1 = codes.CyclicCode(length=n, field=F, D=[Integer(1), Integer(2),␣
˓→Integer(4)])>>> C1.generator_polynomial() == g
True

Another one, in a reversed order:
sage: n = 13
sage: C1 = codes.CyclicCode(length=n, field=F, D=[1, 2])
sage: g = C1.generator_polynomial()
sage: C2 = codes.CyclicCode(generator_pol=g, length=n)sage: C1.defining_set() == C2.defining_set()True>>> from sage.all import *>>> n = Integer(13)>>> C1 = codes.CyclicCode(length=n, field=F, D=[Integer(1), Integer(2)])>>> g = C1.generator_polynomial()>>> C2 = codes.CyclicCode(generator_pol=g, length=n)>>> C1.defining_set() == C2.defining_set()True

field_embedding()
Return the base field embedding into the splitting field.
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
sage: C = codes.CyclicCode(generator_pol=g, length=n)sage: C.field_embedding()
Ring morphism:
From: Finite Field of size 2(continues on next page)

136

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

To:
Finite Field in z3 of size 2^3
Defn: 1 |--> 1>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> C.field_embedding()
Ring morphism:
From: Finite Field of size 2
To:
Finite Field in z3 of size 2^3
Defn: 1 |--> 1

generator_polynomial()
Return the generator polynomial of self.
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
sage: C = codes.CyclicCode(generator_pol=g, length=n)sage: C.generator_polynomial()x^3 + x + 1>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> C.generator_polynomial()x^3 + x + 1

parity_check_matrix()
Return the parity check matrix of self.
The parity check matrix of a linear code 𝐶 corresponds to the generator matrix of the dual code of 𝐶.
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
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]
[0 0 1 0 1 1 1]>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> C.parity_check_matrix()(continues on next page)

11.3. Cyclic code137

Coding Theory, Release 10.4

(continued from previous page)[1 0 1 1 1 0 0]
[0 1 0 1 1 1 0]
[0 0 1 0 1 1 1]

primitive_root()
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 output of the zeta method of the splitting
field.
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
sage: C = codes.CyclicCode(generator_pol=g, length=n)sage: C.primitive_root()z3
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.primitive_root()a^2 + 1>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> C.primitive_root()z3>>> F = GF(Integer(16), a )>>> n = Integer(15)>>> a = F.gen()>>> Cc = codes.CyclicCode(length=n, field=F, D=[Integer(1),Integer(2)],...
primitive_root=a**Integer(2) + Integer(1))>>> Cc.primitive_root()a^2 + 1surrounding_bch_code()
Return the surrounding BCH code of self.
EXAMPLES:
sage: C = codes.CyclicCode(field=GF(2), length=63, D=[1, 7, 17])
sage: C.dimension()45
sage: CC = C.surrounding_bch_code()sage: CC
[63, 51] BCH Code over GF(2) with designed distance 3
sage: all(r in CC for r in C.generator_matrix())
True

138

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> C = codes.CyclicCode(field=GF(Integer(2)), length=Integer(63),␣
˓→D=[Integer(1), Integer(7), Integer(17)])>>> C.dimension()45>>> CC = C.surrounding_bch_code()>>> CC[63, 51] BCH Code over GF(2) with designed distance 3>>> all(r in CC for r in C.generator_matrix())
Trueclass sage.coding.cyclic_code.CyclicCodePolynomialEncoder(code)
Bases: Encoder
An encoder encoding polynomials into codewords.
Let 𝐶 be a cyclic code over some finite field 𝐹 , and let 𝑔 be its generator polynomial.
This encoder encodes any polynomial 𝑝 ∈ 𝐹 [𝑥]<𝑘 by computing 𝑐 = 𝑝𝑔 and returning the vector of its coefficients.
INPUT:• code – The associated code of this encoder
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
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)>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> E = codes.encoders.CyclicCodePolynomialEncoder(C)>>> E
Polynomial-style encoder for [7, 4] Cyclic Code over GF(2)encode(p)Transforms p into an element of the associated code of self.
INPUT:• p – A polynomial from self message space
OUTPUT:• A codeword in associated code of self
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
sage: C = codes.CyclicCode(generator_pol=g, length=n)(continues on next page)

11.3. Cyclic code139

Coding Theory, Release 10.4

(continued from previous page)

sage: E = codes.encoders.CyclicCodePolynomialEncoder(C)sage: m = x ** 2 + 1
sage: E.encode(m)(1, 1, 1, 0, 0, 1, 0)>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> E = codes.encoders.CyclicCodePolynomialEncoder(C)>>> m = x ** Integer(2) + Integer(1)>>> E.encode(m)(1, 1, 1, 0, 0, 1, 0)

message_space()
Return the message space of self
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
sage: C = codes.CyclicCode(generator_pol=g, length=n)sage: E = codes.encoders.CyclicCodePolynomialEncoder(C)sage: E.message_space()
˓→needs sage.libs.ntl
Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> E = codes.encoders.CyclicCodePolynomialEncoder(C)>>> E.message_space()
˓→needs sage.libs.ntl
Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)#␣#␣

unencode_nocheck(c)Return the message corresponding to c. Does not check if c belongs to the code.
INPUT:• c – A vector with the same length as the code
OUTPUT:• An element of the message space
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
sage: C = codes.CyclicCode(generator_pol=g, length=n)sage: E = codes.encoders.CyclicCodePolynomialEncoder(C)(continues on next page)

140

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: c = vector(GF(2), (1, 1, 1, 0, 0, 1, 0))
sage: E.unencode_nocheck(c)x^2 + 1>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> E = codes.encoders.CyclicCodePolynomialEncoder(C)>>> c = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(1),␣
˓→Integer(0), Integer(0), Integer(1), Integer(0)))>>> E.unencode_nocheck(c)x^2 + 1class sage.coding.cyclic_code.CyclicCodeSurroundingBCHDecoder(code, **kwargs)
Bases: Decoder
A decoder which decodes through the surrounding BCH code of the cyclic code.
INPUT:• code – The associated code of this decoder.
• **kwargs – All extra arguments are forwarded to the BCH decoder
EXAMPLES:
sage: C = codes.CyclicCode(field=GF(16), length=15, D=[14, 1, 2, 11, 12])sage: D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C)sage: D
Decoder through the surrounding BCH code of the [15, 10] Cyclic Code over GF(16)>>> from sage.all import *>>> C = codes.CyclicCode(field=GF(Integer(16)), length=Integer(15),␣
˓→D=[Integer(14), Integer(1), Integer(2), Integer(11), Integer(12)])>>> D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C)>>> D
Decoder through the surrounding BCH code of the [15, 10] Cyclic Code over GF(16)bch_code()
Return the surrounding BCH code of sage.coding.encoder.Encoder.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_code()[15, 12] BCH Code over GF(16) with designed distance 4>>> from sage.all import *>>> C = codes.CyclicCode(field=GF(Integer(16)), length=Integer(15),␣
˓→D=[Integer(14), Integer(1), Integer(2), Integer(11), Integer(12)])>>> D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C)>>> D.bch_code()[15, 12] BCH Code over GF(16) with designed distance 4

11.3. Cyclic code141

Coding Theory, Release 10.4

bch_decoder()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 Codeover GF(16) with designed distance 4>>> from sage.all import *>>> C = codes.CyclicCode(field=GF(Integer(16)), length=Integer(15),␣
˓→D=[Integer(14), Integer(1), Integer(2), Integer(11), Integer(12)])>>> D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C)>>> D.bch_decoder()Decoder through the underlying GRS code of [15, 12] BCH Codeover GF(16) with designed distance 4

decode_to_code(y)Decodes r to an element in sage.coding.encoder.Encoder.code().
EXAMPLES:
sage: F = GF(16, a )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: D.decode_to_code(y) in C
True>>> from sage.all import *>>> F = GF(Integer(16), a )>>> C = codes.CyclicCode(field=F, length=Integer(15), D=[Integer(14),␣
˓→Integer(1), Integer(2), Integer(11), Integer(12)])>>> a = F.gen()>>> D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C)>>> y = vector(F, [Integer(0), a**Integer(3), a**Integer(3) + a**Integer(2) +␣˓→a, Integer(1), a**Integer(2) + Integer(1), a**Integer(3) + a**Integer(2) +␣˓→Integer(1),...
a**Integer(3) + a**Integer(2) + a, a**Integer(3) +␣˓→a**Integer(2) + a, a**Integer(2) + a, a**Integer(2) + Integer(1),...
a**Integer(2) + a + Integer(1), a**Integer(3) + Integer(1),˓→ a**Integer(2), a**Integer(3) + a, a**Integer(3) + a])>>> D.decode_to_code(y) in C
True

decoding_radius()
Return maximal number of errors that self can decode.
EXAMPLES:
sage: C = codes.CyclicCode(field=GF(16), length=15, D=[14, 1, 2, 11, 12])sage: D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C)(continues on next page)

142

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: D.decoding_radius()
1>>> from sage.all import *>>> C = codes.CyclicCode(field=GF(Integer(16)), length=Integer(15),␣
˓→D=[Integer(14), Integer(1), Integer(2), Integer(11), Integer(12)])>>> D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C)>>> D.decoding_radius()
1class sage.coding.cyclic_code.CyclicCodeVectorEncoder(code)
Bases: Encoder
An encoder which can encode vectors into codewords.
Let 𝐶 be a cyclic code over some finite field 𝐹 , and let 𝑔 be its generator polynomial.
Let 𝑚 = (𝑚1 , 𝑚2 , . . . , 𝑚𝑘 ) be a vector in 𝐹 𝑘 . This codeword can be seen as a polynomial over 𝐹 [𝑥], as follows:𝑖
𝑃𝑚 = Σ𝑘−1
𝑖=0 𝑚𝑖 × 𝑥 .
To encode 𝑚, this encoder does the multiplication 𝑃𝑚 𝑔.
INPUT:• code – The associated code of this encoder
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
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)>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> E = codes.encoders.CyclicCodeVectorEncoder(C)>>> E
Vector-style encoder for [7, 4] Cyclic Code over GF(2)encode(m)Transforms m into an element of the associated code of self.
INPUT:• m – an element from self’s message space
OUTPUT:• A codeword in the associated code of self
EXAMPLES:

11.3. Cyclic code143

Coding Theory, Release 10.4

sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
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)(1, 1, 1, 0, 0, 1, 0)>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> E = codes.encoders.CyclicCodeVectorEncoder(C)>>> m = vector(GF(Integer(2)), (Integer(1), Integer(0), Integer(1),␣
˓→Integer(0)))>>> E.encode(m)(1, 1, 1, 0, 0, 1, 0)

generator_matrix()
Return a generator matrix of self
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
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]
[0 1 1 0 1 0 0]
[0 0 1 1 0 1 0]
[0 0 0 1 1 0 1]>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> E = codes.encoders.CyclicCodeVectorEncoder(C)>>> E.generator_matrix()[1 1 0 1 0 0 0]
[0 1 1 0 1 0 0]
[0 0 1 1 0 1 0]
[0 0 0 1 1 0 1]

message_space()
Return the message space of self
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
sage: C = codes.CyclicCode(generator_pol=g, length=n)(continues on next page)

144

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: E = codes.encoders.CyclicCodeVectorEncoder(C)sage: E.message_space()
Vector space of dimension 4 over Finite Field of size 2>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> E = codes.encoders.CyclicCodeVectorEncoder(C)>>> E.message_space()
Vector space of dimension 4 over Finite Field of size 2

unencode_nocheck(c)Return the message corresponding to c. Does not check if c belongs to the code.
INPUT:• c – A vector with the same length as the code
OUTPUT:• An element of the message space
EXAMPLES:
sage: F.<x> = GF(2)[]sage: n = 7
sage: g = x ** 3 + x + 1
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)(1, 0, 1, 0)>>> from sage.all import *>>> F = GF(Integer(2))[ x ]; (x,) = F._first_ngens(1)>>> n = Integer(7)>>> g = x ** Integer(3) + x + Integer(1)>>> C = codes.CyclicCode(generator_pol=g, length=n)>>> E = codes.encoders.CyclicCodeVectorEncoder(C)>>> c = vector(GF(Integer(2)), (Integer(1), Integer(1), Integer(1),␣
˓→Integer(0), Integer(0), Integer(1), Integer(0)))>>> E.unencode_nocheck(c)(1, 0, 1, 0)

sage.coding.cyclic_code.bch_bound(n, D, arithmetic=False)
Return the BCH bound obtained for a cyclic code of length n and defining set D.
Consider a cyclic code 𝐶, with defining set 𝐷, length 𝑛, and minimum distance 𝑑. We have the following bound,called BCH bound, on 𝑑: 𝑑 ≥ 𝛿 + 1, where 𝛿 is the length of the longest arithmetic sequence (modulo 𝑛) of
elements in 𝐷.
That is, if ∃𝑐, gcd(𝑐, 𝑛) = 1 such that {𝑙, 𝑙 + 𝑐, . . . , 𝑙 + (𝛿 − 1) × 𝑐} ⊆ 𝐷, then 𝑑 ≥ 𝛿 + 1 [1]The BCH bound is often known in the particular case 𝑐 = 1. The user can specify by setting arithmetic =False.

11.3. Cyclic code145

Coding Theory, Release 10.4

Note: As this is a specific use case of the BCH bound, it is not available in the global namespace. Call it byusing sage.coding.cyclic_code.bch_bound. You can also load it into the global namespace by typing
from sage.coding.cyclic_code import bch_bound.
INPUT:• n – an integer• D – a list of integers• arithmetic – (default: False), if it is set to True, then it computes the BCH bound using the longest
arithmetic sequence definition
OUTPUT:• (delta + 1, (l, c)) – such that delta + 1 is the BCH bound, and l, c are the parameters of
the longest arithmetic sequence (see below)
EXAMPLES:
sage: n = 15
sage: D = [14,1,2,11,12]
sage: sage.coding.cyclic_code.bch_bound(n, D)(3, (1, 1))
sage: n = 15
sage: D = [14,1,2,11,12]
sage: sage.coding.cyclic_code.bch_bound(n, D, True)(4, (2, 12))>>> from sage.all import *>>> n = Integer(15)>>> D = [Integer(14),Integer(1),Integer(2),Integer(11),Integer(12)]>>> sage.coding.cyclic_code.bch_bound(n, D)(3, (1, 1))>>> n = Integer(15)>>> D = [Integer(14),Integer(1),Integer(2),Integer(11),Integer(12)]>>> sage.coding.cyclic_code.bch_bound(n, D, True)(4, (2, 12))sage.coding.cyclic_code.find_generator_polynomial(code, check=True)
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 generates the code code, then code is cyclic.
If check is set to True, then it also checks that the code is indeed cyclic. Otherwise it doesn’t.
INPUT:• code – a linear code
• check – whether the cyclicity should be checked
OUTPUT:• the generator polynomial of code (if the code is cyclic).
EXAMPLES:

146

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

sage: from sage.coding.cyclic_code import find_generator_polynomial
sage: C = codes.GeneralizedReedSolomonCode(GF(8, a ).list()[1:], 4)
sage: find_generator_polynomial(C)x^3 + (a^2 + 1)*x^2 + a*x + a^2 + 1>>> from sage.all import *>>> from sage.coding.cyclic_code import find_generator_polynomial>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(8), a ).list()[Integer(1):],␣
˓→Integer(4))>>> find_generator_polynomial(C)x^3 + (a^2 + 1)*x^2 + a*x + a^2 + 1

11.4 BCH code
Let 𝐹 = F𝑞 and Φ be the splitting field of 𝑥𝑛 − 1 over 𝐹 , with 𝑛 a positive integer. Let also 𝛼 be an element ofmultiplicative order 𝑛 in Φ. Finally, let 𝑏, 𝛿, ℓ be integers such that 0 ≤ 𝑏 ≤ 𝑛, 1 ≤ 𝛿 ≤ 𝑛 and 𝛼ℓ generates themultiplicative group Φ× .
A BCH code over 𝐹 with designed distance 𝛿 is a cyclic code whose codewords 𝑐(𝑥) ∈ 𝐹 [𝑥] satisfy 𝑐(𝛼𝑎 ) = 0, for all
integers 𝑎 in the arithmetic sequence 𝑏, 𝑏 + ℓ, 𝑏 + 2 × ℓ, . . . , 𝑏 + (𝛿 − 2) × ℓ.
class sage.coding.bch_code.BCHCode(base_field, length, designed_distance, primitive_root=None,
offset=1, jump_size=1, b=0)
Bases: CyclicCode
Representation of a BCH code seen as a cyclic code.
INPUT:• base_field – the base field for this code
• length – the length of the code
• designed_distance – the designed minimum distance of the code
• primitive_root – (default: None) the primitive root to use when creating the set of roots for the generating polynomial over the 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 F16 , it has to be a polynomial in z4.
• offset – (default: 1) the first element in the defining set• jump_size – (default: 1) the jump size between two elements of the defining set. It must be coprime withthe multiplicative order of primitive_root.
• b – (default: 0) is exactly the same as offset. It is only here for retro-compatibility purposes with the oldsignature of codes.BCHCode() and will be removed soon.
EXAMPLES:
As explained above, BCH codes can be built through various parameters:sage: C = codes.BCHCode(GF(2), 15, 7, offset=1)
sage: C
[15, 5] BCH Code over GF(2) with designed distance 7
sage: C.generator_polynomial()x^10 + x^8 + x^5 + x^4 + x^2 + x + 1(continues on next page)

11.4. BCH code147

Coding Theory, Release 10.4

(continued from previous page)

sage: C = codes.BCHCode(GF(2), 15, 4, offset=1, jump_size=8)
sage: C
[15, 7] BCH Code over GF(2) with designed distance 4
sage: C.generator_polynomial()x^8 + x^7 + x^6 + x^4 + 1>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(2)), Integer(15), Integer(7), offset=Integer(1))>>> C[15, 5] BCH Code over GF(2) with designed distance 7>>> C.generator_polynomial()x^10 + x^8 + x^5 + x^4 + x^2 + x + 1>>> C = codes.BCHCode(GF(Integer(2)), Integer(15), Integer(4), offset=Integer(1),␣
˓→jump_size=Integer(8))>>> C[15, 7] BCH Code over GF(2) with designed distance 4>>> C.generator_polynomial()x^8 + x^7 + x^6 + x^4 + 1

BCH codes are cyclic, and can be interfaced into the CyclicCode class. The smallest GRS code which contains
a given BCH code can also be computed, and these two codes may be equal:
sage: C = codes.BCHCode(GF(16), 15, 7)
sage: R = C.bch_to_grs()
sage: codes.CyclicCode(code=R) == codes.CyclicCode(code=C)
True>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(16)), Integer(15), Integer(7))>>> R = C.bch_to_grs()>>> codes.CyclicCode(code=R) == codes.CyclicCode(code=C)
True

The 𝛿 = 15, 1 cases (trivial codes) also work:
sage: C = codes.BCHCode(GF(16), 15, 1)
sage: C.dimension()15
sage: C.defining_set()[]sage: C.generator_polynomial()
1
sage: C = codes.BCHCode(GF(16), 15, 15)
sage: C.dimension()1>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(16)), Integer(15), Integer(1))>>> C.dimension()
15>>> C.defining_set()[]>>> C.generator_polynomial()
1(continues on next page)

148

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> C = codes.BCHCode(GF(Integer(16)), Integer(15), Integer(15))>>> C.dimension()1

bch_to_grs()
Return the underlying GRS code from which self was derived.
EXAMPLES:
sage: C = codes.BCHCode(GF(2), 15, 3)
sage: RS = C.bch_to_grs()
sage: RS
[15, 13, 3] Reed-Solomon Code over GF(16)sage: C.generator_matrix() * RS.parity_check_matrix().transpose() == 0
True>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(2)), Integer(15), Integer(3))>>> RS = C.bch_to_grs()>>> RS[15, 13, 3] Reed-Solomon Code over GF(16)>>> C.generator_matrix() * RS.parity_check_matrix().transpose() == Integer(0)Truedesigned_distance()
Return the designed distance of self.
EXAMPLES:
sage: C = codes.BCHCode(GF(2), 15, 4)
sage: C.designed_distance()
4>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(2)), Integer(15), Integer(4))>>> C.designed_distance()4

jump_size()
Return the jump size between two consecutive elements of the defining set of self.
EXAMPLES:
sage: C = codes.BCHCode(GF(2), 15, 4, jump_size = 2)
sage: C.jump_size()2>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(2)), Integer(15), Integer(4), jump_size =␣˓→Integer(2))>>> C.jump_size()2

offset()Return the offset which was used to compute the elements in the defining set of self.
EXAMPLES:
11.4. BCH code149

Coding Theory, Release 10.4

sage: C = codes.BCHCode(GF(2), 15, 4, offset = 1)
sage: C.offset()1>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(2)), Integer(15), Integer(4), offset =␣
˓→Integer(1))>>> C.offset()
1class sage.coding.bch_code.BCHUnderlyingGRSDecoder(code,
grs_decoder='KeyEquationSyndrome',**kwargs)
Bases: DecoderA
decoderwhich
decodesthroughtheunderlying
GeneralizedReedSolomonCode code of the provided BCH code.

sage.coding.grs_code.

INPUT:• code – The associated code of this decoder.
• grs_decoder – The string name of the decoder to use over the underlying GRS code
• **kwargs – All extra arguments are forwarded to the GRS decoder
bch_word_to_grs(c)Return c converted as a codeword of grs_code().
EXAMPLES:
sage: C = codes.BCHCode(GF(2), 15, 3)
sage: D = codes.decoders.BCHUnderlyingGRSDecoder(C)sage: c = C.random_element()
sage: y = D.bch_word_to_grs(c)sage: y.parent()
Vector space of dimension 15 over Finite Field in z4 of size 2^4sage: y in D.grs_code()True>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(2)), Integer(15), Integer(3))>>> D = codes.decoders.BCHUnderlyingGRSDecoder(C)>>> c = C.random_element()>>> y = D.bch_word_to_grs(c)>>> y.parent()
Vector space of dimension 15 over Finite Field in z4 of size 2^4>>> y in D.grs_code()
True

decode_to_code(y)Decodes y to a codeword in sage.coding.decoder.Decoder.code().
EXAMPLES:
sage: F = GF(4, a )sage: a = F.gen()sage: C = codes.BCHCode(F, 15, 3, jump_size=2)(continues on next page)

150

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

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: 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
True>>> from sage.all import *>>> F = GF(Integer(4), a )>>> a = F.gen()>>> C = codes.BCHCode(F, Integer(15), Integer(3), jump_size=Integer(2))>>> D = codes.decoders.BCHUnderlyingGRSDecoder(C)>>> y = vector(F, [a, a + Integer(1), Integer(1), a + Integer(1), Integer(1),␣
˓→a, a + Integer(1),...
a + Integer(1), Integer(0), Integer(1), a + Integer(1),␣
˓→Integer(1), Integer(1), Integer(1), a])>>> 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)>>> D.decode_to_code(y) in C
True

We check that it still works when, while list-decoding, the GRS decoder output some words which do not lie
in the BCH code:
sage: C = codes.BCHCode(GF(2), 31, 15)
sage: C
[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: 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)]
sage: D.decode_to_code(y) == [c]True>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(2)), Integer(31), Integer(15))>>> C[31, 6] BCH Code over GF(2) with designed distance 15>>> D = codes.decoders.BCHUnderlyingGRSDecoder(C, "GuruswamiSudan",␣
˓→tau=Integer(8))>>> Dgrs = D.grs_decoder()>>> c = vector(GF(Integer(2)), [Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1),␣
˓→Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(0),␣
˓→Integer(0),(continues on next page)

11.4. BCH code151

Coding Theory, Release 10.4

(continued from previous page)...
Integer(1), Integer(0), Integer(1), Integer(0),␣
˓→Integer(1), Integer(1), Integer(1), Integer(1), Integer(0), Integer(1),␣
˓→Integer(1), Integer(0), Integer(1), Integer(0), Integer(0)])>>> y = vector(GF(Integer(2)), [Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1),␣
˓→Integer(0), Integer(1), Integer(0), Integer(1), Integer(0), Integer(1),␣
˓→Integer(1),...
Integer(1), Integer(0), Integer(0), Integer(0),␣
˓→Integer(1), Integer(0), Integer(1), Integer(1), Integer(1), Integer(1),␣
˓→Integer(1), Integer(1), Integer(1), Integer(0), Integer(0)])>>> print (c in C and (c-y).hamming_weight() == Integer(8))
True>>> 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)]>>> D.decode_to_code(y) == [c]Truedecoding_radius()
Return maximal number of errors that self can decode.
EXAMPLES:
sage: C = codes.BCHCode(GF(4, a ), 15, 3, jump_size=2)
sage: D = codes.decoders.BCHUnderlyingGRSDecoder(C)sage: D.decoding_radius()
1>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(4), a ), Integer(15), Integer(3), jump_
˓→size=Integer(2))>>> D = codes.decoders.BCHUnderlyingGRSDecoder(C)>>> D.decoding_radius()
1

grs_code()
Return the underlying GRS code of sage.coding.decoder.Decoder.code().
Note: Let us explain what is the underlying GRS code of a BCH code of length 𝑛 over 𝐹 with parameters𝑏, 𝛿, ℓ. Let 𝑐 ∈ 𝐹 𝑛 and 𝛼 a primitive root of the splitting field. We know:𝑐 ∈ BCH ⇐⇒𝑛−1∑︁𝑐𝑖 (𝛼𝑏+ℓ𝑗 )𝑖 = 0,

𝑗 = 0, . . . , 𝛿 − 2

𝑖=0⇐⇒ 𝐻𝑐 = 0

152

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

where 𝐻 = 𝐴 × 𝐷 with:
⎛

1

𝐴=⎝
(𝛼
⎛

...

0×ℓ 𝛿−2

1⎜0
𝐷=⎜⎝. . .
0

)

0
𝛼𝑏
...

...
...
...
0

⎞

1
(𝛼

(𝑛−1)ℓ 𝛿−200𝛼𝑏(𝑛−1)

⎠

)

⎞
⎟
⎟
⎠

The BCH code is orthogonal to the GRS code 𝐶 ′ of dimension 𝛿 − 1 with evaluation points {1 =𝛼0×ℓ , . . . , 𝛼(𝑛−1)ℓ } and associated multipliers {1 = 𝛼0×𝑏 , . . . , 𝛼(𝑛−1)𝑏 }. The underlying GRS code is
the dual code of 𝐶 ′ .
EXAMPLES:
sage: C = codes.BCHCode(GF(2), 15, 3)
sage: D = codes.decoders.BCHUnderlyingGRSDecoder(C)sage: D.grs_code()[15, 13, 3] Reed-Solomon Code over GF(16)>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(2)), Integer(15), Integer(3))>>> D = codes.decoders.BCHUnderlyingGRSDecoder(C)>>> D.grs_code()[15, 13, 3] Reed-Solomon Code over GF(16)grs_decoder()Return the decoder used to decode words of grs_code().
EXAMPLES:
sage: C = codes.BCHCode(GF(4, a ), 15, 3, jump_size=2)
sage: D = codes.decoders.BCHUnderlyingGRSDecoder(C)sage: D.grs_decoder()Key equation decoder for [15, 13, 3] Generalized Reed-Solomon Code over GF(16)>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(4), a ), Integer(15), Integer(3), jump_
˓→size=Integer(2))>>> D = codes.decoders.BCHUnderlyingGRSDecoder(C)>>> D.grs_decoder()Key equation decoder for [15, 13, 3] Generalized Reed-Solomon Code over GF(16)grs_word_to_bch(c)Return c converted as a codeword of sage.coding.decoder.Decoder.code().
EXAMPLES:
sage: C = codes.BCHCode(GF(4, a ), 15, 3, jump_size=2)
sage: D = codes.decoders.BCHUnderlyingGRSDecoder(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])(continues on next page)

11.4. BCH code153

Coding Theory, Release 10.4

(continued from previous page)

sage: D.grs_word_to_bch(c)(0, a, 1, a, 0, 1, 1, 1, a, 0, 0, a + 1, a, 0, 1)>>> from sage.all import *>>> C = codes.BCHCode(GF(Integer(4), a ), Integer(15), Integer(3), jump_
˓→size=Integer(2))>>> D = codes.decoders.BCHUnderlyingGRSDecoder(C)>>> Cgrs = D.grs_code()>>> Fgrs = Cgrs.base_field()>>> b = Fgrs.gen()>>> c = vector(Fgrs, [Integer(0), b**Integer(2) + b, Integer(1),␣
˓→b**Integer(2) + b, Integer(0), Integer(1), Integer(1), Integer(1),...
b**Integer(2) + b, Integer(0), Integer(0),␣
˓→b**Integer(2) + b + Integer(1), b**Integer(2) + b, Integer(0), Integer(1)])>>> D.grs_word_to_bch(c)(0, a, 1, a, 0, 1, 1, 1, a, 0, 0, a + 1, a, 0, 1)

11.5 Golay code
Golay codes are a set of four specific codes (binary Golay code, extended binary Golay code, ternary Golay and extended
ternary Golay code), known to have some very interesting properties: for example, binary and ternary Golay codes are
perfect codes, while their extended versions are self-dual codes.
REFERENCES:• [HP2003] pp. 31-33 for a definition of Golay codes.
• [MS2011]• Wikipedia article Golay_code
class sage.coding.golay_code.GolayCode(base_field, extended=True)
Bases: AbstractLinearCode
Representation of a Golay Code.
INPUT:• base_field – The base field over which the code is defined. Can only be GF(2) or GF(3).
• extended – (default: True) if set to True, creates an extended Golay code.
EXAMPLES:
sage: codes.GolayCode(GF(2))[24, 12, 8] Extended Golay code over GF(2)>>> from sage.all import *>>> codes.GolayCode(GF(Integer(2)))[24, 12, 8] Extended Golay code over GF(2)Another example with the perfect binary Golay code:
sage: codes.GolayCode(GF(2), False)[23, 12, 7] Golay code over GF(2)154

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> codes.GolayCode(GF(Integer(2)), False)[23, 12, 7] Golay code over GF(2)covering_radius()
Return the covering radius of self.
The covering radius of a linear code 𝐶 is the smallest integer 𝑟 s.t. any element of the ambient space of 𝐶 is
at most at distance 𝑟 to 𝐶.
The covering radii of all Golay codes are known, and are thus returned by this method without performing
any computation
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: C.covering_radius()
4
sage: C = codes.GolayCode(GF(2),False)
sage: C.covering_radius()
3
sage: C = codes.GolayCode(GF(3))
sage: C.covering_radius()
3
sage: C = codes.GolayCode(GF(3),False)
sage: C.covering_radius()
2>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> C.covering_radius()
4>>> C = codes.GolayCode(GF(Integer(2)),False)>>> C.covering_radius()
3>>> C = codes.GolayCode(GF(Integer(3)))>>> C.covering_radius()
3>>> C = codes.GolayCode(GF(Integer(3)),False)>>> C.covering_radius()
2

dual_code()
Return the dual code of self.
If self is an extended Golay code, self is returned. Otherwise, it returns the output of sage.coding.
linear_code_no_metric.AbstractLinearCodeNoMetric.dual_code()
EXAMPLES:
sage: C = codes.GolayCode(GF(2), extended=True)
sage: Cd = C.dual_code(); Cd[24, 12, 8] Extended Golay code over GF(2)sage: Cd == C
True

11.5. Golay code155

Coding Theory, Release 10.4>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)), extended=True)>>> Cd = C.dual_code(); Cd[24, 12, 8] Extended Golay code over GF(2)>>> Cd == C
Truegenerator_matrix()
Return a generator matrix of self
Generator matrices of all Golay codes are known, and are thus returned by this method without performing
any computation
EXAMPLES:
sage: C = codes.GolayCode(GF(2), extended=True)
sage: C.generator_matrix()[1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 0 1 1]
[0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 0 0 1 0]
[0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 1 0 1 1]
[0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1 1 0]
[0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 0 1]
[0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 1]
[0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 1]
[0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 1 1 1 1 0 0 0]
[0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 1 1 1 1 0 0]
[0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 1 1 1 1 0]
[0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 0 1 1 0 1]
[0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 0 1 1 1]>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)), extended=True)>>> C.generator_matrix()[1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 0 1 1]
[0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 0 0 1 0]
[0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 1 0 1 1]
[0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 1 1 0]
[0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 0 1]
[0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 1]
[0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 1]
[0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 1 1 1 1 0 0 0]
[0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 1 1 1 1 0 0]
[0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 1 1 1 1 0]
[0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 0 1 1 0 1]
[0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 0 1 1 1]

minimum_distance()
Return the minimum distance of self.
The minimum distance of Golay codes is already known, and is thus returned immediately without computing
anything.
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: C.minimum_distance()
8

156

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> C.minimum_distance()
8

parity_check_matrix()
Return the parity check matrix of self.
The parity check matrix of a linear code 𝐶 corresponds to the generator matrix of the dual code of 𝐶.
Parity check matrices of all Golay codes are known, and are thus returned by this method without performing
any computation.
EXAMPLES:
sage: C = codes.GolayCode(GF(3), extended=False)
sage: C.parity_check_matrix()[1 0 0 0 0 1 2 2 2 1 0]
[0 1 0 0 0 0 1 2 2 2 1]
[0 0 1 0 0 2 1 2 0 1 2]
[0 0 0 1 0 1 1 0 1 1 1]
[0 0 0 0 1 2 2 2 1 0 1]>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(3)), extended=False)>>> C.parity_check_matrix()[1 0 0 0 0 1 2 2 2 1 0]
[0 1 0 0 0 0 1 2 2 2 1]
[0 0 1 0 0 2 1 2 0 1 2]
[0 0 0 1 0 1 1 0 1 1 1]
[0 0 0 0 1 2 2 2 1 0 1]

weight_distribution()
Return the list whose 𝑖’th entry is the number of words of weight 𝑖 in self.
The weight distribution of all Golay codes are known, and are thus returned by this method without performing
any computation MWS (67, 69)
EXAMPLES:
sage: C = codes.GolayCode(GF(3))
sage: C.weight_distribution()[1, 0, 0, 0, 0, 0, 264, 0, 0, 440, 0, 0, 24]>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(3)))>>> C.weight_distribution()[1, 0, 0, 0, 0, 0, 264, 0, 0, 440, 0, 0, 24]

11.5. Golay code157

Coding Theory, Release 10.4

11.6 Reed-Muller code
Given integers 𝑚, 𝑟 and a finite field 𝐹 , the corresponding Reed-Muller Code is the set:{(𝑓 (𝛼𝑖 ) | 𝛼𝑖 ∈ 𝐹 𝑚 ) | 𝑓 ∈ 𝐹 [𝑥1 , 𝑥2 , . . . , 𝑥𝑚 ], deg 𝑓 ≤ 𝑟}
This file contains the following elements:• QAryReedMullerCode, the class for Reed-Muller codes over non-binary field of size q and 𝑟 < 𝑞• BinaryReedMullerCode, the class for Reed-Muller codes over binary field and 𝑟 <= 𝑚
• ReedMullerVectorEncoder, an encoder with a vectorial message space (for both the two code classes)• ReedMullerPolynomialEncoder, an encoder with a polynomial message space (for both the code classes)
class sage.coding.reed_muller_code.BinaryReedMullerCode(order, num_of_var)
Bases: AbstractLinearCode
Representation of a binary Reed-Muller code.
For details on the definition of Reed-Muller codes, refer to ReedMullerCode().
Note: It is better to use the aforementioned method rather than calling this class directly, as ReedMullerCode() creates either a binary or a 𝑞-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 thecode.
• num_of_var – The number of variables used in the polynomial.
EXAMPLES:
A binary Reed-Muller code can be constructed by simply giving the order of the code and the number of variables:sage: C = codes.BinaryReedMullerCode(2, 4)
sage: C
Binary Reed-Muller Code of order 2 and number of variables 4>>> from sage.all import *>>> C = codes.BinaryReedMullerCode(Integer(2), Integer(4))>>> C
Binary Reed-Muller Code of order 2 and number of variables 4minimum_distance()
Return the minimum distance of self.
The minimum distance of a binary Reed-Muller code of order 𝑑 and number of variables 𝑚 is 𝑞 𝑚−𝑑
EXAMPLES:
sage: C = codes.BinaryReedMullerCode(2, 4)
sage: C.minimum_distance()
4

158

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> C = codes.BinaryReedMullerCode(Integer(2), Integer(4))>>> C.minimum_distance()4

number_of_variables()Return the number of variables of the polynomial ring used in self.
EXAMPLES:
sage: C = codes.BinaryReedMullerCode(2, 4)
sage: C.number_of_variables()4>>> from sage.all import *>>> C = codes.BinaryReedMullerCode(Integer(2), Integer(4))>>> C.number_of_variables()4order()
Return the order of self.
Order is the maximum degree of the polynomial used in the Reed-Muller code.
EXAMPLES:
sage: C = codes.BinaryReedMullerCode(2, 4)
sage: C.order()2>>> from sage.all import *>>> C = codes.BinaryReedMullerCode(Integer(2), Integer(4))>>> C.order()2class sage.coding.reed_muller_code.QAryReedMullerCode(base_field, order, num_of_var)
Bases: AbstractLinearCode
Representation of a 𝑞-ary Reed-Muller code.
For details on the definition of Reed-Muller codes, refer to ReedMullerCode().
Note: It is better to use the aforementioned method rather than calling this class directly, as ReedMullerCode() creates either a binary or a 𝑞-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 thecode.
• 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.

11.6. Reed-Muller code159

Coding Theory, Release 10.4

EXAMPLES:
sage: from sage.coding.reed_muller_code import QAryReedMullerCodesage: F = GF(3)sage: C = QAryReedMullerCode(F, 2, 2)
sage: C
Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3>>> from sage.all import *>>> from sage.coding.reed_muller_code import QAryReedMullerCode>>> F = GF(Integer(3))>>> C = QAryReedMullerCode(F, Integer(2), Integer(2))>>> C
Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3

minimum_distance()
Return the minimum distance between two words in self.
The minimum distance of a 𝑞-ary Reed-Muller code with order 𝑑 and number of variables 𝑚 is (𝑞 − 𝑑)𝑞 𝑚−1
EXAMPLES:
sage: from sage.coding.reed_muller_code import QAryReedMullerCodesage: F = GF(5)sage: C = QAryReedMullerCode(F, 2, 4)
sage: C.minimum_distance()375>>> from sage.all import *>>> from sage.coding.reed_muller_code import QAryReedMullerCode>>> F = GF(Integer(5))>>> C = QAryReedMullerCode(F, Integer(2), Integer(4))>>> C.minimum_distance()375

number_of_variables()Return the number of variables of the polynomial ring used in self.
EXAMPLES:
sage: from sage.coding.reed_muller_code import QAryReedMullerCodesage: F = GF(59)sage: C = QAryReedMullerCode(F, 2, 4)
sage: C.number_of_variables()4>>> from sage.all import *>>> from sage.coding.reed_muller_code import QAryReedMullerCode>>> F = GF(Integer(59))>>> C = QAryReedMullerCode(F, Integer(2), Integer(4))>>> C.number_of_variables()4order()
Return the order of self.
Order is the maximum degree of the polynomial used in the Reed-Muller code.
EXAMPLES:
160

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

sage: from sage.coding.reed_muller_code import QAryReedMullerCodesage: F = GF(59)sage: C = QAryReedMullerCode(F, 2, 4)
sage: C.order()2>>> from sage.all import *>>> from sage.coding.reed_muller_code import QAryReedMullerCode>>> F = GF(Integer(59))>>> C = QAryReedMullerCode(F, Integer(2), Integer(4))>>> C.order()2sage.coding.reed_muller_code.ReedMullerCode(base_field, order, num_of_var)
Return a Reed-Muller code.
A Reed-Muller Code of order 𝑟 and number of variables 𝑚 over a finite field 𝐹 is the set:{(𝑓 (𝛼𝑖 ) | 𝛼𝑖 ∈ 𝐹 𝑚 ) | 𝑓 ∈ 𝐹 [𝑥1 , 𝑥2 , . . . , 𝑥𝑚 ], deg 𝑓 ≤ 𝑟}
INPUT:• base_field – The finite field 𝐹 over which the code is built.
• order – The order of the Reed-Muller Code, which is the maximum degree of the polynomial to be usedin 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. Binary
Reed-Muller codes must have their order less than or equal to their number of variables.
EXAMPLES:
We build a Reed-Muller code:
sage: F = GF(3)sage: C = codes.ReedMullerCode(F, 2, 2)
sage: C
Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3>>> from sage.all import *>>> F = GF(Integer(3))>>> C = codes.ReedMullerCode(F, Integer(2), Integer(2))>>> C
Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3

We ask for its parameters:sage: C.length()9sage: C.dimension()6
sage: C.minimum_distance()3

11.6. Reed-Muller code161

Coding Theory, Release 10.4>>> from sage.all import *>>> C.length()
9>>> C.dimension()
6>>> C.minimum_distance()3

If one provides a finite field of size 2, a Binary Reed-Muller code is built:
sage: F = GF(2)sage: C = codes.ReedMullerCode(F, 2, 2)
sage: C
Binary Reed-Muller Code of order 2 and number of variables 2>>> from sage.all import *>>> F = GF(Integer(2))>>> C = codes.ReedMullerCode(F, Integer(2), Integer(2))>>> C
Binary Reed-Muller Code of order 2 and number of variables 2class sage.coding.reed_muller_code.ReedMullerPolynomialEncoder(code, polynomial_ring=None)
Bases: Encoder
Encoder for Reed-Muller codes which encodes appropriate multivariate polynomials into codewords.
Consider a Reed-Muller code of order 𝑟, number of variables 𝑚, length 𝑛, dimension 𝑘 over some finite field 𝐹 .
Let those variables be (𝑥1 , 𝑥2 , . . . , 𝑥𝑚 ). We order the monomials by lowest power on lowest index variables. If
we have three monomials 𝑥1 𝑥2 , 𝑥1 𝑥22 and 𝑥21 𝑥2 , the ordering is: 𝑥1 𝑥2 < 𝑥1 𝑥22 < 𝑥21 𝑥2
Let now 𝑓 be a polynomial of the multivariate polynomial ring 𝐹 [𝑥1 , . . . , 𝑥𝑚 ].
Let (𝛽1 , 𝛽2 , . . . , 𝛽𝑞 ) be the elements of 𝐹 ordered as they are returned by Sage when calling F.list().
The aforementioned polynomial 𝑓 is encoded as:(𝑓 (𝛼11 , 𝛼12 , . . . , 𝛼1𝑚 ), 𝑓 (𝛼21 , 𝛼22 , . . . , 𝛼2𝑚 ), . . . , 𝑓 (𝛼𝑞𝑚 1 , 𝛼𝑞𝑚 2 , . . . , 𝛼𝑞𝑚 𝑚 ))with 𝛼𝑖𝑗 = 𝛽𝑖 mod 𝑞𝑗 for all 𝑖, 𝑗.
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 𝑥 will be built from the code parameters.
EXAMPLES:
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)sage: E2
Evaluation polynomial-style encoder for
Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3

162

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> C1 = codes.ReedMullerCode(GF(Integer(2)), Integer(2), Integer(4))>>> E1 = codes.encoders.ReedMullerPolynomialEncoder(C1)>>> E1
Evaluation polynomial-style encoder for
Binary Reed-Muller Code of order 2 and number of variables 4>>> C2 = codes.ReedMullerCode(GF(Integer(3)), Integer(2), Integer(2))>>> E2 = codes.encoders.ReedMullerPolynomialEncoder(C2)>>> E2
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: E
Evaluation polynomial-style encoder for
Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(3)), Integer(2), y )>>> C = codes.ReedMullerCode(GF(Integer(3)), Integer(2), Integer(2))>>> E = codes.encoders.ReedMullerPolynomialEncoder(C, R)>>> E
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>>> from sage.all import *>>> E = C1.encoder("EvaluationPolynomial")>>> E
Evaluation polynomial-style encoder for
Binary Reed-Muller Code of order 2 and number of variables 4

encode(p)Transforms the polynomial p into a codeword of code().
INPUT:• p – A polynomial from the message space of self of degree less than self.code().order().
OUTPUT:• A codeword in associated code of self
EXAMPLES:
sage: F = GF(3)sage: Fx.<x0,x1> = F[]sage: C = codes.ReedMullerCode(F, 2, 2)(continues on next page)

11.6. Reed-Muller code163

Coding Theory, Release 10.4

(continued from previous page)

sage: E = C.encoder("EvaluationPolynomial")
sage: p = x0*x1 + x1^2 + x0 + x1 + 1
sage: c = E.encode(p); c(1, 2, 0, 0, 2, 1, 1, 1, 1)
sage: c in C
True>>> from sage.all import *>>> F = GF(Integer(3))>>> Fx = F[ x0, x1 ]; (x0, x1,) = Fx._first_ngens(2)>>> C = codes.ReedMullerCode(F, Integer(2), Integer(2))>>> E = C.encoder("EvaluationPolynomial")>>> p = x0*x1 + x1**Integer(2) + x0 + x1 + Integer(1)>>> c = E.encode(p); c(1, 2, 0, 0, 2, 1, 1, 1, 1)>>> c in C
True

If a polynomial with good monomial degree but wrong monomial degree is given, an error is raised:sage: p = x0^2*x1
sage: E.encode(p)Traceback (most recent call last):...
ValueError: The polynomial to encode must have degree at most 2>>> from sage.all import *>>> p = x0**Integer(2)*x1>>> E.encode(p)Traceback (most recent call last):...
ValueError: The polynomial to encode must have degree at most 2

If p is not an element of the proper polynomial ring, an error is raised:sage: Qy.<y1,y2> = QQ[]
sage: p = y1^2 + 1
sage: E.encode(p)Traceback (most recent call last):...
ValueError: The value to encode must be inMultivariate Polynomial Ring in x0, x1 over Finite Field of size 3>>> from sage.all import *>>> Qy = QQ[ y1, y2 ]; (y1, y2,) = Qy._first_ngens(2)>>> p = y1**Integer(2) + Integer(1)>>> E.encode(p)Traceback (most recent call last):...
ValueError: The value to encode must be inMultivariate Polynomial Ring in x0, x1 over Finite Field of size 3

message_space()
Return the message space of self
EXAMPLES:
164

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

sage: F = GF(11)sage: C = codes.ReedMullerCode(F, 2, 4)
sage: E = C.encoder("EvaluationPolynomial")
sage: E.message_space()
Multivariate Polynomial Ring in x0, x1, x2, x3 over Finite Field of size 11>>> from sage.all import *>>> F = GF(Integer(11))>>> C = codes.ReedMullerCode(F, Integer(2), Integer(4))>>> E = C.encoder("EvaluationPolynomial")>>> E.message_space()
Multivariate Polynomial Ring in x0, x1, x2, x3 over Finite Field of size 11

points()Return the evaluation points in the appropriate order as used by self when encoding a message.
EXAMPLES:
sage: F = GF(3)sage: Fx.<x0,x1> = F[]sage: C = codes.ReedMullerCode(F, 2, 2)
sage: E = C.encoder("EvaluationPolynomial")
sage: E.points()[(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)]>>> from sage.all import *>>> F = GF(Integer(3))>>> Fx = F[ x0, x1 ]; (x0, x1,) = Fx._first_ngens(2)>>> C = codes.ReedMullerCode(F, Integer(2), Integer(2))>>> E = C.encoder("EvaluationPolynomial")>>> E.points()[(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)]polynomial_ring()
Return the polynomial ring associated with self
EXAMPLES:
sage: F = GF(11)sage: C = codes.ReedMullerCode(F, 2, 4)
sage: E = C.encoder("EvaluationPolynomial")
sage: E.polynomial_ring()
Multivariate Polynomial Ring in x0, x1, x2, x3 over Finite Field of size 11>>> from sage.all import *>>> F = GF(Integer(11))>>> C = codes.ReedMullerCode(F, Integer(2), Integer(4))>>> E = C.encoder("EvaluationPolynomial")>>> E.polynomial_ring()
Multivariate Polynomial Ring in x0, x1, x2, x3 over Finite Field of size 11

unencode_nocheck(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 unspecified. Instead, use unencode().

11.6. Reed-Muller code165

Coding Theory, Release 10.4

INPUT:• c – A codeword of code().
OUTPUT:• A polynomial of degree less than self.code().order().
EXAMPLES:
sage: F = GF(3)sage: C = codes.ReedMullerCode(F, 2, 2)
sage: E = C.encoder("EvaluationPolynomial")
sage: c = vector(F, (1, 2, 0, 0, 2, 1, 1, 1, 1))
sage: c in C
True
sage: p = E.unencode_nocheck(c); px0*x1 + x1^2 + x0 + x1 + 1
sage: E.encode(p) == c
True>>> from sage.all import *>>> F = GF(Integer(3))>>> C = codes.ReedMullerCode(F, Integer(2), Integer(2))>>> E = C.encoder("EvaluationPolynomial")>>> c = vector(F, (Integer(1), Integer(2), Integer(0), Integer(0), Integer(2),˓→ Integer(1), Integer(1), Integer(1), Integer(1)))>>> c in C
True>>> p = E.unencode_nocheck(c); px0*x1 + x1^2 + x0 + x1 + 1>>> E.encode(p) == c
True

Note that no error is thrown if c is not a codeword, and that the result is undefined:
sage: c = vector(F, (1, 2, 0, 0, 2, 1, 0, 1, 1))
sage: c in C
False
sage: p = E.unencode_nocheck(c); p-x0*x1 - x1^2 + x0 + 1
sage: E.encode(p) == c
False>>> from sage.all import *>>> c = vector(F, (Integer(1), Integer(2), Integer(0), Integer(0), Integer(2),˓→ Integer(1), Integer(0), Integer(1), Integer(1)))>>> c in C
False>>> p = E.unencode_nocheck(c); p-x0*x1 - x1^2 + x0 + 1>>> E.encode(p) == c
False

class sage.coding.reed_muller_code.ReedMullerVectorEncoder(code)
Bases: Encoder
Encoder for Reed-Muller codes which encodes vectors into codewords.

166

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

Consider a Reed-Muller code of order 𝑟, number of variables 𝑚, length 𝑛, dimension 𝑘 over some finite field 𝐹 .
Let those variables be (𝑥1 , 𝑥2 , . . . , 𝑥𝑚 ). We order the monomials by lowest power on lowest index variables. If
we have three monomials 𝑥1 𝑥2 , 𝑥1 𝑥22 and 𝑥21 𝑥2 , the ordering is: 𝑥1 𝑥2 < 𝑥1 𝑥22 < 𝑥21 𝑥2
Let now (𝑣1 , 𝑣2 , . . . , 𝑣𝑘 ) be a vector of 𝐹 , which corresponds to the polynomial 𝑓 = Σ𝑘𝑖=1 𝑣𝑖 𝑥𝑖 .
Let (𝛽1 , 𝛽2 , . . . , 𝛽𝑞 ) be the elements of 𝐹 ordered as they are returned by Sage when calling F.list().
The aforementioned polynomial 𝑓 is encoded as:(𝑓 (𝛼11 , 𝛼12 , . . . , 𝛼1𝑚 ), 𝑓 (𝛼21 , 𝛼22 , . . . , 𝛼2𝑚 ), . . . , 𝑓 (𝛼𝑞𝑚 1 , 𝛼𝑞𝑚 2 , . . . , 𝛼𝑞𝑚 𝑚 ))with 𝛼𝑖𝑗 = 𝛽𝑖 mod 𝑞𝑗 for all 𝑖, 𝑗).
INPUT:• code – The associated code of this encoder.
EXAMPLES:
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)sage: E2
Evaluation vector-style encoder for
Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3>>> from sage.all import *>>> C1 = codes.ReedMullerCode(GF(Integer(2)), Integer(2), Integer(4))>>> E1 = codes.encoders.ReedMullerVectorEncoder(C1)>>> E1
Evaluation vector-style encoder for
Binary Reed-Muller Code of order 2 and number of variables 4>>> C2 = codes.ReedMullerCode(GF(Integer(3)), Integer(2), Integer(2))>>> E2 = codes.encoders.ReedMullerVectorEncoder(C2)>>> E2
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>>> from sage.all import *>>> C=codes.ReedMullerCode(GF(Integer(2)), Integer(2), Integer(4))>>> E = C.encoder("EvaluationVector")>>> E
Evaluation vector-style encoder for
Binary Reed-Muller Code of order 2 and number of variables 4generator_matrix()
Return a generator matrix of self

11.6. Reed-Muller code167

Coding Theory, Release 10.4

EXAMPLES:
sage: F = GF(3)sage: C = codes.ReedMullerCode(F, 2, 2)
sage: E = codes.encoders.ReedMullerVectorEncoder(C)sage: E.generator_matrix()[1 1 1 1 1 1 1 1 1]
[0 1 2 0 1 2 0 1 2]
[0 0 0 1 1 1 2 2 2]
[0 1 1 0 1 1 0 1 1]
[0 0 0 0 1 2 0 2 1]
[0 0 0 1 1 1 1 1 1]>>> from sage.all import *>>> F = GF(Integer(3))>>> C = codes.ReedMullerCode(F, Integer(2), Integer(2))>>> E = codes.encoders.ReedMullerVectorEncoder(C)>>> E.generator_matrix()[1 1 1 1 1 1 1 1 1]
[0 1 2 0 1 2 0 1 2]
[0 0 0 1 1 1 2 2 2]
[0 1 1 0 1 1 0 1 1]
[0 0 0 0 1 2 0 2 1]
[0 0 0 1 1 1 1 1 1]

points()Return the points of 𝐹 𝑚 , where 𝐹 is the base field and 𝑚 is the number of variables, in order of whichpolynomials are evaluated on.
EXAMPLES:
sage: F = GF(3)sage: Fx.<x0,x1> = F[]sage: C = codes.ReedMullerCode(F, 2, 2)
sage: E = C.encoder("EvaluationVector")sage: E.points()[(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)]>>> from sage.all import *>>> F = GF(Integer(3))>>> Fx = F[ x0, x1 ]; (x0, x1,) = Fx._first_ngens(2)>>> C = codes.ReedMullerCode(F, Integer(2), Integer(2))>>> E = C.encoder("EvaluationVector")>>> E.points()[(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)]

11.7 Reed-Solomon codes and Generalized Reed-Solomon codes
Given 𝑛 different evaluation points 𝛼1 , . . . , 𝛼𝑛 from some finite field 𝐹 , the corresponding Reed-Solomon code (RScode) of dimension 𝑘 is the set:{(𝑓 (𝛼1 ), . . . , 𝑓 (𝛼𝑛 )) | 𝑓 ∈ 𝐹 [𝑥], deg 𝑓 < 𝑘}
An RS code is often called “classical” if 𝛼𝑖 = 𝛼𝑖−1 and 𝛼 is a primitive 𝑛’th root of unity.

168

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

More generally, given also 𝑛 “column multipliers” 𝛽1 , . . . , 𝛽𝑛 , the corresponding Generalized Reed-Solomon code (GRScode) of dimension 𝑘 is the set:{(𝛽1 𝑓 (𝛼1 ), . . . , 𝛽𝑛 𝑓 (𝛼𝑛 )) | 𝑓 ∈ 𝐹 [𝑥], deg 𝑓 < 𝑘}Here is a list of all content related to GRS codes:• GeneralizedReedSolomonCode, the class for GRS codes• ReedSolomonCode(), function for constructing classical Reed-Solomon codes.
• GRSEvaluationVectorEncoder, an encoder with a vectorial message space• GRSEvaluationPolynomialEncoder, an encoder with a polynomial message space• GRSBerlekampWelchDecoder, a decoder which corrects errors using Berlekamp-Welch algorithm• GRSGaoDecoder, a decoder which corrects errors using Gao algorithm• GRSErrorErasureDecoder, a decoder which corrects both errors and erasures• GRSKeyEquationSyndromeDecoder, a decoder which corrects errors using the key equation on syndrome
polynomials
class sage.coding.grs_code.GRSBerlekampWelchDecoder(code)
Bases: Decoder
Decoder for (Generalized) Reed-Solomon codes which uses Berlekamp-Welch decoding algorithm to correct errors
in codewords.
This algorithm recovers the error locator polynomial by solving a linear system. See [HJ2004] pp. 51-52 for details.
INPUT:• code – a code associated to this decoder
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: D = codes.decoders.GRSBerlekampWelchDecoder(C)sage: D
Berlekamp-Welch decoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> D = codes.decoders.GRSBerlekampWelchDecoder(C)>>> D
Berlekamp-Welch decoder for [40, 12, 29] Reed-Solomon Code over GF(59)Actually, we can construct the decoder from C directly:
sage: D = C.decoder("BerlekampWelch")
sage: D
Berlekamp-Welch decoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> D = C.decoder("BerlekampWelch")>>> D
Berlekamp-Welch decoder for [40, 12, 29] Reed-Solomon Code over GF(59)11.7. Reed-Solomon codes and Generalized Reed-Solomon codes

169Coding Theory, Release 10.4

decode_to_code(r)Correct the errors in r and returns a codeword.
Note: If the code associated to self has the same length as its dimension, r will be returned as is.
INPUT:• r – a vector of the ambient space of self.code()
OUTPUT:• a vector of self.code()
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
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: y = Chan(c)sage: c == D.decode_to_code(y)True>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> D = codes.decoders.GRSBerlekampWelchDecoder(C)>>> c = C.random_element()>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(),...
D.decoding_radius())>>> y = Chan(c)>>> c == D.decode_to_code(y)True

decode_to_message(r)Decode r to an element in message space of self.
Note: If the code associated to self has the same length as its dimension, r will be unencoded as is. In
that case, if r is not a codeword, the output is unspecified.
INPUT:• r – a codeword of self
OUTPUT:• a vector of self message space
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)(continues on next page)

170

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: D = codes.decoders.GRSBerlekampWelchDecoder(C)sage: c = C.random_element()
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>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> D = codes.decoders.GRSBerlekampWelchDecoder(C)>>> c = C.random_element()>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(),...
D.decoding_radius())>>> y = Chan(c)>>> D.connected_encoder().unencode(c) == D.decode_to_message(y)Truedecoding_radius()
Return maximal number of errors that self can decode.
OUTPUT:• the number of errors as an integer
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: D = codes.decoders.GRSBerlekampWelchDecoder(C)sage: D.decoding_radius()
14>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> D = codes.decoders.GRSBerlekampWelchDecoder(C)>>> D.decoding_radius()
14class sage.coding.grs_code.GRSErrorErasureDecoder(code)
Bases: Decoder
Decoder for (Generalized) Reed-Solomon codes which is able to correct both errors and erasures in codewords.
Let⌊︀ 𝑑−1𝐶⌋︀ be a GRS code of length 𝑛 and dimension 𝑘. Considering 𝑦 a codeword with at most 𝑡 errors (𝑡 being thedecoding radius), and 𝑒 the erasure vector, this decoder works as follows:2• Puncture the erased coordinates which are identified in 𝑒.
• Create a new GRS code of length 𝑛 − 𝑤(𝑒), where 𝑤 is the Hamming weight function, and dimension 𝑘.
• Use Gao decoder over this new code one the punctured word built on the first step.
• Recover the original message from the decoded word computed on the previous step.
11.7. Reed-Solomon codes and Generalized Reed-Solomon codes171

Coding Theory, Release 10.4

• Encode this message using an encoder over 𝐶.
INPUT:• code – the associated code of this decoder
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: D = codes.decoders.GRSErrorErasureDecoder(C)sage: D
Error-Erasure decoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> D = codes.decoders.GRSErrorErasureDecoder(C)>>> D
Error-Erasure decoder for [40, 12, 29] Reed-Solomon Code over GF(59)Actually, we can construct the decoder from C directly:
sage: D = C.decoder("ErrorErasure")
sage: D
Error-Erasure decoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> D = C.decoder("ErrorErasure")>>> D
Error-Erasure decoder for [40, 12, 29] Reed-Solomon Code over GF(59)decode_to_message(word_and_erasure_vector)
Decode word_and_erasure_vector to an element in message space of self
INPUT:• 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 F2 whose length is the same as the code’s, containing erasure positions
Note: If the code associated to self has the same length as its dimension, r will be unencoded as is. If thenumber of erasures is exactly 𝑛−𝑘, where 𝑛 is the length of the code associated to self and 𝑘 its dimension,r will be returned as is. In either case, if r is not a codeword, the output is unspecified.
OUTPUT:• a vector of self message space
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12(continues on next page)

172

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
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: y = Chan(c)sage: D.connected_encoder().unencode(c) == D.decode_to_message(y)True>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> D = codes.decoders.GRSErrorErasureDecoder(C)>>> c = C.random_element()>>> n_era = randint(Integer(0), C.minimum_distance() - Integer(2))>>> Chan = channels.ErrorErasureChannel(C.ambient_space(),...
D.decoding_radius(n_era), n_era)>>> y = Chan(c)>>> D.connected_encoder().unencode(c) == D.decode_to_message(y)Truedecoding_radius(number_erasures)
Return maximal number of errors that self can decode according to how many erasures it receives.
INPUT:• number_erasures – the number of erasures when we try to decode
OUTPUT:• the number of errors as an integer
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: D = codes.decoders.GRSErrorErasureDecoder(C)sage: D.decoding_radius(5)11>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> D = codes.decoders.GRSErrorErasureDecoder(C)>>> D.decoding_radius(Integer(5))
11

If we receive too many erasures, it returns an exception as codeword will be impossible to decode:
sage: D.decoding_radius(30)Traceback (most recent call last):...
ValueError: The number of erasures exceed decoding capability

11.7. Reed-Solomon codes and Generalized Reed-Solomon codes173

Coding Theory, Release 10.4>>> from sage.all import *>>> D.decoding_radius(Integer(30))
Traceback (most recent call last):...
ValueError: The number of erasures exceed decoding capability

class sage.coding.grs_code.GRSEvaluationPolynomialEncoder(code, polynomial_ring=None)
Bases: Encoder
Encoder for (Generalized) Reed-Solomon codes which uses evaluation of polynomials to obtain codewords.
Let 𝐶 be a GRS code of length 𝑛 and dimension 𝑘 over some finite field 𝐹 . We denote by 𝛼𝑖 its evaluations points
and by 𝛽𝑖 its column multipliers, where 1 ≤ 𝑖 ≤ 𝑛. Let 𝑝 be a polynomial of degree at most 𝑘 − 1 in 𝐹 [𝑥] be themessage.
The encoding of 𝑚 will be the following codeword:(𝛽1 𝑝(𝛼1 ), . . . , 𝛽𝑛 𝑝(𝛼𝑛 )).
INPUT:• code – the associated code of this encoder• polynomial_ring – (default: None) a polynomial ring to specify the message space of self, if needed;
it is set to 𝐹 [𝑥] (where 𝐹 is the base field of code) if default value is kept
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: E = codes.encoders.GRSEvaluationPolynomialEncoder(C)sage: E
Evaluation polynomial-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)sage: E.message_space()
Univariate Polynomial Ring in x over Finite Field of size 59>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> E = codes.encoders.GRSEvaluationPolynomialEncoder(C)>>> E
Evaluation polynomial-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> E.message_space()
Univariate Polynomial Ring in x over Finite Field of size 59

Actually, we can construct the encoder from C directly:
sage: E = C.encoder("EvaluationPolynomial")
sage: E
Evaluation polynomial-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> E = C.encoder("EvaluationPolynomial")>>> E
Evaluation polynomial-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)We can also specify another polynomial ring:
174

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

sage: R = PolynomialRing(F, y )sage: E = C.encoder("EvaluationPolynomial", polynomial_ring=R)
sage: E.message_space()
Univariate Polynomial Ring in y over Finite Field of size 59>>> from sage.all import *>>> R = PolynomialRing(F, y )>>> E = C.encoder("EvaluationPolynomial", polynomial_ring=R)>>> E.message_space()
Univariate Polynomial Ring in y over Finite Field of size 59

encode(p)Transform the polynomial p into a codeword of code().
One can use the following shortcut to encode a word with an encoder E:E(word)INPUT:• p – a polynomial from the message space of self of degree less than self.code().
dimension()
OUTPUT:• a codeword in associated code of self
EXAMPLES:
sage: F = GF(11)sage: Fx.<x> = F[]sage: n, k = 10 , 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: E = C.encoder("EvaluationPolynomial")
sage: p = x^2 + 3*x + 10
sage: c = E.encode(p); c(10, 3, 9, 6, 5, 6, 9, 3, 10, 8)
sage: c in C
True>>> from sage.all import *>>> F = GF(Integer(11))>>> Fx = F[ x ]; (x,) = Fx._first_ngens(1)>>> n, k = Integer(10) , Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> E = C.encoder("EvaluationPolynomial")>>> p = x**Integer(2) + Integer(3)*x + Integer(10)>>> c = E.encode(p); c(10, 3, 9, 6, 5, 6, 9, 3, 10, 8)>>> c in C
True

If a polynomial of too high degree is given, an error is raised:sage: p = x^10
sage: E.encode(p)Traceback (most recent call last):(continues on next page)

11.7. Reed-Solomon codes and Generalized Reed-Solomon codes

175

Coding Theory, Release 10.4

(continued from previous page)...
ValueError: The polynomial to encode must have degree at most 4>>> from sage.all import *>>> p = x**Integer(10)>>> E.encode(p)Traceback (most recent call last):...
ValueError: The polynomial to encode must have degree at most 4

If p is not an element of the proper polynomial ring, an error is raised:sage: Qy.<y> = QQ[]
sage: p = y^2 + 1
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>>> from sage.all import *>>> Qy = QQ[ y ]; (y,) = Qy._first_ngens(1)>>> p = y**Integer(2) + Integer(1)>>> 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

message_space()
Return the message space of self
EXAMPLES:
sage: F = GF(11)sage: n, k = 10 , 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: E = C.encoder("EvaluationPolynomial")
sage: E.message_space()
Univariate Polynomial Ring in x over Finite Field of size 11>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10) , Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> E = C.encoder("EvaluationPolynomial")>>> E.message_space()
Univariate Polynomial Ring in x over Finite Field of size 11

polynomial_ring()
Return the message space of self
EXAMPLES:

176

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

sage: F = GF(11)sage: n, k = 10 , 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: E = C.encoder("EvaluationPolynomial")
sage: E.message_space()
Univariate Polynomial Ring in x over Finite Field of size 11>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10) , Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> E = C.encoder("EvaluationPolynomial")>>> E.message_space()
Univariate Polynomial Ring in x over Finite Field of size 11

unencode_nocheck(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 unspecified. Instead, use unencode().
INPUT:• c – a codeword of code()
OUTPUT:• a polynomial of degree less than self.code().dimension()
EXAMPLES:
sage: F = GF(11)sage: n, k = 10 , 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: E = C.encoder("EvaluationPolynomial")
sage: c = vector(F, (10, 3, 9, 6, 5, 6, 9, 3, 10, 8))
sage: c in C
True
sage: p = E.unencode_nocheck(c); px^2 + 3*x + 10
sage: E.encode(p) == c
True>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10) , Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> E = C.encoder("EvaluationPolynomial")>>> c = vector(F, (Integer(10), Integer(3), Integer(9), Integer(6),␣
˓→Integer(5), Integer(6), Integer(9), Integer(3), Integer(10), Integer(8)))>>> c in C
True>>> p = E.unencode_nocheck(c); px^2 + 3*x + 10>>> E.encode(p) == c
True

Note that no error is thrown if c is not a codeword, and that the result is undefined:

11.7. Reed-Solomon codes and Generalized Reed-Solomon codes

177

Coding Theory, Release 10.4

sage: c = vector(F, (11, 3, 9, 6, 5, 6, 9, 3, 10, 8))
sage: c in C
False
sage: p = E.unencode_nocheck(c); p6*x^4 + 6*x^3 + 2*x^2sage: E.encode(p) == c
False>>> from sage.all import *>>> c = vector(F, (Integer(11), Integer(3), Integer(9), Integer(6),␣
˓→Integer(5), Integer(6), Integer(9), Integer(3), Integer(10), Integer(8)))>>> c in C
False>>> p = E.unencode_nocheck(c); p6*x^4 + 6*x^3 + 2*x^2>>> E.encode(p) == c
False

class sage.coding.grs_code.GRSEvaluationVectorEncoder(code)
Bases: Encoder
Encoder for (Generalized) Reed-Solomon codes that encodes vectors into codewords.
Let 𝐶 be a GRS code of length 𝑛 and dimension 𝑘 over some finite field 𝐹 . We denote by 𝛼𝑖 its evaluations points
and by 𝛽𝑖 its column multipliers, where 1 ≤ 𝑖 ≤ 𝑛. Let 𝑚 = (𝑚1 , . . . , 𝑚𝑘 ), a vector over 𝐹 , be the message. We
build a polynomial using the coordinates of 𝑚 as coefficients:𝑖𝑝 = Σ𝑚𝑖=1 𝑚𝑖 𝑥 .

The encoding of 𝑚 will be the following codeword:(𝛽1 𝑝(𝛼1 ), . . . , 𝛽𝑛 𝑝(𝛼𝑛 )).
INPUT:• code – the associated code of this encoder
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: E = codes.encoders.GRSEvaluationVectorEncoder(C)sage: E
Evaluation vector-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> E = codes.encoders.GRSEvaluationVectorEncoder(C)>>> E
Evaluation vector-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)Actually, we can construct the encoder from C directly:

178

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

sage: E = C.encoder("EvaluationVector")sage: E
Evaluation vector-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> E = C.encoder("EvaluationVector")>>> E
Evaluation vector-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)generator_matrix()
Return a generator matrix of self
Considering a GRS code of length 𝑛, dimension 𝑘, with evaluation points (𝛼1 , . . . , 𝛼𝑛 ) and column multipliers (𝛽1 , . . . , 𝛽𝑛 ), its generator matrix 𝐺 is built using the following formula:
𝐺 = [𝑔𝑖,𝑗 ], 𝑔𝑖,𝑗 = 𝛽𝑗 𝛼𝑗𝑖 .
This matrix is a Vandermonde matrix.
EXAMPLES:
sage: F = GF(11)sage: n, k = 10, 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: E = codes.encoders.GRSEvaluationVectorEncoder(C)sage: E.generator_matrix()[1 1 1 1 1 1 1 1 1 1]
[0 1 2 3 4 5 6 7 8 9]
[0 1 4 9 5 3 3 5 9 4]
[0 1 8 5 9 4 7 2 6 3]
[0 1 5 4 3 9 9 3 4 5]>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10), Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> E = codes.encoders.GRSEvaluationVectorEncoder(C)>>> E.generator_matrix()[1 1 1 1 1 1 1 1 1 1]
[0 1 2 3 4 5 6 7 8 9]
[0 1 4 9 5 3 3 5 9 4]
[0 1 8 5 9 4 7 2 6 3]
[0 1 5 4 3 9 9 3 4 5]class sage.coding.grs_code.GRSGaoDecoder(code)
Bases: Decoder
Decoder for (Generalized) Reed-Solomon codes which uses Gao decoding algorithm to correct errors in codewords.
Gao decoding algorithm uses early terminated extended Euclidean algorithm to find the error locator polynomial.
See [Ga02] for details.
INPUT:• code – the associated code of this decoder
EXAMPLES:

11.7. Reed-Solomon codes and Generalized Reed-Solomon codes179

Coding Theory, Release 10.4

sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: D = codes.decoders.GRSGaoDecoder(C)sage: D
Gao decoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> D = codes.decoders.GRSGaoDecoder(C)>>> D
Gao decoder for [40, 12, 29] Reed-Solomon Code over GF(59)Actually, we can construct the decoder from C directly:
sage: D = C.decoder("Gao")sage: D
Gao decoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> D = C.decoder("Gao")>>> D
Gao decoder for [40, 12, 29] Reed-Solomon Code over GF(59)decode_to_code(r)Correct the errors in r and returns a codeword.
Note: If the code associated to self has the same length as its dimension, r will be returned as is.
INPUT:• r – a vector of the ambient space of self.code()
OUTPUT:• a vector of self.code()
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
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: y = Chan(c)sage: c == D.decode_to_code(y)True>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)(continues on next page)

180

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> D = codes.decoders.GRSGaoDecoder(C)>>> c = C.random_element()>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(),...
D.decoding_radius())>>> y = Chan(c)>>> c == D.decode_to_code(y)True

decode_to_message(r)Decode r to an element in message space of self.
Note: If the code associated to self has the same length as its dimension, r will be unencoded as is. In
that case, if r is not a codeword, the output is unspecified.
INPUT:• r – a codeword of self
OUTPUT:• a vector of self message space
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
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: y = Chan(c)sage: D.connected_encoder().unencode(c) == D.decode_to_message(y)True>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> D = codes.decoders.GRSGaoDecoder(C)>>> c = C.random_element()>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(),...
D.decoding_radius())>>> y = Chan(c)>>> D.connected_encoder().unencode(c) == D.decode_to_message(y)Truedecoding_radius()
Return maximal number of errors that self can decode
OUTPUT:• the number of errors as an integer
EXAMPLES:

11.7. Reed-Solomon codes and Generalized Reed-Solomon codes181

Coding Theory, Release 10.4

sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: D = codes.decoders.GRSGaoDecoder(C)sage: D.decoding_radius()
14>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> D = codes.decoders.GRSGaoDecoder(C)>>> D.decoding_radius()
14class sage.coding.grs_code.GRSKeyEquationSyndromeDecoder(code)
Bases: Decoder
Decoder for (Generalized) Reed-Solomon codes which uses a Key equation decoding based on the syndrome polynomial to correct errors in codewords.
This algorithm uses early terminated extended euclidean algorithm to solve the key equations, as described in[Rot2006], pp. 183-195.
INPUT:• code – The associated code of this decoder.
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)sage: D
Key equation decoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[Integer(1):n+Integer(1)], k)>>> D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)>>> D
Key equation decoder for [40, 12, 29] Reed-Solomon Code over GF(59)Actually, we can construct the decoder from C directly:
sage: D = C.decoder("KeyEquationSyndrome")
sage: D
Key equation decoder for [40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> D = C.decoder("KeyEquationSyndrome")>>> D
Key equation decoder for [40, 12, 29] Reed-Solomon Code over GF(59)decode_to_code(r)Correct the errors in r and returns a codeword.
182

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

Note: If the code associated to self has the same length as its dimension, r will be returned as is.
INPUT:• r – a vector of the ambient space of self.code()
OUTPUT:• a vector of self.code()
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
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: y = Chan(c)sage: c == D.decode_to_code(y)True>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[Integer(1):n+Integer(1)], k)>>> D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)>>> c = C.random_element()>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(),...
D.decoding_radius())>>> y = Chan(c)>>> c == D.decode_to_code(y)True

decode_to_message(r)Decode r to an element in message space of self
Note: If the code associated to self has the same length as its dimension, r will be unencoded as is. In
that case, if r is not a codeword, the output is unspecified.
INPUT:• r – a codeword of self
OUTPUT:• a vector of self message space
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
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(),(continues on next page)

11.7. Reed-Solomon codes and Generalized Reed-Solomon codes183

Coding Theory, Release 10.4

(continued from previous page)....:D.decoding_radius())
sage: y = Chan(c)sage: D.connected_encoder().unencode(c) == D.decode_to_message(y)True>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[Integer(1):n+Integer(1)], k)>>> D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)>>> c = C.random_element()>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(),...
D.decoding_radius())>>> y = Chan(c)>>> D.connected_encoder().unencode(c) == D.decode_to_message(y)Truedecoding_radius()
Return maximal number of errors that self can decode
OUTPUT:• the number of errors as an integer
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)sage: D.decoding_radius()
14>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[Integer(1):n+Integer(1)], k)>>> D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)>>> D.decoding_radius()
14class sage.coding.grs_code.GeneralizedReedSolomonCode(evaluation_points, dimension,column_multipliers=None)
Bases: AbstractLinearCode
Representation of a (Generalized) Reed-Solomon code.
INPUT:• evaluation_points – a list of distinct elements of some finite field 𝐹• dimension – the dimension of the resulting code
• column_multipliers – (default: None) list of non-zero elements of 𝐹 ; all column multipliers are set
to 1 if default value is kept
EXAMPLES:

184

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

Often, one constructs a Reed-Solomon code by taking all non-zero elements of the field as evaluation points,
and specifying no column multipliers (see also ReedSolomonCode() for constructing classical Reed-Solomon
codes directly):
sage: F = GF(7)sage: evalpts = [F(i) for i in range(1,7)]
sage: C = codes.GeneralizedReedSolomonCode(evalpts, 3)
sage: C[6, 3, 4] Reed-Solomon Code over GF(7)>>> from sage.all import *>>> F = GF(Integer(7))>>> evalpts = [F(i) for i in range(Integer(1),Integer(7))]>>> C = codes.GeneralizedReedSolomonCode(evalpts, Integer(3))>>> C[6, 3, 4] Reed-Solomon Code over GF(7)More generally, the following is a Reed-Solomon code where the evaluation points are a subset of the field andincludes zero:sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: C[40, 12, 29] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> C[40, 12, 29] Reed-Solomon Code over GF(59)

It is also possible to specify the column multipliers:
sage: F = GF(59)sage: n, k = 40, 12
sage: colmults = F.list()[1:n+1]
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k, colmults)
sage: C[40, 12, 29] Generalized Reed-Solomon Code over GF(59)>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> colmults = F.list()[Integer(1):n+Integer(1)]>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k, colmults)>>> C[40, 12, 29] Generalized Reed-Solomon Code over GF(59)SageMath implements efficient decoding algorithms for GRS codes:
sage: F = GF(11)sage: n, k = 10, 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
sage: r = vector(F, (8, 2, 6, 10, 6, 10, 7, 6, 7, 2))(continues on next page)

11.7. Reed-Solomon codes and Generalized Reed-Solomon codes

185

Coding Theory, Release 10.4

(continued from previous page)

sage: C.decode_to_message(r)(3, 6, 6, 3, 1)>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10), Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[Integer(1):n+Integer(1)], k)>>> r = vector(F, (Integer(8), Integer(2), Integer(6), Integer(10), Integer(6),␣
˓→Integer(10), Integer(7), Integer(6), Integer(7), Integer(2)))>>> C.decode_to_message(r)(3, 6, 6, 3, 1)

column_multipliers()
Return the vector of column multipliers of self.
EXAMPLES:
sage: F = GF(11)sage: n, k = 10, 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: C.column_multipliers()(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10), Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> C.column_multipliers()(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)

covering_radius()
Return the covering radius of self.
The covering radius of a linear code 𝐶 is the smallest number 𝑟 s.t. any element of the ambient space of 𝐶
is at most at distance 𝑟 to 𝐶.
As GRS codes are Maximum Distance Separable codes (MDS), their covering radius is always 𝑑 − 1, where 𝑑is the minimum distance. This is opposed to random linear codes where the covering radius is computationallyhard to determine.
EXAMPLES:
sage: F = GF(2^8, a )sage: n, k = 256, 100
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: C.covering_radius()
156>>> from sage.all import *>>> F = GF(Integer(2)**Integer(8), a )>>> n, k = Integer(256), Integer(100)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> C.covering_radius()
156

186

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

dual_code()
Return the dual code of self, which is also a GRS code.
EXAMPLES:
sage: F = GF(59)sage: colmults = [ F._random_nonzero_element() for i in range(40) ]sage: C = codes.GeneralizedReedSolomonCode(F.list()[:40], 12, colmults)
sage: Cd = C.dual_code(); Cd[40, 28, 13] Generalized Reed-Solomon Code over GF(59)>>> from sage.all import *>>> F = GF(Integer(59))>>> colmults = [ F._random_nonzero_element() for i in range(Integer(40)) ]>>> C = codes.GeneralizedReedSolomonCode(F.list()[:Integer(40)], Integer(12),␣
˓→colmults)>>> Cd = C.dual_code(); Cd[40, 28, 13] Generalized Reed-Solomon Code over GF(59)The dual code of the dual code is the original code:
sage: C == Cd.dual_code()True>>> from sage.all import *>>> C == Cd.dual_code()Trueevaluation_points()
Return the vector of field elements used for the polynomial evaluations.
EXAMPLES:
sage: F = GF(11)sage: n, k = 10, 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: C.evaluation_points()(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10), Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> C.evaluation_points()(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

is_generalized()
Return whether self is a Generalized Reed-Solomon code or a regular Reed-Solomon code.
self is a Generalized Reed-Solomon code if its column multipliers are not all 1.
EXAMPLES:
sage: F = GF(11)sage: n, k = 10, 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: C.column_multipliers()(continues on next page)

11.7. Reed-Solomon codes and Generalized Reed-Solomon codes187

Coding Theory, Release 10.4

(continued from previous page)(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
sage: C.is_generalized()
False
sage: colmults = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 1]
sage: C2 = codes.GeneralizedReedSolomonCode(F.list()[:n], k, colmults)
sage: C2.is_generalized()True>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10), Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> C.column_multipliers()(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)>>> C.is_generalized()
False>>> colmults = [ Integer(1), Integer(2), Integer(3), Integer(4), Integer(5),␣
˓→Integer(6), Integer(7), Integer(8), Integer(9), Integer(1)]>>> C2 = codes.GeneralizedReedSolomonCode(F.list()[:n], k, colmults)>>> C2.is_generalized()Trueminimum_distance()
Return the minimum distance between any two words in self.
Since a GRS code is always Maximum-Distance-Separable (MDS), this returns C.length() - C.
dimension() + 1.
EXAMPLES:
sage: F = GF(59)sage: n, k = 40, 12
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: C.minimum_distance()
29>>> from sage.all import *>>> F = GF(Integer(59))>>> n, k = Integer(40), Integer(12)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> C.minimum_distance()29

multipliers_product()
Return the component-wise product of the column multipliers of self with the column multipliers of thedual GRS code.
This is a simple Cramer’s rule-like expression on the evaluation points of self. Recall that the column
multipliers of the dual GRS code are also the column multipliers of the parity check matrix of self.
EXAMPLES:
sage: F = GF(11)sage: n, k = 10, 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: C.multipliers_product()[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

188

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10), Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> C.multipliers_product()[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

parity_check_matrix()
Return the parity check matrix of self.
EXAMPLES:
sage: F = GF(11)sage: n, k = 10, 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: C.parity_check_matrix()[10 9 8 7 6 5 4 3 2 1]
[ 0 9 5 10 2 3 2 10 5 9]
[ 0 9 10 8 8 4 1 4 7 4]
[ 0 9 9 2 10 9 6 6 1 3]
[ 0 9 7 6 7 1 3 9 8 5]>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10), Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> C.parity_check_matrix()[10 9 8 7 6 5 4 3 2 1]
[ 0 9 5 10 2 3 2 10 5 9]
[ 0 9 10 8 8 4 1 4 7 4]
[ 0 9 9 2 10 9 6 6 1 3]
[ 0 9 7 6 7 1 3 9 8 5]parity_column_multipliers()
Return the list of column multipliers of the parity check matrix of self. They are also column multipliersof the generator matrix for the dual GRS code of self.
EXAMPLES:
sage: F = GF(11)sage: n, k = 10, 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: C.parity_column_multipliers()[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10), Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> C.parity_column_multipliers()[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

weight_distribution()
Return the list whose 𝑖’th entry is the number of words of weight 𝑖 in self.
Computing the weight distribution for a GRS code is very fast. Note that for random linear codes, it iscomputationally hard.
11.7. Reed-Solomon codes and Generalized Reed-Solomon codes

189

Coding Theory, Release 10.4

EXAMPLES:
sage: F = GF(11)sage: n, k = 10, 5
sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
sage: C.weight_distribution()
˓→needs sage.symbolic[1, 0, 0, 0, 0, 0, 2100, 6000, 29250, 61500, 62200]>>> from sage.all import *>>> F = GF(Integer(11))>>> n, k = Integer(10), Integer(5)>>> C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)>>> C.weight_distribution()
˓→needs sage.symbolic[1, 0, 0, 0, 0, 0, 2100, 6000, 29250, 61500, 62200]#␣

#␣

sage.coding.grs_code.ReedSolomonCode(base_field, length, dimension, primitive_root=None)
Construct a classical Reed-Solomon code.
A classical [𝑛, 𝑘] Reed-Solomon code over F𝑞 with 1 ≤ 𝑘 ≤ 𝑛 and 𝑛|(𝑞 − 1) is a Reed-Solomon code whose
evaluation points are the consecutive powers of a primitive 𝑛’th root of unity 𝛼, i.e. 𝛼𝑖 = 𝛼𝑖−1 , where 𝛼1 , . . . , 𝛼𝑛are the evaluation points. A classical Reed-Solomon codes has all column multipliers equal 1.
Classical Reed-Solomon codes are cyclic, unlike most Generalized Reed-Solomon codes.
Use GeneralizedReedSolomonCode if you instead wish to construct non-classical Reed-Solomon and Generalized Reed-Solomon codes.
INPUT:• base_field – the finite field for which to build the classical Reed-Solomon code.
• length – the length of the classical Reed-Solomon code. Must divide 𝑞 − 1 where 𝑞 is the cardinality ofbase_field.
• dimension – the dimension of the resulting code.
• primitive_root – (default: None) a primitive 𝑛’th root of unity to use for constructing theclassical Reed-Solomon code. If not supplied, one will be computed and can be recovered as C.
evaluation_points()[1] where 𝐶 is the code returned by this method.
EXAMPLES:
sage: C = codes.ReedSolomonCode(GF(7), 6, 3); C[6, 3, 4] Reed-Solomon Code over GF(7)>>> from sage.all import *>>> C = codes.ReedSolomonCode(GF(Integer(7)), Integer(6), Integer(3)); C[6, 3, 4] Reed-Solomon Code over GF(7)This code is cyclic as can be seen by coercing it into a cyclic code:
sage: Ccyc = codes.CyclicCode(code=C); Ccyc
[6, 3] Cyclic Code over GF(7)sage: Ccyc.generator_polynomial()x^3 + 3*x^2 + x + 6

190

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> Ccyc = codes.CyclicCode(code=C); Ccyc
[6, 3] Cyclic Code over GF(7)>>> Ccyc.generator_polynomial()x^3 + 3*x^2 + x + 6

Another example over an extension field:
sage: C = codes.ReedSolomonCode(GF(64, a ), 9, 4); C[9, 4, 6] Reed-Solomon Code over GF(64)>>> from sage.all import *>>> C = codes.ReedSolomonCode(GF(Integer(64), a ), Integer(9), Integer(4)); C[9, 4, 6] Reed-Solomon Code over GF(64)The primitive 𝑛’th root of unity can be recovered as the 2nd evaluation point of the code:
sage: alpha = C.evaluation_points()[1]; alphaa^5 + a^4 + a^2 + a>>> from sage.all import *>>> alpha = C.evaluation_points()[Integer(1)]; alphaa^5 + a^4 + a^2 + a

We can also supply a different primitive 𝑛’th root of unity:
sage: beta = alpha^2; betaa^4 + asage: beta.multiplicative_order()9sage: D = codes.ReedSolomonCode(GF(64), 9, 4, primitive_root=beta); D[9, 4, 6] Reed-Solomon Code over GF(64)sage: C == D
False>>> from sage.all import *>>> beta = alpha**Integer(2); betaa^4 + a>>> beta.multiplicative_order()9>>> D = codes.ReedSolomonCode(GF(Integer(64)), Integer(9), Integer(4), primitive_
˓→root=beta); D[9, 4, 6] Reed-Solomon Code over GF(64)>>> C == D
False

11.7. Reed-Solomon codes and Generalized Reed-Solomon codes

191

Coding Theory, Release 10.4

11.8 Goppa code
This module implements Goppa codes and an encoder for them.
EXAMPLES:
sage: F = GF(2^6)
sage: R.<x> = F[]sage: g = x^9 + 1
sage: L = [a for a in F.list() if g(a) != 0]
sage: C = codes.GoppaCode(g, L)
sage: C[55, 16] Goppa code over GF(2)sage: E = codes.encoders.GoppaCodeEncoder(C)sage: E
Encoder for [55, 16] Goppa code over GF(2)>>> from sage.all import *>>> F = GF(Integer(2)**Integer(6))>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> g = x**Integer(9) + Integer(1)>>> L = [a for a in F.list() if g(a) != Integer(0)]>>> C = codes.GoppaCode(g, L)>>> C[55, 16] Goppa code over GF(2)>>> E = codes.encoders.GoppaCodeEncoder(C)>>> E
Encoder for [55, 16] Goppa code over GF(2)AUTHORS:• Filip Ion, Marketa Slukova (2019-06): initial version
class sage.coding.goppa_code.GoppaCode(generating_pol, defining_set)
Bases: AbstractLinearCode
Implementation of Goppa codes.
Goppa codes are a generalization of narrow-sense BCH codes. These codes are defined by a generating polynomial
𝑔 over a finite field F𝑝𝑚 , and a defining set 𝐿 of elements from F𝑝𝑚 , which are not roots of 𝑔. The number ofdefining elements determines the length of the code.
In binary cases, the minimum distance is 2𝑡 + 1, where 𝑡 is the degree of 𝑔.
INPUT:• generating_pol – a monic polynomial with coefficients in a finite field F𝑝𝑚 , the code is defined overF𝑝 , 𝑝 must be a prime number• defining_set – a set of elements of F𝑝𝑚 that are not roots of 𝑔, its cardinality is the length of the code
EXAMPLES:
sage: F = GF(2^6)
sage: R.<x> = F[]sage: g = x^9 + 1
sage: L = [a for a in F.list() if g(a) != 0]
sage: C = codes.GoppaCode(g, L)
sage: C[55, 16] Goppa code over GF(2)192

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> F = GF(Integer(2)**Integer(6))>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> g = x**Integer(9) + Integer(1)>>> L = [a for a in F.list() if g(a) != Integer(0)]>>> C = codes.GoppaCode(g, L)>>> C[55, 16] Goppa code over GF(2)distance_bound()Return a lower bound for the minimum distance of the code.
Computed using the degree of the generating polynomial of self. The minimum distance is guaranteed tobe bigger than or equal to this bound.
EXAMPLES:
sage: F = GF(2^3)
sage: R.<x> = F[]sage: g = x^2 + x + 1
sage: L = [a for a in F.list() if g(a) != 0]
sage: C = codes.GoppaCode(g, L)
sage: C[8, 2] Goppa code over GF(2)sage: C.distance_bound()3
sage: C.minimum_distance()
˓→needs sage.libs.gap
5>>> from sage.all import *>>> F = GF(Integer(2)**Integer(3))>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> g = x**Integer(2) + x + Integer(1)>>> L = [a for a in F.list() if g(a) != Integer(0)]>>> C = codes.GoppaCode(g, L)>>> C[8, 2] Goppa code over GF(2)>>> C.distance_bound()3>>> C.minimum_distance()
˓→needs sage.libs.gap
5

#␣

#␣

parity_check_matrix()
Return a parity check matrix for self.
The element in row 𝑡, column 𝑖 is ℎ[𝑖](𝐷[𝑖]𝑡 ), where:• ℎ[𝑖] – is the inverse of 𝑔(𝐷[𝑖])• 𝐷[𝑖] – is the 𝑖-th element of the defining set
In the resulting 𝑑 × 𝑛 matrix we interpret each entry as an 𝑚-column vector and return a 𝑑𝑚 × 𝑛 matrix.
EXAMPLES:
sage: F = GF(2^3)
sage: R.<x> = F[](continues on next page)

11.8. Goppa code193

Coding Theory, Release 10.4

(continued from previous page)

sage: g = x^2 + x+ 1
sage: L = [a for a in F.list() if g(a) != 0]
sage: C = codes.GoppaCode(g, L)
sage: C[8, 2] Goppa code over GF(2)sage: C.parity_check_matrix()[1 0 0 0 0 0 0 1]
[0 0 1 0 1 1 1 0]
[0 1 1 1 0 0 1 0]
[0 1 1 1 1 1 1 1]
[0 1 0 1 1 0 1 0]
[0 0 1 1 1 1 0 0]>>> from sage.all import *>>> F = GF(Integer(2)**Integer(3))>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> g = x**Integer(2) + x+ Integer(1)>>> L = [a for a in F.list() if g(a) != Integer(0)]>>> C = codes.GoppaCode(g, L)>>> C[8, 2] Goppa code over GF(2)>>> C.parity_check_matrix()[1 0 0 0 0 0 0 1]
[0 0 1 0 1 1 1 0]
[0 1 1 1 0 0 1 0]
[0 1 1 1 1 1 1 1]
[0 1 0 1 1 0 1 0]
[0 0 1 1 1 1 0 0]class sage.coding.goppa_code.GoppaCodeEncoder(code)
Bases: Encoder
Encoder for Goppa codes
Encodes words represented as vectors of length 𝑘, where 𝑘 is the dimension of self, with entries from F𝑝 , theprime field of the base field of the generating polynomial of self, into codewords of length 𝑛, with entries fromF𝑝 .
EXAMPLES:
sage: F = GF(2^3)
sage: R.<x> = F[]sage: g = x^2 + x + 1
sage: L = [a for a in F.list() if g(a) != 0]
sage: C = codes.GoppaCode(g, L)
sage: C[8, 2] Goppa code over GF(2)sage: E = codes.encoders.GoppaCodeEncoder(C)sage: E
Encoder for [8, 2] Goppa code over GF(2)sage: word = vector(GF(2), (0, 1))
sage: c = E.encode(word)
sage: c(0, 1, 1, 1, 1, 1, 1, 0)
sage: c in C
True

194

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> F = GF(Integer(2)**Integer(3))>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> g = x**Integer(2) + x + Integer(1)>>> L = [a for a in F.list() if g(a) != Integer(0)]>>> C = codes.GoppaCode(g, L)>>> C[8, 2] Goppa code over GF(2)>>> E = codes.encoders.GoppaCodeEncoder(C)>>> E
Encoder for [8, 2] Goppa code over GF(2)>>> word = vector(GF(Integer(2)), (Integer(0), Integer(1)))>>> c = E.encode(word)>>> c(0, 1, 1, 1, 1, 1, 1, 0)>>> c in C
True

generator_matrix()
A generator matrix for self
Dimension of resulting matrix is 𝑘 × 𝑛, where 𝑘 is the dimension of self and 𝑛 is the length of self.
EXAMPLES:
sage: F = GF(2^3)
sage: R.<x> = F[]sage: g = (x^2 + x + 1)^2
sage: L = [a for a in F.list() if g(a) != 0]
sage: C = codes.GoppaCode(g, L)
sage: C[8, 2] Goppa code over GF(2)sage: C.generator_matrix()[1 0 0 1 0 1 1 1]
[0 1 1 1 1 1 1 0]>>> from sage.all import *>>> F = GF(Integer(2)**Integer(3))>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> g = (x**Integer(2) + x + Integer(1))**Integer(2)>>> L = [a for a in F.list() if g(a) != Integer(0)]>>> C = codes.GoppaCode(g, L)>>> C[8, 2] Goppa code over GF(2)>>> C.generator_matrix()[1 0 0 1 0 1 1 1]
[0 1 1 1 1 1 1 0]

11.8. Goppa code

195

Coding Theory, Release 10.4

11.9 Kasami code
This module implements a construction for the extended Kasami codes. The “regular” Kasami codes are obtained fromtruncating the extended version.
The extended Kasami code with parameters (𝑠, 𝑡) is defined as∑︁∑︁∑︁{𝑣 ∈ F𝑠2 |
𝑣𝑎 =
𝑎𝑣𝑎 =
𝑎𝑡+1 𝑣𝑎 = 0}
𝑎∈F𝑠

𝑎∈F𝑠

𝑎∈F𝑠

It follows that these are subfield subcodes of the code having those three equations as parity checks. The only valid
parameters 𝑠, 𝑡 are given by the below, where 𝑞 is a power of 2
• 𝑠 = 𝑞 2𝑗+1 , 𝑡 = 𝑞 𝑚 with 𝑚 ≤ 𝑗 and gcd(𝑚, 2𝑗 + 1) = 1• 𝑠 = 𝑞2 , 𝑡 = 𝑞
The coset graphs of the Kasami codes are distance-regular.
distance-regular graphs with intersection arrays

In particular, the extended Kasami codes result in• [𝑞 2𝑗+1 , 𝑞 2𝑗+1 − 1, 𝑞 2𝑗+1 − 𝑞, 𝑞 2𝑗+1 − 𝑞 2𝑗 + 1; 1, 𝑞, 𝑞 2𝑗 − 1, 𝑞 2𝑗+1 ]• [𝑞 2 , 𝑞 2 − 1, 𝑞 2 − 𝑞, 1; 1, 𝑞, 𝑞 2 − 1, 𝑞 2 ]The Kasami codes result in distance-regular graphs with intersection arrays• [𝑞 2𝑗+1 − 1, 𝑞 2𝑗+1 − 𝑞, 𝑞 2𝑗+1 − 𝑞 2𝑗 + 1; 1, 𝑞, 𝑞 2𝑗 − 1]
• [𝑞 2 − 1, 𝑞 2 − 𝑞, 1; 1, 𝑞, 𝑞 2 − 1]
REFERENCES:• [BCN1989] p. 358 for a definition.
• [Kas1966a]• [Kas1966b]• [Kas1971]
AUTHORS:• Ivo Maffei (2020-07-09): initial version
class sage.coding.kasami_codes.KasamiCode(s, t, extended=True)
Bases: AbstractLinearCode
Representation of a Kasami Code.
The extended Kasami code with parameters (𝑠, 𝑡) is defined as∑︁∑︁∑︁{𝑣 ∈ F𝑠2 |
𝑣𝑎 =
𝑎𝑣𝑎 =
𝑎𝑡+1 𝑣𝑎 = 0}
𝑎∈F𝑠

𝑎∈F𝑠

𝑎∈F𝑠

The only valid parameters 𝑠, 𝑡 are given by the below, where 𝑞 is a power of 2:• 𝑠 = 𝑞 2𝑗+1 , 𝑡 = 𝑞 𝑚 with 𝑚 ≤ 𝑗 and gcd(𝑚, 2𝑗 + 1) = 1• 𝑠 = 𝑞2 , 𝑡 = 𝑞
The Kasami code (𝑠, 𝑡) is obtained from the extended Kasami code (𝑠, 𝑡), via truncation of all words.
INPUT:• s, t – (integer) the parameters of the Kasami code
• extended – (default: True) if set to True, creates an extended Kasami code.
196

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

EXAMPLES:
sage: codes.KasamiCode(16,4)[16, 9] Extended (16, 4)-Kasami code
sage: _.minimum_distance()
˓→needs sage.libs.gap
4#␣

sage: codes.KasamiCode(8, 2, extended=False)[7, 1] (8, 2)-Kasami code
sage: codes.KasamiCode(8,4)
Traceback (most recent call last):...
ValueError: The parameters(=8,4) are invalid. Check the documentation>>> from sage.all import *>>> codes.KasamiCode(Integer(16),Integer(4))[16, 9] Extended (16, 4)-Kasami code>>> _.minimum_distance()
˓→needs sage.libs.gap
4#␣>>> codes.KasamiCode(Integer(8), Integer(2), extended=False)[7, 1] (8, 2)-Kasami code>>> codes.KasamiCode(Integer(8),Integer(4))
Traceback (most recent call last):...
ValueError: The parameters(=8,4) are invalid. Check the documentation

The extended Kasami code is the extension of the Kasami code:
sage: C = codes.KasamiCode(16, 4, extended=False)
sage: Cext = C.extended_code()sage: D = codes.KasamiCode(16, 4, extended=True)
sage: D.generator_matrix() == Cext.generator_matrix()True>>> from sage.all import *>>> C = codes.KasamiCode(Integer(16), Integer(4), extended=False)>>> Cext = C.extended_code()>>> D = codes.KasamiCode(Integer(16), Integer(4), extended=True)>>> D.generator_matrix() == Cext.generator_matrix()
True

See also:
sage.coding.linear_code.
REFERENCES:
For more information on Kasami codes and their use see [BCN1989] or [Kas1966a], [Kas1966b], [Kas1971]
generator_matrix()
Return a generator matrix of self.
EXAMPLES:

11.9. Kasami code197

Coding Theory, Release 10.4

sage: C = codes.KasamiCode(16, 4, extended=False)
sage: C.generator_matrix()[1 0 0 0 0 0 0 0 0 1 0 0 1 1 1]
[0 1 0 0 0 0 0 0 0 1 1 0 1 0 0]
[0 0 1 0 0 0 0 0 0 0 1 1 0 1 0]
[0 0 0 1 0 0 0 0 0 0 0 1 1 0 1]
[0 0 0 0 1 0 0 0 0 0 0 0 1 1 0]
[0 0 0 0 0 1 0 0 0 1 1 0 1 1 1]
[0 0 0 0 0 0 1 0 0 0 1 1 0 1 1]
[0 0 0 0 0 0 0 1 0 1 1 1 0 0 1]
[0 0 0 0 0 0 0 0 1 1 0 1 0 0 0]>>> from sage.all import *>>> C = codes.KasamiCode(Integer(16), Integer(4), extended=False)>>> C.generator_matrix()[1 0 0 0 0 0 0 0 0 1 0 0 1 1 1]
[0 1 0 0 0 0 0 0 0 1 1 0 1 0 0]
[0 0 1 0 0 0 0 0 0 0 1 1 0 1 0]
[0 0 0 1 0 0 0 0 0 0 0 1 1 0 1]
[0 0 0 0 1 0 0 0 0 0 0 0 1 1 0]
[0 0 0 0 0 1 0 0 0 1 1 0 1 1 1]
[0 0 0 0 0 0 1 0 0 0 1 1 0 1 1]
[0 0 0 0 0 0 0 1 0 1 1 1 0 0 1]
[0 0 0 0 0 0 0 0 1 1 0 1 0 0 0]

ALGORITHM:
We build the parity check matrix given by the three equations that the codewords must satisfy. Then we
generate the parity check matrix over F2 and from this the obtain the generator matrix for the extended
Kasami codes.
For the Kasami codes, we truncate the last column.
parameters()
Return the parameters 𝑠, 𝑡 of self.
EXAMPLES:
sage: C = codes.KasamiCode(16, 4, extended=True)
sage: C.parameters()(16, 4)sage: D = codes.KasamiCode(16, 4, extended=False)
sage: D.parameters()(16, 4)sage: C = codes.KasamiCode(8,2)
sage: C.parameters()(8, 2)>>> from sage.all import *>>> C = codes.KasamiCode(Integer(16), Integer(4), extended=True)>>> C.parameters()(16, 4)>>> D = codes.KasamiCode(Integer(16), Integer(4), extended=False)>>> D.parameters()(16, 4)>>> C = codes.KasamiCode(Integer(8),Integer(2))>>> C.parameters()(8, 2)

198

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

11.10 AG codes
Algebraic geometry codes or shortly AG codes are linear codes defined using functions or differentials on algebraic curves
over finite fields. Sage implements evaluation AG codes and differential AG codes as Goppa defined in [Gop1981] andprovides decoding algorithms for them in full generality.
EXAMPLES:
sage: k.<a> = GF(4)sage: A.<x,y> = AffineSpace(k, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: pls.remove(Q)sage: G = 5*Q
sage: codes.EvaluationAGCode(pls, G)[8, 5] evaluation AG code over GF(4)sage: codes.DifferentialAGCode(pls, G)[8, 3] differential AG code over GF(4)>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> A = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = A._first_ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> pls.remove(Q)>>> G = Integer(5)*Q>>> codes.EvaluationAGCode(pls, G)[8, 5] evaluation AG code over GF(4)>>> codes.DifferentialAGCode(pls, G)[8, 3] differential AG code over GF(4)As is well known, the two kinds of AG codes are dual to each other.
sage: E = codes.EvaluationAGCode(pls, G)
sage: D = codes.DifferentialAGCode(pls, G)
sage: E.dual_code() == D
True
sage: D.dual_code() == E
True>>> from sage.all import *>>> E = codes.EvaluationAGCode(pls, G)>>> D = codes.DifferentialAGCode(pls, G)>>> E.dual_code() == D
True>>> D.dual_code() == E
True

Decoders for both evaluation and differential AG codes are available.

11.10. AG codes199

Coding Theory, Release 10.4

11.10.1 Decoders for AG codes
This module implements decoders for evaluation and differential AG codes.
The implemented algorithm for unique decoding of AG codes, named K, is from [LBO2014] and [Lee2016].
EXAMPLES:
sage: F.<a> = GF(9)sage: A2.<x,y> = AffineSpace(F, 2)
sage: C = Curve(y^3 + y - x^4)
sage: Q, = C.places_at_infinity()
sage: O = C(0,0).place()sage: pls = C.places()sage: pls.remove(Q)sage: pls.remove(O)sage: G = -O + 18*Q
sage: code = codes.EvaluationAGCode(pls, G)
sage: code
[26, 15] evaluation AG code over GF(9)sage: decoder = code.decoder( K )sage: tau = decoder.decoding_radius()
sage: tau
4# long time
# long time
# long time
# long time
# long time>>> from sage.all import *>>> F = GF(Integer(9), names=( a ,)); (a,) = F._first_ngens(1)>>> A2 = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = A2._first_ngens(2)>>> C = Curve(y**Integer(3) + y - x**Integer(4))>>> Q, = C.places_at_infinity()>>> O = C(Integer(0),Integer(0)).place()>>> pls = C.places()>>> pls.remove(Q)>>> pls.remove(O)>>> G = -O + Integer(18)*Q>>> code = codes.EvaluationAGCode(pls, G) # long time>>> code# long time
[26, 15] evaluation AG code over GF(9)>>> decoder = code.decoder( K )# long time>>> tau = decoder.decoding_radius()# long time>>> tau# long time4

The decoder is now ready for correcting vectors received from a noisy channel:
sage: # long time
sage: channel = channels.StaticErrorRateChannel(code.ambient_space(), tau)sage: message_space = decoder.message_space()sage: message = message_space.random_element()
sage: encoder = decoder.connected_encoder()sage: sent_codeword = encoder.encode(message)
sage: received_vector = channel(sent_codeword)
sage: (received_vector - sent_codeword).hamming_weight()
4sage: decoder.decode_to_code(received_vector) == sent_codeword
True
sage: decoder.decode_to_message(received_vector) == message
True

200

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> # long time>>> channel = channels.StaticErrorRateChannel(code.ambient_space(), tau)>>> message_space = decoder.message_space()>>> message = message_space.random_element()>>> encoder = decoder.connected_encoder()>>> sent_codeword = encoder.encode(message)>>> received_vector = channel(sent_codeword)>>> (received_vector - sent_codeword).hamming_weight()
4>>> decoder.decode_to_code(received_vector) == sent_codewordTrue>>> decoder.decode_to_message(received_vector) == message
True

AUTHORS:• Kwankyu Lee (2019-03): initial version
class sage.coding.ag_code_decoders.Decoder_K
Bases: object
Common base class for the implementation of decoding algorithm K for AG codes.
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2);
sage: C = Curve(y^2 + y - x^3)
sage: pls = C.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K
sage: circuit = EvaluationAGCodeDecoder_K(D, G, Q)>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> pls = C.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K>>> circuit = EvaluationAGCodeDecoder_K(D, G, Q)

decode(received_vector, verbose=False, detect_decoding_failure=True, detect_Q_polynomial=True)
Return the message vector that corresponds to the corrected codeword from the received vector.
INPUT:• received_vector – a received vector in the ambient space of the code• verbose – boolean; if True, verbose information is printed• detect_decoding_failure – boolean; if True, early failure detection is activated
11.10. AG codes201

Coding Theory, Release 10.4

• detect_Q_polynomial – boolean; if True, a Q-polynomial is detected for fast decoding
If decoding fails for some reason, DecodingError is raised. The message contained in the exception
indicates the type of the decoding failure.
encode(message)
Encode message to a codeword.
info
class sage.coding.ag_code_decoders.Decoder_K_extension
Bases: object
Common base class for decoding algorithm K for AG codes via constant field extension.
INPUT:• pls – a list of places of a function field• G – a divisor of the function field• Q – a non-rational place• verbose – if True, verbose information is printed
EXAMPLES:
sage: A.<x,y> = AffineSpace(GF(4), 2)
sage: C = Curve(y^2 + y - x^3)
sage: pls = C.places()sage: F = C.function_field()sage: G = 1*F.get_place(4)sage: code = codes.EvaluationAGCode(pls, G)
sage: dec = code.decoder( K ); dec # long time
Unique decoder for [9, 4] evaluation AG code over GF(4)>>> from sage.all import *>>> A = AffineSpace(GF(Integer(4)), Integer(2), names=( x ,˓→first_ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> pls = C.places()>>> F = C.function_field()>>> G = Integer(1)*F.get_place(Integer(4))>>> code = codes.EvaluationAGCode(pls, G)>>> dec = code.decoder( K ); dec # long time
Unique decoder for [9, 4] evaluation AG code over GF(4)y ,)); (x, y,) = A._

sage: P.<x,y> = ProjectiveSpace(GF(4), 1)
sage: C = Curve(P)sage: pls = C.places()sage: len(pls)5sage: F = C.function_field()sage: G = F.get_place(2).divisor()
sage: code = codes.EvaluationAGCode(pls, G)
sage: code.decoder( K )Unique decoder for [5, 3] evaluation AG code over GF(4)>>> from sage.all import *>>> P = ProjectiveSpace(GF(Integer(4)), Integer(1), names=( x ,y ,)); (x, y,) =␣
(continues on next page)

202

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)P._first_ngens(2)>>> C = Curve(P)>>> pls = C.places()>>> len(pls)5>>> F = C.function_field()>>> G = F.get_place(Integer(2)).divisor()>>> code = codes.EvaluationAGCode(pls, G)>>> code.decoder( K )Unique decoder for [5, 3] evaluation AG code over GF(4)˓→

decode(received_vector, **kwargs)
Decode the received vector to a message.
INPUT:• received_vector – a vector in the ambient space of the code
encode(message, **kwargs)
Encode message to a codeword.
info
class sage.coding.ag_code_decoders.DifferentialAGCodeDecoder_K
Bases: Decoder_K
This class implements the decoding algorithm K for differential AG codes.
INPUT:• pls – a list of places of a function field• G – a divisor of the function field• Q – a rational place not in pls• verbose – if True, verbose information is printed
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2);
sage: C = Curve(y^2 + y - x^3)
sage: pls = C.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: from sage.coding.ag_code_decoders import DifferentialAGCodeDecoder_K
sage: circuit = DifferentialAGCodeDecoder_K(D, G, Q) # long time
sage: rv = vector([1, a, 1, a, 1, a, a, a + 1])
sage: cw = circuit.encode(circuit.decode(rv)) # long time
sage: rv - cw # long time(0, 0, 0, a + 1, 1, 0, 0, 0)
sage: circuit.info[ designed_distance ] # long time5
sage: circuit.info[ decoding_radius ] # long time2

11.10. AG codes203

Coding Theory, Release 10.4>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> pls = C.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> from sage.coding.ag_code_decoders import DifferentialAGCodeDecoder_K>>> circuit = DifferentialAGCodeDecoder_K(D, G, Q) # long time>>> rv = vector([Integer(1), a, Integer(1), a, Integer(1), a, a, a + Integer(1)])>>> cw = circuit.encode(circuit.decode(rv)) # long time>>> rv - cw # long time(0, 0, 0, a + 1, 1, 0, 0, 0)>>> circuit.info[ designed_distance ] # long time5>>> circuit.info[ decoding_radius ] # long time2

class sage.coding.ag_code_decoders.DifferentialAGCodeDecoder_K_extension
Bases: Decoder_K_extension
This class implements the decoding algorithm K for differential AG codes via constant field extension.
INPUT:• pls – a list of places of a function field• G – a divisor of the function field• Q – a non-rational place• verbose – if True, verbose information is printed
EXAMPLES:
sage: F.<a> = GF(4)sage: A.<x,y> = AffineSpace(F, 2)
sage: C = Curve(y^2 + y - x^3)
sage: pls = C.places()sage: F = C.function_field()sage: G = 1*F.get_place(4)sage: code = codes.DifferentialAGCode(pls, G)
sage: Q = F.get_place(3)sage: from sage.coding.ag_code_decoders import DifferentialAGCodeDecoder_K_
˓→extension
sage: circuit = DifferentialAGCodeDecoder_K_extension(pls, G, Q) # long time
sage: cw = code.random_element()
sage: rv = cw + vector([0,0,a,0,0,0,0,0,0])
sage: circuit.encode(circuit.decode(circuit._lift(rv))) == circuit._lift(cw) #␣˓→long timeTrue>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> A = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = A._first_ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))(continues on next page)

204

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> pls = C.places()>>> F = C.function_field()>>> G = Integer(1)*F.get_place(Integer(4))>>> code = codes.DifferentialAGCode(pls, G)>>> Q = F.get_place(Integer(3))>>> from sage.coding.ag_code_decoders import DifferentialAGCodeDecoder_K_extension>>> circuit = DifferentialAGCodeDecoder_K_extension(pls, G, Q) # long time>>> cw = code.random_element()>>> rv = cw + vector([Integer(0),Integer(0),a,Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(0)])>>> circuit.encode(circuit.decode(circuit._lift(rv))) == circuit._lift(cw) #␣˓→long time
Trueclass sage.coding.ag_code_decoders.DifferentialAGCodeEncoder(code, decoder=None)
Bases: Encoder
Encoder of a differential AG code.
INPUT:• code – a differential AG code
• decoder – a decoder of the code
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2);
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.DifferentialAGCode(D, G)
sage: dec = code.decoder( K , Q) # long time
sage: enc = dec.connected_encoder(); enc # long time
Encoder for [8, 3] differential AG code over GF(4)>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.DifferentialAGCode(D, G)>>> dec = code.decoder( K , Q) # long time>>> enc = dec.connected_encoder(); enc # long time
Encoder for [8, 3] differential AG code over GF(4)encode(message)

11.10. AG codes205

Coding Theory, Release 10.4

Return the codeword encoded from the message.
INPUT:• message – a vector in the message space
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.DifferentialAGCode(D, G)# long time
sage: dec = code.decoder( K , Q)
# long time
sage: enc = dec.connected_encoder()# long time
sage: msg = enc.message_space().random_element() # long time
sage: codeword = enc.encode(msg)# long time
sage: enc.unencode(codeword) == msg# long timeTrue>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.DifferentialAGCode(D, G)# long time>>> dec = code.decoder( K , Q)
# long time>>> enc = dec.connected_encoder()# long time>>> msg = enc.message_space().random_element() # long time>>> codeword = enc.encode(msg)# long time>>> enc.unencode(codeword) == msg# long timeTrueunencode_nocheck(codeword)
Return the message unencoded from codeword.
INPUT:• codeword – a vector in the code
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()(continues on next page)

206

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.DifferentialAGCode(D, G)# long time
sage: dec = code.decoder( K , Q)
# long time
sage: enc = dec.connected_encoder()# long time
sage: msg = enc.message_space().random_element() # long time
sage: codeword = enc.encode(msg)# long time
sage: enc.unencode(codeword) in enc.message_space() # indirect doctest, long␣˓→timeTrue>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.DifferentialAGCode(D, G)# long time>>> dec = code.decoder( K , Q)
# long time>>> enc = dec.connected_encoder()# long time>>> msg = enc.message_space().random_element() # long time>>> codeword = enc.encode(msg)# long time>>> enc.unencode(codeword) in enc.message_space() # indirect doctest, long␣˓→timeTrueclass sage.coding.ag_code_decoders.DifferentialAGCodeUniqueDecoder(code, Q=None,
basis=None,verbose=False)
Bases: Decoder
Unique decoder for a differential AG codes.
INPUT:• code – an evaluation AG code
• Q – (optional) a place, not one of the places supporting the code
• basis – (optional) a basis of the space of differentials to take residues• verbose – if True, verbose information is printed
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2);
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C(0,0)(continues on next page)

11.10. AG codes207

Coding Theory, Release 10.4

(continued from previous page)

sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.DifferentialAGCode(D, G)
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 2)
sage: rv = chan.transmit(code.random_element()) # long time
sage: dec = code.decoder( K , Q) # long time
sage: enc = dec.connected_encoder() # long time
sage: enc.encode(dec.decode_to_message(rv)) in code # long timeTrue>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C(Integer(0),Integer(0))>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.DifferentialAGCode(D, G)>>> chan = channels.StaticErrorRateChannel(code.ambient_space(), Integer(2))>>> rv = chan.transmit(code.random_element()) # long time>>> dec = code.decoder( K , Q) # long time>>> enc = dec.connected_encoder() # long time>>> enc.encode(dec.decode_to_message(rv)) in code # long timeTrue

If basis is given, that defines the associated residue encoding map:
sage: basis = tuple((G - sum(D)).basis_differential_space())
sage: w = basis[0]sage: cw = vector(w.residue(p) for p in D)
sage: dec2 = code.decoder( K , Q, basis) # long time
sage: enc2 = dec2.connected_encoder() # long time
sage: temp = enc2.unencode(cw); temp # long time
(1, 0, 0)
sage: enc2.encode(temp) == cw # long timeTrue
sage: w = basis[1]sage: cw = vector(w.residue(p) for p in D)
sage: temp = enc2.unencode(cw); temp # long time
(0, 1, 0)
sage: enc2.encode(temp) == cw # long timeTrue>>> from sage.all import *>>> basis = tuple((G - sum(D)).basis_differential_space())>>> w = basis[Integer(0)]>>> cw = vector(w.residue(p) for p in D)>>> dec2 = code.decoder( K , Q, basis) # long time>>> enc2 = dec2.connected_encoder() # long time>>> temp = enc2.unencode(cw); temp # long time
(1, 0, 0)(continues on next page)

208

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> enc2.encode(temp) == cw # long timeTrue>>> w = basis[Integer(1)]>>> cw = vector(w.residue(p) for p in D)>>> temp = enc2.unencode(cw); temp # long time
(0, 1, 0)>>> enc2.encode(temp) == cw # long time
True

The default basis is given by code.basis_differentials().
connected_encoder(*args, **kwargs)
Return the connected encoder for this decoder.
INPUT:• args, kwargs – all additional arguments are forwarded to the constructor of the connected encoder
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2);
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.DifferentialAGCode(D, G) # long time
sage: dec = code.decoder( K , Q)
# long time
sage: dec.connected_encoder()# long time
Encoder for [8, 3] differential AG code over GF(4)>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.DifferentialAGCode(D, G) # long time>>> dec = code.decoder( K , Q)
# long time>>> dec.connected_encoder()# long time
Encoder for [8, 3] differential AG code over GF(4)decode_to_code(received_vector, **kwargs)
Return the codeword decoded from received_vector.
INPUT:• received_vector – a vector in the ambient space of the code• verbose – boolean; if True, verbose information on the decoding process is printed

11.10. AG codes209

Coding Theory, Release 10.4

EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2);
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.DifferentialAGCode(D, G) # long time
sage: dec = code.decoder( K , Q)
# long time
sage: enc = dec.connected_encoder()# long time
sage: code = dec.code()# long time
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 2) # long␣˓→timesage: rv = chan.transmit(code.random_element()) # long time
sage: cw = dec.decode_to_code(rv)# long time
sage: (cw - rv).hamming_weight() == 2
# long timeTrue>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.DifferentialAGCode(D, G) # long time>>> dec = code.decoder( K , Q)
# long time>>> enc = dec.connected_encoder()# long time>>> code = dec.code()# long time>>> chan = channels.StaticErrorRateChannel(code.ambient_space(), Integer(2))˓→# long time>>> rv = chan.transmit(code.random_element()) # long time>>> cw = dec.decode_to_code(rv)# long time>>> (cw - rv).hamming_weight() == Integer(2)# long time
True

decode_to_message(received_vector, **kwargs)
Return the message decoded from received_vector.
INPUT:• received_vector – a vector in the ambient space of the code• verbose – boolean; if True, verbose information on the decoding process is printed
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2);
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()(continues on next page)

210

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.DifferentialAGCode(D, G) # long time
sage: dec = code.decoder( K , Q)
# long time
sage: enc = dec.connected_encoder()# long time
sage: code = dec.code()# long time
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 2)
˓→timesage: rv = chan.transmit(code.random_element()) # long time
sage: msg = dec.decode_to_message(rv)# long time
sage: cw = enc.encode(msg)# long time
sage: (cw - rv).hamming_weight() == 2
# long timeTrue

# long␣

>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.DifferentialAGCode(D, G) # long time>>> dec = code.decoder( K , Q)
# long time>>> enc = dec.connected_encoder()# long time>>> code = dec.code()# long time>>> chan = channels.StaticErrorRateChannel(code.ambient_space(), Integer(2))˓→# long time>>> rv = chan.transmit(code.random_element()) # long time>>> msg = dec.decode_to_message(rv)# long time>>> cw = enc.encode(msg)# long time>>> (cw - rv).hamming_weight() == Integer(2)# long time
True

decoding_radius()
Return the decoding radius of the decoder.
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2);
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.DifferentialAGCode(D, G)
sage: dec = code.decoder( K , Q)

# long time
# long time(continues on next page)

11.10. AG codes211

Coding Theory, Release 10.4

(continued from previous page)

sage: dec.decoding_radius()
2# long time>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.DifferentialAGCode(D, G) # long time>>> dec = code.decoder( K , Q)
# long time>>> dec.decoding_radius()# long time2

class sage.coding.ag_code_decoders.EvaluationAGCodeDecoder_K
Bases: Decoder_K
This class implements the decoding algorithm K for evaluation AG codes.
INPUT:• pls – a list of places of a function field• G – a divisor of the function field• Q – a rational place not in pls• verbose – if True, verbose information is printed.
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2);
sage: C = Curve(y^2 + y - x^3)
sage: pls = C.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K
sage: circuit = EvaluationAGCodeDecoder_K(D, G, Q)
sage: rv = vector([a, 0, 0, a, 1, 1, a + 1, 0])
sage: cw = circuit.encode(circuit.decode(rv))
sage: rv - cw
(a + 1, 0, 0, 0, 0, 0, 0, 0)
sage: circuit.info[ designed_distance ]3
sage: circuit.info[ decoding_radius ]1>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_(continues on next page)212

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> pls = C.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K>>> circuit = EvaluationAGCodeDecoder_K(D, G, Q)>>> rv = vector([a, Integer(0), Integer(0), a, Integer(1), Integer(1), a +␣˓→Integer(1), Integer(0)])>>> cw = circuit.encode(circuit.decode(rv))>>> rv - cw
(a + 1, 0, 0, 0, 0, 0, 0, 0)>>> circuit.info[ designed_distance ]3>>> circuit.info[ decoding_radius ]1˓→class sage.coding.ag_code_decoders.EvaluationAGCodeDecoder_K_extension
Bases: Decoder_K_extension
This class implements the decoding algorithm K for evaluation AG codes via constant field extension.
INPUT:• pls – a list of places of a function field• G – a divisor of the function field• Q – a non-rational place• verbose – if True, verbose information is printed
EXAMPLES:
sage: F.<a> = GF(4)sage: A.<x,y> = AffineSpace(F, 2)
sage: C = Curve(y^2 + y - x^3)
sage: pls = C.places()sage: F = C.function_field()sage: G = 1*F.get_place(4)sage: code = codes.EvaluationAGCode(pls, G)
sage: Q = F.get_place(3)sage: from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K_extension
sage: circuit = EvaluationAGCodeDecoder_K_extension(pls, G, Q)
sage: cw = code.random_element()
sage: rv = cw + vector([0,1,1,0,0,0,0,0,0])
sage: circuit.encode(circuit.decode(circuit._lift(rv))) == circuit._lift(cw)True>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> A = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = A._first_ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> pls = C.places()>>> F = C.function_field()>>> G = Integer(1)*F.get_place(Integer(4))(continues on next page)

11.10. AG codes213

Coding Theory, Release 10.4

(continued from previous page)>>> code = codes.EvaluationAGCode(pls, G)>>> Q = F.get_place(Integer(3))>>> from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K_extension>>> circuit = EvaluationAGCodeDecoder_K_extension(pls, G, Q)>>> cw = code.random_element()>>> rv = cw + vector([Integer(0),Integer(1),Integer(1),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(0),Integer(0)])>>> circuit.encode(circuit.decode(circuit._lift(rv))) == circuit._lift(cw)Trueclass sage.coding.ag_code_decoders.EvaluationAGCodeEncoder(code, decoder=None)
Bases: Encoder
Encoder of an evaluation AG code
INPUT:• code – an evaluation AG code
• decoder – a decoder of the code
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2);
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.EvaluationAGCode(D, G)
sage: dec = code.decoder( K , Q)
sage: enc = dec.connected_encoder()sage: enc
Encoder for [8, 5] evaluation AG code over GF(4)>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.EvaluationAGCode(D, G)>>> dec = code.decoder( K , Q)>>> enc = dec.connected_encoder()>>> enc
Encoder for [8, 5] evaluation AG code over GF(4)encode(message)
Return the codeword encoded from the message.
INPUT:
214

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

• message – a vector in the message space
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.EvaluationAGCode(D, G)# long time
sage: dec = code.decoder( K , Q)
# long time
sage: enc = dec.connected_encoder()# long time
sage: msg = enc.message_space().random_element() # long time
sage: codeword = enc.encode(msg)# long time
sage: enc.unencode(codeword) == msg# long timeTrue>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.EvaluationAGCode(D, G)# long time>>> dec = code.decoder( K , Q)
# long time>>> enc = dec.connected_encoder()# long time>>> msg = enc.message_space().random_element() # long time>>> codeword = enc.encode(msg)# long time>>> enc.unencode(codeword) == msg# long timeTrueunencode_nocheck(codeword)
Return the message unencoded from codeword.
INPUT:• codeword – a vector in the code
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.EvaluationAGCode(D, G)# long time(continues on next page)

11.10. AG codes215

Coding Theory, Release 10.4

(continued from previous page)

sage: dec = code.decoder( K , Q)
# long time
sage: enc = dec.connected_encoder()# long time
sage: msg = enc.message_space().random_element() # long time
sage: codeword = enc.encode(msg)# long time
sage: enc.unencode(codeword) in enc.message_space() # long time, indirect␣
˓→doctest
True>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.EvaluationAGCode(D, G)# long time>>> dec = code.decoder( K , Q)
# long time>>> enc = dec.connected_encoder()# long time>>> msg = enc.message_space().random_element() # long time>>> codeword = enc.encode(msg)# long time>>> enc.unencode(codeword) in enc.message_space() # long time, indirect␣
˓→doctest
True

class sage.coding.ag_code_decoders.EvaluationAGCodeUniqueDecoder(code, Q=None,
basis=None,verbose=False)
Bases: Decoder
Unique decoder for evaluation AG codes.
INPUT:• code – an evaluation AG code
• Q – (optional) a place, not one of the places supporting the code
• basis – (optional) a basis of the space of functions to evaluate• verbose – if True, verbose information is printed
EXAMPLES:
sage: k.<a> = GF(4)sage: P.<x,y> = AffineSpace(k, 2);
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C(0,0)
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.EvaluationAGCode(D, G)
sage: dec = code.decoder( K , Q)
(continues on next page)

216

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: enc = dec.connected_encoder()sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 1)
sage: rv = chan.transmit(code.random_element())
sage: enc.encode(dec.decode_to_message(rv)) in code
True>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> P = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2);>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C(Integer(0),Integer(0))>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.EvaluationAGCode(D, G)>>> dec = code.decoder( K , Q)>>> enc = dec.connected_encoder()>>> chan = channels.StaticErrorRateChannel(code.ambient_space(), Integer(1))>>> rv = chan.transmit(code.random_element())>>> enc.encode(dec.decode_to_message(rv)) in codeTrue

If basis is given, that defines the associated evaluation encoding map:
sage: basis = tuple(G.basis_function_space())
sage: dec2 = code.decoder( K , Q, basis)sage: enc2 = dec2.connected_encoder()sage: f = basis[0]sage: cw = vector(f.evaluate(p) for p in D)
sage: enc2.unencode(cw)(1, 0, 0, 0, 0)
sage: enc2.encode(_) == cw
True
sage: f = basis[1]sage: cw = vector(f.evaluate(p) for p in D)
sage: enc2.unencode(cw)(0, 1, 0, 0, 0)
sage: enc2.encode(_) == cw
True>>> from sage.all import *>>> basis = tuple(G.basis_function_space())>>> dec2 = code.decoder( K , Q, basis)>>> enc2 = dec2.connected_encoder()>>> f = basis[Integer(0)]>>> cw = vector(f.evaluate(p) for p in D)>>> enc2.unencode(cw)(1, 0, 0, 0, 0)>>> enc2.encode(_) == cw
True>>> f = basis[Integer(1)]>>> cw = vector(f.evaluate(p) for p in D)>>> enc2.unencode(cw)(continues on next page)

11.10. AG codes217

Coding Theory, Release 10.4

(continued from previous page)(0, 1, 0, 0, 0)>>> enc2.encode(_) == cw
True

The default basis is given by code.basis_functions().
connected_encoder(*args, **kwargs)
Return the connected encoder for this decoder.
INPUT:• args, kwargs – all additional arguments are forwarded to the constructor of the connected encoder
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.EvaluationAGCode(D, G) # long time
sage: dec = code.decoder( K , Q)
# long time
sage: dec.connected_encoder()# long time
Encoder for [8, 5] evaluation AG code over GF(4)>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.EvaluationAGCode(D, G) # long time>>> dec = code.decoder( K , Q)
# long time>>> dec.connected_encoder()# long time
Encoder for [8, 5] evaluation AG code over GF(4)decode_to_code(received_vector, **kwargs)
Return the codeword decoded from received_vector.
INPUT:• received_vector – a vector in the ambient space of the code• verbose – boolean; if True, verbose information on the decoding process is printed
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2)(continues on next page)

218

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.EvaluationAGCode(D, G) # long time
sage: dec = code.decoder( K , Q)
# long time
sage: code = dec.code()# long time
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 1)
˓→timesage: rv = chan.transmit(code.random_element()) # long time
sage: cw = dec.decode_to_code(rv)# long time
sage: (cw - rv).hamming_weight() == 1
# long timeTrue

# long␣

>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.EvaluationAGCode(D, G) # long time>>> dec = code.decoder( K , Q)
# long time>>> code = dec.code()# long time>>> chan = channels.StaticErrorRateChannel(code.ambient_space(), Integer(1))˓→# long time>>> rv = chan.transmit(code.random_element()) # long time>>> cw = dec.decode_to_code(rv)# long time>>> (cw - rv).hamming_weight() == Integer(1)# long time
True

decode_to_message(received_vector, **kwargs)
Return the message decoded from received_vector.
INPUT:• received_vector – a vector in the ambient space of the code• verbose – boolean; if True, verbose information on the decoding process is printed
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q](continues on next page)

11.10. AG codes219

Coding Theory, Release 10.4

(continued from previous page)

sage: G = 5*Q
sage: code = codes.EvaluationAGCode(D, G) # long time
sage: dec = code.decoder( K , Q)
# long time
sage: enc = dec.connected_encoder()# long time
sage: code = dec.code()# long time
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 1)
˓→timesage: rv = chan.transmit(code.random_element()) # long time
sage: msg = dec.decode_to_message(rv)# long time
sage: cw = enc.encode(msg)# long time
sage: (cw - rv).hamming_weight() == 1
# long timeTrue

# long␣

>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.EvaluationAGCode(D, G) # long time>>> dec = code.decoder( K , Q)
# long time>>> enc = dec.connected_encoder()# long time>>> code = dec.code()# long time>>> chan = channels.StaticErrorRateChannel(code.ambient_space(), Integer(1))˓→# long time>>> rv = chan.transmit(code.random_element()) # long time>>> msg = dec.decode_to_message(rv)# long time>>> cw = enc.encode(msg)# long time>>> (cw - rv).hamming_weight() == Integer(1)# long time
True

decoding_radius()
Return the decoding radius of the decoder.
EXAMPLES:
sage: F.<a> = GF(4)sage: P.<x,y> = AffineSpace(F, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: D = [pl for pl in pls if pl != Q]
sage: G = 5*Q
sage: code = codes.EvaluationAGCode(D, G)
sage: dec = code.decoder( K , Q)
sage: dec.decoding_radius()
1

220# long time
# long time
# long time

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> F = GF(Integer(4), names=( a ,)); (a,) = F._first_ngens(1)>>> P = AffineSpace(F, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> D = [pl for pl in pls if pl != Q]>>> G = Integer(5)*Q>>> code = codes.EvaluationAGCode(D, G) # long time>>> dec = code.decoder( K , Q)
# long time>>> dec.decoding_radius()# long time1

A natural generalization of classical Goppa codes is Cartier codes [Cou2014]. Cartier codes are subfield subcodes ofdifferential AG codes.
EXAMPLES:
sage: F.<a> = GF(9)sage: P.<x,y,z> = ProjectiveSpace(F, 2);
sage: C = Curve(x^3*y + y^3*z + x*z^3)
sage: F = C.function_field()sage: pls = F.places()sage: Z, = C([0,0,1]).places()sage: pls.remove(Z)sage: G = 3*Z
sage: codes.CartierCode(pls, G) # long time
[9, 4] Cartier code over GF(3)>>> from sage.all import *>>> F = GF(Integer(9), names=( a ,)); (a,) = F._first_ngens(1)>>> P = ProjectiveSpace(F, Integer(2), names=( x , y , z ,)); (x, y, z,) = P._first_
˓→ngens(3);>>> C = Curve(x**Integer(3)*y + y**Integer(3)*z + x*z**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Z, = C([Integer(0),Integer(0),Integer(1)]).places()>>> pls.remove(Z)>>> G = Integer(3)*Z>>> codes.CartierCode(pls, G) # long time
[9, 4] Cartier code over GF(3)AUTHORS:• Kwankyu Lee (2019-03): initial version
class sage.coding.ag_code.AGCode(base_field, length, default_encoder_name, default_decoder_name)
Bases: AbstractLinearCode
Base class of algebraic geometry codes.
A subclass of this class is required to define _function_field attribute that refers to an abstract functiom fieldor the function field of the underlying curve used to construct a code of the class.
base_function_field()
Return the function field used to construct the code.
11.10. AG codes221

Coding Theory, Release 10.4

EXAMPLES:
sage: k.<a> = GF(4)sage: A.<x,y> = AffineSpace(k, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: p = C([0,0])
sage: Q, = p.places()sage: pls.remove(Q)sage: G = 5*Q
sage: code = codes.EvaluationAGCode(pls, G)
sage: code.base_function_field()
Function field in y defined by y^2 + y + x^3>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> A = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = A._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> p = C([Integer(0),Integer(0)])>>> Q, = p.places()>>> pls.remove(Q)>>> G = Integer(5)*Q>>> code = codes.EvaluationAGCode(pls, G)>>> code.base_function_field()
Function field in y defined by y^2 + y + x^3

class sage.coding.ag_code.CartierCode(pls, G, r=1, name=None)
Bases: AGCode
Cartier code defined by rational places pls and a divisor G of a function field.
INPUT:• pls – a list of rational places• G – a divisor whose support is disjoint from pls• r – integer (default: 1)• name – string; name of the generator of the subfield F𝑝𝑟
OUTPUT: Cartier code over F𝑝𝑟 where 𝑝 is the characteristic of the base constant field of the function field
Note that if r is 1 the default, then name can be omitted.
EXAMPLES:
sage: F.<a> = GF(9)sage: P.<x,y,z> = ProjectiveSpace(F, 2);
sage: C = Curve(x^3*y + y^3*z + x*z^3)
sage: F = C.function_field()sage: pls = F.places()sage: Z, = C(0,0,1).places()sage: pls.remove(Z)sage: G = 3*Z
sage: code = codes.CartierCode(pls, G) # long time(continues on next page)

222

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: code.minimum_distance()2# long time>>> from sage.all import *>>> F = GF(Integer(9), names=( a ,)); (a,) = F._first_ngens(1)>>> P = ProjectiveSpace(F, Integer(2), names=( x , y , z ,)); (x, y, z,) = P._
˓→first_ngens(3);>>> C = Curve(x**Integer(3)*y + y**Integer(3)*z + x*z**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Z, = C(Integer(0),Integer(0),Integer(1)).places()>>> pls.remove(Z)>>> G = Integer(3)*Z>>> code = codes.CartierCode(pls, G) # long time>>> code.minimum_distance()# long time2

designed_distance()
Return the designed distance of the Cartier code.
The designed distance is that of the differential code of which the Cartier code is a subcode.
EXAMPLES:
sage: F.<a> = GF(9)sage: P.<x,y,z> = ProjectiveSpace(F, 2);
sage: C = Curve(x^3*y + y^3*z + x*z^3)
sage: F = C.function_field()sage: pls = F.places()sage: Z, = C(0,0,1).places()sage: pls.remove(Z)sage: G = 3*Z
sage: code = codes.CartierCode(pls, G) # long time
sage: code.designed_distance()# long time1>>> from sage.all import *>>> F = GF(Integer(9), names=( a ,)); (a,) = F._first_ngens(1)>>> P = ProjectiveSpace(F, Integer(2), names=( x , y , z ,)); (x, y, z,) =␣
˓→P._first_ngens(3);>>> C = Curve(x**Integer(3)*y + y**Integer(3)*z + x*z**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Z, = C(Integer(0),Integer(0),Integer(1)).places()>>> pls.remove(Z)>>> G = Integer(3)*Z>>> code = codes.CartierCode(pls, G) # long time>>> code.designed_distance()# long time1

generator_matrix()
Return a generator matrix of the Cartier code.
EXAMPLES:

11.10. AG codes223

Coding Theory, Release 10.4

sage: F.<a> = GF(9)sage: P.<x,y,z> = ProjectiveSpace(F, 2);
sage: C = Curve(x^3*y + y^3*z + x*z^3)
sage: F = C.function_field()sage: pls = F.places()sage: Z, = C(0,0,1).places()sage: pls.remove(Z)sage: G = 3*Z
sage: code = codes.CartierCode(pls, G) # long time
sage: code.generator_matrix()# long time
[1 0 0 2 2 0 2 2 0]
[0 1 0 2 2 0 2 2 0]
[0 0 1 0 0 0 0 0 2]
[0 0 0 0 0 1 0 0 2]>>> from sage.all import *>>> F = GF(Integer(9), names=( a ,)); (a,) = F._first_ngens(1)>>> P = ProjectiveSpace(F, Integer(2), names=( x , y , z ,)); (x, y, z,) =␣
˓→P._first_ngens(3);>>> C = Curve(x**Integer(3)*y + y**Integer(3)*z + x*z**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Z, = C(Integer(0),Integer(0),Integer(1)).places()>>> pls.remove(Z)>>> G = Integer(3)*Z>>> code = codes.CartierCode(pls, G) # long time>>> code.generator_matrix()# long time
[1 0 0 2 2 0 2 2 0]
[0 1 0 2 2 0 2 2 0]
[0 0 1 0 0 0 0 0 2]
[0 0 0 0 0 1 0 0 2]

class sage.coding.ag_code.DifferentialAGCode(pls, G)
Bases: AGCode
Differential AG code defined by rational places pls and a divisor G
INPUT:• pls – a list of rational places of a function field• G – a divisor whose support is disjoint from pls
If G is a place, then it is regarded as a prime divisor.
EXAMPLES:
sage: k.<a> = GF(4)sage: A.<x,y> = AffineSpace(k, 2)
sage: C = A.curve(y^3 + y - x^4)
sage: Q = C.places_at_infinity()[0]sage: O = C([0,0]).place()sage: pls = [p for p in C.places() if p not in [O, Q]]
sage: G = -O + 3*Q
sage: codes.DifferentialAGCode(pls, -O + Q)
[3, 2] differential AG code over GF(4)sage: F = C.function_field()sage: G = F.get_place(1)(continues on next page)

224

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: codes.DifferentialAGCode(pls, G)[3, 1] differential AG code over GF(4)>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> A = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = A._first_ngens(2)>>> C = A.curve(y**Integer(3) + y - x**Integer(4))>>> Q = C.places_at_infinity()[Integer(0)]>>> O = C([Integer(0),Integer(0)]).place()>>> pls = [p for p in C.places() if p not in [O, Q]]>>> G = -O + Integer(3)*Q>>> codes.DifferentialAGCode(pls, -O + Q)
[3, 2] differential AG code over GF(4)>>> F = C.function_field()>>> G = F.get_place(Integer(1))>>> codes.DifferentialAGCode(pls, G)[3, 1] differential AG code over GF(4)basis_differentials()
Return the basis differentials associated with the generator matrix.
EXAMPLES:
sage: k.<a> = GF(4)sage: A.<x,y> = AffineSpace(k, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()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()])
[
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]
[
0
0
0
1
0
a
0 a + 1]
[
0
0
0
0
1
1
1
1]
>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> A = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = A._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Q, = C.places_at_infinity()>>> pls.remove(Q)>>> code = codes.DifferentialAGCode(pls, Integer(3)*Q)>>> 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]
[
0
0
0
1
0
a
0 a + 1]
(continues on next page)

11.10. AG codes225

Coding Theory, Release 10.4

(continued from previous page)

[

0

0

0

0

1

1

1

1]

designed_distance()
Return the designed distance of the differential AG code.
If the code is of dimension zero, then a ValueError is raised.
EXAMPLES:
sage: k.<a> = GF(4)sage: A.<x,y> = AffineSpace(k, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: Q, = C.places_at_infinity()
sage: pls.remove(Q)sage: code = codes.DifferentialAGCode(pls, 3*Q)
sage: code.designed_distance()3>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> A = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = A._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Q, = C.places_at_infinity()>>> pls.remove(Q)>>> code = codes.DifferentialAGCode(pls, Integer(3)*Q)>>> code.designed_distance()3

generator_matrix()
Return a generator matrix of the code.
EXAMPLES:
sage: k.<a> = GF(4)sage: A.<x,y> = AffineSpace(k, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: Q, = C.places_at_infinity()
sage: pls.remove(Q)sage: code = codes.DifferentialAGCode(pls, 3*Q)
sage: code.generator_matrix()
[
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]
[
0
0
0
1
0
a
0 a + 1]
[
0
0
0
0
1
1
1
1]
>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> A = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = A._first_(continues on next page)

226

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Q, = C.places_at_infinity()>>> pls.remove(Q)>>> code = codes.DifferentialAGCode(pls, Integer(3)*Q)>>> code.generator_matrix()
[
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]
[
0
0
0
1
0
a
0 a + 1]
[
0
0
0
0
1
1
1
1]
˓→

class sage.coding.ag_code.EvaluationAGCode(pls, G)
Bases: AGCode
Evaluation AG code defined by rational places pls and a divisor G.
INPUT:• pls – a list of rational places of a function field• G – a divisor whose support is disjoint from pls
If G is a place, then it is regarded as a prime divisor.
EXAMPLES:
sage: k.<a> = GF(4)sage: A.<x,y> = AffineSpace(k, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: Q, = C.places_at_infinity()
sage: pls.remove(Q)sage: G = 5*Q
sage: codes.EvaluationAGCode(pls, G)[8, 5] evaluation AG code over GF(4)sage: G = F.get_place(5)sage: codes.EvaluationAGCode(pls, G)[8, 5] evaluation AG code over GF(4)>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> A = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = A._first_ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Q, = C.places_at_infinity()>>> pls.remove(Q)>>> G = Integer(5)*Q>>> codes.EvaluationAGCode(pls, G)[8, 5] evaluation AG code over GF(4)>>> G = F.get_place(Integer(5))(continues on next page)

11.10. AG codes227

Coding Theory, Release 10.4

(continued from previous page)>>> codes.EvaluationAGCode(pls, G)[8, 5] evaluation AG code over GF(4)basis_functions()
Return the basis functions associated with the generator matrix.
EXAMPLES:
sage: k.<a> = GF(4)sage: A.<x,y> = AffineSpace(k, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: Q, = C.places_at_infinity()
sage: pls.remove(Q)sage: code = codes.EvaluationAGCode(pls, 3*Q)
sage: code.basis_functions()(y + a*x + 1, y + x, (a + 1)*x)
sage: matrix([[f.evaluate(p) for p in pls] for f in code.basis_functions()])
[
1
0
0
1
a a + 1
1
0]
[
0
1
0
1
1
0 a + 1
a]
[
0
0
1
1
a
a a + 1 a + 1]>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> A = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = A._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Q, = C.places_at_infinity()>>> pls.remove(Q)>>> code = codes.EvaluationAGCode(pls, Integer(3)*Q)>>> code.basis_functions()(y + a*x + 1, y + x, (a + 1)*x)>>> matrix([[f.evaluate(p) for p in pls] for f in code.basis_functions()])
[
1
0
0
1
a a + 1
1
0]
[
0
1
0
1
1
0 a + 1
a]
[
0
0
1
1
a
a a + 1 a + 1]

designed_distance()
Return the designed distance of the AG code.
If the code is of dimension zero, then a ValueError is raised.
EXAMPLES:
sage: k.<a> = GF(4)sage: A.<x,y> = AffineSpace(k, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: Q, = C.places_at_infinity()
sage: pls.remove(Q)sage: code = codes.EvaluationAGCode(pls, 3*Q)
sage: code.designed_distance()
5228

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> A = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = A._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Q, = C.places_at_infinity()>>> pls.remove(Q)>>> code = codes.EvaluationAGCode(pls, Integer(3)*Q)>>> code.designed_distance()
5

generator_matrix()
Return a generator matrix of the code.
EXAMPLES:
sage: k.<a> = GF(4)sage: A.<x,y> = AffineSpace(k, 2)
sage: C = Curve(y^2 + y - x^3)
sage: F = C.function_field()sage: pls = F.places()sage: Q, = C.places_at_infinity()
sage: pls.remove(Q)sage: code = codes.EvaluationAGCode(pls, 3*Q)
sage: code.generator_matrix()
[
1
0
0
1
a a + 1
1
0]
[
0
1
0
1
1
0 a + 1
a]
[
0
0
1
1
a
a a + 1 a + 1]>>> from sage.all import *>>> k = GF(Integer(4), names=( a ,)); (a,) = k._first_ngens(1)>>> A = AffineSpace(k, Integer(2), names=( x , y ,)); (x, y,) = A._first_
˓→ngens(2)>>> C = Curve(y**Integer(2) + y - x**Integer(3))>>> F = C.function_field()>>> pls = F.places()>>> Q, = C.places_at_infinity()>>> pls.remove(Q)>>> code = codes.EvaluationAGCode(pls, Integer(3)*Q)>>> code.generator_matrix()
[
1
0
0
1
a a + 1
1
0]
[
0
1
0
1
1
0 a + 1
a]
[
0
0
1
1
a
a a + 1 a + 1]

In contrast, for some code families Sage can only construct their generator matrix and has no other a priori knowledge onthem:

11.10. AG codes229

Coding Theory, Release 10.4

11.11 Linear code constructors that do not preserve the structural
information
This file contains a variety of constructions which builds the generator matrix of special (or random) linear codes andwraps them in a sage.coding.linear_code.LinearCode object. These constructions are therefore not richobjects such as sage.coding.grs_code.GeneralizedReedSolomonCode.
All codes available here can be accessed through the codes object:
sage: codes.random_linear_code(GF(2), 5, 2)[5, 2] linear code over GF(2)>>> from sage.all import *>>> codes.random_linear_code(GF(Integer(2)), Integer(5), Integer(2))[5, 2] linear code over GF(2)REFERENCES:• [HP2003]
AUTHORS:• David Joyner (2007-05): initial version• David Joyner (2008-02): added cyclic codes, Hamming codes• David Joyner (2008-03): added BCH code, LinearCodeFromCheckmatrix, ReedSolomonCode, WalshCode,DuadicCodeEvenPair, DuadicCodeOddPair, QR codes (even and odd)
• David Joyner (2008-09) fix for bug in BCHCode reported by F. Voloch• David Joyner (2008-10) small docstring changes to WalshCode and walsh_matrix
sage.coding.code_constructions.DuadicCodeEvenPair(F, S1, S2)
Constructs the “even pair” of duadic codes associated to the “splitting” (see the docstring for _is_a_splitting
for the definition) S1, S2 of n.
Warning: Maybe the splitting should be associated to a sum of q-cyclotomic cosets mod n, where q is a prime.
EXAMPLES:
sage: from sage.coding.code_constructions import _is_a_splitting
sage: n = 11; q = 3
sage: C = Zmod(n).cyclotomic_cosets(q); C[[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]]sage: S1 = C[1]sage: S2 = C[2]sage: _is_a_splitting(S1,S2,11)
True
sage: codes.DuadicCodeEvenPair(GF(q),S1,S2)([11, 5] Cyclic Code over GF(3),[11, 5] Cyclic Code over GF(3))>>> from sage.all import *>>> from sage.coding.code_constructions import _is_a_splitting>>> n = Integer(11); q = Integer(3)(continues on next page)

230

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> C = Zmod(n).cyclotomic_cosets(q); C[[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]]>>> S1 = C[Integer(1)]>>> S2 = C[Integer(2)]>>> _is_a_splitting(S1,S2,Integer(11))
True>>> codes.DuadicCodeEvenPair(GF(q),S1,S2)([11, 5] Cyclic Code over GF(3),[11, 5] Cyclic Code over GF(3))

sage.coding.code_constructions.DuadicCodeOddPair(F, S1, S2)
Constructs the “odd pair” of duadic codes associated to the “splitting” S1, S2 of n.
Warning: Maybe the splitting should be associated to a sum of q-cyclotomic cosets mod n, where q is a prime.
EXAMPLES:
sage: from sage.coding.code_constructions import _is_a_splitting
sage: n = 11; q = 3
sage: C = Zmod(n).cyclotomic_cosets(q); C[[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]]sage: S1 = C[1]sage: S2 = C[2]sage: _is_a_splitting(S1,S2,11)
True
sage: codes.DuadicCodeOddPair(GF(q),S1,S2)([11, 6] Cyclic Code over GF(3),[11, 6] Cyclic Code over GF(3))>>> from sage.all import *>>> from sage.coding.code_constructions import _is_a_splitting>>> n = Integer(11); q = Integer(3)>>> C = Zmod(n).cyclotomic_cosets(q); C[[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]]>>> S1 = C[Integer(1)]>>> S2 = C[Integer(2)]>>> _is_a_splitting(S1,S2,Integer(11))
True>>> codes.DuadicCodeOddPair(GF(q),S1,S2)([11, 6] Cyclic Code over GF(3),[11, 6] Cyclic Code over GF(3))

This is consistent with Theorem 6.1.3 in [HP2003].
sage.coding.code_constructions.ExtendedQuadraticResidueCode(n, F)
The extended quadratic residue code (or XQR code) is obtained from a QR code by adding a check bit to thelast coordinate. (These codes have very remarkable properties such as large automorphism groups and duality
properties - see [HP2003], Section 6.6.3-6.6.4.)
INPUT:• n – an odd prime• F – a finite prime field whose order must be a quadratic residue modulo 𝑛.
OUTPUT: Returns an extended quadratic residue code.
11.11. Linear code constructors that do not preserve the structural information

231

Coding Theory, Release 10.4

EXAMPLES:
sage: C1 = codes.QuadraticResidueCode(7, GF(2))
sage: C2 = C1.extended_code()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
Extension of [17, 9] Cyclic Code over GF(2)sage: C3 = codes.QuadraticResidueCodeOddPair(7, GF(2))[0]sage: C3x = C3.extended_code()sage: C4 = codes.ExtendedQuadraticResidueCode(7, GF(2))
sage: C3x == C4
True>>> from sage.all import *>>> C1 = codes.QuadraticResidueCode(Integer(7), GF(Integer(2)))>>> C2 = C1.extended_code()>>> C3 = codes.ExtendedQuadraticResidueCode(Integer(7), GF(Integer(2))); C3
Extension of [7, 4] Cyclic Code over GF(2)>>> C2 == C3
True>>> C = codes.ExtendedQuadraticResidueCode(Integer(17), GF(Integer(2)))>>> C
Extension of [17, 9] Cyclic Code over GF(2)>>> C3 = codes.QuadraticResidueCodeOddPair(Integer(7), GF(Integer(2)))[Integer(0)]>>> C3x = C3.extended_code()>>> C4 = codes.ExtendedQuadraticResidueCode(Integer(7), GF(Integer(2)))>>> C3x == C4
True

AUTHORS:• David Joyner (07-2006)
sage.coding.code_constructions.QuadraticResidueCode(n, F)
A quadratic residue code (or QR code) is a cyclic code whose generator polynomial is the product of the polynomials
𝑥 − 𝛼𝑖 (𝛼 is a primitive 𝑛’th root of unity; 𝑖 ranges over the set of quadratic residues modulo 𝑛).
See QuadraticResidueCodeEvenPair and QuadraticResidueCodeOddPair for a more general
construction.
INPUT:• n – an odd prime• F – a finite prime field whose order must be a quadratic residue modulo 𝑛.
OUTPUT: Returns a quadratic residue code.
EXAMPLES:
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
[17, 9] Cyclic Code over GF(2)(continues on next page)

232

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

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 == C2
True>>> from sage.all import *>>> C = codes.QuadraticResidueCode(Integer(7), GF(Integer(2)))>>> C[7, 4] Cyclic Code over GF(2)>>> C = codes.QuadraticResidueCode(Integer(17), GF(Integer(2)))>>> C[17, 9] Cyclic Code over GF(2)>>> C1 = codes.QuadraticResidueCodeOddPair(Integer(7), GF(Integer(2)))[Integer(0)]>>> C2 = codes.QuadraticResidueCode(Integer(7), GF(Integer(2)))>>> C1 == C2
True>>> C1 = codes.QuadraticResidueCodeOddPair(Integer(17),␣
˓→GF(Integer(2)))[Integer(0)]>>> C2 = codes.QuadraticResidueCode(Integer(17), GF(Integer(2)))>>> C1 == C2
True

AUTHORS:• David Joyner (11-2005)
sage.coding.code_constructions.QuadraticResidueCodeEvenPair(n, F)
Quadratic residue codes of a given odd prime length and base ring either don’t exist at all or occur as 4-tuples - apair of “odd-like” codes and a pair of “even-like” codes. If 𝑛 > 2 is prime then (Theorem 6.6.2 in [HP2003]) a
QR code exists over F𝑞 iff q is a quadratic residue mod 𝑛.
They are constructed as “even-like” duadic codes associated the splitting (𝑄, 𝑁 ) mod 𝑛, where 𝑄 is the set of
non-zero quadratic residues and 𝑁 is the non-residues.
EXAMPLES:
sage: codes.QuadraticResidueCodeEvenPair(17, GF(13)) # known bug (#25896)([17, 8] Cyclic Code over GF(13),[17, 8] Cyclic Code over GF(13))
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)([13, 6] Cyclic Code over GF(9),[13, 6] Cyclic Code over GF(9))
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.systematic_generator_matrix() == C4.dual_code().systematic_generator_(continues on next page)

11.11. Linear code constructors that do not preserve the structural information

233

Coding Theory, Release 10.4

(continued from previous page)matrix()True˓→>>> from sage.all import *>>> codes.QuadraticResidueCodeEvenPair(Integer(17), GF(Integer(13))) # known bug␣˓→(#25896)([17, 8] Cyclic Code over GF(13),[17, 8] Cyclic Code over GF(13))>>> codes.QuadraticResidueCodeEvenPair(Integer(17), GF(Integer(2)))([17, 8] Cyclic Code over GF(2),[17, 8] Cyclic Code over GF(2))>>> codes.QuadraticResidueCodeEvenPair(Integer(13), GF(Integer(9),"z")) # known␣
˓→bug (#25896)([13, 6] Cyclic Code over GF(9),[13, 6] Cyclic Code over GF(9))>>> C1,C2 = codes.QuadraticResidueCodeEvenPair(Integer(7), GF(Integer(2)))>>> C1.is_self_orthogonal()
True>>> C2.is_self_orthogonal()
True>>> C3 = codes.QuadraticResidueCodeOddPair(Integer(17),␣
˓→GF(Integer(2)))[Integer(0)]>>> C4 = codes.QuadraticResidueCodeEvenPair(Integer(17),␣
˓→GF(Integer(2)))[Integer(1)]>>> C3.systematic_generator_matrix() == C4.dual_code().systematic_generator_
˓→matrix()
True

This is consistent with Theorem 6.6.9 and Exercise 365 in [HP2003].
sage.coding.code_constructions.QuadraticResidueCodeOddPair(n, F)
Quadratic residue codes of a given odd prime length and base ring either don’t exist at all or occur as 4-tuples - apair 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 F𝑞 𝑖𝑓 𝑓 𝑞 is a quadratic residue mod 𝑛.
They are constructed as “odd-like” duadic codes associated the splitting (𝑄, 𝑁 ) mod 𝑛, where 𝑄 is the set of
non-zero quadratic residues and 𝑁 is the non-residues.
EXAMPLES:
sage: codes.QuadraticResidueCodeOddPair(17, GF(13)) # known bug (#25896)([17, 9] Cyclic Code over GF(13),[17, 9] Cyclic Code over GF(13))
sage: codes.QuadraticResidueCodeOddPair(17, GF(2))([17, 9] Cyclic Code over GF(2),[17, 9] Cyclic Code over GF(2))
sage: codes.QuadraticResidueCodeOddPair(13, GF(9,"z")) # known bug (#25896)([13, 7] Cyclic Code over GF(9),[13, 7] Cyclic Code over GF(9))
sage: C1 = codes.QuadraticResidueCodeOddPair(17, GF(2))[1]sage: C1x = C1.extended_code()sage: C2 = codes.QuadraticResidueCodeOddPair(17, GF(2))[0]sage: C2x = C2.extended_code()sage: C2x.spectrum(); C1x.spectrum()[1, 0, 0, 0, 0, 0, 102, 0, 153, 0, 153, 0, 102, 0, 0, 0, 0, 0, 1][1, 0, 0, 0, 0, 0, 102, 0, 153, 0, 153, 0, 102, 0, 0, 0, 0, 0, 1]
sage: C3 = codes.QuadraticResidueCodeOddPair(7, GF(2))[0](continues on next page)

234

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

sage: C3x = C3.extended_code()sage: C3x.spectrum()[1, 0, 0, 0, 14, 0, 0, 0, 1]>>> from sage.all import *>>> codes.QuadraticResidueCodeOddPair(Integer(17), GF(Integer(13))) # known bug (˓→#25896)([17, 9] Cyclic Code over GF(13),[17, 9] Cyclic Code over GF(13))>>> codes.QuadraticResidueCodeOddPair(Integer(17), GF(Integer(2)))([17, 9] Cyclic Code over GF(2),[17, 9] Cyclic Code over GF(2))>>> codes.QuadraticResidueCodeOddPair(Integer(13), GF(Integer(9),"z")) # known␣
˓→bug (#25896)([13, 7] Cyclic Code over GF(9),[13, 7] Cyclic Code over GF(9))>>> C1 = codes.QuadraticResidueCodeOddPair(Integer(17),␣
˓→GF(Integer(2)))[Integer(1)]>>> C1x = C1.extended_code()>>> C2 = codes.QuadraticResidueCodeOddPair(Integer(17),␣
˓→GF(Integer(2)))[Integer(0)]>>> C2x = C2.extended_code()>>> C2x.spectrum(); C1x.spectrum()[1, 0, 0, 0, 0, 0, 102, 0, 153, 0, 153, 0, 102, 0, 0, 0, 0, 0, 1][1, 0, 0, 0, 0, 0, 102, 0, 153, 0, 153, 0, 102, 0, 0, 0, 0, 0, 1]>>> C3 = codes.QuadraticResidueCodeOddPair(Integer(7), GF(Integer(2)))[Integer(0)]>>> C3x = C3.extended_code()>>> C3x.spectrum()[1, 0, 0, 0, 14, 0, 0, 0, 1]This is consistent with Theorem 6.6.14 in [HP2003].
sage.coding.code_constructions.ToricCode(P, F)
Let 𝑃 denote a list of lattice points in 𝑑 and let 𝑇 denote the set of all points in (𝐹 𝑥 )𝑑 (ordered in some fixedway). Put 𝑛 = |𝑇 | and let 𝑘 denote the dimension of the vector space of functions 𝑉 = Span{𝑥𝑒 | 𝑒 ∈ 𝑃 }. The
associated toric code 𝐶 is the evaluation code which is the image of the evaluation map
eval𝑇 : 𝑉 → 𝐹 𝑛 ,where 𝑥𝑒 is the multi-index notation (𝑥 = (𝑥1 , ..., 𝑥𝑑 ), 𝑒 = (𝑒1 , ..., 𝑒𝑑 ), and 𝑥𝑒 = 𝑥𝑒11 ...𝑥𝑒𝑑𝑑 ), where
eval𝑇 (𝑓 (𝑥)) = (𝑓 (𝑡1 ), ..., 𝑓 (𝑡𝑛 )), and where 𝑇 = {𝑡1 , ..., 𝑡𝑛 }. This function returns the toric codes discussed in[Joy2004].
INPUT:• P – all the integer lattice points in a polytope defining the toric variety.
• F – a finite field.
OUTPUT: Returns toric code with length n = , dimension k over field F.
EXAMPLES:
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()
˓→needs sage.groups#␣(continues on next page)

11.11. Linear code constructors that do not preserve the structural information

235

Coding Theory, Release 10.4

(continued from previous page)24
sage: C.minimum_distance(algorithm="guava") # optional - gap_package_guava...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
[16, 9] linear code over GF(5)sage: C.minimum_distance()
˓→needs sage.groups6
sage: C.minimum_distance(algorithm="guava") # optional - gap_package_guava
6sage: 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)#␣>>> from sage.all import *>>> C = codes.ToricCode([[Integer(0),Integer(0)],[Integer(1),Integer(0)],˓→[Integer(2),Integer(0)],[Integer(0),Integer(1)],[Integer(1),Integer(1)]],␣
˓→GF(Integer(7)))>>> C[36, 5] linear code over GF(7)>>> C.minimum_distance()#␣˓→needs sage.groups
24>>> C.minimum_distance(algorithm="guava") # optional - gap_package_guava...24>>> C = codes.ToricCode([[-Integer(2),-Integer(2)],[-Integer(1),-Integer(2)],[˓→Integer(1),-Integer(1)],[-Integer(1),Integer(0)],...
[Integer(0),-Integer(1)],[Integer(0),Integer(0)],˓→[Integer(0),Integer(1)],[Integer(1),-Integer(1)],[Integer(1),Integer(0)]],␣
˓→GF(Integer(5)))>>> C[16, 9] linear code over GF(5)>>> C.minimum_distance()#␣˓→needs sage.groups
6>>> C.minimum_distance(algorithm="guava") # optional - gap_package_guava
6>>> C = codes.ToricCode([[Integer(0),Integer(0)],[Integer(1),Integer(1)],
˓→[Integer(1),Integer(2)],[Integer(1),Integer(3)],[Integer(1),Integer(4)],
˓→[Integer(2),Integer(1)],...
[Integer(2),Integer(2)],[Integer(2),Integer(3)],
˓→[Integer(3),Integer(1)],[Integer(3),Integer(2)],[Integer(4),Integer(1)]],␣
˓→GF(Integer(8),"a"))>>> C[49, 11] linear code over GF(8)This is in fact a [49,11,28] code over F8 . If you type next C.minimum_distance() and wait overnight (!),
you should get 28.
AUTHOR:• David Joyner (07-2006)
sage.coding.code_constructions.WalshCode(m)Return the binary Walsh code of length 2𝑚 .
236

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

The matrix of codewords correspond to a Hadamard matrix. This is a (constant rate) binary linear [2𝑚 , 𝑚, 2𝑚−1 ]code.
EXAMPLES:
sage: C = codes.WalshCode(4); C[16, 4] linear code over GF(2)sage: C = codes.WalshCode(3); C[8, 3] linear code over GF(2)sage: C.spectrum()[1, 0, 0, 0, 7, 0, 0, 0, 0]
sage: C.minimum_distance()
˓→needs sage.libs.gap
4
sage: C.minimum_distance(algorithm= gap )˓→needs sage.libs.gap
4>>> from sage.all import *>>> C = codes.WalshCode(Integer(4)); C[16, 4] linear code over GF(2)>>> C = codes.WalshCode(Integer(3)); C[8, 3] linear code over GF(2)>>> C.spectrum()[1, 0, 0, 0, 7, 0, 0, 0, 0]>>> C.minimum_distance()
˓→needs sage.libs.gap
4>>> C.minimum_distance(algorithm= gap )˓→needs sage.libs.gap
4#␣# check d=2^(m-1)#␣#␣# check d=2^(m-1)#␣

REFERENCES:• Wikipedia article Hadamard_matrix• Wikipedia article Walsh_code
sage.coding.code_constructions.from_parity_check_matrix(H)Return the linear code that has H as a parity check matrix.
If H has dimensions ℎ × 𝑛 then the linear code will have dimension 𝑛 − ℎ and length 𝑛.
EXAMPLES:
sage: C = codes.HammingCode(GF(2), 3); C[7, 4] Hamming Code over GF(2)sage: H = C.parity_check_matrix(); H[1 0 1 0 1 0 1]
[0 1 1 0 0 1 1]
[0 0 0 1 1 1 1]
sage: C2 = codes.from_parity_check_matrix(H); C2[7, 4] linear code over GF(2)sage: C2.systematic_generator_matrix() == C.systematic_generator_matrix()True>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(2)), Integer(3)); C[7, 4] Hamming Code over GF(2)(continues on next page)

11.11. Linear code constructors that do not preserve the structural information

237

Coding Theory, Release 10.4

(continued from previous page)>>> H = C.parity_check_matrix(); H[1 0 1 0 1 0 1]
[0 1 1 0 0 1 1]
[0 0 0 1 1 1 1]>>> C2 = codes.from_parity_check_matrix(H); C2[7, 4] linear code over GF(2)>>> C2.systematic_generator_matrix() == C.systematic_generator_matrix()
Truesage.coding.code_constructions.permutation_action(g, v)
Returns permutation of rows 𝑔 * 𝑣.
Works on lists, matrices, sequences and vectors (by permuting coordinates). The code requires switching from 𝑖 to
𝑖 + 1 (and back again) since the SymmetricGroup is, by convention, the symmetric group on the “letters” 1, 2,…, 𝑛 (not 0, 1, …, 𝑛 − 1).
EXAMPLES:
sage: # needs sage.groups
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)(1, 2, 0, 0, 1)
sage: g = G([()])
sage: permutation_action(g,v)(0, 1, 2, 0, 1)
sage: g = G([(1,2,3,4,5)])
sage: permutation_action(g,v)(1, 2, 0, 1, 0)
sage: L = Sequence([1,2,3,4,5])
sage: permutation_action(g,L)[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: 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)[0 1 0 1 0 1 0]
[0 0 0 0 0 0 1]
[1 0 0 0 1 1 0]>>> from sage.all import *>>> # needs sage.groups>>> V = VectorSpace(GF(Integer(3)),Integer(5))>>> v = V([Integer(0),Integer(1),Integer(2),Integer(0),Integer(1)])>>> G = SymmetricGroup(Integer(5))>>> g = G([(Integer(1),Integer(2),Integer(3))])>>> permutation_action(g,v)(1, 2, 0, 0, 1)>>> g = G([()])>>> permutation_action(g,v)

238(continues on next page)

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)(0, 1, 2, 0, 1)>>> g = G([(Integer(1),Integer(2),Integer(3),Integer(4),Integer(5))])>>> permutation_action(g,v)(1, 2, 0, 1, 0)>>> L = Sequence([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)])>>> permutation_action(g,L)[2, 3, 4, 5, 1]>>> MS = MatrixSpace(GF(Integer(3)),Integer(3),Integer(7))>>> A = MS([[Integer(1),Integer(0),Integer(0),Integer(0),Integer(1),Integer(1),˓→Integer(0)],[Integer(0),Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0)],[Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(1)]])>>> S5 = SymmetricGroup(Integer(5))>>> g = S5([(Integer(1),Integer(2),Integer(3))])>>> A[1 0 0 0 1 1 0]
[0 1 0 1 0 1 0]
[0 0 0 0 0 0 1]>>> permutation_action(g,A)[0 1 0 1 0 1 0]
[0 0 0 0 0 0 1]
[1 0 0 0 1 1 0]

It also works on lists and is a “left action”:
sage: # needs sage.groups
sage: v = [0,1,2,0,1]
sage: G = SymmetricGroup(5)sage: g = G([(1,2,3)])
sage: gv = permutation_action(g,v); gv[1, 2, 0, 0, 1]
sage: permutation_action(g,v) == g(v)Truesage: h = G([(3,4)])
sage: gv = permutation_action(g,v)
sage: hgv = permutation_action(h,gv)
sage: hgv == permutation_action(h*g,v)
True>>> from sage.all import *>>> # needs sage.groups>>> v = [Integer(0),Integer(1),Integer(2),Integer(0),Integer(1)]>>> G = SymmetricGroup(Integer(5))>>> g = G([(Integer(1),Integer(2),Integer(3))])>>> gv = permutation_action(g,v); gv[1, 2, 0, 0, 1]>>> permutation_action(g,v) == g(v)True>>> h = G([(Integer(3),Integer(4))])>>> gv = permutation_action(g,v)>>> hgv = permutation_action(h,gv)>>> hgv == permutation_action(h*g,v)
True

AUTHORS:• David Joyner, licensed under the GPL v2 or greater.

11.11. Linear code constructors that do not preserve the structural information

239

Coding Theory, Release 10.4

sage.coding.code_constructions.random_linear_code(F, length, dimension)
Generate a random linear code of length length, dimension dimension and over the field F.
This function is Las Vegas probabilistic: always correct, usually fast. Random matrices over the F are drawn until
one with full rank is hit.
If F is infinite, the distribution of the elements in the random generator matrix will be random according to the
distribution of F.random_element().
EXAMPLES:
sage: C = codes.random_linear_code(GF(2), 10, 3)
sage: C
[10, 3] linear code over GF(2)sage: C.generator_matrix().rank()
3>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(2)), Integer(10), Integer(3))>>> C[10, 3] linear code over GF(2)>>> C.generator_matrix().rank()
3sage.coding.code_constructions.walsh_matrix(m0)This is the generator matrix of a Walsh code. The matrix of codewords correspond to a Hadamard matrix.
EXAMPLES:
sage: walsh_matrix(2)[0 0 1 1][0 1 0 1]
sage: walsh_matrix(3)[0 0 0 0 1 1 1 1]
[0 0 1 1 0 0 1 1]
[0 1 0 1 0 1 0 1]
sage: C = LinearCode(walsh_matrix(4)); C[16, 4] linear code over GF(2)sage: C.spectrum()[1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0]>>> from sage.all import *>>> walsh_matrix(Integer(2))[0 0 1 1][0 1 0 1]>>> walsh_matrix(Integer(3))[0 0 0 0 1 1 1 1]
[0 0 1 1 0 0 1 1]
[0 1 0 1 0 1 0 1]>>> C = LinearCode(walsh_matrix(Integer(4))); C[16, 4] linear code over GF(2)>>> C.spectrum()[1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0]This last code has minimum distance 8.
REFERENCES:• Wikipedia article Hadamard_matrix
240

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

11.12 Constructions of generator matrices using the GUAVA package for GAPThis module only contains Guava wrappers (GUAVA is an optional GAP package).
AUTHORS:• David Joyner (2005-11-22, 2006-12-03): initial version• Nick Alexander (2006-12-10): factor GUAVA code to guava.py• David Joyner (2007-05): removed Golay codes, toric and trivial codes and placed them in code_constructions;renamed RandomLinearCode to RandomLinearCodeGuava• David Joyner (2008-03): removed QR, XQR, cyclic and ReedSolomon codes• David Joyner (2009-05): added “optional package” comments, fixed some docstrings to be sphinx compatible• Dima Pasechnik (2019-11): port to libgap
sage.coding.guava.QuasiQuadraticResidueCode(p)A (binary) quasi-quadratic residue code (or QQR code).
Follows the definition of Proposition 2.2 in [BM2003]. The code has a generator matrix in the block form 𝐺 =(𝑄, 𝑁 ). Here 𝑄 is a 𝑝 × 𝑝 circulant matrix whose top row is (0, 𝑥1 , ..., 𝑥𝑝−1 ), where 𝑥𝑖 = 1 if and only if 𝑖 is aquadratic residue mod 𝑝, and 𝑁 is a 𝑝 × 𝑝 circulant matrix whose top row is (0, 𝑦1 , ..., 𝑦𝑝−1 ), where 𝑥𝑖 + 𝑦𝑖 = 1
for all 𝑖.
INPUT:• p – a prime > 2.
OUTPUT:
Returns a QQR code of length 2𝑝.
EXAMPLES:
sage: C = codes.QuasiQuadraticResidueCode(11); C[22, 11] linear code over GF(2)# optional - gap_package_guava>>> from sage.all import *>>> C = codes.QuasiQuadraticResidueCode(Integer(11)); C˓→package_guava[22, 11] linear code over GF(2)# optional - gap_

These are self-orthogonal in general and self-dual when 𝑝 ≡ 3 (mod 4).
AUTHOR: David Joyner (11-2005)
sage.coding.guava.RandomLinearCodeGuava(n, k, F)
The method used is to first construct a 𝑘 × 𝑛 matrix of the block form (𝐼, 𝐴), where 𝐼 is a 𝑘 × 𝑘 identity matrix
and 𝐴 is a 𝑘 × (𝑛 − 𝑘) matrix constructed using random elements of 𝐹 . Then the columns are permuted using arandomly selected element of the symmetric group 𝑆𝑛 .
INPUT:• n, k – integers with 𝑛 > 𝑘 > 1.
OUTPUT:
Returns a “random” linear code with length 𝑛, dimension 𝑘 over field 𝐹 .

11.12. Constructions of generator matrices using the GUAVA package for GAP

241

Coding Theory, Release 10.4

EXAMPLES:
sage: C = codes.RandomLinearCodeGuava(30,15,GF(2)); C˓→package_guava[30, 15] linear code over GF(2)sage: C = codes.RandomLinearCodeGuava(10,5,GF(4, a )); C˓→package_guava[10, 5] linear code over GF(4)# optional - gap_

# optional - gap_>>> from sage.all import *>>> C = codes.RandomLinearCodeGuava(Integer(30),Integer(15),GF(Integer(2))); C␣˓→# optional - gap_package_guava[30, 15] linear code over GF(2)>>> C = codes.RandomLinearCodeGuava(Integer(10),Integer(5),GF(Integer(4), a )); C␣˓→# optional - gap_package_guava[10, 5] linear code over GF(4)AUTHOR: David Joyner (11-2005)

11.13 Enumerating binary self-dual codes
This module implements functions useful for studying binary self-dual codes. 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• "code" – a sd code 𝐶 of length 𝑛, dim 𝑛/2, over F2• "order autgp" – order of the permutation automorphism group of 𝐶
• "Type" – the type of 𝐶 (which can be "I" or "II", in the binary case)• "spectrum" – the spectrum [𝐴0 , 𝐴1 , ..., 𝐴𝑛 ]• "Comment" – possibly an empty string.
Python dictionaries were used since they seemed to be both human-readable and allow others to update the databaseeasiest.
• 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:
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())>>> from sage.all import *>>> for n in [Integer(4),Integer(6),Integer(8),Integer(10),Integer(12),
˓→Integer(14),Integer(16),Integer(18),Integer(20),Integer(22)]:
˓→not tested...
C = self_dual_binary_codes(n); m = len(C.keys())#␣(continues on next page)242

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

...
...
...
...
...
...

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:
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()]])>>> from sage.all import *>>> R = PolynomialRing(CC,"T")# not tested>>> T = R.gen()# not tested>>> for n in [Integer(4),Integer(6),Integer(8),Integer(10),Integer(12),
˓→Integer(14),Integer(16),Integer(18),Integer(20),Integer(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()>Integer(2):...
f = R(C0.sd_zeta_polynomial())...
print([n,i,[z[Integer(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 𝑚, let 𝐴𝑚 denote the 𝑚 × 𝑚 matrix over F2 given by adding the all 1’s matrix to the identity matrix (inMatrixSpace(GF(2),m,m) of course). If 𝑀1 , ..., 𝑀𝑟 are square matrices, let 𝑑𝑖𝑎𝑔(𝑀1 , 𝑀2 , ..., 𝑀𝑟 ) denote the“block diagonal” matrix with the matrices 𝑀𝑖 on the diagonal and 0’s elsewhere. Let 𝐶(𝑚1 , ..., 𝑚𝑟 , 𝑠) denote the linear
code with generator matrix having block form 𝐺 = (𝐼, 𝐴), where 𝐴 = 𝑑𝑖𝑎𝑔(𝐴𝑚1 , 𝐴𝑚2 , ..., 𝐴𝑚𝑟 , 𝐼𝑠 ), for some (even)𝑚𝑖 ’s and 𝑠, where 𝑚1 + 𝑚2 + ... + 𝑚𝑟 + 𝑠 = 𝑛/2. Note: Such codes 𝐶(𝑚1 , ..., 𝑚𝑟 , 𝑠) are SD.
SD codes not of this form will be called (for the purpose of documenting the code below) “exceptional”. Except when 𝑛
is “small”, most sd codes are exceptional (based on a counting argument and table 9.1 in the Huffman+Pless [HP2003],
page 347).

AUTHORS:• David Joyner (2007-08-11)
REFERENCES:• [HP2003] W. C. Huffman, V. Pless, Fundamentals of Error-Correcting Codes, Cambridge Univ. Press, 2003.
• [P] V. Pless, A classification of self-orthogonal codes over GF(2), Discrete Math 3 (1972) 209-246.

11.13. Enumerating binary self-dual codes243

Coding Theory, Release 10.4

sage.coding.self_dual_codes.self_dual_binary_codes(n)Return the dictionary of inequivalent binary self dual codes of length 𝑛.
For 𝑛 = 4 even, returns the sd codes of a given length, up to (perm) equivalence, the (perm) aut gp, and the type.
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 𝑛, where only
∏︀ integers from the set 1, 4, 6, 8, …
are allowed. This is the coefficient of 𝑥𝑛 in the series expansion (1 − 𝑥)−1 2∞ (1−𝑥2𝑗 )−1 . Typing the commandf = (1-x)(-1)\*prod([(1-x(2\*j))(-1) for j in range(2,18)]) into Sage, we obtainfor the coeffs of 𝑥4 , 𝑥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 𝐵𝑛 of inequivalent sd binary codesof length 𝑛 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

According to http://oeis.org/classic/A003179, the next 2 entries are: 3295, 24147.
EXAMPLES:
sage: C = codes.databases.self_dual_binary_codes(10)sage: C["10"]["0"]["code"] == C["10"]["0"]["code"].dual_code()Truesage: C["10"]["1"]["code"] == C["10"]["1"]["code"].dual_code()Truesage: len(C["10"].keys()) # number of inequiv sd codes of length 10
2sage: C = codes.databases.self_dual_binary_codes(12)sage: C["12"]["0"]["code"] == C["12"]["0"]["code"].dual_code()Truesage: C["12"]["1"]["code"] == C["12"]["1"]["code"].dual_code()Truesage: C["12"]["2"]["code"] == C["12"]["2"]["code"].dual_code()True>>> from sage.all import *>>> C = codes.databases.self_dual_binary_codes(Integer(10))>>> C["10"]["0"]["code"] == C["10"]["0"]["code"].dual_code()
True>>> C["10"]["1"]["code"] == C["10"]["1"]["code"].dual_code()
True>>> len(C["10"].keys()) # number of inequiv sd codes of length 10
2>>> C = codes.databases.self_dual_binary_codes(Integer(12))>>> C["12"]["0"]["code"] == C["12"]["0"]["code"].dual_code()
True>>> C["12"]["1"]["code"] == C["12"]["1"]["code"].dual_code()
True>>> C["12"]["2"]["code"] == C["12"]["2"]["code"].dual_code()
True

244

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

11.14 Optimized low-level binary code representation
Some computations with linear binary codes. Fix a basis for F𝑛2 . A linear binary code is a linear subspace of F𝑛2 , together
with this choice of basis. A permutation 𝑔 ∈ 𝑆𝑛 of the fixed basis gives rise to a permutation of the vectors, or words, in
F𝑛2 , sending (𝑤𝑖 ) to (𝑤𝑔(𝑖) ). The permutation automorphism group of the code 𝐶 is the set of permutations of the basisthat bijectively map 𝐶 to itself. Note that if 𝑔 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 F2 , the only scalars are 0 and 1, so the linearity condition has trivial effect.
AUTHOR:• Robert L Miller (Oct-Nov 2007)• compiled code data structure• union-find based orbit partition• optimized partition stack class• NICE-based partition refinement algorithm• canonical generation function
class sage.coding.binary_code.BinaryCode
Bases: object
Minimal, but optimized, binary code object.
EXAMPLES:
sage: import sage.coding.binary_code
sage: from sage.coding.binary_code import *sage: M = Matrix(GF(2), [[1,1,1,1]])
sage: B = BinaryCode(M)# create from matrix
sage: C = BinaryCode(B, 60) # create using glue
sage: D = BinaryCode(C, 240)
sage: E = BinaryCode(D, 85)
sage: B
Binary [4,1] linear code, generator matrix[1111]
sage: C
Binary [6,2] linear code, generator matrix[111100][001111]sage: D
Binary [8,3] linear code, generator matrix[11110000][00111100][00001111]
sage: E
Binary [8,4] linear code, generator matrix[11110000][00111100][00001111][10101010]
sage: M = Matrix(GF(2), [[1]*32])(continues on next page)

11.14. Optimized low-level binary code representation

245

Coding Theory, Release 10.4

(continued from previous page)

sage: B = BinaryCode(M)sage: B
Binary [32,1] linear code, generator matrix[11111111111111111111111111111111]>>> from sage.all import *>>> import sage.coding.binary_code>>> from sage.coding.binary_code import *>>> M = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(1)]])>>> B = BinaryCode(M)# create from matrix>>> C = BinaryCode(B, Integer(60)) # create using glue>>> D = BinaryCode(C, Integer(240))>>> E = BinaryCode(D, Integer(85))>>> B
Binary [4,1] linear code, generator matrix[1111]>>> C
Binary [6,2] linear code, generator matrix[111100][001111]>>> D
Binary [8,3] linear code, generator matrix[11110000][00111100][00001111]>>> E
Binary [8,4] linear code, generator matrix[11110000][00111100][00001111][10101010]>>> M = Matrix(GF(Integer(2)), [[Integer(1)]*Integer(32)])>>> B = BinaryCode(M)>>> B
Binary [32,1] linear code, generator matrix[11111111111111111111111111111111]

apply_permutation(labeling)
Apply a column permutation to the code.
INPUT:• labeling – a list permutation of the columns
EXAMPLES:
sage: from sage.coding.binary_code import *sage: B = BinaryCode(codes.GolayCode(GF(2)).generator_matrix())
sage: B
Binary [24,12] linear code, generator matrix[100000000000101011100011][010000000000111110010010][001000000000110100101011][000100000000110001110110][000010000000110011011001][000001000000011001101101](continues on next page)

246

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)[000000100000001100110111][000000010000101101111000][000000001000010110111100][000000000100001011011110][000000000010101110001101][000000000001010111000111]
sage: B.apply_permutation(list(range(11,-1,-1)) + list(range(12, 24)))
sage: B
Binary [24,12] linear code, generator matrix[000000000001101011100011][000000000010111110010010][000000000100110100101011][000000001000110001110110][000000010000110011011001][000000100000011001101101][000001000000001100110111][000010000000101101111000][000100000000010110111100][001000000000001011011110][010000000000101110001101][100000000000010111000111]>>> from sage.all import *>>> from sage.coding.binary_code import *>>> B = BinaryCode(codes.GolayCode(GF(Integer(2))).generator_matrix())>>> B
Binary [24,12] linear code, generator matrix[100000000000101011100011][010000000000111110010010][001000000000110100101011][000100000000110001110110][000010000000110011011001][000001000000011001101101][000000100000001100110111][000000010000101101111000][000000001000010110111100][000000000100001011011110][000000000010101110001101][000000000001010111000111]>>> B.apply_permutation(list(range(Integer(11),-Integer(1),-Integer(1))) +␣˓→list(range(Integer(12), Integer(24))))>>> B
Binary [24,12] linear code, generator matrix[000000000001101011100011][000000000010111110010010][000000000100110100101011][000000001000110001110110][000000010000110011011001][000000100000011001101101][000001000000001100110111][000010000000101101111000][000100000000010110111100][001000000000001011011110][010000000000101110001101][100000000000010111000111]

matrix()11.14. Optimized low-level binary code representation

247

Coding Theory, Release 10.4

Return the generator matrix of the 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: from sage.coding.binary_code import *sage: B = BinaryCode(M)sage: B.matrix()[1 1 1 1 0 0]
[0 0 1 1 1 1]>>> from sage.all import *>>> M = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(1),˓→Integer(0),Integer(0)], [Integer(0),Integer(0),Integer(1),Integer(1),˓→Integer(1),Integer(1)]])>>> from sage.coding.binary_code import *>>> B = BinaryCode(M)>>> B.matrix()[1 1 1 1 0 0]
[0 0 1 1 1 1]

print_data()
Print all data for self.
EXAMPLES:
sage: # needs sage.graphs
sage: import sage.coding.binary_code
sage: from sage.coding.binary_code import *sage: M = Matrix(GF(2), [[1,1,1,1]])
sage: B = BinaryCode(M)sage: C = BinaryCode(B, 60)
sage: D = BinaryCode(C, 240)
sage: E = BinaryCode(D, 85)
sage: B.print_data() # random - actually "print(P.print_data())"
ncols: 4nrows: 1
nwords: 2
radix: 32
basis:
1111
words:
0000
1111
sage: C.print_data() # random - actually "print(P.print_data())"
ncols: 6nrows: 2
nwords: 4
radix: 32
basis:
111100001111words:
000000111100001111110011
sage: D.print_data() # random - actually "print(P.print_data())"(continues on next page)

248

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)ncols: 8nrows: 3
nwords: 8
radix: 32
basis:
11110000
00111100
00001111
words:
00000000
11110000
00111100
11001100
00001111
11111111
00110011
11000011
sage: E.print_data() # random - actually "print(P.print_data())"
ncols: 8nrows: 4
nwords: 16
radix: 32
basis:
11110000
00111100
00001111
10101010
words:
00000000
11110000
00111100
11001100
00001111
11111111
00110011
11000011
10101010
01011010
1001011001100110
10100101
01010101
10011001
01101001>>> from sage.all import *>>> # needs sage.graphs>>> import sage.coding.binary_code>>> from sage.coding.binary_code import *>>> M = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),˓→Integer(1)]])>>> B = BinaryCode(M)>>> C = BinaryCode(B, Integer(60))>>> D = BinaryCode(C, Integer(240))>>> E = BinaryCode(D, Integer(85))>>> B.print_data() # random - actually "print(P.print_data())"(continues on next page)

11.14. Optimized low-level binary code representation

249

Coding Theory, Release 10.4

(continued from previous page)ncols: 4nrows: 1
nwords: 2
radix: 32
basis:
1111
words:
0000
1111>>> C.print_data() # random - actually "print(P.print_data())"
ncols: 6nrows: 2
nwords: 4
radix: 32
basis:
111100001111words:
000000111100001111110011>>> D.print_data() # random - actually "print(P.print_data())"
ncols: 8nrows: 3
nwords: 8
radix: 32
basis:
11110000
00111100
00001111
words:
00000000
11110000
00111100
11001100
00001111
11111111
00110011
11000011>>> E.print_data() # random - actually "print(P.print_data())"
ncols: 8nrows: 4
nwords: 16
radix: 32
basis:
11110000
00111100
00001111
10101010
words:
00000000
11110000
00111100
11001100
00001111
11111111(continues on next page)

250

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)00110011
11000011
10101010
01011010
1001011001100110
10100101
01010101
10011001
01101001

put_in_std_form()
Put the code in binary form, which is defined by an identity matrix on the left, augmented by a matrix of data.
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: B = BinaryCode(M); B
Binary [6,2] linear code, generator matrix[111100][001111]sage: B.put_in_std_form(); B
0Binary [6,2] linear code, generator matrix[101011][010111]>>> from sage.all import *>>> from sage.coding.binary_code import *>>> M = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(1),˓→Integer(0),Integer(0)], [Integer(0),Integer(0),Integer(1),Integer(1),˓→Integer(1),Integer(1)]])>>> B = BinaryCode(M); B
Binary [6,2] linear code, generator matrix[111100][001111]>>> B.put_in_std_form(); B
0Binary [6,2] linear code, generator matrix[101011][010111]class sage.coding.binary_code.BinaryCodeClassifier
Bases: object
generate_children(B, n, d=2)
Use canonical augmentation to generate children of the code 𝐵.
INPUT:• B – a BinaryCode• n – limit on the degree of the code
• d – test whether new vector has weight divisible by 𝑑. If 𝑑 = 4, this ensures that all doubly-evencanonically augmented children are generated.

11.14. Optimized low-level binary code representation

251

Coding Theory, Release 10.4

EXAMPLES:
sage: from sage.coding.binary_code import *sage: BC = BinaryCodeClassifier()
sage: B = BinaryCode(Matrix(GF(2), [[1,1,1,1]]))
sage: BC.generate_children(B, 6, 4)
˓→needs sage.groups[[1 1 1 1 0 0]
[0 1 0 1 1 1]]#␣>>> from sage.all import *>>> from sage.coding.binary_code import *>>> BC = BinaryCodeClassifier()>>> B = BinaryCode(Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),˓→Integer(1)]]))>>> BC.generate_children(B, Integer(6), Integer(4))␣˓→# needs sage.groups[[1 1 1 1 0 0]
[0 1 0 1 1 1]]

Note: The function codes.databases.self_orthogonal_binary_codes makes heavy use ofthis function.
MORE EXAMPLES:
sage: # needs sage.groups
sage: soc_iter = codes.databases.self_orthogonal_binary_codes(12, 6, 4)
sage: L = list(soc_iter)
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])....:print(s)n= 0 :
000000n= 1 :
000000n= 2 :
000000n= 3 :
000000n= 4 :
100000n= 5 :
000000n= 6 :
01
00
00n= 7 :
001
000n= 8 :
11
1
1
00
n= 9 :
000000n=10 :
01
1
1
00n=11 :
001
1
00n=12 :
12
3
4
2
0>>> from sage.all import *>>> # needs sage.groups>>> soc_iter = codes.databases.self_orthogonal_binary_codes(Integer(12),␣
(continues on next page)

252

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

Integer(6), Integer(4))>>> L = list(soc_iter)>>> for n in range(Integer(13)):...
s = n=%2d : %n...
for k in range(Integer(1),Integer(7)):...
s += %3d %len([C for C in L...
if C.length() == n and C.dimension() == k])...
print(s)n= 0 :
000000n= 1 :
000000n= 2 :
000000n= 3 :
000000n= 4 :
100000n= 5 :
000000n= 6 :
01
00
00n= 7 :
001
000n= 8 :
11
1
1
00
n= 9 :
000000n=10 :
01
1
1
00n=11 :
001
1
00n=12 :
1
2
3
4
2
0
˓→

put_in_canonical_form(B)Puts the code into canonical form.
Canonical form is obtained by performing row reduction, permuting the pivots to the front so that the generator
matrix is of the form: the identity matrix augmented to the right by arbitrary data.
EXAMPLES:
sage: from sage.coding.binary_code import *sage: BC = BinaryCodeClassifier()
sage: B = BinaryCode(codes.GolayCode(GF(2)).generator_matrix())
sage: B.apply_permutation(list(range(24,-1,-1)))
sage: B
Binary [24,12] linear code, generator matrix[011000111010100000000000][001001001111100000000001][011010100101100000000010][001101110001100000000100][010011011001100000001000][010110110011000000010000][011101100110000000100000][000011110110100001000000][000111101101000010000000][001111011010000100000000][010110001110101000000000][011100011101010000000000]
sage: BC.put_in_canonical_form(B)sage: B
Binary [24,12] linear code, generator matrix[100000000000001100111001][010000000000001010001111][001000000000001111010010][000100000000010110101010][000010000000010110010101][000001000000010001101101](continues on next page)

11.14. Optimized low-level binary code representation

253

Coding Theory, Release 10.4

(continued from previous page)[000000100000011000110110][000000010000011111001001][000000001000010101110011][000000000100010011011110][000000000010001011110101][000000000001001101101110]>>> from sage.all import *>>> from sage.coding.binary_code import *>>> BC = BinaryCodeClassifier()>>> B = BinaryCode(codes.GolayCode(GF(Integer(2))).generator_matrix())>>> B.apply_permutation(list(range(Integer(24),-Integer(1),-Integer(1))))>>> B
Binary [24,12] linear code, generator matrix[011000111010100000000000][001001001111100000000001][011010100101100000000010][001101110001100000000100][010011011001100000001000][010110110011000000010000][011101100110000000100000][000011110110100001000000][000111101101000010000000][001111011010000100000000][010110001110101000000000][011100011101010000000000]>>> BC.put_in_canonical_form(B)>>> B
Binary [24,12] linear code, generator matrix[100000000000001100111001][010000000000001010001111][001000000000001111010010][000100000000010110101010][000010000000010110010101][000001000000010001101101][000000100000011000110110][000000010000011111001001][000000001000010101110011][000000000100010011011110][000000000010001011110101][000000000001001101101110]

class sage.coding.binary_code.OrbitPartition
Bases: object
Structure which keeps track of which vertices are equivalent under the part of the automorphism group that has
already been seen, during search. Essentially a disjoint-set data structure*, which also keeps track of the minimum
element and size of each cell of the partition, and the size of the partition.
See Wikipedia article Disjoint-set_data_structureclass sage.coding.binary_code.PartitionStack
Bases: object
Partition stack structure for traversing the search tree during automorphism group computation.
cmp(other, CG)
EXAMPLES:
254

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

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: B = BinaryCode(M)sage: P = PartitionStack(4, 8)
sage: P._refine(0, [[0,0],[1,0]], B)
181
sage: P._split_vertex(0, 1)
0sage: P._refine(1, [[0,0]], B)
290
sage: P._split_vertex(1, 2)
1sage: P._refine(2, [[0,1]], B)
463
sage: P._split_vertex(2, 3)
2sage: P._refine(3, [[0,2]], B)
1500
sage: P._split_vertex(4, 4)
4
sage: P._refine(4, [[0,4]], B)
1224
sage: P._is_discrete(4)1sage: Q = PartitionStack(P)sage: Q._clear(4)sage: Q._split_vertex(5, 4)
4
sage: Q._refine(4, [[0,4]], B)
1224
sage: Q._is_discrete(4)1sage: Q.cmp(P, B)
0>>> from sage.all import *>>> import sage.coding.binary_code>>> from sage.coding.binary_code import *>>> M = Matrix(GF(Integer(2)), [[Integer(1),Integer(1),Integer(1),Integer(1),˓→Integer(0),Integer(0),Integer(0),Integer(0)], [Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0)],...
[Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(1),Integer(1)], [Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0)]])>>> B = BinaryCode(M)>>> P = PartitionStack(Integer(4), Integer(8))>>> P._refine(Integer(0), [[Integer(0),Integer(0)],[Integer(1),Integer(0)]],␣
˓→B)181>>> P._split_vertex(Integer(0), Integer(1))
0>>> P._refine(Integer(1), [[Integer(0),Integer(0)]], B)
290>>> P._split_vertex(Integer(1), Integer(2))
1(continues on next page)

11.14. Optimized low-level binary code representation

255

Coding Theory, Release 10.4

(continued from previous page)>>> P._refine(Integer(2), [[Integer(0),Integer(1)]], B)
463>>> P._split_vertex(Integer(2), Integer(3))
2>>> P._refine(Integer(3), [[Integer(0),Integer(2)]], B)
1500>>> P._split_vertex(Integer(4), Integer(4))
4>>> P._refine(Integer(4), [[Integer(0),Integer(4)]], B)
1224>>> P._is_discrete(Integer(4))
1>>> Q = PartitionStack(P)>>> Q._clear(Integer(4))>>> Q._split_vertex(Integer(5), Integer(4))
4>>> Q._refine(Integer(4), [[Integer(0),Integer(4)]], B)
1224>>> Q._is_discrete(Integer(4))
1>>> Q.cmp(P, B)
0print_basis()
EXAMPLES:
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({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15})˓→{1,2,3,4,5,6,7})({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15})˓→{1},{2,3,4,5,6,7})({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15})˓→{1},{2},{3,4,5,6,7})({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15})˓→{1},{2},{3},{4,5,6,7})({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15})˓→{1},{2},{3},{4},{5,6,7})({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15})˓→{1},{2},{3},{4},{5},{6,7})({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15})˓→{1},{2},{3},{4},{5},{6},{7})sage: P._find_basis()
sage: P.print_basis()
basis_locations:
4
8
0
11

256

({0},
({0},
({0},
({0},
({0},
({0},
({0},

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> import sage.coding.binary_code>>> from sage.coding.binary_code import *>>> P = PartitionStack(Integer(4), Integer(8))>>> P._dangerous_dont_use_set_ents_lvls(...
list(range(Integer(8))),...
list(range(Integer(7))) + [-Integer(1)],...
[Integer(4),Integer(7),Integer(12),Integer(11),Integer(1),Integer(9),˓→Integer(3),Integer(0),Integer(2),Integer(5),Integer(6),Integer(8),˓→Integer(10),Integer(13),Integer(14),Integer(15)],...
[Integer(0)]*Integer(16))>>> 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})({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})({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})({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15}) ({0},˓→{1},{2},{3},{4},{5},{6},{7})>>> P._find_basis()>>> P.print_basis()
basis_locations:
4
8
0
11

print_data()
Prints all data for self.
EXAMPLES:
sage: import sage.coding.binary_code
sage: from sage.coding.binary_code import *sage: P = PartitionStack(2, 6)
sage: print(P.print_data())
nwords:4
nrows:2
ncols:6
radix:32
wd_ents:0
1
2
3
wd_lvls:
12
12
12
-1
(continues on next page)

11.14. Optimized low-level binary code representation

257

Coding Theory, Release 10.4

(continued from previous page)col_ents:
0
1
2
3
4
5
col_lvls:
12
12
12
12
12
-1
col_degs:
0
0
0
0
0
0
col_counts:
0000
col_output:
0
0
0
0
0
0
wd_degs:
0000
wd_counts:
0
0
0
0
0
0
0
wd_output:00
00>>> from sage.all import *>>> import sage.coding.binary_code>>> from sage.coding.binary_code import *>>> P = PartitionStack(Integer(2), Integer(6))(continues on next page)

258

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> print(P.print_data())
nwords:4
nrows:2
ncols:6
radix:32
wd_ents:0
1
2
3
wd_lvls:
12
12
12
-1
col_ents:
0
1
2
3
4
5
col_lvls:
12
12
12
12
12
-1
col_degs:
0
0
0
0
0
0
col_counts:
0000
col_output:
0
0
0
0
0
0
wd_degs:
0000
wd_counts:000(continues on next page)

11.14. Optimized low-level binary code representation

259

Coding Theory, Release 10.4

(continued from previous page)0000
wd_output:00
00

sage.coding.binary_code.test_expand_to_ortho_basis(B=None)
This function is written in pure C for speed, and is tested from this function.
INPUT:• B – a BinaryCode in standard form
OUTPUT:An array of codewords which represent the expansion of a basis for 𝐵 to a basis for (𝐵 ′ )⊥ , where 𝐵 ′ = 𝐵 if the
all-ones vector 1 is in 𝐵, otherwise 𝐵 ′ = span(𝐵, 1) (note that this guarantees that all the vectors in the span of
the output have even weight).
sage.coding.binary_code.test_word_perms(t_limit=5.0)
Test the 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 𝐿 representing
a permutation 𝑖 ↦→ 𝐿[𝑖]. Takes a random word and permutes it by a random list permutation, and tests thatthe 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.
2. Tests create_comp_word_perm(), which creates a WordPermutation as a composition of two
WordPermutation objects. Takes a random word and two random permutations, and tests that the resultof 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 theidentity both return the original word.
Note: The functions permute_word_by_wp() and dealloc_word_perm() are implicitly involved ineach of the above tests.
sage.coding.binary_code.weight_dist(M)Computes the weight distribution of the row space of 𝑀 .
EXAMPLES:
sage: from sage.coding.binary_code import weight_dist
sage: M = Matrix(GF(2), [(continues on next page)

260

Chapter 11. Families of Linear CodesCoding Theory, Release 10.4

(continued from previous page)....: [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],....: [0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1],....: [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), [....: [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), [....: [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],....: [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,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,0,0,0,1,0,0,1,1,1,1,0,0,1]])
sage: weight_dist(M)[1, 0, 0, 0, 0, 0, 68, 0, 85, 0, 68, 0, 34, 0, 0, 0, 0, 0]>>> from sage.all import *>>> from sage.coding.binary_code import weight_dist>>> M = Matrix(GF(Integer(2)), [... [Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),˓→Integer(1),Integer(1),Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(0)],... [Integer(0),Integer(0),Integer(0),Integer(0),Integer(1),Integer(1),˓→Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0)],... [Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),˓→Integer(1),Integer(1),Integer(1)],... [Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(1),Integer(1)],... [Integer(0),Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0),˓→Integer(1),Integer(0),Integer(1)]])>>> weight_dist(M)[1, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 1]>>> M = Matrix(GF(Integer(2)), [... [Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),˓→Integer(1),Integer(1),Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(0),Integer(0)],... [Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),˓→Integer(1),Integer(0),Integer(0),Integer(0)],... [Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),Integer(1),˓→Integer(0),Integer(1),Integer(0),Integer(0),Integer(0),Integer(1),Integer(1),˓→Integer(1),Integer(1),Integer(1),Integer(1)],(continues on next page)

11.14. Optimized low-level binary code representation

261

Coding Theory, Release 10.4

(continued from previous page)... [Integer(0),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),Integer(1),˓→Integer(1),Integer(0),Integer(1),Integer(1)]])>>> weight_dist(M)[1, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 0, 0]>>> M = Matrix(GF(Integer(2)), [... [Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(1),˓→Integer(1),Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(0),Integer(0)],... [Integer(0),Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),˓→Integer(1),Integer(1),Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(0),Integer(0)],... [Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),Integer(1),˓→Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),Integer(1),Integer(0),˓→Integer(0),Integer(0),Integer(0),Integer(0)],... [Integer(0),Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),Integer(1),˓→Integer(0),Integer(0),Integer(0),Integer(0)],... [Integer(0),Integer(0),Integer(0),Integer(0),Integer(1),Integer(0),˓→Integer(0),Integer(1),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(0)],... [Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),Integer(1),˓→Integer(0),Integer(0),Integer(1),Integer(1),Integer(1),Integer(1),Integer(0),˓→Integer(0),Integer(1),Integer(0),Integer(0)],... [Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(1),Integer(1),˓→Integer(0),Integer(0),Integer(1),Integer(0)],... [Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(1),˓→Integer(1),Integer(0),Integer(0),Integer(1)]])>>> weight_dist(M)[1, 0, 0, 0, 0, 0, 68, 0, 85, 0, 68, 0, 34, 0, 0, 0, 0, 0]

262

Chapter 11. Families of Linear Codes

CHAPTERTWELVEDERIVED CODE CONSTRUCTIONS

Sage supports the following derived code constructions. If the constituent code is from a special code family, the derived
codes inherit structural properties like decoding radius or minimum distance:

12.1 Subfield subcode
Let 𝐶 be a [𝑛, 𝑘] code over F𝑞𝑡 . Let 𝐶𝑠 = {𝑐 ∈ 𝐶|∀𝑖, 𝑐𝑖 ∈ F𝑞 }, 𝑐𝑖 being the 𝑖-th coordinate of 𝑐.
𝐶𝑠 is called the subfield subcode of 𝐶 over F𝑞class sage.coding.subfield_subcode.SubfieldSubcode(original_code, subfield,
embedding=None)
Bases: AbstractLinearCode
Representation of a subfield subcode.
INPUT:• original_code – the code self comes from.
• subfield – the base field of self.
• embedding – (default: None) a homomorphism from subfield to original_code’s base field. If
None is provided, it will default to the first homomorphism of the list of homomorphisms Sage can build.
EXAMPLES:
sage: C = codes.random_linear_code(GF(16, aa ), 7, 3)
sage: codes.SubfieldSubcode(C, GF(4, a ))Subfield subcode of [7, 3] linear code over GF(16) down to GF(4)>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(16), aa ), Integer(7), Integer(3))>>> codes.SubfieldSubcode(C, GF(Integer(4), a ))Subfield subcode of [7, 3] linear code over GF(16) down to GF(4)dimension()
Return the dimension of self.
EXAMPLES:
sage: C = codes.GeneralizedReedSolomonCode(GF(16,sage: Cs = codes.SubfieldSubcode(C, GF(4, a ))sage: Cs.dimension()
3aa ).list()[:13], 5)263

Coding Theory, Release 10.4>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16),˓→list()[:Integer(13)], Integer(5))>>> Cs = codes.SubfieldSubcode(C, GF(Integer(4), a ))>>> Cs.dimension()
3

aa ).

dimension_lower_bound()Return a lower bound for the dimension of self.
EXAMPLES:
sage: C = codes.random_linear_code(GF(16,sage: Cs = codes.SubfieldSubcode(C, GF(4,sage: Cs.dimension_lower_bound()-1aa ), 7, 3)
a ))>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(16),
˓→Integer(3))>>> Cs = codes.SubfieldSubcode(C, GF(Integer(4),>>> Cs.dimension_lower_bound()-1aa ), Integer(7),␣
a ))dimension_upper_bound()Return an upper bound for the dimension of self.
EXAMPLES:
sage: C = codes.random_linear_code(GF(16,sage: Cs = codes.SubfieldSubcode(C, GF(4,sage: Cs.dimension_upper_bound()
3aa ), 7, 3)
a ))>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(16),
˓→Integer(3))>>> Cs = codes.SubfieldSubcode(C, GF(Integer(4),>>> Cs.dimension_upper_bound()
3aa ), Integer(7),␣
a ))embedding()
Return the field embedding between the base field of self and the base field of its original code.
EXAMPLES:
sage: C = codes.random_linear_code(GF(16,sage: Cs = codes.SubfieldSubcode(C, GF(4,sage: Cs.embedding()
Ring morphism:
From: Finite Field in a of size 2^2
To:
Finite Field in aa of size 2^4
Defn: a |--> aa^2 + aaaa ), 7, 3)
a ))>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(16),aa ), Integer(7),␣
(continues on next page)264

Chapter 12. Derived Code Constructions

Coding Theory, Release 10.4

(continued from previous page)

Integer(3))>>> Cs = codes.SubfieldSubcode(C, GF(Integer(4),>>> Cs.embedding()
Ring morphism:
From: Finite Field in a of size 2^2
To:
Finite Field in aa of size 2^4
Defn: a |--> aa^2 + aa
˓→

a ))

original_code()
Return the original code of self.
EXAMPLES:
sage: C = codes.random_linear_code(GF(16,sage: Cs = codes.SubfieldSubcode(C, GF(4,sage: Cs.original_code()[7, 3] linear code over GF(16)aa ), 7, 3)
a ))>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(16),
˓→Integer(3))>>> Cs = codes.SubfieldSubcode(C, GF(Integer(4),>>> Cs.original_code()[7, 3] linear code over GF(16)aa ), Integer(7),␣
a ))parity_check_matrix()
Return a parity check matrix of self.
EXAMPLES:
sage: C = codes.GeneralizedReedSolomonCode(GF(16,sage: Cs = codes.SubfieldSubcode(C, GF(4, a ))sage: Cs.parity_check_matrix()
[
1
0
0
0
0
0
0
0
˓→1]
[
0
1
0
0
0
0
0
0
˓→a]
[
0
0
1
0
0
0
0
0
˓→0]
[
0
0
0
1
0
0
0
0
˓→a]
[
0
0
0
0
1
0
0
0
˓→1]
[
0
0
0
0
0
1
0
0
˓→1]
[
0
0
0
0
0
0
1
0
˓→1]
[
0
0
0
0
0
0
0
1
˓→a]
[
0
0
0
0
0
0
0
0
˓→1]
[
0
0
0
0
0
0
0
0
˓→1]

aa ).list()[:13], 5)

0

0

0

0 a + 10␣00 a + 1

a

␣

0

0

0 a + 1␣

0

0 a + 1

1 a +␣

0

0

1

1

␣

0

0

a

a

␣

0

0

a

1

␣

1

0 a + 1 a + 1

␣

0

1

>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16),

1 a + 1 a +␣a

0 a +␣

aa ).
(continues on next page)12.1. Subfield subcode

265Coding Theory, Release 10.4

(continued from previous page)list()[:Integer(13)], Integer(5))>>> Cs = codes.SubfieldSubcode(C, GF(Integer(4),>>> Cs.parity_check_matrix()
[
1
0
0
0
0
0
0
0
˓→1]
[
0
1
0
0
0
0
0
0
˓→a]
[
0
0
1
0
0
0
0
0
˓→0]
[
0
0
0
1
0
0
0
0
˓→a]
[
0
0
0
0
1
0
0
0
˓→1]
[
0
0
0
0
0
1
0
0
˓→1]
[
0
0
0
0
0
0
1
0
˓→1]
[
0
0
0
0
0
0
0
1
˓→a]
[
0
0
0
0
0
0
0
0
˓→1]
[
0
0
0
0
0
0
0
0
˓→1]
˓→

a ))
0

0

1 a + 1 a +␣0

0 a + 10␣00 a + 1

a

␣

0

0

0 a + 1␣

0

0 a + 1

1 a +␣

0

0

1

1

␣

0

0

a

a

␣

0

0

a

1

␣

1

0 a + 1 a + 1

␣

0

1

a

0 a +␣

class sage.coding.subfield_subcode.SubfieldSubcodeOriginalCodeDecoder(code,original_decoder=None,**kwargs)
Bases: Decoder
Decoder decoding through a decoder over the original code of code.
INPUT:• code – The associated code of this decoder• original_decoder – (default: None) The decoder that will be used over the original code. It has to bea decoder object over the original code. If it is set to None, the default decoder over the original code will
be used.
• **kwargs – All extra arguments are forwarded to original code’s decoder
EXAMPLES:
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)>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), aa ).
˓→list()[:Integer(13)], Integer(5))>>> Cs = codes.SubfieldSubcode(C, GF(Integer(4), a ))>>> codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs)Decoder of Subfield subcode of [13, 5, 9] Reed-Solomon Code over GF(16) down to␣(continues on next page)

266

Chapter 12. Derived Code Constructions

Coding Theory, Release 10.4

(continued from previous page)GF(4)through Gao decoder for [13, 5, 9] Reed-Solomon Code over GF(16)˓→

decode_to_code(y)Return an error-corrected codeword from y.
EXAMPLES:
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: c = Cs.random_element()
sage: y = Chan(c)sage: c == D.decode_to_code(y)True>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), aa ).
˓→list()[:Integer(13)], Integer(5))>>> Cs = codes.SubfieldSubcode(C, GF(Integer(4), a ))>>> D = codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs)>>> Chan = channels.StaticErrorRateChannel(Cs.ambient_space(),...
D.decoding_radius())>>> c = Cs.random_element()>>> y = Chan(c)>>> c == D.decode_to_code(y)True

decoding_radius(**kwargs)
Return the maximal number of errors self can decode.
INPUT:• kwargs – Optional arguments are forwarded to original decoder’s sage.coding.decoder.
Decoder.decoding_radius() method.
EXAMPLES:
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: D.decoding_radius()
4>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), aa ).
˓→list()[:Integer(13)], Integer(5))>>> Cs = codes.SubfieldSubcode(C, GF(Integer(4), a ))>>> D = codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs)>>> D.decoding_radius()
4

original_decoder()Return the decoder over the original code that will be used to decode words of sage.coding.decoder.
Decoder.code().
12.1. Subfield subcode267

Coding Theory, Release 10.4

EXAMPLES:
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: D.original_decoder()Gao decoder for [13, 5, 9] Reed-Solomon Code over GF(16)>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), aa ).
˓→list()[:Integer(13)], Integer(5))>>> Cs = codes.SubfieldSubcode(C, GF(Integer(4), a ))>>> D = codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs)>>> D.original_decoder()Gao decoder for [13, 5, 9] Reed-Solomon Code over GF(16)12.2 Punctured code
Let 𝐶 be a linear code. Let 𝐶𝑖 be the set of all words of 𝐶 with the 𝑖-th coordinate being removed. 𝐶𝑖 is the punctured
code of 𝐶 on the 𝑖-th position.
class sage.coding.punctured_code.PuncturedCode(C, positions)
Bases: AbstractLinearCode
Representation of a punctured code.
• C – A linear code
• positions – the positions where C will be punctured. It can be either an integer if one need to puncture
only one position, a list or a set of positions to puncture. If the same position is passed several times, it will
be considered only once.
EXAMPLES:
sage: C = codes.random_linear_code(GF(7), 11, 5)
sage: Cp = codes.PuncturedCode(C, 3)
sage: Cp
Puncturing of [11, 5] linear code over GF(7) on position(s) [3]sage: Cp = codes.PuncturedCode(C, {3, 5})
sage: Cp
Puncturing of [11, 5] linear code over GF(7) on position(s) [3, 5]>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(7)), Integer(11), Integer(5))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> Cp
Puncturing of [11, 5] linear code over GF(7) on position(s) [3]>>> Cp = codes.PuncturedCode(C, {Integer(3), Integer(5)})>>> Cp
Puncturing of [11, 5] linear code over GF(7) on position(s) [3, 5]

dimension()
Return the dimension of self.
EXAMPLES:
268

Chapter 12. Derived Code Constructions

Coding Theory, Release 10.4

sage: set_random_seed(42)sage: C = codes.random_linear_code(GF(7), 11, 5)
sage: Cp = codes.PuncturedCode(C, 3)
sage: Cp.dimension()5>>> from sage.all import *>>> set_random_seed(Integer(42))>>> C = codes.random_linear_code(GF(Integer(7)), Integer(11), Integer(5))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> Cp.dimension()
5

encode(m, original_encode=False, encoder_name=None, **kwargs)
Transforms an element of the message space into an element of the code.
INPUT:• m – a vector of the message space of the code.
• original_encode – (default: False) if this is set to True, m will be encoded using an Encoderof self’s original_code(). This allow to avoid the computation of a generator matrix for self.
• encoder_name – (default: None) Name of the encoder which will be used to encode word. The
default encoder of self will be used if default value is kept
OUTPUT:• an element of self
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: C_original = LinearCode(M)sage: Cp = codes.PuncturedCode(C_original, 2)
sage: m = vector(GF(7), [1, 3, 5])
sage: Cp.encode(m)(1, 3, 5, 5, 0, 2)>>> from sage.all import *>>> M = matrix(GF(Integer(7)), [[Integer(1), Integer(0), Integer(0),␣
˓→Integer(0), Integer(3), Integer(4), Integer(6)],...
[Integer(0), Integer(1), Integer(0), Integer(6),␣
˓→Integer(1), Integer(6), Integer(4)],...
[Integer(0), Integer(0), Integer(1), Integer(5),␣
˓→Integer(2), Integer(2), Integer(4)]])>>> C_original = LinearCode(M)>>> Cp = codes.PuncturedCode(C_original, Integer(2))>>> m = vector(GF(Integer(7)), [Integer(1), Integer(3), Integer(5)])>>> Cp.encode(m)(1, 3, 5, 5, 0, 2)

original_code()
Return the linear code which was punctured to get self.
EXAMPLES:

12.2. Punctured code269

Coding Theory, Release 10.4

sage: C = codes.random_linear_code(GF(7), 11, 5)
sage: Cp = codes.PuncturedCode(C, 3)
sage: Cp.original_code()[11, 5] linear code over GF(7)>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(7)), Integer(11), Integer(5))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> Cp.original_code()[11, 5] linear code over GF(7)punctured_positions()
Return the list of positions which were punctured on the original code.
EXAMPLES:
sage: C = codes.random_linear_code(GF(7), 11, 5)
sage: Cp = codes.PuncturedCode(C, 3)
sage: Cp.punctured_positions(){3}>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(7)), Integer(11), Integer(5))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> Cp.punctured_positions(){3}

random_element(*args, **kwds)
Return a random codeword of self.
This method does not trigger the computation of self’s sage.coding.linear_code_no_metric.
generator_matrix().
INPUT:• agrs, kwds – extra positional arguments passed to sage.modules.free_module.
random_element().
EXAMPLES:
sage: C = codes.random_linear_code(GF(7), 11, 5)
sage: Cp = codes.PuncturedCode(C, 3)
sage: Cp.random_element() in Cp
True>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(7)), Integer(11), Integer(5))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> Cp.random_element() in Cp
True

structured_representation()
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 sage.coding.linear_code.LinearCode.
EXAMPLES:
270

Chapter 12. Derived Code Constructions

Coding Theory, Release 10.4

We consider a GRS code:
sage: C_grs = codes.GeneralizedReedSolomonCode(GF(59).list()[:40], 12)>>> from sage.all import *>>> C_grs = codes.GeneralizedReedSolomonCode(GF(Integer(59)).
˓→list()[:Integer(40)], Integer(12))

A punctured GRS code is still a GRS code:
sage: Cp_grs = codes.PuncturedCode(C_grs, 3)
sage: Cp_grs.structured_representation()[39, 12, 28] Reed-Solomon Code over GF(59)>>> from sage.all import *>>> Cp_grs = codes.PuncturedCode(C_grs, Integer(3))>>> Cp_grs.structured_representation()[39, 12, 28] Reed-Solomon Code over GF(59)Another example with structureless linear codes:
sage: set_random_seed(42)sage: C_lin = codes.random_linear_code(GF(2), 10, 5)
sage: Cp_lin = codes.PuncturedCode(C_lin, 2)
sage: Cp_lin.structured_representation()[9, 5] linear code over GF(2)>>> from sage.all import *>>> set_random_seed(Integer(42))>>> C_lin = codes.random_linear_code(GF(Integer(2)), Integer(10), Integer(5))>>> Cp_lin = codes.PuncturedCode(C_lin, Integer(2))>>> Cp_lin.structured_representation()[9, 5] linear code over GF(2)class sage.coding.punctured_code.PuncturedCodeOriginalCodeDecoder(code,
strategy=None,original_decoder=None,**kwargs)
Bases: Decoder
Decoder decoding through a decoder over the original code of its punctured code.
INPUT:• code – The associated code of this encoder• 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.

–

random-values – fills the punctured positions with random elements in code’s base field andtries 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– None – uses error-erasure if an error-erasure decoder is available, switch to random-values
behaviour otherwise
12.2. Punctured code271

Coding Theory, Release 10.4

• original_decoder – (default: None) the decoder that will be used over the original code. It has to bea decoder object over the original code. This argument takes precedence over strategy: if both original_decoder and strategy are filled, self will use the original_decoder to decode over theoriginal code. If original_decoder is set to None, it will use the decoder picked by strategy.
• **kwargs – all extra arguments are forwarded to original code’s decoder
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)>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> 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 theoriginal decoder. Now, if one forces strategy to try-all or random-values , the default decoderof 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>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, strategy="try-all")>>> "error-erasure" in D.decoder_type()
False

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

272

Chapter 12. Derived Code Constructions

Coding Theory, Release 10.4>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> Dor = C.decoder("Gao")>>> D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, original_decoder=Dor,...
strategy="error-erasure")>>> D.original_decoder() == Dor
True

decode_to_code(y)Decode y to an element in sage.coding.decoder.Decoder.code().
EXAMPLES:
sage: C = codes.GeneralizedReedSolomonCode(GF(16, a ).list()[:15], 7)
sage: Cp = codes.PuncturedCode(C, 3)
sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp)sage: c = Cp.random_element()
sage: Chan = channels.StaticErrorRateChannel(Cp.ambient_space(), 3)
sage: y = Chan(c)sage: y in Cp
False
sage: D.decode_to_code(y) == c
True>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp)>>> c = Cp.random_element()>>> Chan = channels.StaticErrorRateChannel(Cp.ambient_space(), Integer(3))>>> y = Chan(c)>>> y in Cp
False>>> D.decode_to_code(y) == c
Truedecoding_radius(number_erasures=None)
Return the maximal number of errors that self can decode.
EXAMPLES:
sage: C = codes.GeneralizedReedSolomonCode(GF(16, a ).list()[:15], 7)
sage: Cp = codes.PuncturedCode(C, 3)
sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp)sage: D.decoding_radius(2)2>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp)>>> D.decoding_radius(Integer(2))
212.2. Punctured code273

Coding Theory, Release 10.4

original_decoder()Return the decoder over the original code that will be used to decode words of sage.coding.decoder.
Decoder.code().
EXAMPLES:
sage: C = codes.GeneralizedReedSolomonCode(GF(16, a ).list()[:15], 7)
sage: Cp = codes.PuncturedCode(C, 3)
sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp)sage: D.original_decoder()Error-Erasure decoder for [15, 7, 9] Reed-Solomon Code over GF(16)>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp)>>> D.original_decoder()Error-Erasure decoder for [15, 7, 9] Reed-Solomon Code over GF(16)class sage.coding.punctured_code.PuncturedCodePuncturedMatrixEncoder(code)
Bases: Encoder
Encoder using original code generator matrix to compute the punctured code’s one.
INPUT:• code – The associated code of this encoder.
EXAMPLES:
sage: C = codes.random_linear_code(GF(7), 11, 5)
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]>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(7)), Integer(11), Integer(5))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> E = codes.encoders.PuncturedCodePuncturedMatrixEncoder(Cp)>>> E
Punctured matrix-based encoder for the
Puncturing of [11, 5] linear code over GF(7) on position(s) [3]generator_matrix()
Return a generator matrix of the associated code of self.
EXAMPLES:
sage: set_random_seed(10)sage: C = codes.random_linear_code(GF(7), 11, 5)
sage: Cp = codes.PuncturedCode(C, 3)
sage: E = codes.encoders.PuncturedCodePuncturedMatrixEncoder(Cp)sage: E.generator_matrix()[1 0 0 0 0 5 2 6 0 6]
[0 1 0 0 0 5 2 2 1 1](continues on next page)274

Chapter 12. Derived Code Constructions

Coding Theory, Release 10.4

(continued from previous page)[0 0 1 0 0 6 2 4 0 4]
[0 0 0 1 0 0 6 3 3 3]
[0 0 0 0 1 0 1 3 4 3]>>> from sage.all import *>>> set_random_seed(Integer(10))>>> C = codes.random_linear_code(GF(Integer(7)), Integer(11), Integer(5))>>> Cp = codes.PuncturedCode(C, Integer(3))>>> E = codes.encoders.PuncturedCodePuncturedMatrixEncoder(Cp)>>> E.generator_matrix()[1 0 0 0 0 5 2 6 0 6]
[0 1 0 0 0 5 2 2 1 1]
[0 0 1 0 0 6 2 4 0 4]
[0 0 0 1 0 0 6 3 3 3]
[0 0 0 0 1 0 1 3 4 3]

12.3 Extended code
Let 𝐶 be a linear code of length 𝑛 over F𝑞 . The extended code of 𝐶 is the code𝐶^ = {𝑥1 𝑥2 . . . 𝑥𝑛+1 ∈ F𝑛+1
| 𝑥1 𝑥2 . . . 𝑥𝑛 ∈ 𝐶 with 𝑥1 + 𝑥2 + · · · + 𝑥𝑛+1 = 0}.
𝑞
See [HP2003] (pp 15-16) for details.
class sage.coding.extended_code.ExtendedCode(C)Bases: AbstractLinearCode
Representation of an extended code.
INPUT:• C – A linear code
EXAMPLES:
sage: C = codes.random_linear_code(GF(7), 11, 5)
sage: Ce = codes.ExtendedCode(C)sage: Ce
Extension of [11, 5] linear code over GF(7)>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(7)), Integer(11), Integer(5))>>> Ce = codes.ExtendedCode(C)>>> CeExtension of [11, 5] linear code over GF(7)original_code()
Return the code which was extended to get self.
EXAMPLES:
sage: C = codes.random_linear_code(GF(7), 11, 5)
sage: Ce = codes.ExtendedCode(C)sage: Ce.original_code()[11, 5] linear code over GF(7)12.3. Extended code275

Coding Theory, Release 10.4>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(7)), Integer(11), Integer(5))>>> Ce = codes.ExtendedCode(C)>>> Ce.original_code()[11, 5] linear code over GF(7)parity_check_matrix()
Return a parity check matrix of self.
This matrix is computed directly from original_code().
EXAMPLES:
sage: C = LinearCode(matrix(GF(2),[[1,0,0,1,1],\[0,1,0,1,0],\[0,0,1,1,1]]))
sage: C.parity_check_matrix()[1 0 1 0 1]
[0 1 0 1 1]
sage: Ce = codes.ExtendedCode(C)sage: Ce.parity_check_matrix()[1 1 1 1 1 1]
[1 0 1 0 1 0]
[0 1 0 1 1 0]>>> from sage.all import *>>> C = LinearCode(matrix(GF(Integer(2)),[[Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1)],\[0,1,0,1,0],\[0,0,1,1,1]]))>>> C.parity_check_matrix()[1 0 1 0 1]
[0 1 0 1 1]>>> Ce = codes.ExtendedCode(C)>>> Ce.parity_check_matrix()[1 1 1 1 1 1]
[1 0 1 0 1 0]
[0 1 0 1 1 0]

random_element()
Return a random element of self.
This random element is computed directly from the original code, and does not compute a generator matrixof self in the process.
EXAMPLES:
sage: C = codes.random_linear_code(GF(7), 9, 5)
sage: Ce = codes.ExtendedCode(C)sage: c = Ce.random_element() #random
sage: c in Ce
True>>> from sage.all import *>>> C = codes.random_linear_code(GF(Integer(7)), Integer(9), Integer(5))>>> Ce = codes.ExtendedCode(C)>>> c = Ce.random_element() #random(continues on next page)

276

Chapter 12. Derived Code Constructions

Coding Theory, Release 10.4

(continued from previous page)>>> c in Ce
Trueclass sage.coding.extended_code.ExtendedCodeExtendedMatrixEncoder(code)
Bases: Encoder
Encoder using original code’s generator matrix to compute the extended code’s one.
INPUT:• code – The associated code of self.
generator_matrix()
Return a generator matrix of the associated code of self.
EXAMPLES:
sage: C = LinearCode(matrix(GF(2),[[1,0,0,1,1],\[0,1,0,1,0],\[0,0,1,1,1]]))
sage: Ce = codes.ExtendedCode(C)sage: E = codes.encoders.ExtendedCodeExtendedMatrixEncoder(Ce)sage: E.generator_matrix()[1 0 0 1 1 1]
[0 1 0 1 0 0]
[0 0 1 1 1 1]>>> from sage.all import *>>> C = LinearCode(matrix(GF(Integer(2)),[[Integer(1),Integer(0),Integer(0),˓→Integer(1),Integer(1)],\[0,1,0,1,0],\[0,0,1,1,1]]))>>> Ce = codes.ExtendedCode(C)>>> E = codes.encoders.ExtendedCodeExtendedMatrixEncoder(Ce)>>> E.generator_matrix()[1 0 0 1 1 1]
[0 1 0 1 0 0]
[0 0 1 1 1 1]class sage.coding.extended_code.ExtendedCodeOriginalCodeDecoder(code, original_decoder=None,**kwargs)
Bases: Decoder
Decoder which decodes through a decoder over the original code.
INPUT:• code – The associated code of this decoder• original_decoder – (default: None) the decoder that will be used over the original code. It has tobe a decoder object over the original code. If original_decoder is set to None, it will use the default
decoder of the original code.
• **kwargs – all extra arguments are forwarded to original code’s decoder
EXAMPLES:

12.3. Extended code277

Coding Theory, Release 10.4

sage: C = codes.GeneralizedReedSolomonCode(GF(16, a ).list()[:15], 7)
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)>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Ce = codes.ExtendedCode(C)>>> D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce)>>> 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)decode_to_code(y, **kwargs)
Decode y to an element in sage.coding.decoder.Decoder.code().
EXAMPLES:
sage: C = codes.GeneralizedReedSolomonCode(GF(16, a ).list()[:15], 7)
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: y = Chan(c)sage: y in Ce
False
sage: D.decode_to_code(y) == c
True>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Ce = codes.ExtendedCode(C)>>> D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce)>>> c = Ce.random_element()>>> Chan = channels.StaticErrorRateChannel(Ce.ambient_space(),...
D.decoding_radius())>>> y = Chan(c)>>> y in Ce
False>>> D.decode_to_code(y) == c
True

Another example, with a list decoder:sage: # needs sage.symbolic
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: c = Ce.random_element()(continues on next page)

278

Chapter 12. Derived Code Constructions

Coding Theory, Release 10.4

(continued from previous page)

sage: Chan = channels.StaticErrorRateChannel(Ce.ambient_space(),....:D.decoding_radius())
sage: y = Chan(c)sage: y in Ce
False
sage: c in D.decode_to_code(y)True>>> from sage.all import *>>> # needs sage.symbolic>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Ce = codes.ExtendedCode(C)>>> Dgrs = C.decoder( GuruswamiSudan , tau=Integer(4))>>> D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce,...
original_decoder=Dgrs)>>> c = Ce.random_element()>>> Chan = channels.StaticErrorRateChannel(Ce.ambient_space(),...
D.decoding_radius())>>> y = Chan(c)>>> y in Ce
False>>> c in D.decode_to_code(y)True

decoding_radius(*args, **kwargs)
Return maximal number of errors that self can decode.
INPUT:• *args, **kwargs – arguments and optional arguments are forwarded to original decoder’s decoding_radius method.
EXAMPLES:
sage: C = codes.GeneralizedReedSolomonCode(GF(16, a ).list()[:15], 7)
sage: Ce = codes.ExtendedCode(C)sage: D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce)sage: D.decoding_radius()
4>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Ce = codes.ExtendedCode(C)>>> D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce)>>> D.decoding_radius()
4

original_decoder()Return the decoder over the original code that will be used to decode words of sage.coding.decoder.
Decoder.code().
EXAMPLES:

12.3. Extended code279

Coding Theory, Release 10.4

sage: C = codes.GeneralizedReedSolomonCode(GF(16, a ).list()[:15], 7)
sage: Ce = codes.ExtendedCode(C)sage: D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce)sage: D.original_decoder()Gao decoder for [15, 7, 9] Reed-Solomon Code over GF(16)>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(16), a ).
˓→list()[:Integer(15)], Integer(7))>>> Ce = codes.ExtendedCode(C)>>> D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce)>>> D.original_decoder()Gao decoder for [15, 7, 9] Reed-Solomon Code over GF(16)Other derived constructions that simply produce the modified generator matrix can be found among the methods of aconstructed code.

280

Chapter 12. Derived Code Constructions

CHAPTERTHIRTEENDECODING

Information-set decoding for linear codes:

13.1 Information-set decoding for linear codes
Information-set decoding is a probabilistic decoding strategy that essentially tries to guess 𝑘 correct positions in thereceived word, where 𝑘 is the dimension of the code. A codeword agreeing with the received word on the guessed
position can easily be computed, and their difference is one possible error vector. A “correct” guess is assumed when thiserror vector has low Hamming weight.
This simple algorithm is not very efficient in itself, but there are numerous refinements to the strategy that make it very
capable over rather large codes. Still, the decoding algorithm is exponential in dimension of the code and the log of the
field size.
The ISD strategy requires choosing how many errors is deemed acceptable. One choice could be 𝑑/2, where 𝑑 is theminimum distance of the code, but sometimes 𝑑 is not known, or sometimes more errors are expected. If one chooses
anything above 𝑑/2, the algorithm does not guarantee to return a nearest codeword.
AUTHORS:• David Lucas, Johan Rosenkilde, Yann Laigle-Chapuy (2016-02, 2017-06): initial version
class sage.coding.information_set_decoder.InformationSetAlgorithm(code,
decoding_interval,
algorithm_name,parameters=None)
Bases: SageObject
Abstract
classforalgorithms
forLinearCodeInformationSetDecoder.

sage.coding.information_set_decoder.

To sub-class this class, override decode and calibrate, and call the super constructor from __init__.
INPUT:• code – A linear code for which to decode.
• number_errors – an integer, the maximal number of errors to accept as correct decoding. An interval
can also be specified by giving a pair of integers, where both end values are taken to be in the interval.
• algorithm_name – A name for the specific ISD algorithm used (used for printing).
• parameters – (optional) A dictionary for setting the parameters of this ISD algorithm. Note that sanity
checking this dictionary for the individual sub-classes should be done in the sub-class constructor.

281

Coding Theory, Release 10.4

EXAMPLES:
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>>> from sage.all import *>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> LeeBrickellISDAlgorithm(codes.GolayCode(GF(Integer(2))), (Integer(0),˓→Integer(4)))
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:sage: from sage.coding.information_set_decoder import InformationSetAlgorithm
sage: from sage.coding.decoder import DecodingError
sage: class MinimalISD(InformationSetAlgorithm):....:
def __init__(self, code, decoding_interval):....:
super().__init__(code, decoding_interval, "MinimalISD")....:
def calibrate(self):....:
self._parameters = { } # calibrate parameters here....:
self._time_estimate = 10.0 # calibrated time estimate....:
def decode(self, r):....:# 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>>> from sage.all import *>>> from sage.coding.information_set_decoder import InformationSetAlgorithm>>> from sage.coding.decoder import DecodingError>>> class MinimalISD(InformationSetAlgorithm):...
def __init__(self, code, decoding_interval):...
super().__init__(code, decoding_interval, "MinimalISD")...
def calibrate(self):...
self._parameters = { } # calibrate parameters here...
self._time_estimate = RealNumber( 10.0 ) # calibrated time estimate...
def decode(self, r):...
# decoding algorithm here...
raise DecodingError("I failed")>>> MinimalISD(codes.GolayCode(GF(Integer(2))), (Integer(0),Integer(4)))
ISD Algorithm (MinimalISD) for [24, 12, 8] Extended Golay code over GF(2)decoding up to 4 errors

calibrate()
Uses test computations to estimate optimal values for any parameters this ISD algorithm may take.
Must be overridden by sub-classes.
If self._parameters_specified is False, this method shall set self._parameters to thebest parameters estimated. It shall always set self._time_estimate to the time estimate of using
self._parameters.
EXAMPLES:

282

Chapter 13. Decoding

Coding Theory, Release 10.4

sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm
sage: C = codes.GolayCode(GF(2))
sage: A = LeeBrickellISDAlgorithm(C, (0,3))
sage: A.calibrate()sage: A.parameters() #random{ search_size : 1}>>> from sage.all import *>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> C = codes.GolayCode(GF(Integer(2)))>>> A = LeeBrickellISDAlgorithm(C, (Integer(0),Integer(3)))>>> A.calibrate()>>> A.parameters() #random{ search_size : 1}code()
Return the code associated to this ISD algorithm.
EXAMPLES:
sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm
sage: C = codes.GolayCode(GF(2))
sage: A = LeeBrickellISDAlgorithm(C, (0,3))
sage: A.code()[24, 12, 8] Extended Golay code over GF(2)>>> from sage.all import *>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> C = codes.GolayCode(GF(Integer(2)))>>> A = LeeBrickellISDAlgorithm(C, (Integer(0),Integer(3)))>>> A.code()[24, 12, 8] Extended Golay code over GF(2)decode(r)Decode a received word using this ISD decoding algorithm.
Must be overridden by sub-classes.
EXAMPLES:
sage: M = matrix(GF(2), [[1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0],\[0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1],\[0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0],\[0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1],\[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1]])
sage: C = codes.LinearCode(M)sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm
sage: A = LeeBrickellISDAlgorithm(C, (2,2))
sage: r = vector(GF(2), [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
sage: A.decode(r)(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)>>> from sage.all import *>>> M = matrix(GF(Integer(2)), [[Integer(1), Integer(0), Integer(0),␣
˓→Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(1),␣
˓→Integer(0), Integer(1), Integer(0)],\(continues on next page)

13.1. Information-set decoding for linear codes283

Coding Theory, Release 10.4

(continued from previous page)[0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1],\[0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0],\[0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1],\[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1]])>>> C = codes.LinearCode(M)>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> A = LeeBrickellISDAlgorithm(C, (Integer(2),Integer(2)))>>> r = vector(GF(Integer(2)), [Integer(1), Integer(1), Integer(0),␣
˓→Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0),␣
˓→Integer(0), Integer(0), Integer(0)])>>> A.decode(r)(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

decoding_interval()
A pair of integers specifying the interval of number of errors this ISD algorithm will attempt tocorrect.
The interval includes both end values.
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm
sage: A = LeeBrickellISDAlgorithm(C, (0,2))
sage: A.decoding_interval()(0, 2)>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> A = LeeBrickellISDAlgorithm(C, (Integer(0),Integer(2)))>>> A.decoding_interval()(0, 2)

name()
Return the name of this ISD algorithm.
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm
sage: A = LeeBrickellISDAlgorithm(C, (0,2))
sage: A.name()
Lee-Brickell>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> A = LeeBrickellISDAlgorithm(C, (Integer(0),Integer(2)))>>> A.name()
Lee-Brickell

parameters()
Return any parameters this ISD algorithm uses.
If the parameters have not already been set, efficient values will first be calibrated and returned.
284

Chapter 13. Decoding

Coding Theory, Release 10.4

EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm
sage: A = LeeBrickellISDAlgorithm(C, (0,4), search_size=3)
sage: A.parameters(){ search_size : 3}>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> A = LeeBrickellISDAlgorithm(C, (Integer(0),Integer(4)), search_
˓→size=Integer(3))>>> A.parameters(){ search_size : 3}

If not set, calibration will determine a sensible value:
sage: A = LeeBrickellISDAlgorithm(C, (0,4))
sage: A.parameters() #random{ search_size : 1}>>> from sage.all import *>>> A = LeeBrickellISDAlgorithm(C, (Integer(0),Integer(4)))>>> A.parameters() #random{ search_size : 1}

time_estimate()
Estimate for how long this ISD algorithm takes to perform a single decoding.
The estimate is for a received word whose number of errors is within the decoding interval of this ISD
algorithm.
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm
sage: A = LeeBrickellISDAlgorithm(C, (0,2))
sage: A.time_estimate() #random
0.0008162108571427874>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> A = LeeBrickellISDAlgorithm(C, (Integer(0),Integer(2)))>>> A.time_estimate() #random
0.0008162108571427874

class sage.coding.information_set_decoder.LeeBrickellISDAlgorithm(code,
decoding_interval,
search_size=None)
Bases: InformationSetAlgorithm
The Lee-Brickell algorithm for information-set decoding.
For a description of the information-set decoding paradigm (ISD),
information_set_decoder.LinearCodeInformationSetDecoder.

13.1. Information-set decoding for linear codessee

sage.coding.

285

Coding Theory, Release 10.4

This implements the Lee-Brickell variant of ISD, see [LB1988] for the original binary case, and [Pet2010] for the
𝑞-ary extension.
Let 𝐶 be a [𝑛, 𝑘]-linear code over F𝑞 , and let 𝑟 ∈ F𝑛𝑞 be a received word in a transmission. We seek the codeword
whose Hamming distance from 𝑟 is minimal. Let 𝑝 and 𝑤 be integers, such that 0 ≤ 𝑝 ≤ 𝑤, Let 𝐺 be a generator
matrix of 𝐶, and for any set of indices 𝐼, we write 𝐺𝐼 for the matrix formed by the columns of 𝐺 indexed by 𝐼.
The Lee-Brickell ISD loops the following until it is successful:
1. Choose an information set 𝐼 of 𝐶.
2. Compute 𝑟′ = 𝑟 − 𝑟𝐼 𝐺−1
𝐼 𝐺𝑝
3. Consider every size-𝑝∑︀𝑝 subset of 𝐼, {𝑎1 , . . . , 𝑎𝑝 }. For each 𝑚 = (𝑚1 , . . . , 𝑚𝑝 ) ∈ F𝑞 , compute the error′
vector 𝑒 = 𝑟 − 𝑖=1 𝑚𝑖 𝑔𝑎𝑖 ,4. If 𝑒 has a Hamming weight at most 𝑤, return 𝑟 − 𝑒.
INPUT:• code – A linear code for which to decode.
• decoding_interval – a pair of integers specifying an interval of number of errors to correct. Includes
both end values.
• search_size – (optional) the size of subsets to use on step 3 of the algorithm as described above. Usually asmall number. It has to be at most the largest allowed number of errors. A good choice will be approximated if
this option is not set; see sage.coding.LeeBrickellISDAlgorithm.calibrate() for details.
EXAMPLES:
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
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>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> A = LeeBrickellISDAlgorithm(C, (Integer(0),Integer(4))); A
ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2)decoding up to 4 errors>>> C = codes.GolayCode(GF(Integer(2)))>>> A = LeeBrickellISDAlgorithm(C, (Integer(2),Integer(3))); A
ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2)decoding between 2 and 3 errors

calibrate()
Run some test computations to estimate the optimal search size.
Let 𝑝 be the search size. We should simply choose 𝑝 such that the average expected time is minimal. The
algorithm succeeds when it chooses an information set with at least 𝑘 − 𝑝 correct positions, where 𝑘 is the286

Chapter 13. Decoding

Coding Theory, Release 10.4

dimension of the code and 𝑝 the search size. The expected number of trials we need before this occurs is:(︂ )︂
)︂(︂ )︂
𝑝 (︂
∑︁
𝑛
𝑛−𝜏
𝜏
/(𝜌
)
𝑘
𝑘
−
𝑖
𝑖
𝑖=0
Here 𝜌 is the fraction of 𝑘 subsets of indices which are information sets. If 𝑇 is the average time for steps 1 and
2 (including selecting 𝐼 until an information set is found), while 𝑃 (𝑖) is the time for theof the(︀ )︀for-loop∑︀body𝑝
in step 3 for 𝑚 of weight 𝑖, then each information set trial takes roughly time 𝑇 + 𝑖=0 𝑃 (𝑖) 𝑘𝑖 (𝑞 − 1)𝑖 ,where F𝑞 is the base field.
The values 𝑇 and 𝑃 are here estimated by running a few test computations similar to those done by the
decoding algorithm. We don’t explicitly estimate 𝜌.
OUTPUT: Does not output anything but sets private fields used by sage.coding.
information_set_decoder.InformationSetAlgorithm.parameters()
andsage.coding.information_set_decoder.InformationSetAlgorithm.
time_estimate() ().
EXAMPLES:
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
sage: A.calibrate()sage: A.parameters() #random{ search_size : 1}sage: A.time_estimate() #random
0.0008162108571427874>>> from sage.all import *>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> C = codes.GolayCode(GF(Integer(2)))>>> A = LeeBrickellISDAlgorithm(C, (Integer(0),Integer(3))); A
ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2)decoding up to 3 errors>>> A.calibrate()>>> A.parameters() #random{ search_size : 1}>>> A.time_estimate() #random
0.0008162108571427874

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
sage: A.parameters(){ search_size : 2}sage: A.calibrate()sage: A.parameters(){ search_size : 2}sage: A.time_estimate() #random
0.0008162108571427874>>> from sage.all import *>>> A = LeeBrickellISDAlgorithm(C, (Integer(0),Integer(3)), search_(continues on next page)

13.1. Information-set decoding for linear codes287

Coding Theory, Release 10.4

(continued from previous page)

size=Integer(2)); A
ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2)decoding up to 3 errors>>> A.parameters(){ search_size : 2}>>> A.calibrate()>>> A.parameters(){ search_size : 2}>>> A.time_estimate() #random
0.0008162108571427874
˓→

decode(r)The Lee-Brickell algorithm as described in the class doc.
Note that either parameters must be given at construction time or sage.coding.
information_set_decoder.InformationSetAlgorithm.calibrate()shouldbecalled before calling this method.
INPUT:• 𝑟 – a received word, i.e. a vector in the ambient space of decoder.Decoder.code().
OUTPUT: A codeword whose distance to 𝑟 satisfies self.decoding_interval().
EXAMPLES:
sage: M = matrix(GF(2), [[1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0],\[0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1],\[0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0],\[0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1],\[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1]])
sage: C = codes.LinearCode(M)sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm
sage: A = LeeBrickellISDAlgorithm(C, (2,2))
sage: c = C.random_element()
sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), 2)
sage: r = Chan(c)sage: c_out = A.decode(r)sage: (r - c).hamming_weight() == 2
True>>> from sage.all import *>>> M = matrix(GF(Integer(2)), [[Integer(1), Integer(0), Integer(0),␣
˓→Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(1),␣
˓→Integer(0), Integer(1), Integer(0)],\[0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1],\[0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0],\[0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1],\[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1]])>>> C = codes.LinearCode(M)>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> A = LeeBrickellISDAlgorithm(C, (Integer(2),Integer(2)))>>> c = C.random_element()>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(), Integer(2))>>> r = Chan(c)>>> c_out = A.decode(r)>>> (r - c).hamming_weight() == Integer(2)
True

288

Chapter 13. Decoding

Coding Theory, Release 10.4class sage.coding.information_set_decoder.LinearCodeInformationSetDecoder(code,
number_errors,
algorithm=None,**kwargs)
Bases: Decoder
Information-set decoder for any linear code.
Information-set decoding is a probabilistic decoding strategy that essentially tries to guess 𝑘 correct positions in thereceived word, where 𝑘 is the dimension of the code. A codeword agreeing with the received word on the guessed
position can easily be computed, and their difference is one possible error vector. A “correct” guess is assumed
when this error vector has low Hamming weight.
The ISD strategy requires choosing how many errors is deemed acceptable. One choice could be 𝑑/2, where 𝑑 isthe minimum distance of the code, but sometimes 𝑑 is not known, or sometimes more errors are expected. If one
chooses anything above 𝑑/2, the algorithm does not guarantee to return a nearest codeword.
This simple algorithm is not very efficient in itself, but there are numerous refinements to the strategy. Specifying
which strategy to use among those that Sage knows is done using the algorithm keyword. If this is not set, an
efficient choice will be made for you.
The various ISD algorithms all need to select a number of parameters. If you choose a specific algorithm to use,
you can pass these parameters as named parameters directly to this class’ constructor. If you don’t, efficient choices
will be calibrated for you.
Warning: If there is no codeword within the specified decoding distance, then the decoder may never terminate, or it may raise a sage.coding.decoder.DecodingError exception, depending on the ISD
algorithm used.
INPUT:• code – A linear code for which to decode.
• number_errors – an integer, the maximal number of errors to accept as correct decoding. An interval
can also be specified by giving a pair of integers, where both end values are taken to be in the interval.
• algorithm – (optional) the string name of the ISD algorithm to employ. If this is not set, an
appropriate one will be chosen. A constructed sage.coding.information_set_decoder.
InformationSetAlgorithm object may also be given. In this case number_errors must matchthat of the passed algorithm.
• **kwargs – (optional) any number of named arguments passed on to the ISD algorithm. Such are usually
not required, and they can only be set if algorithm is set to a specific algorithm. See the documentation for each individual ISD algorithm class for information on any named arguments they may accept.
The easiest way to access this documentation is to first construct the decoder without passing any named
arguments, then accessing the ISD algorithm using sage.coding.information_set_decoder.
LinearCodeInformationSetDecoder.algorithm(), and then reading the ? help on the constructed object.
EXAMPLES:
The principal way to access this class is through the sage.code.linear_code.AbstractLinearCode.
decoder() method:

13.1. Information-set decoding for linear codes289

Coding Theory, Release 10.4

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>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(3)))>>> D = C.decoder("InformationSet", Integer(2)); D
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
sage: D2.algorithm()
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}>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(3)))>>> D2 = C.decoder("InformationSet", Integer(2), algorithm="Lee-Brickell", search_
˓→size=Integer(2)); D2
Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over␣
˓→GF(3)decoding up to 2 errors>>> D2.algorithm()
ISD Algorithm (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3)decoding up to 2 errors>>> D2.algorithm().parameters(){ search_size : 2}

If you specify an algorithm which is not known, you get a friendly error message:
sage: C.decoder("InformationSet", 2, algorithm="NoSuchThing")
Traceback (most recent call last):...
ValueError: Unknown ISD algorithm NoSuchThing .
The known algorithms are [ Lee-Brickell ].
>>> from sage.all import *>>> C.decoder("InformationSet", Integer(2), algorithm="NoSuchThing")
Traceback (most recent call last):...
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:
290

Chapter 13. Decoding

Coding Theory, Release 10.4

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>>> from sage.all import *>>> from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm>>> A = LeeBrickellISDAlgorithm(C, (Integer(0), Integer(2)))>>> D = C.decoder("InformationSet", Integer(2), algorithm=A); D
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 whenconstructing the 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>>> from sage.all import *>>> C.decoder("InformationSet", Integer(2), algorithm=A, search_size=Integer(2))
Traceback (most recent call last):...
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>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(3)))>>> D = C.decoder("InformationSet", Integer(2)); D
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
sage: from sage.coding.information_set_decoder import␣
˓→LinearCodeInformationSetDecoder
sage: D = LinearCodeInformationSetDecoder(C, 2); D(continues on next page)

13.1. Information-set decoding for linear codes291

Coding Theory, Release 10.4

(continued from previous page)

Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over␣
˓→GF(3)decoding up to 2 errors>>> from sage.all import *>>> D = codes.decoders.LinearCodeInformationSetDecoder(C, Integer(2)); D
Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over␣
˓→GF(3)decoding up to 2 errors>>> from sage.coding.information_set_decoder import␣
˓→LinearCodeInformationSetDecoder>>> D = LinearCodeInformationSetDecoder(C, Integer(2)); D
Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over␣
˓→GF(3)decoding up to 2 errors

algorithm()
Return the ISD algorithm used by this ISD decoder.
EXAMPLES:
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>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> D = C.decoder("InformationSet", (Integer(2),Integer(4)), "Lee-Brickell")>>> D.algorithm()
ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2)decoding between 2 and 4 errors

decode_to_code(r)Decodes a received word with respect to the associated code of this decoder.
Warning: If there is no codeword within the decoding radius of this decoder, this method may neverterminate, or it may raise a sage.coding.decoder.DecodingError exception, depending on
the ISD algorithm used.
INPUT:• r – a vector in the ambient space of decoder.Decoder.code().
OUTPUT: a codeword of decoder.Decoder.code().
EXAMPLES:
sage: M = matrix(GF(2), [[1,0,0,0,0,0,1,0,1,0,1,1,0,0,1],\[0,1,0,0,0,1,1,1,1,0,0,0,0,1,1],\[0,0,1,0,0,0,0,1,0,1,1,1,1,1,0],\[0,0,0,1,0,0,1,0,1,0,0,0,1,1,0],\(continues on next page)292

Chapter 13. Decoding

Coding Theory, Release 10.4

(continued from previous page)[0,0,0,0,1,0,0,0,1,0,1,1,0,1,0]])
sage: C = LinearCode(M)sage: c = C.random_element()
sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), 2)
sage: r = Chan(c)sage: D = C.decoder( InformationSet , 2)
sage: c == D.decode_to_code(r)True>>> from sage.all import *>>> M = matrix(GF(Integer(2)), [[Integer(1),Integer(0),Integer(0),Integer(0),˓→Integer(0),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0),˓→Integer(1),Integer(1),Integer(0),Integer(0),Integer(1)],\[0,1,0,0,0,1,1,1,1,0,0,0,0,1,1],\[0,0,1,0,0,0,0,1,0,1,1,1,1,1,0],\[0,0,0,1,0,0,1,0,1,0,0,0,1,1,0],\[0,0,0,0,1,0,0,0,1,0,1,1,0,1,0]])>>> C = LinearCode(M)>>> c = C.random_element()>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(), Integer(2))>>> r = Chan(c)>>> D = C.decoder( InformationSet , Integer(2))>>> c == D.decode_to_code(r)TrueInformation-set decoding a non-binary code:
sage: C = codes.GolayCode(GF(3)); C[12, 6, 6] Extended Golay code over GF(3)sage: c = C.random_element()
sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), 2)
sage: r = Chan(c)sage: D = C.decoder( InformationSet , 2)
sage: c == D.decode_to_code(r)True>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(3))); C[12, 6, 6] Extended Golay code over GF(3)>>> c = C.random_element()>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(), Integer(2))>>> r = Chan(c)>>> D = C.decoder( InformationSet , Integer(2))>>> c == D.decode_to_code(r)TrueLet’s take a bigger example, for which syndrome decoding or nearest-neighbor decoding would be infeasible:
the [59, 30] Quadratic Residue code over F3 has true minimum distance 17, so we can correct 8 errors:
sage: C = codes.QuadraticResidueCode(59, GF(3))
sage: c = C.random_element()
sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), 2)
sage: r = Chan(c)sage: D = C.decoder( InformationSet , 8)
sage: c == D.decode_to_code(r) # long timeTrue

13.1. Information-set decoding for linear codes

293

Coding Theory, Release 10.4>>> from sage.all import *>>> C = codes.QuadraticResidueCode(Integer(59), GF(Integer(3)))>>> c = C.random_element()>>> Chan = channels.StaticErrorRateChannel(C.ambient_space(), Integer(2))>>> r = Chan(c)>>> D = C.decoder( InformationSet , Integer(8))>>> c == D.decode_to_code(r) # long time
True

decoding_interval()
A pair of integers specifying the interval of number of errors this decoder will attempt to correct.
The interval includes both end values.
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: D = C.decoder("InformationSet", 2)
sage: D.decoding_interval()(0, 2)>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> D = C.decoder("InformationSet", Integer(2))>>> D.decoding_interval()(0, 2)

decoding_radius()
Return the maximal number of errors this decoder can decode.
EXAMPLES:
sage: C = codes.GolayCode(GF(2))
sage: D = C.decoder("InformationSet", 2)
sage: D.decoding_radius()
2>>> from sage.all import *>>> C = codes.GolayCode(GF(Integer(2)))>>> D = C.decoder("InformationSet", Integer(2))>>> D.decoding_radius()
2

static known_algorithms(dictionary=False)
Return the list of ISD algorithms that Sage knows.
Passing any of these to the constructor of sage.coding.information_set_decoder.
LinearCodeInformationSetDecoder will make the ISD decoder use that algorithm.
INPUT:• dictionary – optional. If set to True, return a dict mapping decoding algorithm name to its class.
OUTPUT: a list of strings or a dict from string to ISD algorithm class.
EXAMPLES:

294

Chapter 13. Decoding

Coding Theory, Release 10.4

sage: from sage.coding.information_set_decoder import␣
˓→LinearCodeInformationSetDecoder
sage: sorted(LinearCodeInformationSetDecoder.known_algorithms())[ Lee-Brickell ]>>> from sage.all import *>>> from sage.coding.information_set_decoder import␣
˓→LinearCodeInformationSetDecoder>>> sorted(LinearCodeInformationSetDecoder.known_algorithms())[ Lee-Brickell ]Guruswami-Sudan interpolation-based list decoding for Reed-Solomon codes:

13.2 Guruswami-Sudan decoder for (Generalized) Reed-Solomon
codes
REFERENCES:• [GS1999]• [Nie2013]
AUTHORS:• Johan S. R. Nielsen, original implementation (see [Nie] for details)• David Lucas, ported the original implementation in Sage
class sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder(code,
tau=None,parameters=None,interpolation_alg=None,root_finder=None)
Bases: Decoder
The Guruswami-Sudan list-decoding algorithm for decoding Generalized Reed-Solomon codes.
The Guruswami-Sudan algorithm is a polynomial time algorithm√︀ to decode beyond half the minimum distance ofthe code. It can decode up to the Johnson radius which is 𝑛 − (𝑛(𝑛 − 𝑑)), where 𝑛, 𝑑 is the length, respectively
minimum distance of the RS code. See [GS1999] for more details. It is a list-decoder meaning that it returns a list of
all closest codewords or their corresponding message polynomials. Note that the output of the decode_to_code
and decode_to_message methods are therefore lists.
The algorithm has two free parameters, the list size and the multiplicity, and these determine how many errors themethod will correct: generally, higher decoding radius requires larger values of these parameters. To decode all
the way to the Johnson radius, one generally needs values in the order of 𝑂(𝑛2 ), while decoding just one error lessrequires just 𝑂(𝑛).
This class has static methods for computing choices of parameters given the decoding radius or vice versa.
The Guruswami-Sudan consists of two computationally intensive steps: Interpolation and Root finding, either ofwhich can be completed in multiple ways. This implementation allows choosing the sub-algorithms among currently
implemented possibilities, or supplying your own.
INPUT:

13.2. Guruswami-Sudan decoder for (Generalized) Reed-Solomon codes295

Coding Theory, Release 10.4

• code – A code associated to this decoder.
• tau – (default: None) an integer, the number of errors one wants the 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.
• 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.
You can also supply your own function to perform the interpolation. See NOTE section for details on thesignature of this function.
• root_finder – (default: None) the rootfinding algorithm that will be used. The following possibilities
are currently available:– "Alekhnovich" – uses Alekhnovich’s algorithm.
– "RothRuckenstein" – uses Roth-Ruckenstein algorithm.
– 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 thesignature of this function.
Note: One has to provide either tau or parameters. If neither are given, an exception will be raised.
If one provides a function as root_finder, its signature has to be: my_rootfinder(Q,maxd=default_value,
precision=default_value). 𝑄 will be given as an element of𝐹 [𝑥][𝑦]. The function must return the roots as a list of polynomials over a univariate polynomial ring. See
roth_ruckenstein_root_finder() for an example.
If one provides a function as interpolation_alg,
its signature has to be:
my_inter(interpolation_points,tau,s_and_l,wy).
See sage.coding.
guruswami_sudan.interpolation.gs_interpolation_linalg() for an example.
EXAMPLES:
sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70)
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)>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(251)).list()[:Integer(250)],␣
˓→Integer(70))>>> D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau=Integer(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:296

Chapter 13. Decoding

Coding Theory, Release 10.4

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)>>> from sage.all import *>>> D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters=(Integer(1),˓→Integer(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_
˓→findersage: rf = roth_ruckenstein_root_finder
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)>>> from sage.all import *>>> from sage.coding.guruswami_sudan.gs_decoder import roth_ruckenstein_root_
˓→finder>>> rf = roth_ruckenstein_root_finder>>> D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters=(Integer(1),˓→Integer(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");␣
˓→DGuruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251)decoding 97 errors with parameters (1, 2)>>> from sage.all import *>>> D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters=(Integer(1),˓→Integer(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); D
Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251)decoding 97 errors with parameters (1, 2)>>> from sage.all import *>>> D = C.decoder("GuruswamiSudan", tau=Integer(97)); D
Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251)decoding 97 errors with parameters (1, 2)

13.2. Guruswami-Sudan decoder for (Generalized) Reed-Solomon codes297

Coding Theory, Release 10.4

decode_to_code(r)Return the list of all codeword within radius self.decoding_radius() of the received word 𝑟.
INPUT:• r – a received word, i.e. a vector in 𝐹 𝑛 where 𝐹 and 𝑛 are the base field respectively length of self.
code().
EXAMPLES:
sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder
sage: C = codes.GeneralizedReedSolomonCode(GF(17).list()[:15], 6)
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
sage: r = vector(GF(17), [3,13,12,0,0,7,5,1,8,11,15,12,14,7,10])
sage: r in C
False
sage: codewords = D.decode_to_code(r)sage: len(codewords)2
sage: c in codewords
True>>> from sage.all import *>>> GSD = codes.decoders.GRSGuruswamiSudanDecoder>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(17)).list()[:Integer(15)],
˓→ Integer(6))>>> D = GSD(C, tau=Integer(5))>>> c = vector(GF(Integer(17)), [Integer(3),Integer(13),Integer(12),
˓→Integer(0),Integer(0),Integer(7),Integer(5),Integer(1),Integer(8),˓→Integer(11),Integer(1),Integer(9),Integer(4),Integer(12),Integer(14)])>>> c in C
True>>> r = vector(GF(Integer(17)), [Integer(3),Integer(13),Integer(12),
˓→Integer(0),Integer(0),Integer(7),Integer(5),Integer(1),Integer(8),˓→Integer(11),Integer(15),Integer(12),Integer(14),Integer(7),Integer(10)])>>> r in C
False>>> codewords = D.decode_to_code(r)>>> len(codewords)
2>>> c in codewords
True

decode_to_message(r)Decode r to the list of polynomials whose encoding by self.code() is within Hamming distance self.
decoding_radius() of r.
INPUT:• r – a received word, i.e. a vector in 𝐹 𝑛 where 𝐹 and 𝑛 are the base field respectively length of self.
code().
EXAMPLES:
sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder
sage: C = codes.GeneralizedReedSolomonCode(GF(17).list()[:15], 6)(continues on next page)

298

Chapter 13. Decoding

Coding Theory, Release 10.4

(continued from previous page)

sage: D = GSD(C, tau=5)
sage: F.<x> = GF(17)[]
sage: m = 13*x^4 + 7*x^3 + 10*x^2 + 14*x + 3
sage: c = D.connected_encoder().encode(m)sage: r = vector(GF(17), [3,13,12,0,0,7,5,1,8,11,15,12,14,7,10])
sage: (c-r).hamming_weight()
5sage: messages = D.decode_to_message(r)sage: len(messages)
2
sage: m in messages
True>>> from sage.all import *>>> GSD = codes.decoders.GRSGuruswamiSudanDecoder>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(17)).list()[:Integer(15)],
˓→ Integer(6))>>> D = GSD(C, tau=Integer(5))>>> F = GF(Integer(17))[ x ]; (x,) = F._first_ngens(1)>>> m = Integer(13)*x**Integer(4) + Integer(7)*x**Integer(3) +␣˓→Integer(10)*x**Integer(2) + Integer(14)*x + Integer(3)>>> c = D.connected_encoder().encode(m)>>> r = vector(GF(Integer(17)), [Integer(3),Integer(13),Integer(12),
˓→Integer(0),Integer(0),Integer(7),Integer(5),Integer(1),Integer(8),˓→Integer(11),Integer(15),Integer(12),Integer(14),Integer(7),Integer(10)])>>> (c-r).hamming_weight()
5>>> messages = D.decode_to_message(r)>>> len(messages)
2>>> m in messages
True

decoding_radius()
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.decoding_radius()
97>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(251)).
˓→list()[:Integer(250)], Integer(70))>>> D = C.decoder("GuruswamiSudan", tau=Integer(97))>>> 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.decoding_radius()
105

13.2. Guruswami-Sudan decoder for (Generalized) Reed-Solomon codes299

Coding Theory, Release 10.4>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(251)).
˓→list()[:Integer(250)], Integer(70))>>> D = C.decoder("GuruswamiSudan", parameters=(Integer(2),Integer(4)))>>> D.decoding_radius()
105

static gs_satisfactory(tau, s, l, C=None, n_k=None)
Return whether input parameters satisfy the governing equation of Guruswami-Sudan.
See [Nie2013] page 49, definition 3.3 and proposition 3.4 for details.
INPUT:• tau – an integer, number of errors one expects Guruswami-Sudan algorithm to correct• s – an integer, multiplicity parameter of Guruswami-Sudan algorithm• l – an integer, list size parameter• C – (default: None) a GeneralizedReedSolomonCode• n_k – (default: None) a tuple of integers, respectively the length and the dimension of the GeneralizedReedSolomonCode
Note: One has to provide either C or (n, k). If none or both are given, an exception will be raised.
EXAMPLES:
sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder
sage: tau, s, l = 97, 1, 2
sage: n, k = 250, 70
sage: GSD.gs_satisfactory(tau, s, l, n_k=(n, k))True>>> from sage.all import *>>> GSD = codes.decoders.GRSGuruswamiSudanDecoder>>> tau, s, l = Integer(97), Integer(1), Integer(2)>>> n, k = Integer(250), Integer(70)>>> 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: GSD.gs_satisfactory(tau, s, l, C=C)
True>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(251)).
˓→list()[:Integer(250)], Integer(70))>>> GSD.gs_satisfactory(tau, s, l, C=C)
True

Another example where s and l does not satisfy the equation:

300

Chapter 13. Decoding

Coding Theory, Release 10.4

sage: tau, s, l = 118, 47, 80
sage: GSD.gs_satisfactory(tau, s, l, n_k=(n, k))False>>> from sage.all import *>>> tau, s, l = Integer(118), Integer(47), Integer(80)>>> GSD.gs_satisfactory(tau, s, l, n_k=(n, k))
False

If one provides both C and n_k an exception is returned:
sage: tau, s, l = 97, 1, 2
sage: n, k = 250, 70
sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70)
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>>> from sage.all import *>>> tau, s, l = Integer(97), Integer(1), Integer(2)>>> n, k = Integer(250), Integer(70)>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(251)).
˓→list()[:Integer(250)], Integer(70))>>> 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: GSD.gs_satisfactory(tau, s, l)Traceback (most recent call last):...
ValueError: Please provide either the code or its length and dimension>>> from sage.all import *>>> GSD.gs_satisfactory(tau, s, l)Traceback (most recent call last):...
ValueError: Please provide either the code or its length and dimension

static guruswami_sudan_decoding_radius(C=None, n_k=None, l=None, s=None)
Return the maximal decoding radius of the Guruswami-Sudan decoder and the parameter choices needed forthis.
If s is set but l is not it will return the best decoding radius using this s alongside with the required l. Viceversa for l. If both are set, it returns the decoding radius given this parameter choice.
INPUT:• C – (default: None) a GeneralizedReedSolomonCode• n_k – (default: None) a pair of integers, respectively the length and the dimension of the GeneralizedReedSolomonCode• s – (default: None) an integer, the multiplicity parameter of Guruswami-Sudan algorithm

13.2. Guruswami-Sudan decoder for (Generalized) Reed-Solomon codes301

Coding Theory, Release 10.4

• l – (default: None) an integer, the list size parameter
Note: One has to provide either C or n_k. If none or both are given, an exception will be raised.
OUTPUT:• (tau, (s, l)) – where– tau is the obtained decoding radius, and– (s, l) are the multiplicity parameter and the list size parameter giving the radius
EXAMPLES:
sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder
sage: n, k = 250, 70
sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k))(118, (47, 89))>>> from sage.all import *>>> GSD = codes.decoders.GRSGuruswamiSudanDecoder>>> n, k = Integer(250), Integer(70)>>> 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: GSD.guruswami_sudan_decoding_radius(n_k=(n, k), s=3)(109, (3, 5))
sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k), l=7)(111, (4, 7))>>> from sage.all import *>>> n, k = Integer(250), Integer(70)>>> GSD.guruswami_sudan_decoding_radius(n_k=(n, k), s=Integer(3))(109, (3, 5))>>> GSD.guruswami_sudan_decoding_radius(n_k=(n, k), l=Integer(7))(111, (4, 7))

The function can also just compute the decoding radius given the parameters:sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k), s=2, l=6)(92, (2, 6))>>> from sage.all import *>>> GSD.guruswami_sudan_decoding_radius(n_k=(n, k), s=Integer(2),␣
˓→l=Integer(6))(92, (2, 6))interpolation_algorithm()
Return the interpolation algorithm that will be used.
Remember that its signature has to be: my_inter(interpolation_points,tau,s_and_l,wy).
See sage.coding.guruswami_sudan.interpolation.
gs_interpolation_linalg() for an example.
EXAMPLES:
302

Chapter 13. Decoding

Coding Theory, Release 10.4

sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70)
sage: D = C.decoder("GuruswamiSudan", tau=97)
sage: D.interpolation_algorithm()<function gs_interpolation_lee_osullivan at 0x...>>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(251)).
˓→list()[:Integer(250)], Integer(70))>>> D = C.decoder("GuruswamiSudan", tau=Integer(97))>>> D.interpolation_algorithm()<function gs_interpolation_lee_osullivan at 0x...>list_size()
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.list_size()2>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(251)).
˓→list()[:Integer(250)], Integer(70))>>> D = C.decoder("GuruswamiSudan", tau=Integer(97))>>> D.list_size()2

multiplicity()
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.multiplicity()1>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(251)).
˓→list()[:Integer(250)], Integer(70))>>> D = C.decoder("GuruswamiSudan", tau=Integer(97))>>> D.multiplicity()
1parameters()
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.parameters()(1, 2)

13.2. Guruswami-Sudan decoder for (Generalized) Reed-Solomon codes303

Coding Theory, Release 10.4>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(251)).
˓→list()[:Integer(250)], Integer(70))>>> D = C.decoder("GuruswamiSudan", tau=Integer(97))>>> D.parameters()(1, 2)

static parameters_given_tau(tau, C=None, n_k=None)
Return the smallest possible multiplicity and list size given the given parameters of the code and decoding
radius.
INPUT:• tau – an integer, number of errors one wants the Guruswami-Sudan algorithm to correct• C – (default: None) a GeneralizedReedSolomonCode• n_k – (default: None) a pair of integers, respectively the length and the dimension of the GeneralizedReedSolomonCode
OUTPUT:• (s, l) – a pair of integers, where:– s is the multiplicity parameter, and– l is the list size parameter.
Note: One should to provide either C or (n, k). If neither or both are given, an exception will be raised.
EXAMPLES:
sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder
sage: tau, n, k = 97, 250, 70
sage: GSD.parameters_given_tau(tau, n_k=(n, k))(1, 2)>>> from sage.all import *>>> GSD = codes.decoders.GRSGuruswamiSudanDecoder>>> tau, n, k = Integer(97), Integer(250), Integer(70)>>> 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: GSD.parameters_given_tau(tau, n_k=(n, k))(47, 89)>>> from sage.all import *>>> tau, n, k = Integer(118), Integer(250), Integer(70)>>> GSD.parameters_given_tau(tau, n_k=(n, k))(47, 89)

Choosing a decoding radius which is too large results in an errors:

304

Chapter 13. Decoding

Coding Theory, Release 10.4

sage: tau = 200
sage: GSD.parameters_given_tau(tau, n_k=(n, k))Traceback (most recent call last):...
ValueError: The decoding radius must be less thanthe Johnson radius (which is 118.66)>>> from sage.all import *>>> tau = Integer(200)>>> GSD.parameters_given_tau(tau, n_k=(n, k))Traceback (most recent call last):...
ValueError: The decoding radius must be less thanthe Johnson radius (which is 118.66)

rootfinding_algorithm()
Return the rootfinding algorithm that will be used.
Remember that its signature has to be: my_rootfinder(Q, maxd=default_value, precision=default_value). See roth_ruckenstein_root_finder() for an example.
EXAMPLES:
sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70)
sage: D = C.decoder("GuruswamiSudan", tau=97)
sage: D.rootfinding_algorithm()<function alekhnovich_root_finder at 0x...>>>> from sage.all import *>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(251)).
˓→list()[:Integer(250)], Integer(70))>>> D = C.decoder("GuruswamiSudan", tau=Integer(97))>>> D.rootfinding_algorithm()<function alekhnovich_root_finder at 0x...>sage.coding.guruswami_sudan.gs_decoder.alekhnovich_root_finder(p, maxd=None,
precision=None)
Wrapper for Alekhnovich’s algorithm to compute the roots of a polynomial with coefficients in 𝐹 [𝑥].
sage.coding.guruswami_sudan.gs_decoder.n_k_params(C, n_k)
Internal helper function for the GRSGuruswamiSudanDecoder class for allowing to specify either a GRS code
𝐶 or the length and dimensions 𝑛, 𝑘 directly, in all the static functions.
If neither 𝐶 or 𝑛, 𝑘 were specified to those functions, an appropriate error should be raised. Otherwise, 𝑛, 𝑘 of thecode or the supplied tuple directly is returned.
INPUT:• C – A GRS code or None
• n_k – A tuple (𝑛, 𝑘) being length and dimension of a GRS code, or None.
OUTPUT:• n_k – A tuple (𝑛, 𝑘) being length and dimension of a GRS code.
EXAMPLES:

13.2. Guruswami-Sudan decoder for (Generalized) Reed-Solomon codes305

Coding Theory, Release 10.4

sage: from sage.coding.guruswami_sudan.gs_decoder import n_k_params
sage: n_k_params(None, (10, 5))(10, 5)sage: C = codes.GeneralizedReedSolomonCode(GF(11).list()[:10], 5)
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))Traceback (most recent call last):...
ValueError: Please provide only the code or its length and dimension>>> from sage.all import *>>> from sage.coding.guruswami_sudan.gs_decoder import n_k_params>>> n_k_params(None, (Integer(10), Integer(5)))(10, 5)>>> C = codes.GeneralizedReedSolomonCode(GF(Integer(11)).list()[:Integer(10)],␣
˓→Integer(5))>>> n_k_params(C, None)(10, 5)>>> n_k_params(None,None)
Traceback (most recent call last):...
ValueError: Please provide either the code or its length and dimension>>> n_k_params(C, (Integer(12), Integer(2)))
Traceback (most recent call last):...
ValueError: Please provide only the code or its length and dimension

sage.coding.guruswami_sudan.gs_decoder.roth_ruckenstein_root_finder(p, maxd=None,
precision=None)
Wrapper for Roth-Ruckenstein algorithm to compute the roots of a polynomial with coefficients in 𝐹 [𝑥].

13.3 Interpolation algorithms for the Guruswami-Sudan decoder
AUTHORS:• Johan S. R. Nielsen, original implementation (see [Nie] for details)• David Lucas, ported the original implementation in Sagesage.coding.guruswami_sudan.interpolation.gs_interpolation_lee_osullivan(points,tau,
parameters,
wy)
Returns an interpolation polynomial Q(x,y) for the given input using the module-based algorithm of Lee and O’Sullivan.
This algorithm constructs an explicit (ℓ + 1) × (ℓ + 1) polynomial matrix whose rows span the F𝑞 [𝑥] module of
all interpolation polynomials. It then runs a row reduction algorithm to find a low-shifted degree vector in this row

306

Chapter 13. Decoding

Coding Theory, Release 10.4

space, corresponding to a low weighted-degree interpolation polynomial.
INPUT:• points – a list of tuples (xi, yi) such that we seek Q with (xi,yi) being a root of Q with multiplicitys.
• 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 𝑦-weight, where we seek Q of low (1,wy) weighted degree.
EXAMPLES:
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: tau = 1
sage: params = (1, 1)
sage: wy = 1
sage: Q = gs_interpolation_lee_osullivan(points, tau, params, wy)
sage: Q / Q.lc() # make monicx^3*y + 2*x^3 - x^2*y + 5*x^2 + 5*x*y - 5*x + 2*y - 4>>> from sage.all import *>>> from sage.coding.guruswami_sudan.interpolation import gs_interpolation_lee_
˓→osullivan>>> F = GF(Integer(11))>>> points = [(F(Integer(0)), F(Integer(2))), (F(Integer(1)), F(Integer(5))),␣
˓→(F(Integer(2)), F(Integer(0))), (F(Integer(3)), F(Integer(4))),...
(F(Integer(4)), F(Integer(9))), (F(Integer(5)), F(Integer(1))),␣
˓→(F(Integer(6)), F(Integer(9))), (F(Integer(7)), F(Integer(10)))]>>> tau = Integer(1)>>> params = (Integer(1), Integer(1))>>> wy = Integer(1)>>> Q = gs_interpolation_lee_osullivan(points, tau, params, wy)>>> Q / Q.lc() # make monicx^3*y + 2*x^3 - x^2*y + 5*x^2 + 5*x*y - 5*x + 2*y - 4

sage.coding.guruswami_sudan.interpolation.gs_interpolation_linalg(points, tau,parameters, wy)
Compute an interpolation polynomial 𝑄(𝑥, 𝑦) for the Guruswami-Sudan algorithm by solving a linear system of
equations.
𝑄 is a bivariate polynomial over the field of the points, such that the polynomial has a zero of multiplicity at least𝑠 at each of the points, where 𝑠 is the multiplicity parameter. Furthermore, its (1, wy)-weighted degree shouldbe less than _interpolation_max_weighted_deg(n, tau, wy), where n is the number of points
INPUT:• points – a list of tuples (xi, yi) such that we seek Q with (xi,yi) being a root of Q with multiplicitys.
• tau – an integer, the number of errors one wants to decode.

13.3. Interpolation algorithms for the Guruswami-Sudan decoder

307

Coding Theory, Release 10.4

• 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 𝑦-weight, where we seek 𝑄 of low (1, wy)-weighted degree.
EXAMPLES:
The following parameters arise from Guruswami-Sudan decoding of an [6,2,5] GRS code over F(11) with multiplicity 2 and list size 4:
sage: from sage.coding.guruswami_sudan.interpolation import gs_interpolation_
˓→linalgsage: 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: 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>>> from sage.all import *>>> from sage.coding.guruswami_sudan.interpolation import gs_interpolation_linalg>>> F = GF(Integer(11))>>> points = [(F(x), F(y))...
for (x, y) in [(Integer(0), Integer(5)), (Integer(1), Integer(1)),␣
˓→(Integer(2), Integer(4)), (Integer(3), Integer(6)), (Integer(4), Integer(3)),␣
˓→(Integer(5), Integer(3))]]>>> tau = Integer(3)>>> params = (Integer(2), Integer(4))>>> wy = Integer(1)>>> 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

We verify that the interpolation polynomial has a zero of multiplicity at least 2 in each point:
sage: all( Q(x=a, y=b).is_zero() for (a,b) in points )Truesage: x,y = Q.parent().gens()
sage: dQdx = Q.derivative(x)sage: all( dQdx(x=a, y=b).is_zero() for (a,b) in points )Truesage: dQdy = Q.derivative(y)sage: all( dQdy(x=a, y=b).is_zero() for (a,b) in points )True>>> from sage.all import *>>> all( Q(x=a, y=b).is_zero() for (a,b) in points )True>>> x,y = Q.parent().gens()>>> dQdx = Q.derivative(x)>>> all( dQdx(x=a, y=b).is_zero() for (a,b) in points )True>>> dQdy = Q.derivative(y)(continues on next page)

308

Chapter 13. Decoding

Coding Theory, Release 10.4

(continued from previous page)>>> all( dQdy(x=a, y=b).is_zero() for (a,b) in points )True

sage.coding.guruswami_sudan.interpolation.lee_osullivan_module(points, parameters,
wy)
Return the analytically straight-forward basis for the F𝑞 [𝑥] module containing all interpolation polynomials, as
according to Lee and O’Sullivan.
The module is constructed in the following way: Let 𝑅(𝑥) be the Lagrange
interpolation polynomial through the∏︀𝑛sought interpolation points (𝑥𝑖 , 𝑦𝑖 ), i.e. 𝑅(𝑥𝑖 ) = 𝑦𝑖 . Let 𝐺(𝑥) = 𝑖=1 (𝑥 − 𝑥𝑖 ). Then the 𝑖’th row of the basis
matrix of the module is the coefficient-vector of the following polynomial in F𝑞 [𝑥][𝑦]:𝑃𝑖 (𝑥, 𝑦) = 𝐺(𝑥)[𝑖−𝑠] (𝑦 − 𝑅(𝑥))𝑖−[𝑖−𝑠] 𝑦 [𝑖−𝑠] ,where [𝑎] for real 𝑎 is 𝑎 when 𝑎 > 0 and 0 otherwise. It is easily seen that 𝑃𝑖 (𝑥, 𝑦) is an interpolation polynomial,i.e. it is zero with multiplicity at least 𝑠 on each of the points (𝑥𝑖 , 𝑦𝑖 ).
INPUT:• points – a list of tuples (xi, yi) such that we seek 𝑄 with (xi,yi) being a root of 𝑄 with multiplicity𝑠.
• 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 𝑦-weight, where we seek 𝑄 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: params = (1, 1)
sage: wy = 1
sage: lee_osullivan_module(points, params, wy)[x^8 + 5*x^7 + 3*x^6 + 9*x^5 + 4*x^4 + 2*x^3 + 9*x
0][ 10*x^7 + 4*x^6 + 9*x^4 + 7*x^3 + 2*x^2 + 9*x + 9
1]>>> from sage.all import *>>> from sage.coding.guruswami_sudan.interpolation import lee_osullivan_module>>> F = GF(Integer(11))>>> points = [(F(Integer(0)), F(Integer(2))), (F(Integer(1)), F(Integer(5))),␣
˓→(F(Integer(2)), F(Integer(0))), (F(Integer(3)), F(Integer(4))),...
(F(Integer(4)), F(Integer(9))), (F(Integer(5)), F(Integer(1))),␣
˓→(F(Integer(6)), F(Integer(9))), (F(Integer(7)), F(Integer(10)))]>>> params = (Integer(1), Integer(1))>>> wy = Integer(1)>>> lee_osullivan_module(points, params, wy)[x^8 + 5*x^7 + 3*x^6 + 9*x^5 + 4*x^4 + 2*x^3 + 9*x
0][ 10*x^7 + 4*x^6 + 9*x^4 + 7*x^3 + 2*x^2 + 9*x + 9
1]

13.3. Interpolation algorithms for the Guruswami-Sudan decoder309

Coding Theory, Release 10.4

13.4 Guruswami-Sudan utility methods
AUTHORS:• Johan S. R. Nielsen, original implementation (see [Nie] for details)• David Lucas, ported the original implementation in Sagesage.coding.guruswami_sudan.utils.gilt(x)Returns the greatest integer smaller than x.
EXAMPLES:
sage: from sage.coding.guruswami_sudan.utils import gilt
sage: gilt(43)42>>> from sage.all import *>>> from sage.coding.guruswami_sudan.utils import gilt>>> gilt(Integer(43))
42

It works with any type of numbers (not only integers):
sage: gilt(43.041)
43>>> from sage.all import *>>> gilt(RealNumber( 43.041 ))43

sage.coding.guruswami_sudan.utils.johnson_radius(n, d)
Returns the Johnson-radius for the code length 𝑛 and the minimum distance 𝑑.
√︀
The Johnson radius is defined as 𝑛 − (𝑛(𝑛 − 𝑑)).
INPUT:• n – an integer, the length of the code
• d – an integer, the minimum distance of the code
EXAMPLES:
sage: sage.coding.guruswami_sudan.utils.johnson_radius(250, 181)
˓→needs sage.symbolic-5*sqrt(690) + 250#␣>>> from sage.all import *>>> sage.coding.guruswami_sudan.utils.johnson_radius(Integer(250), Integer(181)) ␣˓→# needs sage.symbolic-5*sqrt(690) + 250

sage.coding.guruswami_sudan.utils.ligt(x)Returns the least integer greater than x.
EXAMPLES:

310

Chapter 13. Decoding

Coding Theory, Release 10.4

sage: from sage.coding.guruswami_sudan.utils import ligt
sage: ligt(41)42>>> from sage.all import *>>> from sage.coding.guruswami_sudan.utils import ligt>>> ligt(Integer(41))
42

It works with any type of numbers (not only integers):
sage: ligt(41.041)
42>>> from sage.all import *>>> ligt(RealNumber( 41.041 ))42

sage.coding.guruswami_sudan.utils.polynomial_to_list(p, len)Returns p as a list of its coefficients of length len.
INPUT:• p – a polynomial• len – an integer. If len is smaller than the degree of p, the returned list will be of size degree of p, else it
will be of size len.
EXAMPLES:
sage: from sage.coding.guruswami_sudan.utils import polynomial_to_list
sage: F.<x> = GF(41)[]
sage: p = 9*x^2 + 8*x + 37
sage: polynomial_to_list(p, 4)[37, 8, 9, 0]>>> from sage.all import *>>> from sage.coding.guruswami_sudan.utils import polynomial_to_list>>> F = GF(Integer(41))[ x ]; (x,) = F._first_ngens(1)>>> p = Integer(9)*x**Integer(2) + Integer(8)*x + Integer(37)>>> polynomial_to_list(p, Integer(4))[37, 8, 9, 0]

sage.coding.guruswami_sudan.utils.solve_degree2_to_integer_range(a, b, c)
Returns the greatest integer range [𝑖1 , 𝑖2 ] such that 𝑖1 > 𝑥1 and 𝑖2 < 𝑥2 where 𝑥1 , 𝑥2 are the two zeroes of theequation in 𝑥: 𝑎𝑥2 + 𝑏𝑥 + 𝑐 = 0.
If there is no real solution to the equation, it returns an empty range with negative coefficients.
INPUT:• a, b and c – coefficients of a second degree equation, a being the coefficient of the higher degree term.
EXAMPLES:
sage: from sage.coding.guruswami_sudan.utils import solve_degree2_to_integer_range
sage: solve_degree2_to_integer_range(1, -5, 1)#␣˓→needs sage.symbolic(1, 4)

13.4. Guruswami-Sudan utility methods

311

Coding Theory, Release 10.4>>> from sage.all import *>>> from sage.coding.guruswami_sudan.utils import solve_degree2_to_integer_range>>> solve_degree2_to_integer_range(Integer(1), -Integer(5), Integer(1))␣˓→# needs sage.symbolic(1, 4)

If there is no real solution:
sage: solve_degree2_to_integer_range(50, 5, 42)(-2, -1)>>> from sage.all import *>>> solve_degree2_to_integer_range(Integer(50), Integer(5), Integer(42))(-2, -1)

312

Chapter 13. Decoding

CHAPTERFOURTEEN

AUTOMORPHISM GROUPS OF LINEAR CODES

14.1 Canonical forms and automorphism group computation for linear codes over finite fields
We implemented the algorithm described in [Feu2009] which computes the unique semilinearly isometric code (canonicalform) in the equivalence class of a given linear code C. Furthermore, this algorithm will return the automorphism groupof C, too.
The algorithm should be started via a further class LinearCodeAutGroupCanLabel. This class removes duplicatedcolumns (up to multiplications by units) and zero columns. Hence, we can suppose that the input for the algorithm
developed here is a set of points in 𝑃 𝐺(𝑘 − 1, 𝑞).
The implementation is based on the class sage.groups.perm_gps.partn_ref2.refinement_generic.
PartitionRefinement_generic. See the description of this algorithm in sage.groups.perm_gps.
partn_ref2.refinement_generic. In the language given there, we have to implement the group action of
𝐺 = (𝐺𝐿(𝑘, 𝑞) × F*𝑞 𝑛 ) o 𝐴𝑢𝑡(F𝑞 ) on the set 𝑋 = (F𝑘𝑞 )𝑛 of 𝑘 × 𝑛 matrices over F𝑞 (with the above restrictions).
The derived class here implements the stabilizers 𝐺Π(𝐼) (𝑥) of the projections Π(𝐼) (𝑥) of 𝑥 to the coordinates specified
in the sequence 𝐼. Furthermore, we implement the inner minimization, i.e. the computation of a canonical form of the
projection Π(𝐼) (𝑥) under the action of 𝐺Π(𝐼 (𝑖−1) ) (𝑥) . Finally, we provide suitable homomorphisms of group actions forthe refinements and methods to compute the applied group elements in 𝐺 o 𝑆𝑛 .
The algorithm also uses Jeffrey Leon’s idea of maintaining an invariant set of codewords which is computed in the
beginning, see _init_point_hyperplane_incidence(). An example for such a set is the set of all codewords of weight ≤ 𝑤 for some uniquely defined 𝑤. In our case, we interpret the codewords as a set of hyperplanes (via the corresponding information word) and compute invariants of the bipartite, colored derived subgraphof the point-hyperplane incidence graph, see PartitionRefinementLinearCode._point_refine() andPartitionRefinementLinearCode._hyp_refine().
Since we are interested in subspaces (linear codes) instead of matrices,
our group elements
returnedinPartitionRefinementLinearCode.get_transporter()andPartitionRefinementLinearCode.get_autom_gens() will be elements in the group (F*𝑞 𝑛 o 𝐴𝑢𝑡(F𝑞 )) o
𝑆𝑛 = (F*𝑞 𝑛 o (𝐴𝑢𝑡(F𝑞 ) × 𝑆𝑛 ).
AUTHORS:• Thomas Feulner (2012-11-15): initial version
REFERENCES:• [Feu2009]
EXAMPLES:
Get the canonical form of the Simplex code:313

Coding Theory, Release 10.4

sage: from sage.coding.codecan.codecan import PartitionRefinementLinearCodesage: mat = codes.HammingCode(GF(3), 3).dual_code().generator_matrix()
sage: P = PartitionRefinementLinearCode(mat.ncols(), mat)sage: cf = P.get_canonical_form(); cf[1 0 0 0 0 1 1 1 1 1 1 1 1]
[0 1 0 1 1 0 0 1 1 2 2 1 2]
[0 0 1 1 2 1 2 1 2 1 2 0 0]>>> from sage.all import *>>> from sage.coding.codecan.codecan import PartitionRefinementLinearCode>>> mat = codes.HammingCode(GF(Integer(3)), Integer(3)).dual_code().generator_matrix()>>> P = PartitionRefinementLinearCode(mat.ncols(), mat)>>> cf = P.get_canonical_form(); cf[1 0 0 0 0 1 1 1 1 1 1 1 1]
[0 1 0 1 1 0 0 1 1 2 2 1 2]
[0 0 1 1 2 1 2 1 2 1 2 0 0]

The transporter element is a group element which maps the input to its canonical form:
sage: cf.echelon_form() == (P.get_transporter() * mat).echelon_form()True>>> from sage.all import *>>> cf.echelon_form() == (P.get_transporter() * mat).echelon_form()
True

The automorphism group of the input, i.e. the stabilizer under this group action, is returned by generators:
sage: P.get_autom_order_permutation() == GL(3, GF(3)).order()/(len(GF(3))-1)
True
sage: A = P.get_autom_gens()
sage: all((a*mat).echelon_form() == mat.echelon_form() for a in A)
True>>> from sage.all import *>>> P.get_autom_order_permutation() == GL(Integer(3), GF(Integer(3))).order()/
˓→(len(GF(Integer(3)))-Integer(1))
True>>> A = P.get_autom_gens()>>> all((a*mat).echelon_form() == mat.echelon_form() for a in A)
True

class sage.coding.codecan.codecan.InnerGroupBases: object
This class implements the stabilizers 𝐺Π(𝐼) (𝑥) described in sage.groups.perm_gps.partn_ref2.
refinement_generic with 𝐺 = (𝐺𝐿(𝑘, 𝑞) × F𝑛𝑞 ) o 𝐴𝑢𝑡(F𝑞 ).
Those stabilizers can be stored as triples:• rank – an integer in {0, . . . , 𝑘}
• row_partition – a partition of {0, . . . , 𝑘 − 1} with discrete cells for all integers 𝑖 ≥ rank.
• frob_pow – an integer 𝑠 in {0, . . . , 𝑟 − 1} if 𝑞 = 𝑝𝑟
The group 𝐺Π(𝐼) (𝑥) contains all elements (𝐴, 𝜙, 𝛼) ∈ 𝐺, where314

Chapter 14. Automorphism Groups of Linear CodesCoding Theory, Release 10.4

• 𝐴 is a 2 × 2 blockmatrix, whose upper left matrix is a 𝑘 × 𝑘 diagonal matrix whose entries 𝐴𝑖,𝑖 are constanton the cells of the partition row_partition. The lower left matrix is zero. And the right part is arbitrary.
• The support of the columns given by 𝑖 ∈ 𝐼 intersect exactly one cell of the partition. The entry 𝜙𝑖 is equal tothe entries of the corresponding diagonal entry of 𝐴.
• 𝛼 is a power of 𝜏 𝑠 , where 𝜏 denotes the Frobenius automorphism of the finite field F𝑞 and 𝑠 = frob_pow.
See [Feu2009] for more details.
column_blocks(mat)Let mat be a matrix which is stabilized by self having no zero columns. We know that for each column of
mat there is a uniquely defined cell in self.row_partition having a nontrivial intersection with thesupport of this particular column.
This function returns a partition (as list of lists) of the columns indices according to the partition of the rows
given by self.
EXAMPLES:
sage: from sage.coding.codecan.codecan import InnerGroupsage: I = InnerGroup(3)sage: mat = Matrix(GF(3), [[0,1,0],[1,0,0], [0,0,1]])
sage: I.column_blocks(mat)[[1], [0], [2]]>>> from sage.all import *>>> from sage.coding.codecan.codecan import InnerGroup>>> I = InnerGroup(Integer(3))>>> mat = Matrix(GF(Integer(3)), [[Integer(0),Integer(1),Integer(0)],˓→[Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(0),Integer(1)]])>>> I.column_blocks(mat)[[1], [0], [2]]get_frob_pow()
Return the power of the Frobenius automorphism which generates the corresponding component of self.
EXAMPLES:
sage: from sage.coding.codecan.codecan import InnerGroupsage: I = InnerGroup(10)sage: I.get_frob_pow()
1>>> from sage.all import *>>> from sage.coding.codecan.codecan import InnerGroup>>> I = InnerGroup(Integer(10))>>> I.get_frob_pow()
1

class sage.coding.codecan.codecan.PartitionRefinementLinearCode
Bases: PartitionRefinement_genericSee sage.coding.codecan.codecan.
EXAMPLES:
sage: from sage.coding.codecan.codecan import PartitionRefinementLinearCodesage: mat = codes.HammingCode(GF(3), 3).dual_code().generator_matrix()(continues on next page)

14.1. Canonical forms and automorphism group computation for linear codes over finite fields315

Coding Theory, Release 10.4

(continued from previous page)

sage: P = PartitionRefinementLinearCode(mat.ncols(), mat)sage: cf = P.get_canonical_form(); cf[1 0 0 0 0 1 1 1 1 1 1 1 1]
[0 1 0 1 1 0 0 1 1 2 2 1 2]
[0 0 1 1 2 1 2 1 2 1 2 0 0]>>> from sage.all import *>>> from sage.coding.codecan.codecan import PartitionRefinementLinearCode>>> mat = codes.HammingCode(GF(Integer(3)), Integer(3)).dual_code().generator_
˓→matrix()>>> P = PartitionRefinementLinearCode(mat.ncols(), mat)>>> cf = P.get_canonical_form(); cf[1 0 0 0 0 1 1 1 1 1 1 1 1]
[0 1 0 1 1 0 0 1 1 2 2 1 2]
[0 0 1 1 2 1 2 1 2 1 2 0 0]
sage: cf.echelon_form() == (P.get_transporter() * mat).echelon_form()True>>> from sage.all import *>>> cf.echelon_form() == (P.get_transporter() * mat).echelon_form()True
sage: P.get_autom_order_permutation() == GL(3, GF(3)).order()/(len(GF(3))-1)
True
sage: A = P.get_autom_gens()
sage: all((a*mat).echelon_form() == mat.echelon_form() for a in A)
True>>> from sage.all import *>>> P.get_autom_order_permutation() == GL(Integer(3), GF(Integer(3))).order()/
˓→(len(GF(Integer(3)))-Integer(1))
True>>> A = P.get_autom_gens()>>> all((a*mat).echelon_form() == mat.echelon_form() for a in A)
True

get_autom_gens()
Return generators of the automorphism group of the initial matrix.
EXAMPLES:
sage: from sage.coding.codecan.codecan import PartitionRefinementLinearCodesage: mat = codes.HammingCode(GF(3), 3).dual_code().generator_matrix()
sage: P = PartitionRefinementLinearCode(mat.ncols(), mat)sage: A = P.get_autom_gens()
sage: all((a*mat).echelon_form() == mat.echelon_form() for a in A)
True>>> from sage.all import *>>> from sage.coding.codecan.codecan import PartitionRefinementLinearCode>>> mat = codes.HammingCode(GF(Integer(3)), Integer(3)).dual_code().generator_
˓→matrix()>>> P = PartitionRefinementLinearCode(mat.ncols(), mat)(continues on next page)

316

Chapter 14. Automorphism Groups of Linear CodesCoding Theory, Release 10.4

(continued from previous page)>>> A = P.get_autom_gens()>>> all((a*mat).echelon_form() == mat.echelon_form() for a in A)
True

get_autom_order_inner_stabilizer()
Return the order of the stabilizer of the initial matrix under the action of the inner group 𝐺.
EXAMPLES:
sage: from sage.coding.codecan.codecan import PartitionRefinementLinearCodesage: mat = codes.HammingCode(GF(3), 3).dual_code().generator_matrix()
sage: P = PartitionRefinementLinearCode(mat.ncols(), mat)sage: P.get_autom_order_inner_stabilizer()2
sage: mat2 = Matrix(GF(4, a ), [[1,0,1], [0,1,1]])
sage: P2 = PartitionRefinementLinearCode(mat2.ncols(), mat2)
sage: P2.get_autom_order_inner_stabilizer()
6>>> from sage.all import *>>> from sage.coding.codecan.codecan import PartitionRefinementLinearCode>>> mat = codes.HammingCode(GF(Integer(3)), Integer(3)).dual_code().generator_
˓→matrix()>>> P = PartitionRefinementLinearCode(mat.ncols(), mat)>>> P.get_autom_order_inner_stabilizer()2>>> mat2 = Matrix(GF(Integer(4), a ), [[Integer(1),Integer(0),Integer(1)],␣
˓→[Integer(0),Integer(1),Integer(1)]])>>> P2 = PartitionRefinementLinearCode(mat2.ncols(), mat2)>>> P2.get_autom_order_inner_stabilizer()6

get_canonical_form()
Return the canonical form for this matrix.
EXAMPLES:
sage: from sage.coding.codecan.codecan import PartitionRefinementLinearCodesage: mat = codes.HammingCode(GF(3), 3).dual_code().generator_matrix()
sage: P1 = PartitionRefinementLinearCode(mat.ncols(), mat)sage: CF1 = P1.get_canonical_form()
sage: s = SemimonomialTransformationGroup(GF(3), mat.ncols()).an_element()
sage: P2 = PartitionRefinementLinearCode(mat.ncols(), s*mat)sage: CF1 == P2.get_canonical_form()True>>> from sage.all import *>>> from sage.coding.codecan.codecan import PartitionRefinementLinearCode>>> mat = codes.HammingCode(GF(Integer(3)), Integer(3)).dual_code().generator_
˓→matrix()>>> P1 = PartitionRefinementLinearCode(mat.ncols(), mat)>>> CF1 = P1.get_canonical_form()>>> s = SemimonomialTransformationGroup(GF(Integer(3)), mat.ncols()).an_˓→element()>>> P2 = PartitionRefinementLinearCode(mat.ncols(), s*mat)(continues on next page)

14.1. Canonical forms and automorphism group computation for linear codes over finite fields317

Coding Theory, Release 10.4

(continued from previous page)>>> CF1 == P2.get_canonical_form()
True

get_transporter()
Return the transporter element, mapping the initial matrix to its canonical form.
EXAMPLES:
sage: from sage.coding.codecan.codecan import PartitionRefinementLinearCodesage: mat = codes.HammingCode(GF(3), 3).dual_code().generator_matrix()
sage: P = PartitionRefinementLinearCode(mat.ncols(), mat)sage: CF = P.get_canonical_form()
sage: t = P.get_transporter()sage: (t*mat).echelon_form() == CF.echelon_form()True>>> from sage.all import *>>> from sage.coding.codecan.codecan import PartitionRefinementLinearCode>>> mat = codes.HammingCode(GF(Integer(3)), Integer(3)).dual_code().generator_
˓→matrix()>>> P = PartitionRefinementLinearCode(mat.ncols(), mat)>>> CF = P.get_canonical_form()>>> t = P.get_transporter()>>> (t*mat).echelon_form() == CF.echelon_form()
True

14.2 Canonical forms and automorphisms for linear codes over finite
fieldsWe implemented the algorithm described in [Feu2009] which computes, a unique code (canonical form) in the equivalenceclass of a given linear code 𝐶 ≤ F𝑛𝑞 . Furthermore, this algorithm will return the automorphism group of 𝐶, too. You
will find more details about the algorithm in the documentation of the class LinearCodeAutGroupCanLabel.
The equivalence of codes is modeled as a group action by the group 𝐺 = F*𝑞 𝑛 o (𝐴𝑢𝑡(F𝑞 ) × 𝑆𝑛 ) on the set of subspacesof F𝑛𝑞 . The group 𝐺 will be called the semimonomial group of degree 𝑛.
The algorithm is started by initializing the class LinearCodeAutGroupCanLabel. When the object gets available,
all computations are already finished and you can access the relevant data using the member functions:• get_canonical_form()• get_transporter()• get_autom_gens()
People do also use some weaker notions of equivalence, namely permutational equivalence and monomial equivalence(linear isometries). These can be seen as the subgroups 𝑆𝑛 and F*𝑞 𝑛 o 𝑆𝑛 of 𝐺. If you are interested in one of thesenotions, you can just pass the optional parameter algorithm_type.
A second optional parameter P allows you to restrict the group of permutations 𝑆𝑛 to a subgroup which respects thecoloring given by P.
AUTHORS:• Thomas Feulner (2012-11-15): initial version
EXAMPLES:
318

Chapter 14. Automorphism Groups of Linear CodesCoding Theory, Release 10.4

sage: from sage.coding.codecan.autgroup_can_label import LinearCodeAutGroupCanLabelsage: C = codes.HammingCode(GF(3), 3).dual_code()sage: P = LinearCodeAutGroupCanLabel(C)sage: P.get_canonical_form().generator_matrix()[1 0 0 0 0 1 1 1 1 1 1 1 1]
[0 1 0 1 1 0 0 1 1 2 2 1 2]
[0 0 1 1 2 1 2 1 2 1 2 0 0]
sage: LinearCode(P.get_transporter()*C.generator_matrix()) == P.get_canonical_form()True
sage: A = P.get_autom_gens()
sage: all(LinearCode(a*C.generator_matrix()) == C for a in A)
True
sage: P.get_autom_order() == GL(3, GF(3)).order()True>>> from sage.all import *>>> from sage.coding.codecan.autgroup_can_label import LinearCodeAutGroupCanLabel>>> C = codes.HammingCode(GF(Integer(3)), Integer(3)).dual_code()>>> P = LinearCodeAutGroupCanLabel(C)>>> P.get_canonical_form().generator_matrix()[1 0 0 0 0 1 1 1 1 1 1 1 1]
[0 1 0 1 1 0 0 1 1 2 2 1 2]
[0 0 1 1 2 1 2 1 2 1 2 0 0]>>> LinearCode(P.get_transporter()*C.generator_matrix()) == P.get_canonical_form()
True>>> A = P.get_autom_gens()>>> all(LinearCode(a*C.generator_matrix()) == C for a in A)
True>>> P.get_autom_order() == GL(Integer(3), GF(Integer(3))).order()True

If the dimension of the dual code is smaller, we will work on this code:
sage: C2 = codes.HammingCode(GF(3), 3)
sage: P2 = LinearCodeAutGroupCanLabel(C2)sage: P2.get_canonical_form().parity_check_matrix() == P.get_canonical_form().
˓→generator_matrix()True>>> from sage.all import *>>> C2 = codes.HammingCode(GF(Integer(3)), Integer(3))>>> P2 = LinearCodeAutGroupCanLabel(C2)>>> P2.get_canonical_form().parity_check_matrix() == P.get_canonical_form().generator_
˓→matrix()
True

There is a specialization of this algorithm to pass a coloring on the coordinates. This is just a list of lists, telling thealgorithm which columns do share the same coloring:sage: C = codes.HammingCode(GF(4, a ), 3).dual_code()sage: P = LinearCodeAutGroupCanLabel(C, P=[ [0], [1], list(range(2, C.length())) ])sage: P.get_autom_order()864
sage: A = [a.get_perm() for a in P.get_autom_gens()]sage: H = SymmetricGroup(21).subgroup(A)sage: H.orbits()((1,),(continues on next page)

14.2. Canonical forms and automorphisms for linear codes over finite fields

319

Coding Theory, Release 10.4

(continued from previous page)(2,),(3, 5, 4),(6, 19, 16, 21, 9, 10, 15, 8, 20, 11, 14, 13, 7, 12, 18, 17))>>> from sage.all import *>>> C = codes.HammingCode(GF(Integer(4), a ), Integer(3)).dual_code()>>> P = LinearCodeAutGroupCanLabel(C, P=[ [Integer(0)], [Integer(1)],␣
˓→list(range(Integer(2), C.length())) ])>>> P.get_autom_order()864>>> A = [a.get_perm() for a in P.get_autom_gens()]>>> H = SymmetricGroup(Integer(21)).subgroup(A)>>> H.orbits()((1,),(2,),(3, 5, 4),(6, 19, 16, 21, 9, 10, 15, 8, 20, 11, 14, 13, 7, 12, 18, 17))

We can also restrict the group action to linear isometries:
sage: P = LinearCodeAutGroupCanLabel(C, algorithm_type="linear")sage: P.get_autom_order() == GL(3, GF(4, a )).order()True>>> from sage.all import *>>> P = LinearCodeAutGroupCanLabel(C, algorithm_type="linear")>>> P.get_autom_order() == GL(Integer(3), GF(Integer(4), a )).order()Trueand to the action of the symmetric group only:
sage: P = LinearCodeAutGroupCanLabel(C, algorithm_type="permutational")
sage: P.get_autom_order() == C.permutation_automorphism_group().order()True>>> from sage.all import *>>> P = LinearCodeAutGroupCanLabel(C, algorithm_type="permutational")>>> P.get_autom_order() == C.permutation_automorphism_group().order()
Trueclass sage.coding.codecan.autgroup_can_label.LinearCodeAutGroupCanLabel(C,P=None,algorithm_type='semilinear')
Bases: object
Canonical representatives and automorphism group computation for linear codes over finite fields.
There are several notions of equivalence for linear codes: Let 𝐶, 𝐷 be linear codes of length 𝑛 and dimension 𝑘.
The codes 𝐶 and 𝐷 are said to be• permutational equivalent, if there is some permutation 𝜋 ∈ 𝑆𝑛 such that (𝑐𝜋(0) , . . . , 𝑐𝜋(𝑛−1) ) ∈ 𝐷 for all𝑐 ∈ 𝐶.
• linear equivalent, if there is some permutation 𝜋 ∈ 𝑆𝑛 and a vector 𝜑 ∈ F*𝑞 𝑛 of units of length 𝑛 such that−1(𝑐𝜋(0) 𝜑−1
0 , . . . , 𝑐𝜋(𝑛−1) 𝜑𝑛−1 ) ∈ 𝐷 for all 𝑐 ∈ 𝐶.
320

Chapter 14. Automorphism Groups of Linear CodesCoding Theory, Release 10.4

• semilinear equivalent, if there is some permutation 𝜋 ∈ 𝑆𝑛 , a vector 𝜑 of units of length 𝑛 and a field−1
automorphism 𝛼 such that (𝛼(𝑐𝜋(0) )𝜑−1
0 , . . . , 𝛼(𝑐𝜋(𝑛−1) )𝜑𝑛−1 ) ∈ 𝐷 for all 𝑐 ∈ 𝐶.
These are group actions. This class provides an algorithm that will compute a unique representative 𝐷 in the orbitof the given linear code 𝐶. Furthermore, the group element 𝑔 with 𝑔 * 𝐶 = 𝐷 and the automorphism group of 𝐶
will be computed as well.
There is also the possibility to restrict the permutational part of this action to a Young subgroup of 𝑆𝑛 . This could beachieved by passing a partition 𝑃 (as a list of lists) of the set {0, . . . , 𝑛−1}. This is an option which is also available
in the computation of a canonical form of a graph, see sage.graphs.generic_graph.GenericGraph.
canonical_label().
EXAMPLES:
sage: from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabelsage: C = codes.HammingCode(GF(3), 3).dual_code()sage: P = LinearCodeAutGroupCanLabel(C)sage: P.get_canonical_form().generator_matrix()[1 0 0 0 0 1 1 1 1 1 1 1 1]
[0 1 0 1 1 0 0 1 1 2 2 1 2]
[0 0 1 1 2 1 2 1 2 1 2 0 0]
sage: LinearCode(P.get_transporter()*C.generator_matrix()) == P.get_canonical_
˓→form()True
sage: a = P.get_autom_gens()[0]sage: (a*C.generator_matrix()).echelon_form() == C.generator_matrix().echelon_
˓→form()True
sage: P.get_autom_order() == GL(3, GF(3)).order()True>>> from sage.all import *>>> from sage.coding.codecan.autgroup_can_label import LinearCodeAutGroupCanLabel>>> C = codes.HammingCode(GF(Integer(3)), Integer(3)).dual_code()>>> P = LinearCodeAutGroupCanLabel(C)>>> P.get_canonical_form().generator_matrix()[1 0 0 0 0 1 1 1 1 1 1 1 1]
[0 1 0 1 1 0 0 1 1 2 2 1 2]
[0 0 1 1 2 1 2 1 2 1 2 0 0]>>> LinearCode(P.get_transporter()*C.generator_matrix()) == P.get_canonical_form()True>>> a = P.get_autom_gens()[Integer(0)]>>> (a*C.generator_matrix()).echelon_form() == C.generator_matrix().echelon_form()
True>>> P.get_autom_order() == GL(Integer(3), GF(Integer(3))).order()True

get_PGammaL_gens()
Return the set of generators translated to the group 𝑃 Γ𝐿(𝑘, 𝑞).
There is a geometric point of view of code equivalence. A linear code is identified with the multiset of points
in the finite projective geometry 𝑃 𝐺(𝑘 − 1, 𝑞). The equivalence of codes translates to the natural action of𝑃 Γ𝐿(𝑘, 𝑞). Therefore, we may interpret the group as a subgroup of 𝑃 Γ𝐿(𝑘, 𝑞) as well.
EXAMPLES:

14.2. Canonical forms and automorphisms for linear codes over finite fields

321

Coding Theory, Release 10.4

sage: from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabelsage: C = codes.HammingCode(GF(4, a ), 3).dual_code()sage: A = LinearCodeAutGroupCanLabel(C).get_PGammaL_gens()
sage: Gamma = C.generator_matrix()
sage: N = [ x.monic() for x in Gamma.columns() ]sage: all((g[0]*n.apply_map(g[1])).monic() in N for n in N for g in A)
True>>> from sage.all import *>>> from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabel>>> C = codes.HammingCode(GF(Integer(4), a ), Integer(3)).dual_code()>>> A = LinearCodeAutGroupCanLabel(C).get_PGammaL_gens()>>> Gamma = C.generator_matrix()>>> N = [ x.monic() for x in Gamma.columns() ]>>> all((g[Integer(0)]*n.apply_map(g[Integer(1)])).monic() in N for n in N␣˓→for g in A)
True

get_PGammaL_order()Return the size of the automorphism group as a subgroup of 𝑃 Γ𝐿(𝑘, 𝑞).
There is a geometric point of view of code equivalence. A linear code is identified with the multiset of points
in the finite projective geometry 𝑃 𝐺(𝑘 − 1, 𝑞). The equivalence of codes translates to the natural action of𝑃 Γ𝐿(𝑘, 𝑞). Therefore, we may interpret the group as a subgroup of 𝑃 Γ𝐿(𝑘, 𝑞) as well.
EXAMPLES:
sage: from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabelsage: C = codes.HammingCode(GF(4, a ), 3).dual_code()sage: LinearCodeAutGroupCanLabel(C).get_PGammaL_order() == GL(3, GF(4,˓→order()*2/3
True

a )).

>>> from sage.all import *>>> from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabel>>> C = codes.HammingCode(GF(Integer(4), a ), Integer(3)).dual_code()>>> LinearCodeAutGroupCanLabel(C).get_PGammaL_order() == GL(Integer(3),␣
˓→GF(Integer(4),a )).order()*Integer(2)/Integer(3)True

get_autom_gens()
Return a generating set for the automorphism group of the code.
EXAMPLES:
sage: from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabelsage: C = codes.HammingCode(GF(2), 3).dual_code()sage: A = LinearCodeAutGroupCanLabel(C).get_autom_gens()
sage: Gamma = C.generator_matrix().echelon_form()
sage: all((g*Gamma).echelon_form() == Gamma for g in A)
True

322

Chapter 14. Automorphism Groups of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabel>>> C = codes.HammingCode(GF(Integer(2)), Integer(3)).dual_code()>>> A = LinearCodeAutGroupCanLabel(C).get_autom_gens()>>> Gamma = C.generator_matrix().echelon_form()>>> all((g*Gamma).echelon_form() == Gamma for g in A)
True

get_autom_order()Return the size of the automorphism group of the code.
EXAMPLES:
sage: from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabelsage: C = codes.HammingCode(GF(2), 3).dual_code()sage: LinearCodeAutGroupCanLabel(C).get_autom_order()168>>> from sage.all import *>>> from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabel>>> C = codes.HammingCode(GF(Integer(2)), Integer(3)).dual_code()>>> LinearCodeAutGroupCanLabel(C).get_autom_order()168

get_canonical_form()
Return the canonical orbit representative we computed.
EXAMPLES:
sage: from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabelsage: C = codes.HammingCode(GF(3), 3).dual_code()sage: CF1 = LinearCodeAutGroupCanLabel(C).get_canonical_form()
sage: s = SemimonomialTransformationGroup(GF(3), C.length()).an_element()
sage: C2 = LinearCode(s*C.generator_matrix())
sage: CF2 = LinearCodeAutGroupCanLabel(C2).get_canonical_form()
sage: CF1 == CF2
True>>> from sage.all import *>>> from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabel>>> C = codes.HammingCode(GF(Integer(3)), Integer(3)).dual_code()>>> CF1 = LinearCodeAutGroupCanLabel(C).get_canonical_form()>>> s = SemimonomialTransformationGroup(GF(Integer(3)), C.length()).an_˓→element()>>> C2 = LinearCode(s*C.generator_matrix())>>> CF2 = LinearCodeAutGroupCanLabel(C2).get_canonical_form()>>> CF1 == CF2
True

get_transporter()
Return the element which maps the code to its canonical form.
EXAMPLES:
14.2. Canonical forms and automorphisms for linear codes over finite fields

323

Coding Theory, Release 10.4

sage: from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabelsage: C = codes.HammingCode(GF(2), 3).dual_code()sage: P = LinearCodeAutGroupCanLabel(C)sage: g = P.get_transporter()sage: D = P.get_canonical_form()
sage: (g*C.generator_matrix()).echelon_form() == D.generator_matrix().echelon_
˓→form()True>>> from sage.all import *>>> from sage.coding.codecan.autgroup_can_label import␣
˓→LinearCodeAutGroupCanLabel>>> C = codes.HammingCode(GF(Integer(2)), Integer(3)).dual_code()>>> P = LinearCodeAutGroupCanLabel(C)>>> g = P.get_transporter()>>> D = P.get_canonical_form()>>> (g*C.generator_matrix()).echelon_form() == D.generator_matrix().echelon_
˓→form()True

324

Chapter 14. Automorphism Groups of Linear Codes

CHAPTERFIFTEEN

BOUNDS FOR PARAMETERS OF LINEAR CODES

15.1 Bounds for parameters of codes
This module provided some upper and lower bounds for the parameters of codes.
AUTHORS:• David Joyner (2006-07): initial implementation.
• William Stein (2006-07): minor editing of docs and code (fixed bug in elias_bound_asymp)• David Joyner (2006-07): fixed dimension_upper_bound to return an integer, added example to elias_bound_asymp.
• “ (2009-05): removed all calls to Guava but left it as an option.
• Dima Pasechnik (2012-10): added LP bounds.
Let 𝐹 be a finite set of size 𝑞. A subset 𝐶 of 𝑉 = 𝐹 𝑛 is called a code of length 𝑛. Often one considers the case where 𝐹
is a finite field, denoted by F𝑞 . Then 𝑉 is an 𝐹 -vector space. A subspace of 𝑉 (with the standard basis) is called a linear
code of length 𝑛. If its dimension is denoted 𝑘 then we typically store a basis of 𝐶 as a 𝑘 × 𝑛 matrix (the rows are thebasis vectors). If 𝐹 = F2 then 𝐶 is called a binary code. If 𝐹 has 𝑞 elements then 𝐶 is called a 𝑞-ary code. The elementsof a code 𝐶 are called codewords. The information rate of 𝐶 is𝑅=

log𝑞 |𝐶|,𝑛where |𝐶| denotes the number of elements of 𝐶. If v = (𝑣1 , 𝑣2 , ..., 𝑣𝑛 ), w = (𝑤1 , 𝑤2 , ..., 𝑤𝑛 ) are elements of 𝑉 = 𝐹 𝑛then we define𝑑(v, w) = |{𝑖 | 1 ≤ 𝑖 ≤ 𝑛, 𝑣𝑖 ̸= 𝑤𝑖 }|to be the Hamming distance between v and w. The function 𝑑 : 𝑉 × 𝑉 → N is called the Hamming metric. The weightof an element (in the Hamming metric) is 𝑑(v, 0), where 0 is a distinguished element of 𝐹 ; in particular it is 0 of the field
if 𝐹 is a field. The minimum distance of a linear code is the smallest non-zero weight of a codeword in 𝐶. The relatively
minimum distance is denoted𝛿 = 𝑑/𝑛.
A linear code with length 𝑛, dimension 𝑘, and minimum distance 𝑑 is called an [𝑛, 𝑘, 𝑑]𝑞 -code and 𝑛, 𝑘, 𝑑 are called
its parameters. A (not necessarily linear) code 𝐶 with length 𝑛, size 𝑀 = |𝐶|, and minimum distance 𝑑 is called an(𝑛, 𝑀, 𝑑)𝑞 -code (using parentheses instead of square brackets). Of course, 𝑘 = log𝑞 (𝑀 ) for linear codes.
What is the “best” code of a given length? Let 𝐴𝑞 (𝑛, 𝑑) denote the largest 𝑀 such that there exists a (𝑛, 𝑀, 𝑑) code in𝑛
𝐹 𝑛 . Let 𝐵𝑞 (𝑛, 𝑑) (also denoted 𝐴𝑙𝑖𝑛𝑞 (𝑛, 𝑑)) denote the largest 𝑘 such that there exists a [𝑛, 𝑘, 𝑑] code in 𝐹 . (Of course,
𝐴𝑞 (𝑛, 𝑑) ≥ 𝐵𝑞 (𝑛, 𝑑).) Determining 𝐴𝑞 (𝑛, 𝑑) and 𝐵𝑞 (𝑛, 𝑑) is one of the main problems in the theory of error-correcting
codes. For more details see [HP2003] and [Lin1999].
325

Coding Theory, Release 10.4

These quantities related to solving a generalization of the childhood game of “20 questions”.
GAME: Player 1 secretly chooses a number from 1 to 𝑀 (𝑀 is large but fixed). Player 2 asks a series of “yes/no questions”
in an attempt to determine that number. Player 1 may lie at most 𝑒 times (𝑒 ≥ 0 is fixed). What is the minimum numberof “yes/no questions” Player 2 must ask to (always) be able to correctly determine the number Player 1 chose?
If feedback is not allowed (the only situation considered here), call this minimum number 𝑔(𝑀, 𝑒).
Lemma: For fixed 𝑒 and 𝑀 , 𝑔(𝑀, 𝑒) is the smallest 𝑛 such that 𝐴2 (𝑛, 2𝑒 + 1) ≥ 𝑀 .
Thus, solving the solving a generalization of the game of “20 questions” is equivalent to determining 𝐴2 (𝑛, 𝑑)! Using
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;
2. codesize_upper_bound(n,d,q),
best_known_linear_code(n, k, F).

dimension_upper_bound(n,d,q),and

The output of best_known_linear_code(), best_known_linear_code_www(), or dimension_upper_bound() would give only special solutions to the GAME because the bounds are applicable to only linear codes.
The output of codesize_upper_bound() would give the best possible solution, that may belong to a linear or
nonlinear code.
This module implements:• codesize_upper_bound(n,d,q), for the best known (as of May, 2006) upper bound 𝐴(𝑛, 𝑑) for the sizeof a code of length 𝑛, minimum distance 𝑑 over a field of size 𝑞.
• dimension_upper_bound(n,d,q), an upper bound 𝐵(𝑛, 𝑑) = 𝐵𝑞 (𝑛, 𝑑) for the dimension of a linear
code of length 𝑛, minimum distance 𝑑 over a field of size 𝑞.
• gilbert_lower_bound(n,q,d), a lower bound for number of elements in the largest code of min distance𝑑 in F𝑛𝑞 .
• gv_info_rate(n,delta,q), 𝑙𝑜𝑔𝑞 (𝐺𝐿𝐵)/𝑛, where GLB is the Gilbert lower bound and 𝛿 = 𝑑/𝑛.
• gv_bound_asymp(delta,q), asymptotic analog of Gilbert lower bound.
• plotkin_upper_bound(n,q,d)• plotkin_bound_asymp(delta,q), asymptotic analog of Plotkin bound.
• griesmer_upper_bound(n,q,d)• elias_upper_bound(n,q,d)• elias_bound_asymp(delta,q), asymptotic analog of Elias bound.
• hamming_upper_bound(n,q,d)• hamming_bound_asymp(delta,q), asymptotic analog of Hamming bound.
• singleton_upper_bound(n,q,d)• singleton_bound_asymp(delta,q), asymptotic analog of Singleton bound.
• 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 𝑘, given 𝑛, 𝑑, 𝑞, (b) seek bounds on 𝑅, 𝛿, 𝑞(assuming 𝑛 is “infinity”).
Todo:
326

Chapter 15. Bounds for Parameters of Linear CodesCoding Theory, Release 10.4

• Johnson bounds for binary codes.
• mrrw2_bound_asymp(delta,q), “second” asymptotic McEliese-Rumsey-Rodemich-Welsh bound for the information rate.
sage.coding.code_bounds.codesize_upper_bound(n, d, q, algorithm=None)
Return an upper bound on the number of codewords in a (possibly non-linear) code.
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 𝐴(𝑛, 𝑑) = 𝐴𝑞 (𝑛, 𝑑) for the size of a codeof length 𝑛, minimum distance 𝑑 over a field of size 𝑞. The function first checks for trivial cases (like 𝑑 = 1 or𝑛 = 𝑑), and if the value is in the built-in table. Then it calculates the minimum value of the upper bound using thealgorithms of Singleton, Hamming, Johnson, Plotkin and Elias. If the code is binary, 𝐴(𝑛, 2ℓ − 1) = 𝐴(𝑛 + 1, 2ℓ),
so the function takes the minimum of the values obtained from all algorithms for the parameters (𝑛, 2ℓ − 1) and(𝑛 + 1, 2ℓ). This 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 Programming) upper bound.
EXAMPLES:
sage: codes.bounds.codesize_upper_bound(10, 3, 2)
93
sage: codes.bounds.codesize_upper_bound(24, 8, 2, algorithm="LP")˓→needs sage.numerical.mip
4096
sage: codes.bounds.codesize_upper_bound(10, 3, 2, algorithm="gap")
˓→optional - gap_package_guava
85
sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm=None)˓→needs sage.symbolic
123361
sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm="gap")
˓→optional - gap_package_guava
123361
sage: codes.bounds.codesize_upper_bound(11, 3, 4, algorithm="LP")˓→needs sage.numerical.mip
109226

#␣

#␣

#␣

#␣

#␣

>>> from sage.all import *>>> codes.bounds.codesize_upper_bound(Integer(10), Integer(3), Integer(2))
93>>> codes.bounds.codesize_upper_bound(Integer(24), Integer(8), Integer(2),␣
˓→algorithm="LP")# needs sage.numerical.mip
4096>>> codes.bounds.codesize_upper_bound(Integer(10), Integer(3), Integer(2),␣
˓→algorithm="gap")# optional - gap_package_guava
85>>> codes.bounds.codesize_upper_bound(Integer(11), Integer(3), Integer(4),␣
˓→algorithm=None)# needs sage.symbolic
123361>>> codes.bounds.codesize_upper_bound(Integer(11), Integer(3), Integer(4),␣
˓→algorithm="gap")# optional - gap_package_guava
123361>>> codes.bounds.codesize_upper_bound(Integer(11), Integer(3), Integer(4),␣
˓→algorithm="LP")# needs sage.numerical.mip
10922615.1. Bounds for parameters of codes327

Coding Theory, Release 10.4

sage.coding.code_bounds.dimension_upper_bound(n, d, q, algorithm=None)
Return an upper bound for the dimension of a linear code.
Return an upper bound 𝐵(𝑛, 𝑑) = 𝐵𝑞 (𝑛, 𝑑) for the dimension of a linear code of length 𝑛, minimum distance 𝑑over a field of size 𝑞.
Parameter algorithm has the same meaning as in codesize_upper_bound()
EXAMPLES:
sage: codes.bounds.dimension_upper_bound(10,3,2)
˓→needs sage.libs.pari sage.symbolic
6
sage: codes.bounds.dimension_upper_bound(30,15,4)
˓→needs sage.libs.pari sage.symbolic13
sage: codes.bounds.dimension_upper_bound(30,15,4,algorithm="LP")˓→needs sage.libs.pari sage.numerical.mip
12

#␣

#␣

#␣

>>> from sage.all import *>>> codes.bounds.dimension_upper_bound(Integer(10),Integer(3),Integer(2))˓→# needs sage.libs.pari sage.symbolic
6>>> codes.bounds.dimension_upper_bound(Integer(30),Integer(15),Integer(4))˓→# needs sage.libs.pari sage.symbolic13>>> codes.bounds.dimension_upper_bound(Integer(30),Integer(15),Integer(4),˓→algorithm="LP")# needs sage.libs.pari sage.numerical.mip
12

␣

␣

sage.coding.code_bounds.elias_bound_asymp(delta, q)
The asymptotic Elias bound for the information rate.
This only makes sense when 0 < 𝛿 < 1 − 1/𝑞.
EXAMPLES:
sage: codes.bounds.elias_bound_asymp(1/4,2)
˓→needs sage.symbolic
0.39912396330...

#␣>>> from sage.all import *>>> codes.bounds.elias_bound_asymp(Integer(1)/Integer(4),Integer(2))˓→# needs sage.symbolic
0.39912396330...

␣sage.coding.code_bounds.elias_upper_bound(n, q, d, algorithm=None)
Return the Elias upper bound.
Return the Elias upper bound for number of elements in the largest code of minimum distance 𝑑 in F𝑛𝑞 , cf.
[HP2003]. If algorithm="gap", it wraps GAP’s UpperBoundElias.
EXAMPLES:
sage: codes.bounds.elias_upper_bound(10,2,3)
232
sage: codes.bounds.elias_upper_bound(10,2,3,algorithm="gap")# optional - gap_
(continues on next page)

328

Chapter 15. Bounds for Parameters of Linear CodesCoding Theory, Release 10.4

(continued from previous page)

package_guava
232˓→>>> from sage.all import *>>> codes.bounds.elias_upper_bound(Integer(10),Integer(2),Integer(3))
232>>> codes.bounds.elias_upper_bound(Integer(10),Integer(2),Integer(3),algorithm=
˓→"gap")# optional - gap_package_guava
232

sage.coding.code_bounds.entropy(x, q=2)
Compute the entropy at 𝑥 on the 𝑞-ary symmetric channel.
INPUT:• x – real number in the interval [0, 1].
• q – (default: 2) integer greater than 1. This is the base of the logarithm.
EXAMPLES:
sage: codes.bounds.entropy(0, 2)
0sage: codes.bounds.entropy(1/5,4).factor()˓→needs sage.symbolic
1/10*(log(3) - 4*log(4/5) - log(1/5))/log(2)sage: codes.bounds.entropy(1, 3)
˓→needs sage.symboliclog(2)/log(3)#␣#␣>>> from sage.all import *>>> codes.bounds.entropy(Integer(0), Integer(2))
0>>> codes.bounds.entropy(Integer(1)/Integer(5),Integer(4)).factor()˓→# needs sage.symbolic
1/10*(log(3) - 4*log(4/5) - log(1/5))/log(2)>>> codes.bounds.entropy(Integer(1), Integer(3))˓→# needs sage.symboliclog(2)/log(3)␣␣Check that values not within the limits are properly handled:
sage: codes.bounds.entropy(1.1, 2)
Traceback (most recent call last):...
ValueError: The entropy function is defined only for x in the interval [0, 1]
sage: codes.bounds.entropy(1, 1)
Traceback (most recent call last):...
ValueError: The value q must be an integer greater than 1>>> from sage.all import *>>> codes.bounds.entropy(RealNumber( 1.1 ), Integer(2))
Traceback (most recent call last):...
ValueError: The entropy function is defined only for x in the interval [0, 1](continues on next page)

15.1. Bounds for parameters of codes329

Coding Theory, Release 10.4

(continued from previous page)>>> codes.bounds.entropy(Integer(1), Integer(1))
Traceback (most recent call last):...
ValueError: The value q must be an integer greater than 1

sage.coding.code_bounds.entropy_inverse(x, q=2)
Find the inverse of the 𝑞-ary entropy function at the point x.
INPUT:• x – real number in the interval [0, 1].
• q – (default: 2) integer greater than 1. This is the base of the logarithm.
OUTPUT:
Real number in the interval [0, 1 − 1/𝑞]. The function has multiple values if we include the entire interval [0, 1];
hence only the values in the above interval is returned.
EXAMPLES:
sage: # needs sage.symbolic
sage: from sage.coding.code_bounds import entropy_inverse
sage: entropy_inverse(0.1)˓→needs scipy
0.012986862055...
sage: entropy_inverse(1)1/2
sage: entropy_inverse(0, 3)
0sage: entropy_inverse(1, 3)
2/3>>> from sage.all import *>>> # needs sage.symbolic>>> from sage.coding.code_bounds import entropy_inverse>>> entropy_inverse(RealNumber( 0.1 ))˓→# needs scipy
0.012986862055...
>>> entropy_inverse(Integer(1))
1/2>>> entropy_inverse(Integer(0), Integer(3))
0>>> entropy_inverse(Integer(1), Integer(3))
2/3

#␣

␣

sage.coding.code_bounds.gilbert_lower_bound(n, q, d)
Return the Gilbert-Varshamov lower bound.
Return the Gilbert-Varshamov lower bound for number of elements in a largest code of minimum distance d in
F𝑛𝑞 . See Wikipedia article Gilbert-Varshamov_bound
EXAMPLES:
sage: codes.bounds.gilbert_lower_bound(10,2,3)
128/7

330

Chapter 15. Bounds for Parameters of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> codes.bounds.gilbert_lower_bound(Integer(10),Integer(2),Integer(3))
128/7

sage.coding.code_bounds.griesmer_upper_bound(n, q, d, algorithm=None)
Return the Griesmer upper bound.
Return the Griesmer upper bound for the number of elements in a largest linear code of minimum distance 𝑑 in
F𝑛𝑞 , cf. [HP2003]. If the method is “gap”, it wraps GAP’s UpperBoundGriesmer.
The bound states:
𝑛≥

𝑘−1
∑︁

⌈𝑑/𝑞 𝑖 ⌉.

𝑖=0

EXAMPLES:
The bound is reached for the ternary Golay codes:
sage: codes.bounds.griesmer_upper_bound(12,3,6)
˓→needs sage.libs.pari729
sage: codes.bounds.griesmer_upper_bound(11,3,5)
˓→needs sage.libs.pari
729

#␣

#␣

>>> from sage.all import *>>> codes.bounds.griesmer_upper_bound(Integer(12),Integer(3),Integer(6))˓→# needs sage.libs.pari729>>> codes.bounds.griesmer_upper_bound(Integer(11),Integer(3),Integer(5))˓→# needs sage.libs.pari729
sage: codes.bounds.griesmer_upper_bound(10,2,3)
˓→needs sage.libs.pari
128
sage: codes.bounds.griesmer_upper_bound(10,2,3,algorithm="gap")
˓→optional - gap_package_guava, needs sage.libs.pari
128

␣

␣

#␣

#␣

>>> from sage.all import *>>> codes.bounds.griesmer_upper_bound(Integer(10),Integer(2),Integer(3))␣˓→# needs sage.libs.pari
128>>> codes.bounds.griesmer_upper_bound(Integer(10),Integer(2),Integer(3),algorithm=
˓→"gap")# optional - gap_package_guava, needs sage.libs.pari
128

sage.coding.code_bounds.gv_bound_asymp(delta, q)
The asymptotic Gilbert-Varshamov bound for the information rate, R.
EXAMPLES:
sage: # needs sage.symbolic
sage: RDF(codes.bounds.gv_bound_asymp(1/4,2))#␣(continues on next page)

15.1. Bounds for parameters of codes331

Coding Theory, Release 10.4

(continued from previous page)needs sage.libs.pari
0.18872187554086...
sage: f = lambda x: codes.bounds.gv_bound_asymp(x,2)
sage: plot(f,0,1)
˓→needs sage.libs.pari sage.plot
Graphics object consisting of 1 graphics primitive˓→>>> from sage.all import *>>> # needs sage.symbolic>>> RDF(codes.bounds.gv_bound_asymp(Integer(1)/Integer(4),Integer(2)))˓→# needs sage.libs.pari
0.18872187554086...
>>> f = lambda x: codes.bounds.gv_bound_asymp(x,Integer(2))>>> plot(f,Integer(0),Integer(1))˓→# needs sage.libs.pari sage.plot
Graphics object consisting of 1 graphics primitive

#␣

␣

␣

sage.coding.code_bounds.gv_info_rate(n, delta, q)
The Gilbert-Varshamov lower bound for information rate.
The Gilbert-Varshamov lower bound for information rate of a 𝑞-ary code of length 𝑛 and minimum distance 𝑛𝛿.
EXAMPLES:
sage: RDF(codes.bounds.gv_info_rate(100,1/4,3))
˓→needs sage.libs.pari sage.symbolic
0.36704992608261894# abs tol 1e-15#␣>>> from sage.all import *>>> RDF(codes.bounds.gv_info_rate(Integer(100),Integer(1)/Integer(4),Integer(3)))␣
˓→ # abs tol 1e-15# needs sage.libs.pari sage.symbolic
0.36704992608261894

sage.coding.code_bounds.hamming_bound_asymp(delta, q)
The asymptotic Hamming bound for the information rate.
EXAMPLES:
sage: # needs sage.symbolic
sage: RDF(codes.bounds.hamming_bound_asymp(1/4,2))
˓→needs sage.libs.pari
0.456435556800...
sage: f = lambda x: codes.bounds.hamming_bound_asymp(x,2)
sage: plot(f,0,1)
˓→needs sage.libs.pari sage.plot
Graphics object consisting of 1 graphics primitive>>> from sage.all import *>>> # needs sage.symbolic>>> RDF(codes.bounds.hamming_bound_asymp(Integer(1)/Integer(4),Integer(2)))˓→# needs sage.libs.pari
0.456435556800...
>>> f = lambda x: codes.bounds.hamming_bound_asymp(x,Integer(2))>>> plot(f,Integer(0),Integer(1))˓→# needs sage.libs.pari sage.plot
Graphics object consisting of 1 graphics primitive

332

#␣

#␣

␣

␣

Chapter 15. Bounds for Parameters of Linear CodesCoding Theory, Release 10.4

sage.coding.code_bounds.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 𝑛 and minimum distance𝑑 over alphabet of size 𝑞.
The Hamming bound (also known as the sphere packing bound) returns an upper bound on the size of a codeof length 𝑛, minimum distance 𝑑, over an alphabet of size 𝑞. The Hamming bound is obtained by dividing thecontents of the entire Hamming space 𝑞 𝑛 by the contents of a ball with radius 𝑓 𝑙𝑜𝑜𝑟((𝑑 − 1)/2). As all these balls
are disjoint, they can never contain more than the whole vector space.
𝑀≤𝑞𝑛,
𝑉 (𝑛, 𝑒)where 𝑀 is the maximum number of codewords and 𝑉 (𝑛, 𝑒) is equal to the contents of a ball of radius 𝑒. Thisbound is useful for small values of 𝑑. Codes for which equality holds are called perfect. See e.g. [HP2003].
EXAMPLES:
sage: codes.bounds.hamming_upper_bound(10,2,3)
93>>> from sage.all import *>>> codes.bounds.hamming_upper_bound(Integer(10),Integer(2),Integer(3))
93

sage.coding.code_bounds.mrrw1_bound_asymp(delta, q)
The first asymptotic McEliese-Rumsey-Rodemich-Welsh bound.
This only makes sense when 0 < 𝛿 < 1 − 1/𝑞.
EXAMPLES:
sage: codes.bounds.mrrw1_bound_asymp(1/4,2)
˓→needs sage.symbolic
0.3545789026652697# abs tol 4e-16>>> from sage.all import *>>> codes.bounds.mrrw1_bound_asymp(Integer(1)/Integer(4),Integer(2))˓→4e-16# needs sage.symbolic
0.3545789026652697#␣# abs tol␣sage.coding.code_bounds.plotkin_bound_asymp(delta, q)
The asymptotic Plotkin bound for the information rate.
This only makes sense when 0 < 𝛿 < 1 − 1/𝑞.
EXAMPLES:
sage: codes.bounds.plotkin_bound_asymp(1/4,2)
1/2>>> from sage.all import *>>> codes.bounds.plotkin_bound_asymp(Integer(1)/Integer(4),Integer(2))
1/2

15.1. Bounds for parameters of codes333

Coding Theory, Release 10.4

sage.coding.code_bounds.plotkin_upper_bound(n, q, d, algorithm=None)
Return the Plotkin upper bound.
Return the Plotkin upper bound for the number of elements in a largest code of minimum distance 𝑑 in F𝑛𝑞 . Moreprecisely this is a generalization of Plotkin’s result for 𝑞 = 2 to bigger 𝑞 due to Berlekamp.
The algorithm="gap" option wraps Guava’s UpperBoundPlotkin.
EXAMPLES:
sage: codes.bounds.plotkin_upper_bound(10,2,3)
192
sage: codes.bounds.plotkin_upper_bound(10,2,3,algorithm="gap")
˓→package_guava
192# optional - gap_>>> from sage.all import *>>> codes.bounds.plotkin_upper_bound(Integer(10),Integer(2),Integer(3))
192>>> codes.bounds.plotkin_upper_bound(Integer(10),Integer(2),Integer(3),algorithm=
˓→"gap")# optional - gap_package_guava
192

sage.coding.code_bounds.singleton_bound_asymp(delta, q)
The asymptotic Singleton bound for the information rate.
EXAMPLES:
sage: codes.bounds.singleton_bound_asymp(1/4,2)
3/4
sage: f = lambda x: codes.bounds.singleton_bound_asymp(x,2)
sage: plot(f,0,1)
˓→needs sage.plot
Graphics object consisting of 1 graphics primitive>>> from sage.all import *>>> codes.bounds.singleton_bound_asymp(Integer(1)/Integer(4),Integer(2))
3/4>>> f = lambda x: codes.bounds.singleton_bound_asymp(x,Integer(2))>>> plot(f,Integer(0),Integer(1))˓→# needs sage.plot
Graphics object consisting of 1 graphics primitive#␣␣

sage.coding.code_bounds.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 𝑑 in F𝑛𝑞 .
This bound is based on the shortening of codes. By shortening an (𝑛, 𝑀, 𝑑) code 𝑑 − 1 times, an (𝑛 − 𝑑 + 1, 𝑀, 1)
code results, with 𝑀 ≤ 𝑞 𝑛 − 𝑑 + 1. Thus
𝑀 ≤ 𝑞 𝑛−𝑑+1 .
Codes that meet this bound are called maximum distance separable (MDS).
EXAMPLES:
sage: codes.bounds.singleton_upper_bound(10,2,3)
256

334

Chapter 15. Bounds for Parameters of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> codes.bounds.singleton_upper_bound(Integer(10),Integer(2),Integer(3))
256

sage.coding.code_bounds.volume_hamming(n, q, r)
Return the number of elements in a Hamming ball.
Return the number of elements in a Hamming ball of radius 𝑟 in F𝑛𝑞 .
EXAMPLES:
sage: codes.bounds.volume_hamming(10,2,3)
176>>> from sage.all import *>>> codes.bounds.volume_hamming(Integer(10),Integer(2),Integer(3))
176

15.2 Delsarte (or linear programming) bounds
This module provides LP upper bounds for the parameters of codes, introduced in by P. Delsarte in [De1973].
The exact LP solver PPL is used by default, ensuring that no rounding/overflow problems occur.
AUTHORS:• Dmitrii V. (Dima) Pasechnik (2012-10): initial implementation• Dmitrii V. (Dima) Pasechnik (2015, 2021): minor fixes• Charalampos Kokkalis (2021): Eberlein polynomials, general Q matrix codes
sage.coding.delsarte_bounds.delsarte_bound_Q_matrix(q, d, return_data=False, solver='PPL',
isinteger=False)
Delsarte bound on a code with Q matrix q and lower bound on min. dist. d.
Find the Delsarte bound on a code with Q matrix q and lower bound on minimal distance d.
INPUT:• q – the Q matrix• d – the (lower bound on) minimal distance of the code
• return_data – if True, return a triple (W,LP,bound), where W is a weights vector, and LP the
Delsarte upper bound LP; both of them are Sage LP data. W need not be a weight distribution of a code.
• solver – the LP/ILP solver to be used. Defaults to PPL. It is arbitrary precision, thus there will be norounding errors. With other solvers (see MixedIntegerLinearProgram for the list), you are on yourown!
• isinteger – if True, uses an integer programming solver (ILP), rather that an LP solver. Can be very
slow if set to True.
EXAMPLES:
The bound on dimension of linear F2 -codes of length 10 and minimal distance 6:

15.2. Delsarte (or linear programming) bounds

335

Coding Theory, Release 10.4

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
sage: a,p,val = codes.bounds.delsarte_bound_Q_matrix(q_matrix, 6, return_
˓→data=True)
sage: [j for i,j in p.get_values(a).items()][1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]>>> from sage.all import *>>> q_matrix = Matrix([[codes.bounds.krawtchouk(Integer(10),Integer(2),i,j) for i␣˓→in range(Integer(11))]...
for j in range(Integer(11))])>>> codes.bounds.delsarte_bound_Q_matrix(q_matrix, Integer(6))
2>>> a,p,val = codes.bounds.delsarte_bound_Q_matrix(q_matrix, Integer(6), return_
˓→data=True)>>> [j for i,j in p.get_values(a).items()][1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

sage.coding.delsarte_bounds.delsarte_bound_additive_hamming_space(n, d, q, d_star=1,
q_base=0, return_data=False,
solver='PPL',
isinteger=False)
Find a modified Delsarte bound on additive codes in Hamming space 𝐻𝑞𝑛 of minimal distance 𝑑.
Find the Delsarte LP bound on F_{q_base}-dimension of additive codes in Hamming space 𝐻𝑞𝑛 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 powerof q_base, and the code is, formally, linear over F_{q_base}. Otherwise it is assumed that q_base==q.
INPUT:• n – the code length• d – the (lower bound on) minimal distance of the code
• q – the size of the alphabet• d_star – the (lower bound on) minimal distance of the dual code; only makes sense for additive codes.
• q_base – if 0, the code is assumed to be linear. Otherwise, q=q_base^m and the code is linear overF_{q_base}.
• return_data – if True, return a triple (W,LP,bound), where W is a weights vector, and LP the
Delsarte bound LP; both of them are Sage LP 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 precision, thus there will be norounding errors. With other solvers (see MixedIntegerLinearProgram for the list), you are on yourown!
• isinteger – if True, uses an integer programming solver (ILP), rather that an LP solver. Can be very
slow if set to True.
EXAMPLES:
The bound on dimension of linear F2 -codes of length 11 and minimal distance 6:

336

Chapter 15. Bounds for Parameters of Linear CodesCoding Theory, Release 10.4

sage: codes.bounds.delsarte_bound_additive_hamming_space(11, 6, 2)
3
sage: a,p,val = codes.bounds.delsarte_bound_additive_hamming_space(\11, 6, 2, return_data=True)
sage: [j for i,j in p.get_values(a).items()][1, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0]>>> from sage.all import *>>> codes.bounds.delsarte_bound_additive_hamming_space(Integer(11), Integer(6),␣
˓→Integer(2))
3>>> a,p,val = codes.bounds.delsarte_bound_additive_hamming_space(\11, 6, 2, return_data=True)>>> [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 F4 -codes of length 11 and minimal distance 3:
sage: codes.bounds.delsarte_bound_additive_hamming_space(11,3,4)
8>>> from sage.all import *>>> codes.bounds.delsarte_bound_additive_hamming_space(Integer(11),Integer(3),˓→Integer(4))
8The bound on the F2 -dimension of additive F4 -codes of length 11 and minimal distance 3:
sage: codes.bounds.delsarte_bound_additive_hamming_space(11,3,4,q_base=2)
16>>> from sage.all import *>>> codes.bounds.delsarte_bound_additive_hamming_space(Integer(11),Integer(3),˓→Integer(4),q_base=Integer(2))
16Such a d_star is not possible:
sage: codes.bounds.delsarte_bound_additive_hamming_space(11,3,4,d_star=9)
Solver exception: PPL : There is no feasible solution
False>>> from sage.all import *>>> codes.bounds.delsarte_bound_additive_hamming_space(Integer(11),Integer(3),˓→Integer(4),d_star=Integer(9))
Solver exception: PPL : There is no feasible solution
False

sage.coding.delsarte_bounds.delsarte_bound_constant_weight_code(n, d, w,
return_data=False,
solver='PPL',
isinteger=False)
Find the Delsarte bound on a constant weight code.
Find the Delsarte bound on a constant weight code of weight w, length n, lower bound on minimal distance d.
INPUT:
15.2. Delsarte (or linear programming) bounds

337

Coding Theory, Release 10.4

• n – the code length• d – the (lower bound on) minimal distance of the code
• w – the weight of the code
• return_data – if True, return a triple (W,LP,bound), where W is a weights vector, and LP the
Delsarte upper bound LP; both of them are Sage LP data. W need not be a weight distribution of a code.
• solver – the LP/ILP solver to be used. Defaults to PPL. It is arbitrary precision, thus there will be norounding errors. With other solvers (see MixedIntegerLinearProgram for the list), you are on yourown!
• isinteger – if True, uses an integer programming solver (ILP), rather that an LP solver. Can be very
slow if set to True.
EXAMPLES:
The bound on the size of codes of length 17, weight 3, and minimal distance 4:
sage: codes.bounds.delsarte_bound_constant_weight_code(17, 4, 3)
45
sage: a, p, val = codes.bounds.delsarte_bound_constant_weight_code(17, 4, 3,␣
˓→return_data=True)
sage: [j for i,j in p.get_values(a).items()][21, 70/3]>>> from sage.all import *>>> codes.bounds.delsarte_bound_constant_weight_code(Integer(17), Integer(4),␣
˓→Integer(3))
45>>> a, p, val = codes.bounds.delsarte_bound_constant_weight_code(Integer(17),␣
˓→Integer(4), Integer(3), return_data=True)>>> [j for i,j in p.get_values(a).items()][21, 70/3]

The stricter bound (using ILP) on codes of length 17, weight 3, and minimal distance 4:
sage: codes.bounds.delsarte_bound_constant_weight_code(17, 4, 3, isinteger=True)
43>>> from sage.all import *>>> codes.bounds.delsarte_bound_constant_weight_code(Integer(17), Integer(4),␣
˓→Integer(3), isinteger=True)
43

sage.coding.delsarte_bounds.delsarte_bound_hamming_space(n, d, q, return_data=False,
solver='PPL', isinteger=False)
Find the Delsarte bound on codes in H_q^n of minimal distance d
Find the Delsarte bound [De1973] on the size of codes in the Hamming space H_q^n of minimal distance d.
INPUT:• n – the code length• d – the (lower bound on) minimal distance of the code
• q – the size of the alphabet• return_data – if True, return a triple (W,LP,bound), where W is a weights vector, and LP the
Delsarte upper bound LP; both of them are Sage LP data. W need not be a weight distribution of a code.
338

Chapter 15. Bounds for Parameters of Linear CodesCoding Theory, Release 10.4

• solver – the LP/ILP solver to be used. Defaults to PPL. It is arbitrary precision, thus there will be norounding errors. With other solvers (see MixedIntegerLinearProgram for the list), you are on yourown!
• isinteger – if True, uses an integer programming solver (ILP), rather that an LP solver. Can be very
slow if set to True.
EXAMPLES:
The bound on the size of the F2 -codes of length 11 and minimal distance 6:
sage: codes.bounds.delsarte_bound_hamming_space(11, 6, 2)
12
sage: a, p, val = codes.bounds.delsarte_bound_hamming_space(11, 6, 2, return_
˓→data=True)
sage: [j for i,j in p.get_values(a).items()][1, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0]>>> from sage.all import *>>> codes.bounds.delsarte_bound_hamming_space(Integer(11), Integer(6), Integer(2))
12>>> a, p, val = codes.bounds.delsarte_bound_hamming_space(Integer(11), Integer(6),˓→ Integer(2), return_data=True)>>> [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 F2 -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)
sage: x4096
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]>>> from sage.all import *>>> a,p,x = codes.bounds.delsarte_bound_hamming_space(Integer(24),Integer(8),˓→Integer(2),return_data=True)
>>> x
4096
>>> [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 F4 -codes of length 11 and minimal distance 3:
sage: codes.bounds.delsarte_bound_hamming_space(11,3,4)
327680/3>>> from sage.all import *>>> codes.bounds.delsarte_bound_hamming_space(Integer(11),Integer(3),Integer(4))
327680/3

An improvement of a known upper bound (150) from https://www.win.tue.nl/ aeb/codes/binary-1.html
sage: a,p,x = codes.bounds.delsarte_bound_hamming_space(23,10,2,return_data=True,
˓→isinteger=True); x # long time148
(continues on next page)

15.2. Delsarte (or linear programming) bounds

339

Coding Theory, Release 10.4

(continued from previous page)

sage: [j for i,j in p.get_values(a).items()]
˓→# long time
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 2, 0, 36, 0, 14, 0, 0, 0, 0, 0, 0, 0]>>> from sage.all import *>>> a,p,x = codes.bounds.delsarte_bound_hamming_space(Integer(23),Integer(10),
˓→Integer(2),return_data=True,isinteger=True); x # long time148>>> [j for i,j in p.get_values(a).items()]
˓→long time
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 2, 0, 36, 0, 14, 0, 0, 0, 0, 0, 0, 0]#␣Note that a usual LP, without integer variables, won’t do the trick
sage: codes.bounds.delsarte_bound_hamming_space(23,10,2).n(20)151.86>>> from sage.all import *>>> codes.bounds.delsarte_bound_hamming_space(Integer(23),Integer(10),Integer(2)).
˓→n(Integer(20))
151.86

Such an input is invalid:
sage: codes.bounds.delsarte_bound_hamming_space(11,3,-4)
Solver exception: PPL : There is no feasible solution
False>>> from sage.all import *>>> codes.bounds.delsarte_bound_hamming_space(Integer(11),Integer(3),-Integer(4))
Solver exception: PPL : There is no feasible solution
False

sage.coding.delsarte_bounds.eberlein(n, w, k, u, check=True)
Compute 𝐸𝑘𝑤,𝑛 (𝑥), the Eberlein polynomial.
See Wikipedia article Eberlein_polynomials.
It is defined as:
𝐸𝑘𝑤,𝑛 (𝑢) =

𝑘
∑︁

(−1)𝑗

𝑗=0

(︂ )︂(︂)︂(︂)︂𝑢 𝑤−𝑢 𝑛−𝑤−𝑢
,
𝑗
𝑘−𝑗
𝑘−𝑗

INPUT:• w, k, x – arbitrary numbers• n – a nonnegative integer• check – check the input for correctness. True by default. Otherwise, pass it as it is. Use check=False
at your own risk.
EXAMPLES:
sage: codes.bounds.eberlein(24,10,2,6)-9340

Chapter 15. Bounds for Parameters of Linear CodesCoding Theory, Release 10.4>>> from sage.all import *>>> codes.bounds.eberlein(Integer(24),Integer(10),Integer(2),Integer(6))-9sage.coding.delsarte_bounds.krawtchouk(n, q, l, x, check=True)
Compute 𝐾𝑙𝑛,𝑞 (𝑥), the Krawtchouk (a.k.a. Kravchuk) polynomial.
See Wikipedia article Kravchuk_polynomials.
It is defined by the generating function(1 + (𝑞 − 1)𝑧)𝑛−𝑥 (1 − 𝑧)𝑥 =∑︁𝐾𝑙𝑛,𝑞 (𝑥)𝑧 𝑙𝑙

and is equal to𝐾𝑙𝑛,𝑞 (𝑥) =(︂ )︂(︂
)︂
𝑙
∑︁
𝑥 𝑛−𝑥
(−1)𝑗 (𝑞 − 1)(𝑙−𝑗)
.
𝑗
𝑙−𝑗
𝑗=0

INPUT:• n, q, x – arbitrary numbers• l – a nonnegative integer• check – check the input for correctness. True by default. Otherwise, pass it as it is. Use check=False
at your own risk.
See also:˜ 𝑙 (𝑥; 𝑛, 𝑝) which are related by
Symbolic Krawtchouk polynomials 𝐾(−𝑞)𝑙 𝐾𝑙𝑛,𝑞−1

˜ 𝑙 (𝑥; 𝑛, 1 − 𝑞).
(𝑥) = 𝐾

EXAMPLES:
sage: codes.bounds.krawtchouk(24,2,5,4)
2224
sage: codes.bounds.krawtchouk(12300,4,5,6)
567785569973042442072>>> from sage.all import *>>> codes.bounds.krawtchouk(Integer(24),Integer(2),Integer(5),Integer(4))
2224>>> codes.bounds.krawtchouk(Integer(12300),Integer(4),Integer(5),Integer(6))
567785569973042442072

15.2. Delsarte (or linear programming) bounds

341

Coding Theory, Release 10.4

342

Chapter 15. Bounds for Parameters of Linear Codes

CHAPTERSIXTEENDATABASES FOR CODING THEORY

16.1 Access functions to online databases for coding theory
sage.coding.databases.best_linear_code_in_codetables_dot_de(n, k, F, verbose=False)
Return the best linear code and its construction as per the web database http://www.codetables.de/
INPUT:• n – Integer, the length of the code
• k – Integer, the dimension of the code
• F – Finite field, of order 2, 3, 4, 5, 7, 8, or 9• verbose – Bool (default: False)
OUTPUT:• An unparsed text explaining the construction of the code.
EXAMPLES:
sage: L = codes.databases.best_linear_code_in_codetables_dot_de(72, 36, GF(2))˓→# optional - internet
sage: print(L)˓→# optional - internet
Construction of a linear code
[72,36,15] over GF(2):[1]: [73, 36, 16] Cyclic Linear Code over GF(2)CyclicCode of length 73 with generating polynomial x^37 + x^36 + x^34 +x^33 + x^32 + x^27 + x^25 + x^24 + x^22 + x^21 + x^19 + x^18 + x^15 + x^11 +x^10 + x^8 + x^7 + x^5 + x^3 + 1[2]: [72, 36, 15] Linear Code over GF(2)Puncturing of [1] at 1
last modified: 2002-03-20>>> from sage.all import *>>> L = codes.databases.best_linear_code_in_codetables_dot_de(Integer(72),␣
˓→Integer(36), GF(Integer(2)))# optional - internet>>> print(L)˓→optional - internet
Construction of a linear code
[72,36,15] over GF(2):[1]: [73, 36, 16] Cyclic Linear Code over GF(2)CyclicCode of length 73 with generating polynomial x^37 + x^36 + x^34 +#␣

(continues on next page)343

Coding Theory, Release 10.4

(continued from previous page)x^33 + x^32 + x^27 + x^25 + x^24 + x^22 + x^21 + x^19 + x^18 + x^15 + x^11 +x^10 + x^8 + x^7 + x^5 + x^3 + 1[2]: [72, 36, 15] Linear Code over GF(2)Puncturing of [1] at 1
<BLANKLINE>
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.
AUTHORS:• Steven Sivek (2005-11-14)• David Joyner (2008-03)
sage.coding.databases.best_linear_code_in_guava(n, k, F)
Return the linear code of length n, dimension k over field F with the maximal minimum distance which is known
to the GAP package GUAVA.
The function uses the tables described in bounds_on_minimum_distance_in_guava() to construct thiscode. This requires the optional GAP package GUAVA.
INPUT:• n – the length of the code to look up• k – the dimension of the code to look up• F – the base field of the code to look up
OUTPUT:A LinearCode which is a best linear code of the given parameters known to GUAVA.
EXAMPLES:
sage: codes.databases.best_linear_code_in_guava(10,5,GF(2))˓→optional - gap_package_guava[10, 5] linear code over GF(2)sage: libgap.LoadPackage( guava )˓→optional - gap_package_guava...
sage: libgap.BestKnownLinearCode(10,5,libgap.GF(2))˓→optional - gap_package_guava
a linear [10,5,4]2..4 shortened code

# long time;␣

# long time;␣

# long time;␣

>>> from sage.all import *>>> codes.databases.best_linear_code_in_guava(Integer(10),Integer(5),˓→GF(Integer(2)))# long time; optional - gap_package_guava[10, 5] linear code over GF(2)>>> libgap.LoadPackage( guava )# long time;␣
˓→optional - gap_package_guava...
>>> libgap.BestKnownLinearCode(Integer(10),Integer(5),libgap.GF(Integer(2)))˓→# long time; optional - gap_package_guava
a linear [10,5,4]2..4 shortened code␣This means that the best possible binary linear code of length 10 and dimension 5 is acode with minimum distance 4 and covering radius s somewhere between 2 and 4.
Usebounds_on_minimum_distance_in_guava(10,5,GF(2)) for further details.
344

Chapter 16. Databases for Coding Theory

Coding Theory, Release 10.4

sage.coding.databases.bounds_on_minimum_distance_in_guava(n, k, F)
Compute a lower and upper bound on the greatest minimum distance of a [𝑛, 𝑘] linear code over the field F.
This function requires the optional GAP package GUAVA.
The function returns a GAP record with the two bounds and an explanation for each bound. The method Display
can be used to show the explanations.
The values for the lower and upper bound are obtained from a table constructed by Cen Tjhai for GUAVA, derived
from the table of Brouwer. See http://www.codetables.de/ for the most recent data. These tables contain lower andupper bounds for 𝑞 = 2 (when n <= 257), 𝑞 = 3 (when n <= 243), 𝑞 = 4 (n <= 256). (Current as of 11
May 2006.) For codes over other fields and for larger word lengths, trivial bounds are used.
INPUT:• n – the length of the code to look up• k – the dimension of the code to look up• F – the base field of the code to look up
OUTPUT:• A GAP record object. See below for an example.
EXAMPLES:
sage: gap_rec = codes.databases.bounds_on_minimum_distance_in_guava(10,5,GF(2))˓→# optional - gap_package_guava
sage: gap_rec.Display()˓→# optional - gap_package_guava
rec(construction := [ <Operation "ShortenedCode">,[ [ <Operation "UUVCode">,[ [ <Operation "DualCode">,[ [ <Operation "RepetitionCode">, [ 8, 2 ] ] ] ],[ <Operation "UUVCode">, [ [ <Operation "DualCode">,[ [ <Operation "RepetitionCode">, [ 4, 2 ] ] ] ],[ <Operation "RepetitionCode">, [ 4, 2 ] ] ] ] ] ],[ 1, 2, 3, 4, 5, 6 ] ] ],k := 5,lowerBound := 4,lowerBoundExplanation := ...
n := 10,q := 2,
references := rec(),
upperBound := 4,
upperBoundExplanation := ... )>>> from sage.all import *>>> gap_rec = codes.databases.bounds_on_minimum_distance_in_guava(Integer(10),
˓→Integer(5),GF(Integer(2)))# optional - gap_package_guava>>> gap_rec.Display()#␣˓→optional - gap_package_guava
rec(construction := [ <Operation "ShortenedCode">,[ [ <Operation "UUVCode">,[ [ <Operation "DualCode">,[ [ <Operation "RepetitionCode">, [ 8, 2 ] ] ] ],[ <Operation "UUVCode">, [ [ <Operation "DualCode">,(continues on next page)

16.1. Access functions to online databases for coding theory345

Coding Theory, Release 10.4

(continued from previous page)[ [ <Operation "RepetitionCode">, [ 4, 2 ] ] ] ],[ <Operation "RepetitionCode">, [ 4, 2 ] ] ] ] ] ],[ 1, 2, 3, 4, 5, 6 ] ] ],k := 5,lowerBound := 4,lowerBoundExplanation := ...
n := 10,q := 2,
references := rec(),
upperBound := 4,
upperBoundExplanation := ... )sage.coding.databases.self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None,equal=False, in_test=None)
Returns a Python iterator which generates a complete set of representatives of all permutation equivalence classesof self-orthogonal binary linear codes of length in [1..n] and dimension in [1..k].
INPUT:• n – Integer, maximal length• k – Integer, maximal dimension• 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)• BC – Used in recursion (default: None)• equal – If True, generates only [n, k] codes (default: False)• in_test – Used in recursion (default: None)
EXAMPLES:
Generate all self-orthogonal codes of length up to 7 and dimension up to 3:
sage: # needs sage.groups
sage: for B in codes.databases.self_orthogonal_binary_codes(7,3):....:
print(B)[2, 1] linear code over GF(2)[4, 2] linear code over GF(2)[6, 3] linear code over GF(2)[4, 1] linear code over GF(2)[6, 2] linear code over GF(2)[6, 2] linear code over GF(2)[7, 3] linear code over GF(2)[6, 1] linear code over GF(2)>>> from sage.all import *>>> # needs sage.groups>>> for B in codes.databases.self_orthogonal_binary_codes(Integer(7),Integer(3)):...
print(B)[2, 1] linear code over GF(2)[4, 2] linear code over GF(2)[6, 3] linear code over GF(2)[4, 1] linear code over GF(2)(continues on next page)

346

Chapter 16. Databases for Coding Theory

Coding Theory, Release 10.4

(continued from previous page)[6, 2] linear code over GF(2)[6, 2] linear code over GF(2)[7, 3] linear code over GF(2)[6, 1] linear code over GF(2)Generate all doubly-even codes of length up to 7 and dimension up to 3:
sage: # needs sage.groups
sage: for B in codes.databases.self_orthogonal_binary_codes(7,3,4):....:
print(B); print(B.generator_matrix())[4, 1] linear code over GF(2)[1 1 1 1][6, 2] linear code over GF(2)[1 1 1 1 0 0]
[0 1 0 1 1 1]
[7, 3] linear code over GF(2)[1 0 1 1 0 1 0]
[0 1 0 1 1 1 0]
[0 0 1 0 1 1 1]>>> from sage.all import *>>> # needs sage.groups>>> for B in codes.databases.self_orthogonal_binary_codes(Integer(7),Integer(3),˓→Integer(4)):...
print(B); print(B.generator_matrix())[4, 1] linear code over GF(2)[1 1 1 1][6, 2] linear code over GF(2)[1 1 1 1 0 0]
[0 1 0 1 1 1]
[7, 3] linear code over GF(2)[1 0 1 1 0 1 0]
[0 1 0 1 1 1 0]
[0 0 1 0 1 1 1]

Generate all doubly-even codes of length up to 7 and dimension up to 2:
sage: # needs sage.groups
sage: for B in codes.databases.self_orthogonal_binary_codes(7,2,4):....:
print(B); print(B.generator_matrix())[4, 1] linear code over GF(2)[1 1 1 1][6, 2] linear code over GF(2)[1 1 1 1 0 0]
[0 1 0 1 1 1]>>> from sage.all import *>>> # needs sage.groups>>> for B in codes.databases.self_orthogonal_binary_codes(Integer(7),Integer(2),˓→Integer(4)):...
print(B); print(B.generator_matrix())[4, 1] linear code over GF(2)[1 1 1 1][6, 2] linear code over GF(2)[1 1 1 1 0 0]
[0 1 0 1 1 1]

16.1. Access functions to online databases for coding theory347

Coding Theory, Release 10.4

Generate all self-orthogonal codes of length equal to 8 and dimension equal to 4:
sage: # needs sage.groups
sage: for B in codes.databases.self_orthogonal_binary_codes(8, 4, equal=True):....:
print(B); print(B.generator_matrix())[8, 4] linear code over GF(2)[1 0 0 1 0 0 0 0]
[0 1 0 0 1 0 0 0]
[0 0 1 0 0 1 0 0]
[0 0 0 0 0 0 1 1]
[8, 4] linear code over GF(2)[1 0 0 1 1 0 1 0]
[0 1 0 1 1 1 0 0]
[0 0 1 0 1 1 1 0]
[0 0 0 1 0 1 1 1]>>> from sage.all import *>>> # needs sage.groups>>> for B in codes.databases.self_orthogonal_binary_codes(Integer(8), Integer(4),␣
˓→equal=True):...
print(B); print(B.generator_matrix())[8, 4] linear code over GF(2)[1 0 0 1 0 0 0 0]
[0 1 0 0 1 0 0 0]
[0 0 1 0 0 1 0 0]
[0 0 0 0 0 0 1 1]
[8, 4] linear code over GF(2)[1 0 0 1 1 0 1 0]
[0 1 0 1 1 1 0 0]
[0 0 1 0 1 1 1 0]
[0 0 0 1 0 1 1 1]

Since all the codes will be self-orthogonal, b must be divisible by 2:
sage: list(codes.databases.self_orthogonal_binary_codes(8, 4, 1, equal=True))
Traceback (most recent call last):...
ValueError: b (1) must be a positive even integer.
>>> from sage.all import *>>> list(codes.databases.self_orthogonal_binary_codes(Integer(8), Integer(4),␣
˓→Integer(1), equal=True))
Traceback (most recent call last):...
ValueError: b (1) must be a positive even integer.

348

Chapter 16. Databases for Coding Theory

Coding Theory, Release 10.4

16.2 Database of two-weight codes
This module stores a database of two-weight codes.
𝑞=2
𝑞=2
𝑞=2
𝑞=2
𝑞=2
𝑞=2
𝑞=3
𝑞=3
𝑞=3
𝑞=3
𝑞=3
𝑞=3
𝑞=3
𝑞=3
𝑞=3
𝑞=4
𝑞=4
𝑞=4
𝑞=4
𝑞=5
𝑞=5
𝑞=5

𝑛 =
68
𝑛 =
85
𝑛 =
70
𝑛 =
73
𝑛 =
219
𝑛 =
198
𝑛 =
15
𝑛 =
55
𝑛 =
56
𝑛 =
84
𝑛 =
98
𝑛 =
126
𝑛 =
140
𝑛 =
154
𝑛 =
168
𝑛 =
34
𝑛 =
121
𝑛 =
132
𝑛 =
143
𝑛 =
39
𝑛 =
52
𝑛 =
65

𝑘=8
𝑘=8
𝑘=9
𝑘=9
𝑘=9
𝑘 =
10
𝑘=4
𝑘=5
𝑘=6
𝑘=6
𝑘=6
𝑘=6
𝑘=6
𝑘=6
𝑘=6
𝑘=4
𝑘=5
𝑘=5
𝑘=5
𝑘=4
𝑘=4
𝑘=4

𝑤1 =
32
𝑤1 =
40
𝑤1 =
32
𝑤1 =
32
𝑤1 =
96
𝑤1 =
96
𝑤1 =
9
𝑤1 =
36
𝑤1 =
36
𝑤1 =
54
𝑤1 =
63
𝑤1 =
81
𝑤1 =
90
𝑤1 =
99
𝑤1 =
108
𝑤1 =
24
𝑤1 =
88
𝑤1 =
96
𝑤1 =
104
𝑤1 =
30
𝑤1 =
40
𝑤1 =
50

𝑤2 =
40
𝑤2 =
48
𝑤2 =
40
𝑤2 =
40
𝑤2 =
112
𝑤2 =
112
𝑤2 =
12
𝑤2 =
45
𝑤2 =
45
𝑤2 =
63
𝑤2 =
72
𝑤2 =
90
𝑤2 =
99
𝑤2 =
108
𝑤2 =
117
𝑤2 =
28
𝑤2 =
96
𝑤2 =
104
𝑤2 =
112
𝑤2 =
35
𝑤2 =
45
𝑤2 =
55

Shared by Eric Chen [ChenDB].
Shared by Eric Chen [ChenDB].
Found by Axel Kohnert [Koh2007] and shared by Alfred Wassermann.
Shared by Eric Chen [ChenDB].
Shared by Eric Chen [ChenDB].
Shared by Eric Chen [ChenDB].
Shared by Eric Chen [ChenDB].
Shared by Eric Chen [ChenDB].
Shared by Eric Chen [ChenDB].
Shared by Eric Chen [ChenDB].
Shared by Eric Chen [ChenDB].
Shared by Eric Chen [ChenDB].
Found by Axel Kohnert [Koh2007] and shared by Alfred Wassermann.
Shared by Eric Chen [ChenDB].
From [Di2000]
Shared by Eric Chen [ChenDB].
From [Di2000]
From [Di2000]
From [Di2000]
From Bouyukliev and Simonis ([BS2003], Theorem 4.1)
Shared by Eric Chen [ChenDB].
Shared by Eric Chen [ChenDB].

REFERENCE:• [BS2003]

16.2. Database of two-weight codes349

Coding Theory, Release 10.4

• [ChenDB]• [Koh2007]• [Di2000]

350

Chapter 16. Databases for Coding Theory

CHAPTERSEVENTEENMISCELLANEOUS MODULES

There is at least one module in Sage for source coding in communications theory:

17.1 Huffman encodingThis module implements functionalities relating to Huffman encoding and decoding.
AUTHOR:• Nathann Cohen (2010-05): initial version.

17.1.1 Classes and functionsclass sage.coding.source_coding.huffman.Huffman(source)
Bases: SageObject
This class implements the basic functionalities of Huffman codes.
It can build a Huffman code from a given string, or from the information of a dictionary associating to each key(the elements of the alphabet) a weight (most of the time, a probability value or a number of occurrences).
INPUT:• source – can be either– 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 frequencyof each alphabetic symbol, then source is considered as the frequency table of the alphabet with eachnumeric (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:
1. Let source be a string of symbols over an alphabet and feed source to the constructor of this class.
Based on the input string, a frequency table is constructed that contains the frequency of each unique symbol
in source. The alphabet in question is then all the unique symbols in source. A significant implicationof this is that any subsequent string that we want to encode must contain only symbols that can be found insource.
2. Let source be the frequency table of an alphabet. We can feed this table to the constructor of this class.
The table source can be a table of frequencies or a table of weights.

351

Coding Theory, Release 10.4

In either case, the alphabet must consist of at least two symbols.
EXAMPLES:
sage: from sage.coding.source_coding.huffman import Huffman, frequency_tablesage: h1 = Huffman("There once was a french fry")sage: for letter, code in sorted(h1.encoding_table().items()):....:
print(" {} : {}".format(letter, code)): 00
T : 11100
a : 0111c : 1010
e : 100
f : 1011
h : 1100n : 1101o : 11101
r : 010s : 11110
w : 11111
y : 0110>>> from sage.all import *>>> from sage.coding.source_coding.huffman import Huffman, frequency_table>>> h1 = Huffman("There once was a french fry")>>> for letter, code in sorted(h1.encoding_table().items()):...
print(" {} : {}".format(letter, code)): 00
T : 11100
a : 0111c : 1010
e : 100
f : 1011
h : 1100n : 1101o : 11101
r : 010s : 11110
w : 11111
y : 0110

We can obtain the same result by “training” the Huffman code with the following table of frequency:
sage: ft = frequency_table("There once was a french fry")sage: sorted(ft.items())[(, 5),( T , 1),
( a , 2),( c , 2),( e , 4),
( f , 2),( h , 2),( n , 2),( o , 1),
( r , 3),( s , 1),
( w , 1),( y , 1)]
(continues on next page)352

Chapter 17. Miscellaneous Modules

Coding Theory, Release 10.4

(continued from previous page)

sage: h2 = Huffman(ft)>>> from sage.all import *>>> ft = frequency_table("There once was a french fry")>>> sorted(ft.items())[(, 5),( T , 1),
( a , 2),( c , 2),( e , 4),
( f , 2),( h , 2),( n , 2),( o , 1),
( r , 3),( s , 1),
( w , 1),( y , 1)]>>> h2 = Huffman(ft)Once h1 has been trained, and hence possesses an encoding table, it is possible to obtain the Huffman encoding of
any string (possibly the same) using this code:
sage: encoded = h1.encode("There once was a french fry"); encoded˓→111001100100010100001110111011010100001111101111111000011100101101010011011010110000101101001

˓→>>> from sage.all import *>>> encoded = h1.encode("There once was a french fry"); encoded˓→111001100100010100001110111011010100001111101111111000011100101101010011011010110000101101001

˓→

We can decode the above encoded string in the following way:sage: h1.decode(encoded)
There once was a french fry>>> from sage.all import *>>> h1.decode(encoded)
There once was a french fry

Obviously, if we try to decode a string using a Huffman instance which has been trained on a different sample (andhence has a different encoding table), we are likely to get some random-looking string:sage: h3 = Huffman("There once were two french fries")
sage: h3.decode(encoded)
eierhffcoeft TfewrnwrTrsc>>> from sage.all import *>>> h3 = Huffman("There once were two french fries")(continues on next page)

17.1. Huffman encoding

353

Coding Theory, Release 10.4

(continued from previous page)>>> h3.decode(encoded)
eierhffcoeft TfewrnwrTrsc

This does not look like our original string.
Instead of using frequency, we can assign weights to each alphabetic symbol:
sage: from sage.coding.source_coding.huffman import Huffman
sage: T = {"a":45, "b":13, "c":12, "d":16, "e":9, "f":5}
sage: H = Huffman(T)sage: L = ["deaf", "bead", "fab", "bee"]sage: E = []sage: for e in L:....:
E.append(H.encode(e))....:
print(E[-1])111110101100
10111010111
11000101
10111011101
sage: D = []sage: for e in E:....:
D.append(H.decode(e))....:
print(D[-1])
deaf
bead
fab
bee
sage: D == L
True>>> from sage.all import *>>> from sage.coding.source_coding.huffman import Huffman>>> T = {"a":Integer(45), "b":Integer(13), "c":Integer(12), "d":Integer(16), "e˓→":Integer(9), "f":Integer(5)}>>> H = Huffman(T)>>> L = ["deaf", "bead", "fab", "bee"]>>> E = []>>> for e in L:...
E.append(H.encode(e))...
print(E[-Integer(1)])
111110101100
10111010111
11000101
10111011101>>> D = []>>> for e in E:...
D.append(H.decode(e))...
print(D[-Integer(1)])
deaf
bead
fab
bee
>>> D == L
Truedecode(string)
Decode the given string using the current encoding table.
354

Chapter 17. Miscellaneous Modules

Coding Theory, Release 10.4

INPUT:• string – a string of Huffman encodings.
OUTPUT:• The Huffman decoding of string.
EXAMPLES:This is how a string is encoded and then decoded:
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: encoded = h.encode(str); encoded˓→11000011010001010101100001111101001110011101001101101111011110111001111010000101101110100

˓→

sage: h.decode(encoded)
Sage is my most favorite general purpose computer algebra system>>> from sage.all import *>>> from sage.coding.source_coding.huffman import Huffman>>> str = "Sage is my most favorite general purpose computer algebra system">>> h = Huffman(str)>>> encoded = h.encode(str); encoded˓→11000011010001010101100001111101001110011101001101101111011110111001111010000101101110100

˓→>>> h.decode(encoded)
Sage is my most favorite general purpose computer algebra system

encode(string)
Encode the given string based on the current encoding table.
INPUT:• string – a string of symbols over an alphabet.
OUTPUT:• A Huffman encoding of string.
EXAMPLES:This is how a string is encoded and then decoded:
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: encoded = h.encode(str); encoded˓→11000011010001010101100001111101001110011101001101101111011110111001111010000101101110100

˓→

sage: h.decode(encoded)
Sage is my most favorite general purpose computer algebra system>>> from sage.all import *>>> from sage.coding.source_coding.huffman import Huffman>>> str = "Sage is my most favorite general purpose computer algebra system"(continues on next page)

17.1. Huffman encoding

355

Coding Theory, Release 10.4

(continued from previous page)>>> h = Huffman(str)>>> encoded = h.encode(str); encoded˓→11000011010001010101100001111101001110011101001101101111011110111001111010000101101110100

˓→>>> h.decode(encoded)
Sage is my most favorite general purpose computer algebra system

encoding_table()
Returns the current encoding table.
INPUT:• None.
OUTPUT:• A dictionary associating an alphabetic symbol to a Huffman encoding.
EXAMPLES:
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 = sorted(h.encoding_table().items())
sage: for symbol, code in T:....:
print("{} {}".format(symbol, code))101
S 110000
a 1101b 110001
c 110010
e 010
f 110011
g 0001i 10000
l 10001
m 0011n 00000
o 0110p 0010r 1110s 1111
t 0111
u 10010v 00001
y 10011>>> from sage.all import *>>> from sage.coding.source_coding.huffman import Huffman>>> str = "Sage is my most favorite general purpose computer algebra system">>> h = Huffman(str)>>> T = sorted(h.encoding_table().items())>>> for symbol, code in T:...
print("{} {}".format(symbol, code))101
S 110000
a 1101(continues on next page)

356

Chapter 17. Miscellaneous Modules

Coding Theory, Release 10.4

(continued from previous page)b 110001
c 110010
e 010
f 110011
g 0001i 10000
l 10001
m 0011n 00000
o 0110p 0010r 1110s 1111
t 0111
u 10010v 00001
y 10011tree()
Returns the Huffman tree corresponding to the current encoding.
INPUT:• None.
OUTPUT:• The binary tree representing a Huffman code.
EXAMPLES:
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#␣˓→needs sage.graphs
Digraph on 39 vertices
sage: T.show(figsize=[20,20])#␣˓→needs sage.graphs sage.plot>>> from sage.all import *>>> from sage.coding.source_coding.huffman import Huffman>>> str = "Sage is my most favorite general purpose computer algebra system">>> h = Huffman(str)>>> T = h.tree(); T#␣˓→needs sage.graphs
Digraph on 39 vertices>>> T.show(figsize=[Integer(20),Integer(20)])␣˓→# needs sage.graphs sage.plot<BLANKLINE>

sage.coding.source_coding.huffman.frequency_table(string)
Return the frequency table corresponding to the given string.
INPUT:• string – a string of symbols over some alphabet.
OUTPUT:17.1. Huffman encoding

357

Coding Theory, Release 10.4

• A table of frequency of each unique symbol in string. If string is an empty string, return an empty
table.
EXAMPLES:
The frequency table of a non-empty string:sage: from sage.coding.source_coding.huffman import frequency_tablesage: str = "Stop counting my characters!"
sage: T = sorted(frequency_table(str).items())
sage: for symbol, code in T:....:
print("{} {}".format(symbol, code))
3
! 1
S 1
a 2
c 3
e 1
g 1
h 1
i 1
m 1
n 2
o 2
p 1
r 2
s 1
t 3
u 1
y 1
>>> from sage.all import *>>> from sage.coding.source_coding.huffman import frequency_table>>> str = "Stop counting my characters!">>> T = sorted(frequency_table(str).items())>>> for symbol, code in T:...
print("{} {}".format(symbol, code))
3
! 1
S 1
a 2
c 3
e 1
g 1
h 1
i 1
m 1
n 2
o 2
p 1
r 2
s 1
t 3
u 1
y 1

The frequency of an empty string:

358

Chapter 17. Miscellaneous Modules

Coding Theory, Release 10.4

sage: frequency_table("")
defaultdict(<... int >, {})>>> from sage.all import *>>> frequency_table("")
defaultdict(<... int >, {})17.1. Huffman encoding359

Coding Theory, Release 10.4

360

Chapter 17. Miscellaneous Modules

CHAPTEREIGHTEEN

INDICES AND TABLES• Index• Module Index• Search Page

361

Coding Theory, Release 10.4

362

Chapter 18. Indices and Tables

PYTHON MODULE INDEX

csage.coding.abstract_code, 3
sage.coding.ag_code, 199
sage.coding.ag_code_decoders, 200
sage.coding.bch_code, 147
sage.coding.binary_code, 245
sage.coding.bounds_catalog, 51
sage.coding.channel, 19
sage.coding.channels_catalog, 43
sage.coding.code_bounds, 325
sage.coding.code_constructions, 230
sage.coding.codecan.autgroup_can_label, 318
sage.coding.codecan.codecan, 313
sage.coding.codes_catalog, 45
sage.coding.cyclic_code, 132
sage.coding.databases, 343
sage.coding.decoder, 37
sage.coding.decoders_catalog, 47
sage.coding.delsarte_bounds, 335
sage.coding.encoder, 31
sage.coding.encoders_catalog, 49
sage.coding.extended_code, 275
sage.coding.golay_code, 154
sage.coding.goppa_code, 192
sage.coding.grs_code, 168
sage.coding.guava, 241
sage.coding.guruswami_sudan.gs_decoder, 295
sage.coding.guruswami_sudan.interpolation, 306
sage.coding.guruswami_sudan.utils, 310
sage.coding.hamming_code, 131
sage.coding.information_set_decoder, 281
sage.coding.kasami_codes, 196
sage.coding.linear_code, 73
sage.coding.linear_code_no_metric, 53
sage.coding.linear_rank_metric, 114
sage.coding.parity_check_code, 127
sage.coding.punctured_code, 268
sage.coding.reed_muller_code, 158
sage.coding.self_dual_codes, 242

sage.coding.source_coding.huffman, 351
sage.coding.subfield_subcode, 263
sage.coding.two_weight_db, 349

363

Coding Theory, Release 10.4

364

Python Module Index

INDEXA
AbstractCode (class in sage.coding.abstract_code), 4
AbstractLinearCode (class in sage.coding.linear_code), 76
AbstractLinearCodeNoMetric (class in sage.coding.linear_code_no_metric), 53
AbstractLinearRankMetricCode(classin
sage.coding.linear_rank_metric), 116
add_decoder() (sage.coding.abstract_code.AbstractCode method), 5
add_encoder() (sage.coding.abstract_code.AbstractCode method), 6
AGCode (class in sage.coding.ag_code), 221
alekhnovich_root_finder()(inmodulesage.coding.guruswami_sudan.gs_decoder),305
algorithm()(sage.coding.information_set_decoder.LinearCodeInformationSetDecoder
method), 292
ambient_space()(sage.coding.abstract_code.AbstractCode method), 7
ambient_space() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 54
apply_permutation() (sage.coding.binary_code.BinaryCode method), 246
assmus_mattson_designs()(sage.coding.linear_code.AbstractLinearCode method), 77
automorphism_group_gens()(sage.coding.linear_code.AbstractLinearCode method), 78

B
base_field() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 54
base_function_field() (sage.coding.ag_code.AGCode method), 221
basis() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 54
basis_differentials() (sage.coding.ag_code.DifferentialAGCode method), 225
basis_functions() (sage.coding.ag_code.EvaluationAGCode method), 228
bch_bound() (in module sage.coding.cyclic_code), 145

bch_bound()(sage.coding.cyclic_code.CyclicCode
method), 134
bch_code() (sage.coding.cyclic_code.CyclicCodeSurroundingBCHDecoder method), 141
bch_decoder() (sage.coding.cyclic_code.CyclicCodeSurroundingBCHDecoder method), 141
bch_to_grs()(sage.coding.bch_code.BCHCodemethod), 149
bch_word_to_grs() (sage.coding.bch_code.BCHUnderlyingGRSDecoder method), 150
BCHCode (class in sage.coding.bch_code), 147
BCHUnderlyingGRSDecoder (class in sage.coding.bch_code), 150
best_linear_code_in_codetables_dot_de() (in module sage.coding.databases), 343
best_linear_code_in_guava() (in module
sage.coding.databases), 344
BinaryCode (class in sage.coding.binary_code), 245
BinaryCodeClassifier (class in sage.coding.binary_code), 251
BinaryReedMullerCode (class in sage.coding.reed_muller_code), 158
binomial_moment()(sage.coding.linear_code.AbstractLinearCode method), 81
bounds_on_minimum_distance_in_guava()(in module sage.coding.databases), 345

Ccalibrate() (sage.coding.information_set_decoder.InformationSetAlgorithm method), 282
calibrate()(sage.coding.information_set_decoder.LeeBrickellISDAlgorithm method), 286
canonical_representative() (sage.coding.linear_code.AbstractLinearCode method), 81
cardinality()(sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 55
CartierCode (class in sage.coding.ag_code), 222
Channel (class in sage.coding.channel), 19
characteristic()(sage.coding.linear_code.AbstractLinearCode method), 83

365

Coding Theory, Release 10.4

characteristic_polynomial() (sage.coding.linear_code.AbstractLinearCode method), 83
check_polynomial()(sage.coding.cyclic_code.CyclicCode method), 134
chinen_polynomial() (sage.coding.linear_code.AbstractLinearCode method), 83
cmp() (sage.coding.binary_code.PartitionStack method),254
code() (sage.coding.decoder.Decoder method), 37
code() (sage.coding.encoder.Encoder method), 31
code() (sage.coding.information_set_decoder.InformationSetAlgorithm method), 283
codesize_upper_bound() (in module sage.coding.code_bounds), 327
column_blocks() (sage.coding.codecan.codecan.InnerGroup method), 315
column_multipliers() (sage.coding.grs_code.GeneralizedReedSolomonCode method), 186connected_encoder()(sage.coding.ag_code_decoders.DifferentialAGCodeUniqueDecoder
method), 209
connected_encoder()(sage.coding.ag_code_decoders.EvaluationAGCodeUniqueDecoder
method), 218
connected_encoder()(sage.coding.decoder.Decoder method), 38
construction_x()(sage.coding.linear_code.AbstractLinearCode method), 84
cosetGraph() (sage.coding.linear_code.AbstractLinearCode method), 85
covering_radius() (sage.coding.golay_code.GolayCode method), 155
covering_radius() (sage.coding.grs_code.GeneralizedReedSolomonCode method), 186covering_radius()(sage.coding.linear_code.AbstractLinearCode method), 85
CyclicCode (class in sage.coding.cyclic_code), 132
CyclicCodePolynomialEncoder(classin
sage.coding.cyclic_code), 139
CyclicCodeSurroundingBCHDecoder (class insage.coding.cyclic_code), 141
CyclicCodeVectorEncoder (class in sage.coding.cyclic_code), 143

decode() (sage.coding.source_coding.huffman.Huffman
method), 354
decode_to_code() (sage.coding.abstract_code.AbstractCode method), 7
decode_to_code()(sage.coding.ag_code_decoders.DifferentialAGCodeUniqueDecoder
method), 209
decode_to_code()(sage.coding.ag_code_decoders.EvaluationAGCodeUniqueDecoder
method), 218
decode_to_code() (sage.coding.bch_code.BCHUnderlyingGRSDecoder method), 150
decode_to_code() (sage.coding.cyclic_code.CyclicCodeSurroundingBCHDecoder method), 142
decode_to_code()(sage.coding.decoder.Decoder
method), 38
decode_to_code() (sage.coding.extended_code.ExtendedCodeOriginalCodeDecoder
method),278
decode_to_code() (sage.coding.grs_code.GRSBerlekampWelchDecoder method), 169
decode_to_code()(sage.coding.grs_code.GRSGaoDecoder method), 180
decode_to_code() (sage.coding.grs_code.GRSKeyEquationSyndromeDecoder method), 182
decode_to_code()(sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder
method), 297
decode_to_code() (sage.coding.information_set_decoder.LinearCodeInformationSetDecoder
method), 292
decode_to_code()(sage.coding.linear_code.LinearCodeNearestNeighborDecoder
method),107
decode_to_code()(sage.coding.linear_code.LinearCodeSyndromeDecoder method), 111
decode_to_code()(sage.coding.linear_rank_metric.LinearRankMetricCodeNearestNeighborDecoder method), 121
decode_to_code()(sage.coding.punctured_code.PuncturedCodeOriginalCodeDecoder
method), 273
decode_to_code()(sage.coding.subfield_subcode.SubfieldSubcodeOriginalCodeDecoderD
method), 267
decode_to_message()(sage.coding.abdecode() (sage.coding.ag_code_decoders.Decoder_K
stract_code.AbstractCode
method),8
method), 201
decode_to_message()(sage.coding.ag_code_dedecode()(sage.coding.ag_code_decoders.Decoders.DifferentialAGCodeUniqueDecoder
coder_K_extension method), 203
method), 210
decode() (sage.coding.information_set_decoder.Infordecode_to_message()(sage.coding.ag_code_demationSetAlgorithm method), 283
coders.EvaluationAGCodeUniqueDecoder
decode()(sage.coding.information_set_decoder.Leemethod), 219
BrickellISDAlgorithm method), 288
decode_to_message()(sage.coding.decoder.De366

Index

Coding Theory, Release 10.4

coder method), 39
decode_to_message() (sage.coding.grs_code.GRSBerlekampWelchDecoder method), 170
decode_to_message()(sage.coding.grs_code.GRSErrorErasureDecoder method),172
decode_to_message() (sage.coding.grs_code.GRSGaoDecoder method), 181
decode_to_message()(sage.coding.grs_code.GRSKeyEquationSyndromeDecoder
method), 183
decode_to_message() (sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder
method), 298
Decoder (class in sage.coding.decoder), 37
decoder()(sage.coding.abstract_code.AbstractCode
method), 9
Decoder_K (class in sage.coding.ag_code_decoders), 201
Decoder_K_extension(classin
sage.coding.ag_code_decoders), 202
decoder_type() (sage.coding.decoder.Decoder classmethod), 40
decoders_available()(sage.coding.abstract_code.AbstractCode method), 11
decoding_interval()(sage.coding.information_set_decoder.InformationSetAlgorithm
method), 284
decoding_interval()(sage.coding.information_set_decoder.LinearCodeInformationSetDecoder method), 294
decoding_radius()(sage.coding.ag_code_decoders.DifferentialAGCodeUniqueDecoder
method), 211
decoding_radius()(sage.coding.ag_code_decoders.EvaluationAGCodeUniqueDecoder
method), 220
decoding_radius() (sage.coding.bch_code.BCHUnderlyingGRSDecoder method), 152
decoding_radius() (sage.coding.cyclic_code.CyclicCodeSurroundingBCHDecoder method), 142
decoding_radius() (sage.coding.decoder.Decoder
method), 41
decoding_radius() (sage.coding.extended_code.ExtendedCodeOriginalCodeDecoder method), 279
decoding_radius() (sage.coding.grs_code.GRSBerlekampWelchDecoder method), 171
decoding_radius() (sage.coding.grs_code.GRSErrorErasureDecoder method), 173
decoding_radius()(sage.coding.grs_code.GRSGaoDecoder method), 181
decoding_radius()(sage.coding.grs_code.GRSKeyEquationSyndromeDecoder
method), 184
decoding_radius()(sage.coding.guruswami_suIndex

dan.gs_decoder.GRSGuruswamiSudanDecoder
method), 299
decoding_radius()(sage.coding.information_set_decoder.LinearCodeInformationSetDecoder method), 294
decoding_radius() (sage.coding.linear_code.LinearCodeNearestNeighborDecoder
method),108
decoding_radius() (sage.coding.linear_code.LinearCodeSyndromeDecoder method), 112
decoding_radius() (sage.coding.linear_rank_metric.LinearRankMetricCodeNearestNeighborDecoder method), 121
decoding_radius()(sage.coding.punctured_code.PuncturedCodeOriginalCodeDecoder
method), 273
decoding_radius()(sage.coding.subfield_subcode.SubfieldSubcodeOriginalCodeDecoder
method), 267
DecodingError, 42
defining_set() (sage.coding.cyclic_code.CyclicCode
method), 135delsarte_bound_additive_hamming_space() (in module sage.coding.delsarte_bounds), 336
delsarte_bound_constant_weight_code()(in module sage.coding.delsarte_bounds), 337
delsarte_bound_hamming_space() (in module
sage.coding.delsarte_bounds), 338delsarte_bound_Q_matrix()(inmodulesage.coding.delsarte_bounds), 335
designed_distance()(sage.coding.ag_code.CartierCode method), 223
designed_distance() (sage.coding.ag_code.DifferentialAGCode method), 226
designed_distance() (sage.coding.ag_code.EvaluationAGCode method), 228
designed_distance() (sage.coding.bch_code.BCHCode method), 149
DifferentialAGCode (class in sage.coding.ag_code),224
DifferentialAGCodeDecoder_K(classin
sage.coding.ag_code_decoders), 203
DifferentialAGCodeDecoder_K_extension(class in sage.coding.ag_code_decoders), 204
DifferentialAGCodeEncoder (class in sage.coding.ag_code_decoders), 205
DifferentialAGCodeUniqueDecoder (class insage.coding.ag_code_decoders), 207
dimension() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 55
dimension() (sage.coding.punctured_code.PuncturedCode method), 268
dimension() (sage.coding.subfield_subcode.Subfield367

Coding Theory, Release 10.4

Subcode method), 263
dimension_lower_bound()(sage.coding.subfield_subcode.SubfieldSubcode method), 264
dimension_upper_bound() (in module sage.coding.code_bounds), 327
dimension_upper_bound()(sage.coding.subfield_subcode.SubfieldSubcode method), 264
direct_sum() (sage.coding.linear_code.AbstractLinearCode method), 86
distance_bound() (sage.coding.goppa_code.GoppaCode method), 193
divisor()(sage.coding.linear_code.AbstractLinearCode method), 87
DuadicCodeEvenPair() (in module sage.coding.code_constructions), 230
DuadicCodeOddPair() (in module sage.coding.code_constructions), 231
dual_code()(sage.coding.golay_code.GolayCode
method), 155
dual_code() (sage.coding.grs_code.GeneralizedReedSolomonCode method), 186
dual_code() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 56

Eeberlein() (in module sage.coding.delsarte_bounds),
340
elias_bound_asymp() (in module sage.coding.code_bounds), 328
elias_upper_bound() (in module sage.coding.code_bounds), 328
embedding() (sage.coding.subfield_subcode.SubfieldSubcode method), 264
encode()(sage.coding.abstract_code.AbstractCode
method), 12
encode() (sage.coding.ag_code_decoders.Decoder_K
method), 202
encode()(sage.coding.ag_code_decoders.Decoder_K_extension method), 203
encode()(sage.coding.ag_code_decoders.DifferentialAGCodeEncoder method), 205
encode() (sage.coding.ag_code_decoders.EvaluationAGCodeEncoder method), 214
encode() (sage.coding.cyclic_code.CyclicCodePolynomialEncoder method), 139
encode() (sage.coding.cyclic_code.CyclicCodeVectorEncoder method), 143
encode() (sage.coding.encoder.Encoder method), 32
encode() (sage.coding.grs_code.GRSEvaluationPolynomialEncoder method), 175
encode() (sage.coding.parity_check_code.ParityCheckCodeStraightforwardEncoder method), 129
encode() (sage.coding.punctured_code.PuncturedCode
method), 269
368

encode() (sage.coding.reed_muller_code.ReedMullerPolynomialEncoder method), 163
encode() (sage.coding.source_coding.huffman.Huffman
method), 355
Encoder (class in sage.coding.encoder), 31
encoder()(sage.coding.abstract_code.AbstractCode
method), 13
encoders_available()(sage.coding.abstract_code.AbstractCode method), 15
encoding_table() (sage.coding.source_coding.huffman.Huffman method), 356
EncodingError, 36
entropy() (in module sage.coding.code_bounds), 329
entropy_inverse()(inmodulesage.coding.code_bounds), 330
error_probability()(sage.coding.channel.QarySymmetricChannel method), 25
ErrorErasureChannel (class in sage.coding.channel), 22
evaluation_points() (sage.coding.grs_code.GeneralizedReedSolomonCode method), 187
EvaluationAGCode (class in sage.coding.ag_code),227
EvaluationAGCodeDecoder_K (class in sage.coding.ag_code_decoders), 212
EvaluationAGCodeDecoder_K_extension(class in sage.coding.ag_code_decoders), 213
EvaluationAGCodeEncoder (class in sage.coding.ag_code_decoders), 214
EvaluationAGCodeUniqueDecoder (class insage.coding.ag_code_decoders), 216
extended_code() (sage.coding.linear_code.AbstractLinearCode method), 87
ExtendedCode (class in sage.coding.extended_code),
275
ExtendedCodeExtendedMatrixEncoder (classin sage.coding.extended_code), 277
ExtendedCodeOriginalCodeDecoder (class insage.coding.extended_code), 277
ExtendedQuadraticResidueCode() (in module
sage.coding.code_constructions), 231
extension_degree() (sage.coding.linear_rank_metric.AbstractLinearRankMetricCode method), 116

Ffield_embedding() (sage.coding.cyclic_code.CyclicCode method), 136
field_extension() (sage.coding.linear_rank_metric.AbstractLinearRankMetricCode
method),116
find_generator_polynomial() (in module
sage.coding.cyclic_code), 146
format_interval() (in module sage.coding.channel), 28
Index

Coding Theory, Release 10.4

frequency_table()(inmodulesage.cod- generator_matrix()(sage.coding.source_coding.huffman), 357
ing.reed_muller_code.ReedMullerVectorEncoder
from_matrix_representation() (in module
method), 167
sage.coding.linear_rank_metric), 122generator_polynomial()(sage.codfrom_parity_check_matrix()(inmoduleing.cyclic_code.CyclicCode method), 137
sage.coding.code_constructions), 237
gens() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 56
G
genus() (sage.coding.linear_code.AbstractLinearCode
method), 88
galois_closure()(sage.coding.linear_code.Abget_autom_gens()(sage.coding.codecan.autstractLinearCode method), 87
group_can_label.LinearCodeAutGroupCanLabel
GeneralizedReedSolomonCode (class in sage.codmethod), 322
ing.grs_code), 184(sage.coding.codecan.codegenerate_children() (sage.coding.binary_code.Bi- get_autom_gens()
can.PartitionRefinementLinearCode
method),naryCodeClassifier method), 251316
generator_matrix() (sage.coding.ag_code.Cartierget_autom_order()(sage.coding.codecan.autCode method), 223
group_can_label.LinearCodeAutGroupCanLabelgenerator_matrix() (sage.coding.ag_code.Differenmethod), 323
tialAGCode method), 226
generator_matrix() (sage.coding.ag_code.Evalua- get_autom_order_inner_stabilizer()(sage.coding.codecan.codecan.PartitionRefinetionAGCode method), 229
mentLinearCode method), 317
generator_matrix()(sage.codget_canonical_form() (sage.coding.codecan.auting.cyclic_code.CyclicCodeVectorEncodergroup_can_label.LinearCodeAutGroupCanLabelmethod), 144
method), 323
generator_matrix() (sage.coding.encoder.Encoder
get_canonical_form() (sage.coding.codecan.codemethod), 33
can.PartitionRefinementLinearCode
method),generator_matrix()(sage.coding.ex317
tended_code.ExtendedCodeExtendedMatrixget_frob_pow() (sage.coding.codecan.codecan.InnerEncoder method), 277
Group method), 315
generator_matrix() (sage.coding.golay_code.Goget_PGammaL_gens()(sage.coding.codecan.autlayCode method), 156
group_can_label.LinearCodeAutGroupCanLabelgenerator_matrix() (sage.coding.goppa_code.Gopmethod), 321
paCodeEncoder method), 195(sage.coding.codecan.autgenerator_matrix()(sage.coding.grs_code.GR- get_PGammaL_order()group_can_label.LinearCodeAutGroupCanLabel
SEvaluationVectorEncoder method), 179
method), 322
generator_matrix()(sage.codget_transporter()(sage.coding.codecan.auting.kasami_codes.KasamiCode method), 197
group_can_label.LinearCodeAutGroupCanLabelgenerator_matrix()(sage.coding.linmethod), 323
ear_code_no_metric.AbstractLinearCodeNoget_transporter()(sage.coding.codecan.codeMetric method), 56
can.PartitionRefinementLinearCode
method),generator_matrix()(sage.coding.lin318
ear_code_no_metric.LinearCodeSystematigilbert_lower_bound() (in module sage.codcEncoder method), 69
ing.code_bounds), 330
generator_matrix() (sage.coding.linear_code.Lingilt() (in module sage.coding.guruswami_sudan.utils),
earCode method), 106
310
generator_matrix() (sage.coding.linear_code.LinGolayCode(class in sage.coding.golay_code), 154
earCodeGeneratorMatrixEncoder method), 107
GoppaCode(class in sage.coding.goppa_code), 192
generator_matrix() (sage.coding.linear_rank_metGoppaCodeEncoder(class in sage.coding.goppa_code),ric.LinearRankMetricCode method), 120
194
generator_matrix()(sage.coding.pargriesmer_upper_bound() (in module sage.codity_check_code.ParityCheckCodeGeneratoring.code_bounds), 331
MatrixEncoder method), 128
grs_code()(sage.coding.bch_code.BCHUnderlyinggenerator_matrix()(sage.coding.puncGRSDecoder
method), 152
tured_code.PuncturedCodePuncturedMatrixgrs_decoder()(sage.coding.bch_code.BCHUnderlyEncoder method), 274
Index

369

Coding Theory, Release 10.4

ingGRSDecoder method), 153
grs_word_to_bch() (sage.coding.bch_code.BCHUnderlyingGRSDecoder method), 153
GRSBerlekampWelchDecoder (class in sage.coding.grs_code), 169
GRSErrorErasureDecoder (class in sage.coding.grs_code), 171
GRSEvaluationPolynomialEncoder (class insage.coding.grs_code), 174
GRSEvaluationVectorEncoder (class in sage.coding.grs_code), 178
GRSGaoDecoder (class in sage.coding.grs_code), 179
GRSGuruswamiSudanDecoder (class in sage.coding.guruswami_sudan.gs_decoder), 295
GRSKeyEquationSyndromeDecoder (class insage.coding.grs_code), 182
gs_interpolation_lee_osullivan() (in module sage.coding.guruswami_sudan.interpolation),306
gs_interpolation_linalg()(inmodulesage.coding.guruswami_sudan.interpolation),307
gs_satisfactory()(sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder
static method), 300
guruswami_sudan_decoding_radius()(sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder
staticmethod), 301
gv_bound_asymp()(inmodulesage.coding.code_bounds), 331
gv_info_rate()(inmodulesage.coding.code_bounds), 332

InnerGroup (class in sage.coding.codecan.codecan),314
input_space()(sage.coding.channel.Channel
method), 20
input_space()(sage.coding.decoder.Decoder
method), 41
interpolation_algorithm()(sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder method), 302
is_galois_closed() (sage.coding.linear_code.AbstractLinearCode method), 88
is_generalized() (sage.coding.grs_code.GeneralizedReedSolomonCode method), 187
is_information_set()(sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 57
is_permutation_automorphism()(sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 58
is_permutation_equivalent() (sage.coding.linear_code.AbstractLinearCode method), 89
is_projective() (sage.coding.linear_code.AbstractLinearCode method), 89
is_self_dual() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 59
is_self_orthogonal()(sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 59
is_subcode() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 59

Jjohnson_radius() (in module sage.coding.guruswami_sudan.utils), 310
H
jump_size()(sage.coding.bch_code.BCHCodemethod), 149
hamming_bound_asymp() (in module sage.codjuxtapose()(sage.coding.linear_code.AbstractLining.code_bounds), 332
earCode method), 90
hamming_upper_bound() (in module sage.coding.code_bounds), 332
HammingCode (class in sage.coding.hamming_code), 131 K
Huffman (class in sage.coding.source_coding.huffman), KasamiCode (class in sage.coding.kasami_codes), 196
351
known_algorithms()(sage.coding.information_set_decoder.LinearCodeInformationSetI
Decoder static method), 294(inmodulesage.coding.delinfo (sage.coding.ag_code_decoders.Decoder_K at- krawtchouk()sarte_bounds), 341
tribute), 202
info (sage.coding.ag_code_decoders.Decoder_K_extenL
sion attribute), 203
information_set()(sage.coding.lin- lee_osullivan_module() (in module sage.codear_code_no_metric.AbstractLinearCodeNoing.guruswami_sudan.interpolation), 309
Metric method), 57
LeeBrickellISDAlgorithm (class in sage.codInformationSetAlgorithm (class in sage.coding.information_set_decoder), 285
ing.information_set_decoder), 281
length()(sage.coding.abstract_code.AbstractCode
method), 16
370

Index

Coding Theory, Release 10.4

ligt() (in module sage.coding.guruswami_sudan.utils),
310
LinearCode (class in sage.coding.linear_code), 104
LinearCodeAutGroupCanLabel (class in sage.coding.codecan.autgroup_can_label), 320
LinearCodeGeneratorMatrixEncoder (class insage.coding.linear_code), 106
LinearCodeInformationSetDecoder (class insage.coding.information_set_decoder), 288
LinearCodeNearestNeighborDecoder (class insage.coding.linear_code), 107
LinearCodeSyndromeDecoder (class in sage.coding.linear_code), 108
LinearCodeSystematicEncoder(classin
sage.coding.linear_code_no_metric), 67
LinearRankMetricCode (class in sage.coding.linear_rank_metric), 119
LinearRankMetricCodeNearestNeighborDecoder (class in sage.coding.linear_rank_metric), 121list()(sage.coding.abstract_code.AbstractCode
method), 16
list_size() (sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder method),303

Mmatrix()(sage.coding.binary_code.BinaryCode
method), 247
matrix_form_of_vector()(sage.coding.linear_rank_metric.AbstractLinearRankMetricCode
method), 117
maximum_error_weight()(sage.coding.linear_code.LinearCodeSyndromeDecoder
method), 112
message_space()(sage.coding.cyclic_code.CyclicCodePolynomialEncoder method), 140
message_space()(sage.coding.cyclic_code.CyclicCodeVectorEncoder method), 144
message_space()(sage.coding.decoder.Decoder
method), 42
message_space()(sage.coding.encoder.Encoder
method), 33
message_space() (sage.coding.grs_code.GRSEvaluationPolynomialEncoder method), 176
message_space()(sage.coding.parity_check_code.ParityCheckCodeStraightforwardEncoder method), 130
message_space()(sage.coding.reed_muller_code.ReedMullerPolynomialEncoder method), 164
metric()(sage.coding.abstract_code.AbstractCode
method), 17

Index

minimum_distance() (sage.coding.golay_code.GolayCode method), 156
minimum_distance() (sage.coding.grs_code.GeneralizedReedSolomonCode method), 188
minimum_distance()(sage.coding.hamming_code.HammingCode method), 131
minimum_distance() (sage.coding.linear_code.AbstractLinearCode method), 90
minimum_distance() (sage.coding.linear_rank_metric.AbstractLinearRankMetricCode method), 117
minimum_distance()(sage.coding.parity_check_code.ParityCheckCode
method),127
minimum_distance()(sage.coding.reed_muller_code.BinaryReedMullerCode
method), 158
minimum_distance()(sage.coding.reed_muller_code.QAryReedMullerCode
method), 160
modulesage.coding.abstract_code, 3
sage.coding.ag_code, 199
sage.coding.ag_code_decoders, 200
sage.coding.bch_code, 147
sage.coding.binary_code, 245
sage.coding.bounds_catalog, 51
sage.coding.channel, 19
sage.coding.channels_catalog, 43
sage.coding.code_bounds, 325
sage.coding.code_constructions, 230
sage.coding.codecan.autgroup_can_label, 318
sage.coding.codecan.codecan, 313
sage.coding.codes_catalog, 45
sage.coding.cyclic_code, 132
sage.coding.databases, 343
sage.coding.decoder, 37
sage.coding.decoders_catalog, 47
sage.coding.delsarte_bounds, 335
sage.coding.encoder, 31
sage.coding.encoders_catalog, 49
sage.coding.extended_code, 275
sage.coding.golay_code, 154
sage.coding.goppa_code, 192
sage.coding.grs_code, 168
sage.coding.guava, 241
sage.coding.guruswami_sudan.gs_decoder, 295
sage.coding.guruswami_sudan.interpolation, 306
sage.coding.guruswami_sudan.utils,
310
sage.coding.hamming_code, 131371

Coding Theory, Release 10.4

sage.coding.information_set_decoder, 281
sage.coding.kasami_codes, 196
sage.coding.linear_code, 73
sage.coding.linear_code_no_metric,
53
sage.coding.linear_rank_metric, 114
sage.coding.parity_check_code, 127
sage.coding.punctured_code, 268
sage.coding.reed_muller_code, 158
sage.coding.self_dual_codes, 242
sage.coding.source_coding.huffman,351
sage.coding.subfield_subcode, 263
sage.coding.two_weight_db, 349
module_composition_factors()(sage.coding.linear_code.AbstractLinearCode
method),91
mrrw1_bound_asymp() (in module sage.coding.code_bounds), 333
multiplicity()(sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder
method), 303
multipliers_product()(sage.coding.grs_code.GeneralizedReedSolomonCode
method), 188N
n_k_params() (in module sage.coding.guruswami_sudan.gs_decoder), 305
name() (sage.coding.information_set_decoder.InformationSetAlgorithm method), 284
number_erasures() (sage.coding.channel.ErrorErasureChannel method), 23
number_errors()(sage.coding.channel.ErrorErasureChannel method), 23
number_errors() (sage.coding.channel.StaticErrorRateChannel method), 27
number_of_variables()(sage.coding.reed_muller_code.BinaryReedMullerCode
method), 159
number_of_variables()(sage.coding.reed_muller_code.QAryReedMullerCode
method), 160

O
offset() (sage.coding.bch_code.BCHCode method),149
OrbitPartition (class in sage.coding.binary_code),254
order()(sage.coding.reed_muller_code.BinaryReedMullerCode method), 159
order()(sage.coding.reed_muller_code.QAryReedMullerCode method), 160
372

original_code()(sage.coding.extended_code.ExtendedCode method), 275
original_code() (sage.coding.punctured_code.PuncturedCode method), 269
original_code() (sage.coding.subfield_subcode.SubfieldSubcode method), 265
original_decoder()(sage.coding.extended_code.ExtendedCodeOriginalCodeDecoder method), 279
original_decoder()(sage.coding.punctured_code.PuncturedCodeOriginalCodeDecoder
method), 273
original_decoder()(sage.coding.subfield_subcode.SubfieldSubcodeOriginalCodeDecoder
method), 267
output_space()(sage.coding.channel.Channel
method), 20

P
parameters() (sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder method),303
parameters()(sage.coding.information_set_decoder.InformationSetAlgorithm method), 284
parameters() (sage.coding.kasami_codes.KasamiCode
method), 198
parameters_given_tau()(sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder static method), 304
parity_check_matrix()(sage.coding.cyclic_code.CyclicCode method), 137parity_check_matrix()(sage.coding.extended_code.ExtendedCode method), 276
parity_check_matrix()(sage.coding.golay_code.GolayCode method), 157
parity_check_matrix()(sage.coding.goppa_code.GoppaCode method), 193
parity_check_matrix()(sage.coding.grs_code.GeneralizedReedSolomonCode
method), 189parity_check_matrix()(sage.coding.hamming_code.HammingCode method), 131parity_check_matrix()(sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 60
parity_check_matrix() (sage.coding.subfield_subcode.SubfieldSubcode method), 265
parity_column_multipliers()(sage.coding.grs_code.GeneralizedReedSolomonCode
method), 189
ParityCheckCode(classin
sage.coding.parity_check_code), 127
ParityCheckCodeGeneratorMatrixEncoder(class in sage.coding.parity_check_code), 128
Index

Coding Theory, Release 10.4

ParityCheckCodeStraightforwardEncoder(class in sage.coding.parity_check_code), 129
PartitionRefinementLinearCode (class insage.coding.codecan.codecan), 315
PartitionStack (class in sage.coding.binary_code),254
permutation_action() (in module sage.coding.code_constructions), 238
permutation_automorphism_group()(sage.coding.linear_code.AbstractLinearCode
method), 92
permuted_code() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 61
plotkin_bound_asymp() (in module sage.coding.code_bounds), 333
plotkin_upper_bound() (in module sage.coding.code_bounds), 333
points() (sage.coding.reed_muller_code.ReedMullerPolynomialEncoder method), 165
points()(sage.coding.reed_muller_code.ReedMullerVectorEncoder method), 168
polynomial_ring() (sage.coding.grs_code.GRSEvaluationPolynomialEncoder method), 176
polynomial_ring()(sage.coding.reed_muller_code.ReedMullerPolynomialEncoder method), 165
polynomial_to_list() (in module sage.coding.guruswami_sudan.utils), 311
primitive_root() (sage.coding.cyclic_code.CyclicCode method), 138
print_basis() (sage.coding.binary_code.PartitionStack method), 256
print_data() (sage.coding.binary_code.BinaryCode
method), 248
print_data() (sage.coding.binary_code.PartitionStackmethod), 257
probability_of_at_most_t_errors()(sage.coding.channel.QarySymmetricChannel method), 25
probability_of_exactly_t_errors()(sage.coding.channel.QarySymmetricChannel method), 25
product_code() (sage.coding.linear_code.AbstractLinearCode method), 95
punctured()(sage.coding.linear_code.AbstractLinearCode method), 96
punctured_positions()(sage.coding.punctured_code.PuncturedCode method), 270
PuncturedCode (class in sage.coding.punctured_code),
268
PuncturedCodeOriginalCodeDecoder (class insage.coding.punctured_code), 271
PuncturedCodePuncturedMatrixEncoder(class in sage.coding.punctured_code), 274
Index

put_in_canonical_form()(sage.coding.binary_code.BinaryCodeClassifier method), 253
put_in_std_form() (sage.coding.binary_code.BinaryCode method), 251

Q
QAryReedMullerCode(classin
sage.coding.reed_muller_code), 159
QarySymmetricChannel (class in sage.coding.channel), 24
QuadraticResidueCode() (in module sage.coding.code_constructions), 232
QuadraticResidueCodeEvenPair() (in module
sage.coding.code_constructions), 233
QuadraticResidueCodeOddPair() (in module
sage.coding.code_constructions), 234
QuasiQuadraticResidueCode() (in module
sage.coding.guava), 241R
random_element() (sage.coding.abstract_code.AbstractCode method), 17
random_element() (sage.coding.extended_code.ExtendedCode method), 276
random_element()(sage.coding.punctured_code.PuncturedCode method), 270
random_error_vector() (in module sage.coding.channel), 28
random_linear_code() (in module sage.coding.code_constructions), 239
RandomLinearCodeGuava() (in module sage.coding.guava), 241
rank_distance() (in module sage.coding.linear_rank_metric), 122
rank_distance_between_vectors() (sage.coding.linear_rank_metric.AbstractLinearRankMetricCode method), 118
rank_weight()(inmodulesage.coding.linear_rank_metric), 124
rank_weight_of_vector()(sage.coding.linear_rank_metric.AbstractLinearRankMetricCode
method), 118rate() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 62
redundancy_matrix()(sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 62
ReedMullerCode()(inmodulesage.coding.reed_muller_code), 161
ReedMullerPolynomialEncoder(classin
sage.coding.reed_muller_code), 162
ReedMullerVectorEncoder (class in sage.coding.reed_muller_code), 166373

Coding Theory, Release 10.4

ReedSolomonCode()(inmodulesage.coding.grs_code), 190
relative_distance() (sage.coding.linear_code.AbstractLinearCode method), 96
rootfinding_algorithm()(sage.coding.guruswami_sudan.gs_decoder.GRSGuruswamiSudanDecoder method), 305
roth_ruckenstein_root_finder() (in module
sage.coding.guruswami_sudan.gs_decoder), 306

S
sage.coding.abstract_code
module, 3
sage.coding.ag_code
module, 199
sage.coding.ag_code_decoders
module, 200
sage.coding.bch_code
module, 147
sage.coding.binary_code
module, 245
sage.coding.bounds_catalog
module, 51
sage.coding.channel
module, 19
sage.coding.channels_catalog
module, 43
sage.coding.code_bounds
module, 325
sage.coding.code_constructions
module, 230
sage.coding.codecan.autgroup_can_label
module, 318
sage.coding.codecan.codecan
module, 313
sage.coding.codes_catalog
module, 45
sage.coding.cyclic_code
module, 132
sage.coding.databases
module, 343
sage.coding.decoder
module, 37
sage.coding.decoders_catalog
module, 47
sage.coding.delsarte_bounds
module, 335
sage.coding.encoder
module, 31
sage.coding.encoders_catalog
module, 49
sage.coding.extended_code
module, 275
sage.coding.golay_code374

module, 154
sage.coding.goppa_code
module, 192
sage.coding.grs_code
module, 168
sage.coding.guava
module, 241
sage.coding.guruswami_sudan.gs_decoder
module, 295
sage.coding.guruswami_sudan.interpolation
module, 306
sage.coding.guruswami_sudan.utils
module, 310
sage.coding.hamming_code
module, 131
sage.coding.information_set_decoder
module, 281
sage.coding.kasami_codes
module, 196
sage.coding.linear_code
module, 73
sage.coding.linear_code_no_metricmodule, 53
sage.coding.linear_rank_metricmodule, 114
sage.coding.parity_check_code
module, 127
sage.coding.punctured_code
module, 268
sage.coding.reed_muller_code
module, 158
sage.coding.self_dual_codes
module, 242
sage.coding.source_coding.huffman
module, 351
sage.coding.subfield_subcode
module, 263
sage.coding.two_weight_db
module, 349
self_dual_binary_codes() (in module sage.coding.self_dual_codes), 243
self_orthogonal_binary_codes() (in module
sage.coding.databases), 346
shortened()(sage.coding.linear_code.AbstractLinearCode method), 96
singleton_bound_asymp() (in module sage.coding.code_bounds), 334
singleton_upper_bound() (in module sage.coding.code_bounds), 334
solve_degree2_to_integer_range() (in module sage.coding.guruswami_sudan.utils), 311
spectrum()(sage.coding.linear_code.AbstractLinearCode method), 97
Index

Coding Theory, Release 10.4

standard_form() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 63
StaticErrorRateChannel (class in sage.coding.channel), 26
structured_representation()(sage.coding.punctured_code.PuncturedCode
method),270
sub_field()(sage.coding.linear_rank_metric.AbstractLinearRankMetricCode method), 119
SubfieldSubcode (class in sage.coding.subfield_subcode), 263
SubfieldSubcodeOriginalCodeDecoder (classin sage.coding.subfield_subcode), 266
support()(sage.coding.linear_code.AbstractLinearCode method), 98
surrounding_bch_code()(sage.coding.cyclic_code.CyclicCode method), 138
syndrome() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 64
syndrome_table()(sage.coding.linear_code.LinearCodeSyndromeDecoder method), 113
systematic_generator_matrix()(sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 65
systematic_permutation()(sage.coding.linear_code_no_metric.LinearCodeSystematicEncoder method), 71
systematic_positions()(sage.coding.linear_code_no_metric.LinearCodeSystematicEncoder method), 71

U
u_u_plus_v_code()(sage.coding.linear_code.AbstractLinearCode method), 99
unencode() (sage.coding.abstract_code.AbstractCode
method), 17
unencode() (sage.coding.encoder.Encoder method), 34
unencode_nocheck()(sage.coding.ag_code_decoders.DifferentialAGCodeEncoder
method),206
unencode_nocheck()(sage.coding.ag_code_decoders.EvaluationAGCodeEncoder
method),215
unencode_nocheck()(sage.coding.cyclic_code.CyclicCodePolynomialEncoder
method), 140
unencode_nocheck()(sage.coding.cyclic_code.CyclicCodeVectorEncoder
method), 145
unencode_nocheck() (sage.coding.encoder.Encoder
method), 35
unencode_nocheck()(sage.coding.grs_code.GRSEvaluationPolynomialEncoder method), 177
unencode_nocheck()(sage.coding.parity_check_code.ParityCheckCodeStraightforwardEncoder method), 130
unencode_nocheck()(sage.coding.reed_muller_code.ReedMullerPolynomialEncoder method), 165

Vvector_form_of_matrix()(sage.coding.linear_rank_metric.AbstractLinearRankMetricCode
test_expand_to_ortho_basis() (in module
method), 119
sage.coding.binary_code), 260
volume_hamming()(inmodulesage.codtest_word_perms() (in module sage.coding.biing.code_bounds), 335
nary_code), 260
time_estimate() (sage.coding.information_set_de- W
coder.InformationSetAlgorithm method), 285
walsh_matrix() (in module sage.coding.code_conto_matrix_representation()(inmodulestructions), 240
sage.coding.linear_rank_metric), 124
WalshCode() (in module sage.coding.code_construcToricCode() (in module sage.coding.code_constructions), 236
tions), 235
weight_dist() (in module sage.coding.binary_code),transmit() (sage.coding.channel.Channel method), 20
260
transmit_unsafe() (sage.coding.channel.Channel
weight_distribution()(sage.coding.gomethod), 21
lay_code.GolayCode method), 157
transmit_unsafe() (sage.coding.channel.ErrorEraweight_distribution()(sage.codsureChannel method), 23
ing.grs_code.GeneralizedReedSolomonCode
transmit_unsafe() (sage.coding.channel.QarySymmethod), 189
metricChannel method), 26
weight_distribution()(sage.coding.lintransmit_unsafe() (sage.coding.channel.StaticErear_code.AbstractLinearCode method), 99
rorRateChannel method), 27
weight_enumerator() (sage.coding.linear_code.Abtree()(sage.coding.source_coding.huffman.Huffman
stractLinearCode method), 101
method), 357

T

Index

375

Coding Theory, Release 10.4

Z
zero() (sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric method), 66
zeta_function() (sage.coding.linear_code.AbstractLinearCode method), 102
zeta_polynomial()(sage.coding.linear_code.AbstractLinearCode method), 102376

Index