Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 170e79c

Browse files
author
David Lucas
committedAug 3, 2016
Merge branch 'u/dlucas/systematic_encoder' of git://trac.sagemath.org/sage into systematic_encoder
2 parents c4f3c93 + bb41e21 commit 170e79c

File tree

4 files changed

+183
-16
lines changed

4 files changed

+183
-16
lines changed
 

‎src/doc/en/thematic_tutorials/coding_theory.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ Let us see how one can explore this::
297297

298298
sage: C = codes.GeneralizedReedSolomonCode(GF(59).list()[:40], 12, GF(59).list()[1:41])
299299
sage: C.encoders_available()
300-
['EvaluationPolynomial', 'EvaluationVector']
300+
['EvaluationPolynomial', 'EvaluationVector', 'Systematic']
301301
sage: C.decoders_available()
302302
['Syndrome',
303303
'NearestNeighbor',

‎src/sage/coding/encoders_catalog.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
88
:class:`linear_code.LinearCodeGeneratorMatrixEncoder <sage.coding.linear_code.LinearCodeGeneratorMatrixEncoder>`
99
:class:`linear_code.LinearCodeParityCheckEncoder <sage.coding.linear_code.LinearCodeParityCheckEncoder>`
10+
:class:`linear_code.LinearCodeSystematicEncoder <sage.coding.linear_code.LinearCodeSystematicEncoder>`
1011
1112
**Generalized Reed-Solomon code encoders**
1213
@@ -35,7 +36,8 @@
3536

3637
from sage.misc.lazy_import import lazy_import as _lazy_import
3738
_lazy_import('sage.coding.linear_code', ['LinearCodeGeneratorMatrixEncoder',
38-
'LinearCodeParityCheckEncoder'])
39+
'LinearCodeParityCheckEncoder',
40+
'LinearCodeSystematicEncoder'])
3941
_lazy_import('sage.coding.grs', ['GRSEvaluationVectorEncoder', 'GRSEvaluationPolynomialEncoder'])
4042
_lazy_import('sage.coding.reed_muller_code', ['ReedMullerVectorEncoder', 'ReedMullerPolynomialEncoder'])
4143
_lazy_import('sage.coding.extended_code', 'ExtendedCodeExtendedMatrixEncoder')

‎src/sage/coding/hamming_code.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def __init__(self, base_field, order):
8080

8181
q = base_field.order()
8282
length = Integer((q ** order - 1) / (q - 1))
83-
super(HammingCode, self).__init__(base_field, length, "ParityCheck", "Syndrome")
83+
super(HammingCode, self).__init__(base_field, length, "Systematic", "Syndrome")
8484
self._dimension = length - order
8585

8686
def __eq__(self, other):

‎src/sage/coding/linear_code.py

+178-13
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,7 @@ def __init__(self, base_field, length, default_encoder_name, default_decoder_nam
807807
### Add here any generic encoder/decoder ###
808808
#This allows any class which inherits from AbstractLinearCode
809809
#to use generic decoders/encoders
810+
self._registered_encoders["Systematic"] = LinearCodeSystematicEncoder
810811
self._registered_decoders["Syndrome"] = LinearCodeSyndromeDecoder
811812
self._registered_decoders["NearestNeighbor"] = LinearCodeNearestNeighborDecoder
812813

@@ -954,13 +955,13 @@ def add_encoder(self, name, encoder):
954955
955956
sage: C.add_encoder("MyEncoder", MyEncoder)
956957
sage: C.encoders_available()
957-
['MyEncoder', 'ParityCheck']
958+
['MyEncoder', 'ParityCheck', 'Systematic']
958959
959960
We can verify that any new code will not know MyEncoder::
960961
961962
sage: C2 = codes.HammingCode(GF(2), 3)
962963
sage: C2.encoders_available()
963-
['ParityCheck']
964+
['Systematic', 'ParityCheck']
964965
965966
TESTS:
966967
@@ -1911,7 +1912,7 @@ def encode(self, word, encoder_name=None, **kwargs):
19111912
It is possible to manually choose the encoder amongst the list of the available ones::
19121913
19131914
sage: C.encoders_available()
1914-
['GeneratorMatrix']
1915+
['GeneratorMatrix', 'Systematic']
19151916
sage: word = vector((0, 1, 1, 0))
19161917
sage: C.encode(word, 'GeneratorMatrix')
19171918
(1, 1, 0, 0, 1, 1, 0)
@@ -1964,7 +1965,7 @@ def encoder(self, encoder_name=None, **kwargs):
19641965
an exception will be raised::
19651966
19661967
sage: C.encoders_available()
1967-
['GeneratorMatrix']
1968+
['GeneratorMatrix', 'Systematic']
19681969
sage: C.encoder('NonExistingEncoder')
19691970
Traceback (most recent call last):
19701971
...
@@ -1993,10 +1994,10 @@ def encoders_available(self, classes=False):
19931994
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]])
19941995
sage: C = LinearCode(G)
19951996
sage: C.encoders_available()
1996-
['GeneratorMatrix']
1997-
1997+
['GeneratorMatrix', 'Systematic']
19981998
sage: C.encoders_available(True)
1999-
{'GeneratorMatrix': <class 'sage.coding.linear_code.LinearCodeGeneratorMatrixEncoder'>}
1999+
{'GeneratorMatrix': <class 'sage.coding.linear_code.LinearCodeGeneratorMatrixEncoder'>,
2000+
'Systematic': <class 'sage.coding.linear_code.LinearCodeSystematicEncoder'>}
20002001
"""
20012002
if classes == True:
20022003
return copy(self._registered_encoders)
@@ -2209,7 +2210,7 @@ def generator_matrix_systematic(self):
22092210
[1 2 0]
22102211
[0 0 1]
22112212
"""
2212-
return self.generator_matrix().echelon_form()
2213+
return LinearCodeSystematicEncoder(self).generator_matrix()
22132214

