@@ -807,6 +807,7 @@ def __init__(self, base_field, length, default_encoder_name, default_decoder_nam
807
807
### Add here any generic encoder/decoder ###
808
808
#This allows any class which inherits from AbstractLinearCode
809
809
#to use generic decoders/encoders
810
+ self ._registered_encoders ["Systematic" ] = LinearCodeSystematicEncoder
810
811
self ._registered_decoders ["Syndrome" ] = LinearCodeSyndromeDecoder
811
812
self ._registered_decoders ["NearestNeighbor" ] = LinearCodeNearestNeighborDecoder
812
813
@@ -954,13 +955,13 @@ def add_encoder(self, name, encoder):
954
955
955
956
sage: C.add_encoder("MyEncoder", MyEncoder)
956
957
sage: C.encoders_available()
957
- ['MyEncoder', 'ParityCheck']
958
+ ['MyEncoder', 'ParityCheck', 'Systematic' ]
958
959
959
960
We can verify that any new code will not know MyEncoder::
960
961
961
962
sage: C2 = codes.HammingCode(GF(2), 3)
962
963
sage: C2.encoders_available()
963
- ['ParityCheck']
964
+ ['Systematic', ' ParityCheck']
964
965
965
966
TESTS:
966
967
@@ -1911,7 +1912,7 @@ def encode(self, word, encoder_name=None, **kwargs):
1911
1912
It is possible to manually choose the encoder amongst the list of the available ones::
1912
1913
1913
1914
sage: C.encoders_available()
1914
- ['GeneratorMatrix']
1915
+ ['GeneratorMatrix', 'Systematic' ]
1915
1916
sage: word = vector((0, 1, 1, 0))
1916
1917
sage: C.encode(word, 'GeneratorMatrix')
1917
1918
(1, 1, 0, 0, 1, 1, 0)
@@ -1964,7 +1965,7 @@ def encoder(self, encoder_name=None, **kwargs):
1964
1965
an exception will be raised::
1965
1966
1966
1967
sage: C.encoders_available()
1967
- ['GeneratorMatrix']
1968
+ ['GeneratorMatrix', 'Systematic' ]
1968
1969
sage: C.encoder('NonExistingEncoder')
1969
1970
Traceback (most recent call last):
1970
1971
...
@@ -1993,10 +1994,10 @@ def encoders_available(self, classes=False):
1993
1994
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]])
1994
1995
sage: C = LinearCode(G)
1995
1996
sage: C.encoders_available()
1996
- ['GeneratorMatrix']
1997
-
1997
+ ['GeneratorMatrix', 'Systematic']
1998
1998
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'>}
2000
2001
"""
2001
2002
if classes == True :
2002
2003
return copy (self ._registered_encoders )
@@ -2209,7 +2210,7 @@ def generator_matrix_systematic(self):
2209
2210
[1 2 0]
2210
2211
[0 0 1]
2211
2212
"""
2212
- return self . generator_matrix (). echelon_form ()
2213
+ return LinearCodeSystematicEncoder ( self ). generator_matrix ()
2213
2214
2214
2215
@cached_method
2215
2216
def gens (self ):
@@ -4004,9 +4005,13 @@ def __init__(self, code):
4004
4005
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]])
4005
4006
sage: C = LinearCode(G)
4006
4007
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.
4007
4010
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
4009
4012
"""
4013
+ from sage .misc .superseded import deprecation
4014
+ deprecation (20835 , "LinearCodeParityCheckEncoder is now deprecated. Please use LinearCodeSystematicEncoder instead." )
4010
4015
super (LinearCodeParityCheckEncoder , self ).__init__ (code )
4011
4016
4012
4017
def _repr_ (self ):
@@ -4018,10 +4023,12 @@ def _repr_(self):
4018
4023
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]])
4019
4024
sage: C = LinearCode(G)
4020
4025
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.
4021
4028
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
4023
4030
"""
4024
- return "Parity check matrix-based encoder for the %s" % self .code ()
4031
+ return "Parity check matrix-based encoder for %s" % self .code ()
4025
4032
4026
4033
def _latex_ (self ):
4027
4034
r"""
@@ -4032,10 +4039,12 @@ def _latex_(self):
4032
4039
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]])
4033
4040
sage: C = LinearCode(G)
4034
4041
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.
4035
4044
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}
4037
4046
"""
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_ ()
4039
4048
4040
4049
@cached_method
4041
4050
def generator_matrix (self ):
@@ -4047,6 +4056,8 @@ def generator_matrix(self):
4047
4056
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]])
4048
4057
sage: C = LinearCode(G)
4049
4058
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.
4050
4061
sage: E.generator_matrix()
4051
4062
[1 0 0 0 0 1 1]
4052
4063
[0 1 0 0 1 0 1]
@@ -4055,6 +4066,160 @@ def generator_matrix(self):
4055
4066
"""
4056
4067
return self .code ().parity_check_matrix ().right_kernel_matrix ()
4057
4068
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
+
4058
4223
####################### decoders ###############################
4059
4224
class LinearCodeSyndromeDecoder (Decoder ):
4060
4225
r"""
0 commit comments