-
galois.BCH.decode(codeword: ArrayLike, erasures: NDArray | None =
None, output: 'message' | 'codeword' ='message', errors: False =False) FieldArray -
galois.BCH.decode(codeword: ArrayLike, erasures: NDArray | None =
None, output: 'message' | 'codeword' ='message', errors: True =True) tuple[FieldArray, int | ndarray] Decodes the codeword \(\mathbf{c}\) into the message \(\mathbf{m}\).
- Parameters:¶
- codeword: ArrayLike¶
The codeword as either a \(n\)-length vector or \((N, n)\) matrix, where \(N\) is the number of codewords.
Shortened codes
For the shortened \([n-s,\ k-s,\ d]\) code, pass \(n-s\) codeword symbols into
decode()to return the \(k-s\) message symbols.- erasures: NDArray | None =
None¶ Optionally specify the erasure locations as a boolean array with shape equal to the codeword, where
Trueindicates an erasure at that location. The default isNone, which indicates no erasures.- output: 'message' | 'codeword' =
'message'¶ Specify whether to return the error-corrected message or entire codeword. The default is
"message".- errors: False =
False¶ - errors: True =
True Optionally specify whether to return the number of corrected errors. The default is
False. If erasures are provided, the number of corrected errors does not include the number of erasures corrected, only the number of unknown symbol errors corrected.
- Returns:¶
If
output="message", the error-corrected message as either a \(k\)-length vector or \((N, k)\) matrix. Ifoutput="codeword", the error-corrected codeword as either a \(n\)-length vector or \((N, n)\) matrix.If
errors=True, returns the number of corrected symbol errors as either a scalar or \(N\)-length array. Valid number of corrections are in \([0, t]\). If a codeword has too many errors and cannot be corrected, -1 will be returned.
Notes¶
The message vector \(\mathbf{m}\) is a member of \(\mathrm{GF}(q)^k\). The corresponding message polynomial \(m(x)\) is a degree-\(k\) polynomial over \(\mathrm{GF}(q)\).
\[\mathbf{m} = [m_{k-1},\ \dots,\ m_1,\ m_0] \in \mathrm{GF}(q)^k\]\[m(x) = m_{k-1} x^{k-1} + \dots + m_1 x + m_0 \in \mathrm{GF}(q)[x]\]The codeword vector \(\mathbf{c}\) is a member of \(\mathrm{GF}(q)^n\). The corresponding codeword polynomial \(c(x)\) is a degree-\(n\) polynomial over \(\mathrm{GF}(q)\). Each codeword polynomial \(c(x)\) is divisible by the generator polynomial \(g(x)\).
\[\mathbf{c} = [c_{n-1},\ \dots,\ c_1,\ c_0] \in \mathrm{GF}(q)^n\]\[c(x) = c_{n-1} x^{n-1} + \dots + c_1 x + c_0 \in \mathrm{GF}(q)[x]\]In decoding, the syndrome vector \(\mathbf{s}\) is computed by evaluating the received codeword \(\mathbf{r}\) in the extension field \(\mathrm{GF}(q^m)\) at the roots \(\alpha^c, \dots, \alpha^{c+d-2}\) of the generator polynomial \(g(x)\). The equivalent polynomial operation computes the remainder of \(r(x)\) by \(g(x)\) in the extension field \(\mathrm{GF}(q^m)\).
\[\mathbf{s} = [r(\alpha^c),\ \dots,\ r(\alpha^{c+d-2})] \in \mathrm{GF}(q^m)^{d-1}\]\[s(x) = r(x)\ \textrm{mod}\ g(x) \in \mathrm{GF}(q^m)[x]\]A syndrome of zeros indicates the received codeword is a valid codeword and there are no errors. If the syndrome is non-zero, the decoder will find an error-locator polynomial \(\sigma(x)\) and the corresponding error locations and values.
Note
The \([n, k, d]_q\) code has \(d_{min} \ge d\) minimum distance. It can detect up to \(d_{min}-1\) errors.
Examples¶
Encode a single message using the \(\textrm{BCH}(15, 7)\) code.
In [1]: bch = galois.BCH(15, 7) In [2]: GF = bch.field In [3]: m = GF.Random(bch.k); m Out[3]: GF([0, 0, 1, 0, 1, 1, 0], order=2) In [4]: c = bch.encode(m); c Out[4]: GF([0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1], order=2)Corrupt \(t\) symbols of the codeword.
In [5]: bch.t Out[5]: 2 In [6]: c[0:bch.t] ^= 1; c Out[6]: GF([1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1], order=2)Decode the codeword and recover the message.
In [7]: d = bch.decode(c); d Out[7]: GF([0, 0, 1, 0, 1, 1, 0], order=2) In [8]: assert np.array_equal(d, m)Decode the codeword, outputting the number of corrected errors, and recover the message.
In [9]: d, e = bch.decode(c, errors=True); d, e Out[9]: (GF([0, 0, 1, 0, 1, 1, 0], order=2), 2) In [10]: assert np.array_equal(d, m)Encode a single message using the shortened \(\textrm{BCH}(12, 4)\) code.
In [11]: bch = galois.BCH(15, 7) In [12]: GF = bch.field In [13]: m = GF.Random(bch.k - 3); m Out[13]: GF([1, 1, 0, 0], order=2) In [14]: c = bch.encode(m); c Out[14]: GF([1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1], order=2)Corrupt \(t\) symbols of the codeword.
In [15]: bch.t Out[15]: 2 In [16]: c[0:bch.t] ^= 1; c Out[16]: GF([0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1], order=2)Decode the codeword and recover the message.
In [17]: d = bch.decode(c); d Out[17]: GF([1, 1, 0, 0], order=2) In [18]: assert np.array_equal(d, m)Decode the codeword, outputting the number of corrected errors, and recover the message.
In [19]: d, e = bch.decode(c, errors=True); d, e Out[19]: (GF([1, 1, 0, 0], order=2), 2) In [20]: assert np.array_equal(d, m)Encode a matrix of three messages using the \(\textrm{BCH}(15, 7)\) code.
In [21]: bch = galois.BCH(15, 7) In [22]: GF = bch.field In [23]: m = GF.Random((3, bch.k)); m Out[23]: GF([[1, 0, 0, 1, 1, 0, 1], [0, 0, 1, 0, 0, 1, 1], [0, 1, 1, 0, 1, 1, 1]], order=2) In [24]: c = bch.encode(m); c Out[24]: GF([[1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0], [0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0], [0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0]], order=2)Corrupt the codeword. Add zero errors to the first codeword, one to the second, and two to the third.
In [25]: c[1,0:1] ^= 1 In [26]: c[2,0:2] ^= 1 In [27]: c Out[27]: GF([[1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0], [1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0], [1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0]], order=2)Decode the codeword and recover the message.
In [28]: d = bch.decode(c); d Out[28]: GF([[1, 0, 0, 1, 1, 0, 1], [0, 0, 1, 0, 0, 1, 1], [0, 1, 1, 0, 1, 1, 1]], order=2) In [29]: assert np.array_equal(d, m)Decode the codeword, outputting the number of corrected errors, and recover the message.
In [30]: d, e = bch.decode(c, errors=True); d, e Out[30]: (GF([[1, 0, 0, 1, 1, 0, 1], [0, 0, 1, 0, 0, 1, 1], [0, 1, 1, 0, 1, 1, 1]], order=2), array([0, 1, 2])) In [31]: assert np.array_equal(d, m)Encode a matrix of three messages using the shortened \(\textrm{BCH}(12, 4)\) code.
In [32]: bch = galois.BCH(15, 7) In [33]: GF = bch.field In [34]: m = GF.Random((3, bch.k - 3)); m Out[34]: GF([[1, 1, 0, 1], [0, 0, 0, 1], [0, 1, 1, 0]], order=2) In [35]: c = bch.encode(m); c Out[35]: GF([[1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0], [0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1], [0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1]], order=2)Corrupt the codeword. Add zero errors to the first codeword, one to the second, and two to the third.
In [36]: c[1,0:1] ^= 1 In [37]: c[2,0:2] ^= 1 In [38]: c Out[38]: GF([[1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0], [1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1], [1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1]], order=2)Decode the codeword and recover the message.
In [39]: d = bch.decode(c); d Out[39]: GF([[1, 1, 0, 1], [0, 0, 0, 1], [0, 1, 1, 0]], order=2) In [40]: assert np.array_equal(d, m)Decode the codeword, outputting the number of corrected errors, and recover the message.
In [41]: d, e = bch.decode(c, errors=True); d, e Out[41]: (GF([[1, 1, 0, 1], [0, 0, 0, 1], [0, 1, 1, 0]], order=2), array([0, 1, 2])) In [42]: assert np.array_equal(d, m)Encode a matrix of three messages using the \(\textrm{BCH}(15, 7)\) code.
In [43]: bch = galois.BCH(15, 7) In [44]: GF = bch.field In [45]: m = GF.Random((3, bch.k)); m Out[45]: GF([[0, 0, 1, 0, 0, 1, 1], [0, 0, 1, 0, 0, 0, 1], [0, 1, 1, 0, 0, 1, 1]], order=2) In [46]: c = bch.encode(m); c Out[46]: GF([[0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1], [0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0]], order=2)Corrupt the codeword. Add one error to the first codeword, two to the second, and \(d - 1\) to the third.
In [47]: erasures = np.zeros(c.shape, dtype=bool) In [48]: erasures[0,0:1] = True In [49]: erasures[1,0:2] = True In [50]: erasures[2,0:bch.d - 1] = True In [51]: c[erasures] += GF.Random(np.sum(erasures), low=1) In [52]: c Out[52]: GF([[1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0], [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1], [1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0]], order=2)Decode the codeword using known error locations (erasures) and recover the message.
In [53]: d = bch.decode(c, erasures=erasures); d Out[53]: GF([[0, 0, 1, 0, 0, 1, 1], [0, 0, 1, 0, 0, 0, 1], [0, 1, 1, 0, 0, 1, 1]], order=2) In [54]: assert np.array_equal(d, m)Decode the codeword, outputting the number of corrected errors, and recover the message. Notice that zero unknown errors were corrected, since all errors were provided as erasures.
In [55]: d, e = bch.decode(c, erasures=erasures, errors=True); d, e Out[55]: (GF([[0, 0, 1, 0, 0, 1, 1], [0, 0, 1, 0, 0, 0, 1], [0, 1, 1, 0, 0, 1, 1]], order=2), array([0, 0, 0])) In [56]: assert np.array_equal(d, m)