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

Commit 6ad583f

Browse files
author
David Lucas
committed
Fixed bug in KeyEquation decoder's decode_to_code, added sanity checks, enhanced doctests
1 parent a074cb8 commit 6ad583f

File tree

1 file changed

+49
-19
lines changed

1 file changed

+49
-19
lines changed

src/sage/coding/grs.py

+49-19
Original file line numberDiff line numberDiff line change
@@ -1718,7 +1718,7 @@ def _syndrome(self, r):
17181718

17191719
def _forney_formula(self, error_evaluator, error_locator):
17201720
r"""
1721-
Returns the error vector computed through Forney's formula.
1721+
Returns the error vector computed through Forney's formula as a list.
17221722
17231723
INPUT:
17241724
@@ -1737,7 +1737,7 @@ def _forney_formula(self, error_evaluator, error_locator):
17371737
sage: R.<x> = F[]
17381738
sage: evaluator, locator = R(10), R([10, 10])
17391739
sage: D._forney_formula(evaluator, locator)
1740-
(0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
1740+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
17411741
"""
17421742
C = self.code()
17431743
alphas = C.evaluation_points()
@@ -1754,7 +1754,7 @@ def _forney_formula(self, error_evaluator, error_locator):
17541754
else:
17551755
e.append(zero)
17561756

1757-
return vector(F, e)
1757+
return e
17581758

17591759
def decode_to_code(self, r):
17601760
r"""
@@ -1775,31 +1775,59 @@ def decode_to_code(self, r):
17751775
17761776
EXAMPLES::
17771777
1778-
sage: F = GF(11)
1779-
sage: n, k = 10, 5
1778+
sage: F = GF(59)
1779+
sage: n, k = 40, 12
17801780
sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
17811781
sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
1782-
sage: r = vector(F, (8, 2, 6, 10, 6, 10, 7, 6, 7, 2))
1783-
sage: D.decode_to_code(r)
1784-
(8, 2, 6, 10, 6, 10, 7, 6, 7, 1)
1782+
sage: c = C.random_element()
1783+
sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius())
1784+
sage: y = Chan(c)
1785+
sage: c == D.decode_to_code(y)
1786+
True
1787+
1788+
TESTS:
1789+
1790+
If one tries to decode a word with too many errors, it returns
1791+
an exception::
1792+
1793+
sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()+1)
1794+
sage: y = Chan(c)
1795+
sage: D.decode_to_message(y)
1796+
Traceback (most recent call last):
1797+
...
1798+
DecodingError: Decoding failed because the number of errors exceeded the decoding radius
1799+
1800+
If one tries to decode something which is not in the ambient space of the code,
1801+
an exception is raised::
1802+
1803+
sage: D.decode_to_code(42)
1804+
Traceback (most recent call last):
1805+
...
1806+
ValueError: The word to decode has to be in the ambient space of the code
17851807
"""
17861808
C = self.code()
1809+
if r not in C.ambient_space():
1810+
raise ValueError("The word to decode has to be in the ambient space of the code")
17871811
F = C.base_field()
17881812
PolRing = C.base_field()['x']
17891813
x = PolRing.gen()
17901814

1791-
if C.length() == C.dimension():
1792-
return r
1793-
if r in C:
1815+
if C.length() == C.dimension() or r in C:
17941816
return r
17951817

1796-
S = PolRing(self.syndrome(r))
1818+
S = PolRing(self._syndrome(r))
17971819
a = x ** (C.minimum_distance() - 1)
17981820

17991821
(EEP, ELP) = self._partial_xgcd(a, S, PolRing)
18001822

1801-
e = self.forney_formula(EEP, ELP)
1802-
return r - e
1823+
e = self._forney_formula(EEP, ELP)
1824+
dec = []
1825+
for i in range(len(r)):
1826+
dec.append(r[i] - e[i])
1827+
dec = vector(F, dec)
1828+
if not dec in C:
1829+
raise DecodingError("Decoding failed because the number of errors exceeded the decoding radius")
1830+
return dec
18031831

18041832
def decode_to_message(self, r):
18051833
r"""
@@ -1821,13 +1849,15 @@ def decode_to_message(self, r):
18211849
18221850
EXAMPLES::
18231851
1824-
sage: F = GF(11)
1825-
sage: n, k = 10, 5
1852+
sage: F = GF(59)
1853+
sage: n, k = 40, 12
18261854
sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
18271855
sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
1828-
sage: r = vector(F, (8, 2, 6, 10, 6, 10, 7, 6, 7, 2))
1829-
sage: D.decode_to_message(r)
1830-
(3, 6, 6, 3, 1)
1856+
sage: c = C.random_element()
1857+
sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius())
1858+
sage: y = Chan(c)
1859+
sage: D.connected_encoder().unencode(c) == D.decode_to_message(y)
1860+
True
18311861
"""
18321862
C = self.code()
18331863
if C.length() == C.dimension():

0 commit comments

Comments
 (0)