22142215
@cached_method
22152216
def gens(self):
@@ -4004,9 +4005,13 @@ def __init__(self, code):
40044005
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]])
40054006
sage: C = LinearCode(G)
40064007
sage: E = codes.encoders.LinearCodeParityCheckEncoder(C)
4008+
doctest:...: DeprecationWarning: LinearCodeParityCheckEncoder is now deprecated. Please use LinearCodeSystematicEncoder instead.
4009+
See http://trac.sagemath.org/20835 for details.
40074010
sage: E
4008-
Parity check matrix-based encoder for the Linear code of length 7, dimension 4 over Finite Field of size 2
4011+
Parity check matrix-based encoder for Linear code of length 7, dimension 4 over Finite Field of size 2
40094012
"""
4013+
from sage.misc.superseded import deprecation
4014+
deprecation(20835, "LinearCodeParityCheckEncoder is now deprecated. Please use LinearCodeSystematicEncoder instead.")
40104015
super(LinearCodeParityCheckEncoder, self).__init__(code)
40114016

40124017
def _repr_(self):
@@ -4018,10 +4023,12 @@ def _repr_(self):
40184023
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]])
40194024
sage: C = LinearCode(G)
40204025
sage: E = codes.encoders.LinearCodeParityCheckEncoder(C)
4026+
doctest:...: DeprecationWarning: LinearCodeParityCheckEncoder is now deprecated. Please use LinearCodeSystematicEncoder instead.
4027+
See http://trac.sagemath.org/20835 for details.
40214028
sage: E
4022-
Parity check matrix-based encoder for the Linear code of length 7, dimension 4 over Finite Field of size 2
4029+
Parity check matrix-based encoder for Linear code of length 7, dimension 4 over Finite Field of size 2
40234030
"""
4024-
return "Parity check matrix-based encoder for the %s" % self.code()
4031+
return "Parity check matrix-based encoder for %s" % self.code()
40254032

40264033
def _latex_(self):
40274034
r"""
@@ -4032,10 +4039,12 @@ def _latex_(self):
40324039
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]])
40334040
sage: C = LinearCode(G)
40344041
sage: E = codes.encoders.LinearCodeParityCheckEncoder(C)
4042+
doctest:...: DeprecationWarning: LinearCodeParityCheckEncoder is now deprecated. Please use LinearCodeSystematicEncoder instead.
4043+
See http://trac.sagemath.org/20835 for details.
40354044
sage: latex(E)
4036-
\textnormal{Parity check matrix-based encoder for the }[7, 4]\textnormal{ Linear code over }\Bold{F}_{2}
4045+
\textnormal{Parity check matrix-based encoder for }[7, 4]\textnormal{ Linear code over }\Bold{F}_{2}
40374046
"""
4038-
return "\\textnormal{Parity check matrix-based encoder for the }%s" % self.code()._latex_()
4047+
return "\\textnormal{Parity check matrix-based encoder for }%s" % self.code()._latex_()
40394048

40404049
@cached_method
40414050
def generator_matrix(self):
@@ -4047,6 +4056,8 @@ def generator_matrix(self):
40474056
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]])
40484057
sage: C = LinearCode(G)
40494058
sage: E = codes.encoders.LinearCodeParityCheckEncoder(C)
4059+
doctest:...: DeprecationWarning: LinearCodeParityCheckEncoder is now deprecated. Please use LinearCodeSystematicEncoder instead.
4060+
See http://trac.sagemath.org/20835 for details.
40504061
sage: E.generator_matrix()
40514062
[1 0 0 0 0 1 1]
40524063
[0 1 0 0 1 0 1]
@@ -4055,6 +4066,160 @@ def generator_matrix(self):
40554066
"""
40564067
return self.code().parity_check_matrix().right_kernel_matrix()
40574068

4069+
4070+
4071+
4072+
4073+
4074+
4075+
4076+
4077+
4078+
class LinearCodeSystematicEncoder(Encoder):
4079+
r"""
4080+
Encoder based on a generator matrix in systematic form for Linear codes.
4081+
4082+
To encode an element of its message space, this encoder first builds a
4083+
generator matrix in systematic form. What is called systematic form here
4084+
is the row echelon form of a matrix, which is not necessarily
4085+
`[I \vert H]`, where `I` is the identity block and `H` the parity block.
4086+
One can refer to :meth:`LinearCodeSystematicEncoder.generator_matrix`
4087+
for a concrete example.
4088+
Once such a matrix has been computed, it is used to encode any message
4089+
into a codeword.
4090+
4091+
INPUT:
4092+
4093+
- ``code`` -- The associated code of this encoder.
4094+
"""
4095+
4096+
def __init__(self, code):
4097+
r"""
4098+
EXAMPLES::
4099+
4100+
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]])
4101+
sage: C = LinearCode(G)
4102+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
4103+
sage: E
4104+
Systematic encoder for Linear code of length 7, dimension 4 over Finite Field of size 2
4105+
"""
4106+
super(LinearCodeSystematicEncoder, self).__init__(code)
4107+
4108+
def _repr_(self):
4109+
r"""
4110+
Return a string representation of ``self``.
4111+
4112+
EXAMPLES::
4113+
4114+
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]])
4115+
sage: C = LinearCode(G)
4116+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
4117+
sage: E
4118+
Systematic encoder for Linear code of length 7, dimension 4 over Finite Field of size 2
4119+
"""
4120+
return "Systematic encoder for %s" % self.code()
4121+
4122+
def _latex_(self):
4123+
r"""
4124+
Return a latex representation of ``self``.
4125+
4126+
EXAMPLES::
4127+
4128+
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]])
4129+
sage: C = LinearCode(G)
4130+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
4131+
sage: latex(E)
4132+
\textnormal{Systematic encoder for }[7, 4]\textnormal{ Linear code over }\Bold{F}_{2}
4133+
"""
4134+
return "\\textnormal{Systematic encoder for }%s" % self.code()._latex_()
4135+
4136+
@cached_method
4137+
def generator_matrix(self):
4138+
r"""
4139+
Returns a generator matrix of the associated code of ``self``.
4140+
4141+
This generator matrix will be in systematic form.
4142+
4143+
.. NOTE::
4144+
4145+
The matrix returned by this method will not necessarily be `[I \vert H]`, where `I`
4146+
is the identity block and `H` the parity block. If one wants to know which columns
4147+
create the identity block, one should use :meth:`systematic_positions`
4148+
4149+
EXAMPLES::
4150+
4151+
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]])
4152+
sage: C = LinearCode(G)
4153+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
4154+
sage: E.generator_matrix()
4155+
[1 0 0 0 0 1 1]
4156+
[0 1 0 0 1 0 1]
4157+
[0 0 1 0 1 1 0]
4158+
[0 0 0 1 1 1 1]
4159+
4160+
Another one, with a matrix which won't be `[I \vert H]`::
4161+
4162+
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]])
4163+
sage: C = LinearCode(G)
4164+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
4165+
sage: E.generator_matrix()
4166+
[1 1 0 0 0 1 0]
4167+
[0 0 1 0 0 1 0]
4168+
[0 0 0 0 1 1 0]
4169+
[0 0 0 0 0 0 1]
4170+
4171+
"""
4172+
C = self.code()
4173+
if hasattr(self, "_use_pc_matrix"):
4174+
return C.parity_check_matrix().right_kernel_matrix()
4175+
else:
4176+
self._use_pc_matrix = True
4177+
M = C.generator_matrix()
4178+
return M.echelon_form()
4179+
4180+
def systematic_positions(self):
4181+
r"""
4182+
Returns a tuple containing the indices of the columns which form an
4183+
identity matrix when the generator matrix is in systematic form.
4184+
4185+
EXAMPLES::
4186+
4187+
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]])
4188+
sage: C = LinearCode(G)
4189+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
4190+
sage: E.systematic_positions()
4191+
(0, 1, 2, 3)
4192+
4193+
We take another matrix with a less nice shape::
4194+
4195+
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]])
4196+
sage: C = LinearCode(G)
4197+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
4198+
sage: E.systematic_positions()
4199+
(0, 2, 4, 6)
4200+
4201+
These positions correspond to the positions which carry information in a codeword::
4202+
4203+
sage: MS = E.message_space()
4204+
sage: m = MS.random_element()
4205+
sage: c = m * E.generator_matrix()
4206+
sage: pos = E.systematic_positions()
4207+
sage: info = MS([c[i] for i in pos])
4208+
sage: m == info
4209+
True
4210+
"""
4211+
return self.generator_matrix().pivots()
4212+
4213+
4214+
4215+
4216+
4217+
4218+
4219+
4220+
4221+
4222+
40584223
####################### decoders ###############################
40594224
class LinearCodeSyndromeDecoder(Decoder):
40604225
r"""

0 commit comments

Comments
 (0)
This repository has been archived.