galois.BCH¶
-
class galois.BCH(n, k, primitive_poly=
None
, primitive_element=None
, systematic=True
)¶ A primitive, narrow-sense binary
code.A
code is a linear block code with codeword size , message size , minimum distance , and symbols taken from an alphabet of size .To create the shortened
code, construct the full-sized code and then pass bits intoencode()
and bits intodecode()
. Shortened codes are only applicable for systematic codes.Examples
Construct the BCH code.
In [1]: galois.bch_valid_codes(15) Out[1]: [(15, 11, 1), (15, 7, 2), (15, 5, 3), (15, 1, 7)] In [2]: bch = galois.BCH(15, 7); bch Out[2]: <BCH Code: [15, 7, 5] over GF(2)>
Encode a message.
In [3]: m = galois.GF2.Random(bch.k); m Out[3]: GF([0, 0, 1, 0, 1, 0, 0], order=2) In [4]: c = bch.encode(m); c Out[4]: GF([0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0], order=2)
Corrupt the codeword and decode the message.
# Corrupt the first bit in the codeword In [5]: c[0] ^= 1 In [6]: dec_m = bch.decode(c); dec_m Out[6]: GF([0, 0, 1, 0, 1, 0, 0], order=2) In [7]: np.array_equal(dec_m, m) Out[7]: True
# Instruct the decoder to return the number of corrected bit errors In [8]: dec_m, N = bch.decode(c, errors=True); dec_m, N Out[8]: (GF([0, 0, 1, 0, 1, 0, 0], order=2), 1) In [9]: np.array_equal(dec_m, m) Out[9]: True
Constructors
__init__
(n, k[, primitive_poly, ...])Constructs a primitive, narrow-sense binary
code.Special Methods
__repr__
()Return repr(self).
__str__
()Return str(self).
Methods
decode
()Decodes the BCH codeword
into the message .detect
(codeword)Detects if errors are present in the BCH codeword
.encode
(message[, parity_only])Encodes the message
into the BCH codeword .Attributes
The generator matrix
with shape .The parity-check matrix
with shape .The design distance
of the code.The Galois field array class for the
field that defines the BCH code.The generator polynomial
whose roots areroots
.Indicates if the BCH code is narrow sense, meaning the roots of the generator polynomial are consecutive powers of
starting at 1, i.e. .Indicates if the BCH code is primitive, meaning
.The message size
of the codeThe codeword size
of the codeThe
roots of the generator polynomial.Indicates if the code is configured to return codewords in systematic form.
The error-correcting capability of the code.
-
__init__(n, k, primitive_poly=
None
, primitive_element=None
, systematic=True
)¶ Constructs a primitive, narrow-sense binary
code.- Parameters¶
- n : int¶
The codeword size
, must be .- k : int¶
The message size
.- primitive_poly : Optional[Poly]¶
Optionally specify the primitive polynomial that defines the extension field
. The default isNone
which uses Matlab’s default, seegalois.matlab_primitive_poly()
. Matlab tends to use the lexicographically-minimal primitive polynomial as a default instead of the Conway polynomial.- primitive_element : Optional[Union[int, Poly]]¶
Optionally specify the primitive element
whose powers are roots of the generator polynomial . The default isNone
which uses the lexicographically-minimal primitive element in , seegalois.primitive_element()
.- systematic : bool¶
Optionally specify if the encoding should be systematic, meaning the codeword is the message with parity appended. The default is
True
.
- __repr__()¶
Return repr(self).
- __str__()¶
Return str(self).
-
decode(codeword, errors=
False
)¶ Decodes the BCH codeword
into the message .- Parameters¶
- codeword : numpy.ndarray, galois.GF2¶
The codeword as either a
-length vector or matrix, where is the number of codewords. For systematic codes, codeword lengths less than may be provided for shortened codewords.- errors : bool, optional¶
Optionally specify whether to return the nubmer of corrected errors.
- Returns¶
numpy.ndarray, galois.GF2 – The decoded message as either a
-length vector or matrix.numpy.integer, numpy.ndarray – Optional return argument of the number of corrected bit errors as either a scalar or
-length vector. Valid number of corrections are in . If a codeword has too many errors and cannot be corrected, -1 will be returned.
Notes
The codeword vector
is defined as , which corresponds to the codeword polynomial . The message vector is defined as , which corresponds to the message polynomial .In decoding, the syndrome vector
is computed by , where is the parity-check matrix. The equivalent polynomial operation is . 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 and the corresponding error locations and values.For the shortened
code (only applicable for systematic codes), pass bits intodecode()
to return the -bit message.Examples
Encode a single message using the
code.In [1]: bch = galois.BCH(15, 7) In [2]: GF = galois.GF(2) In [3]: m = GF.Random(bch.k); m Out[3]: GF([1, 1, 1, 1, 0, 1, 0], order=2) In [4]: c = bch.encode(m); c Out[4]: GF([1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0], order=2)
Corrupt
bits of the codeword.In [5]: bch.t Out[5]: 2 In [6]: c[0:bch.t] ^= 1; c Out[6]: GF([0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0], order=2)
Decode the codeword and recover the message.
In [7]: d = bch.decode(c); d Out[7]: GF([1, 1, 1, 1, 0, 1, 0], order=2) In [8]: np.array_equal(d, m) Out[8]: True
Decode the codeword, specifying the number of corrected errors, and recover the message.
In [9]: d, e = bch.decode(c, errors=True); d, e Out[9]: (GF([1, 1, 1, 1, 0, 1, 0], order=2), 2) In [10]: np.array_equal(d, m) Out[10]: True
Encode a single message using the shortened
code.In [11]: bch = galois.BCH(15, 7) In [12]: GF = galois.GF(2) In [13]: m = GF.Random(bch.k - 3); m Out[13]: GF([1, 1, 1, 0], order=2) In [14]: c = bch.encode(m); c Out[14]: GF([1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0], order=2)
Corrupt
bits of the codeword.In [15]: bch.t Out[15]: 2 In [16]: c[0:bch.t] ^= 1; c Out[16]: GF([0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0], order=2)
Decode the codeword and recover the message.
In [17]: d = bch.decode(c); d Out[17]: GF([1, 1, 1, 0], order=2) In [18]: np.array_equal(d, m) Out[18]: True
Decode the codeword, specifying 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, 1, 0], order=2), 2) In [20]: np.array_equal(d, m) Out[20]: True
Encode a matrix of three messages using the
code.In [21]: bch = galois.BCH(15, 7) In [22]: GF = galois.GF(2) In [23]: m = GF.Random((3, bch.k)); m Out[23]: GF([[1, 1, 1, 0, 0, 1, 1], [1, 0, 0, 1, 1, 1, 0], [0, 0, 0, 1, 0, 0, 1]], order=2) In [24]: c = bch.encode(m); c Out[24]: GF([[1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 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, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0]], order=2)
Decode the codeword and recover the message.
In [28]: d = bch.decode(c); d Out[28]: GF([[1, 1, 1, 0, 0, 1, 1], [1, 0, 0, 1, 1, 1, 0], [0, 0, 0, 1, 0, 0, 1]], order=2) In [29]: np.array_equal(d, m) Out[29]: True
Decode the codeword, specifying the number of corrected errors, and recover the message.
In [30]: d, e = bch.decode(c, errors=True); d, e Out[30]: (GF([[1, 1, 1, 0, 0, 1, 1], [1, 0, 0, 1, 1, 1, 0], [0, 0, 0, 1, 0, 0, 1]], order=2), array([0, 1, 2])) In [31]: np.array_equal(d, m) Out[31]: True
Encode a matrix of three messages using the shortened
code.In [32]: bch = galois.BCH(15, 7) In [33]: GF = galois.GF(2) In [34]: m = GF.Random((3, bch.k - 3)); m Out[34]: GF([[0, 0, 0, 0], [1, 0, 0, 1], [0, 0, 1, 1]], order=2) In [35]: c = bch.encode(m); c Out[35]: GF([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 1, 0, 0, 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 [36]: c[1,0:1] ^= 1 In [37]: c[2,0:2] ^= 1 In [38]: c Out[38]: GF([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0], [1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0]], order=2)
Decode the codeword and recover the message.
In [39]: d = bch.decode(c); d Out[39]: GF([[0, 0, 0, 0], [1, 0, 0, 1], [0, 0, 1, 1]], order=2) In [40]: np.array_equal(d, m) Out[40]: True
Decode the codeword, specifying the number of corrected errors, and recover the message.
In [41]: d, e = bch.decode(c, errors=True); d, e Out[41]: (GF([[0, 0, 0, 0], [1, 0, 0, 1], [0, 0, 1, 1]], order=2), array([0, 1, 2])) In [42]: np.array_equal(d, m) Out[42]: True
- detect(codeword)¶
Detects if errors are present in the BCH codeword
.The
BCH code has minimum distance. It can detect up to errors.- Parameters¶
- Returns¶
A boolean scalar or array indicating if errors were detected in the corresponding codeword
True
or notFalse
.- Return type¶
Examples
Encode a single message using the
code.In [1]: bch = galois.BCH(15, 7) In [2]: GF = galois.GF(2) In [3]: m = GF.Random(bch.k); m Out[3]: GF([0, 0, 1, 1, 1, 1, 1], order=2) In [4]: c = bch.encode(m); c Out[4]: GF([0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1], order=2)
Detect no errors in the valid codeword.
In [5]: bch.detect(c) Out[5]: False
Detect
errors in the codeword.In [6]: bch.d Out[6]: 5 In [7]: c[0:bch.d - 1] ^= 1; c Out[7]: GF([1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1], order=2) In [8]: bch.detect(c) Out[8]: True
Encode a single message using the shortened
code.In [9]: bch = galois.BCH(15, 7) In [10]: GF = galois.GF(2) In [11]: m = GF.Random(bch.k - 3); m Out[11]: GF([0, 0, 0, 0], order=2) In [12]: c = bch.encode(m); c Out[12]: GF([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], order=2)
Detect no errors in the valid codeword.
In [13]: bch.detect(c) Out[13]: False
Detect
errors in the codeword.In [14]: bch.d Out[14]: 5 In [15]: c[0:bch.d - 1] ^= 1; c Out[15]: GF([1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], order=2) In [16]: bch.detect(c) Out[16]: True
Encode a matrix of three messages using the
code.In [17]: bch = galois.BCH(15, 7) In [18]: GF = galois.GF(2) In [19]: m = GF.Random((3, bch.k)); m Out[19]: GF([[1, 1, 1, 1, 1, 0, 0], [1, 0, 1, 0, 1, 0, 0], [1, 0, 0, 1, 0, 1, 0]], order=2) In [20]: c = bch.encode(m); c Out[20]: GF([[1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1], [1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0], [1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0]], order=2)
Detect no errors in the valid codewords.
In [21]: bch.detect(c) Out[21]: array([False, False, False])
Detect one, two, and
errors in the codewords.In [22]: bch.d Out[22]: 5 In [23]: c[0,0:1] ^= 1 In [24]: c[1,0:2] ^= 1 In [25]: c[2, 0:bch.d - 1] ^= 1 In [26]: c Out[26]: GF([[0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1], [0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0], [0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0]], order=2) In [27]: bch.detect(c) Out[27]: array([ True, True, True])
Encode a matrix of three messages using the shortened
code.In [28]: bch = galois.BCH(15, 7) In [29]: GF = galois.GF(2) In [30]: m = GF.Random((3, bch.k - 3)); m Out[30]: GF([[1, 0, 1, 0], [0, 1, 0, 0], [0, 1, 0, 1]], order=2) In [31]: c = bch.encode(m); c Out[31]: GF([[1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0], [0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0], [0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1]], order=2)
Detect no errors in the valid codewords.
In [32]: bch.detect(c) Out[32]: array([False, False, False])
Detect one, two, and
errors in the codewords.In [33]: bch.d Out[33]: 5 In [34]: c[0,0:1] ^= 1 In [35]: c[1,0:2] ^= 1 In [36]: c[2, 0:bch.d - 1] ^= 1 In [37]: c Out[37]: GF([[0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0], [1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0], [1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1]], order=2) In [38]: bch.detect(c) Out[38]: array([ True, True, True])
-
encode(message, parity_only=
False
)¶ Encodes the message
into the BCH codeword .- Parameters¶
- message : Union[ndarray, GF2]¶
The message as either a
-length vector or matrix, where is the number of messages. For systematic codes, message lengths less than may be provided to produce shortened codewords.- parity_only : bool¶
Optionally specify whether to return only the parity bits. This only applies to systematic codes. The default is
False
.
- Returns¶
The codeword as either a
-length vector or matrix. The return type matches the message type. Ifparity_only=True
, the parity bits are returned as either a -length vector or matrix.- Return type¶
Notes
The message vector
is defined as , which corresponds to the message polynomial . The codeword vector is defined as , which corresponds to the codeword polynomial .The codeword vector is computed from the message vector by
, where is the generator matrix. The equivalent polynomial operation is . For systematic codes, such that . And in polynomial form, with . For systematic and non-systematic codes, each codeword is a multiple of the generator polynomial, i.e. .For the shortened
code (only applicable for systematic codes), pass bits intoencode()
to return the -bit codeword.Examples
Encode a single message using the
code.In [1]: bch = galois.BCH(15, 7) In [2]: GF = galois.GF(2) In [3]: m = GF.Random(bch.k); m Out[3]: GF([0, 0, 0, 1, 0, 1, 0], order=2) In [4]: c = bch.encode(m); c Out[4]: GF([0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0], order=2)
Compute the parity bits only.
In [5]: p = bch.encode(m, parity_only=True); p Out[5]: GF([0, 1, 1, 0, 1, 1, 1, 0], order=2)
Encode a single message using the shortened
code.In [6]: bch = galois.BCH(15, 7) In [7]: GF = galois.GF(2) In [8]: m = GF.Random(bch.k - 3); m Out[8]: GF([1, 0, 0, 0], order=2) In [9]: c = bch.encode(m); c Out[9]: GF([1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1], order=2)
Compute the parity bits only.
In [10]: p = bch.encode(m, parity_only=True); p Out[10]: GF([0, 0, 0, 1, 1, 1, 0, 1], order=2)
Encode a matrix of three messages using the
code.In [11]: bch = galois.BCH(15, 7) In [12]: GF = galois.GF(2) In [13]: m = GF.Random((3, bch.k)); m Out[13]: GF([[0, 1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1], [1, 1, 1, 0, 1, 1, 0]], order=2) In [14]: c = bch.encode(m); c Out[14]: GF([[0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1], [0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1], [1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1]], order=2)
Compute the parity bits only.
In [15]: p = bch.encode(m, parity_only=True); p Out[15]: GF([[0, 1, 0, 1, 0, 0, 1, 1], [0, 1, 1, 0, 0, 0, 1, 1], [0, 0, 1, 1, 0, 0, 1, 1]], order=2)
Encode a matrix of three messages using the shortened
code.In [16]: bch = galois.BCH(15, 7) In [17]: GF = galois.GF(2) In [18]: m = GF.Random((3, bch.k - 3)); m Out[18]: GF([[1, 0, 1, 1], [1, 1, 1, 0], [1, 1, 1, 1]], order=2) In [19]: c = bch.encode(m); c Out[19]: GF([[1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1], [1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0], [1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1]], order=2)
Compute the parity bits only.
In [20]: p = bch.encode(m, parity_only=True); p Out[20]: GF([[1, 0, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 1, 0, 0, 0], [0, 1, 0, 1, 1, 0, 0, 1]], order=2)
- property G : GF2¶
The generator matrix
with shape .Examples
In [1]: bch = galois.BCH(15, 7); bch Out[1]: <BCH Code: [15, 7, 5] over GF(2)> In [2]: bch.G Out[2]: GF([[1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1], [0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1], [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1]], order=2)
- property H : FieldArray¶
The parity-check matrix
with shape .Examples
In [1]: bch = galois.BCH(15, 7); bch Out[1]: <BCH Code: [15, 7, 5] over GF(2)> In [2]: bch.H Out[2]: GF([[ 9, 13, 15, 14, 7, 10, 5, 11, 12, 6, 3, 8, 4, 2, 1], [13, 14, 10, 11, 6, 8, 2, 9, 15, 7, 5, 12, 3, 4, 1], [15, 10, 12, 8, 1, 15, 10, 12, 8, 1, 15, 10, 12, 8, 1], [14, 11, 8, 9, 7, 12, 4, 13, 10, 6, 2, 15, 5, 3, 1]], order=2^4)
- property d : int¶
The design distance
of the code. The minimum distance of a BCH code may be greater than the design distance, .Examples
In [1]: bch = galois.BCH(15, 7); bch Out[1]: <BCH Code: [15, 7, 5] over GF(2)> In [2]: bch.d Out[2]: 5
- property field : FieldClass¶
The Galois field array class for the
field that defines the BCH code.Examples
In [1]: bch = galois.BCH(15, 7); bch Out[1]: <BCH Code: [15, 7, 5] over GF(2)> In [2]: bch.field Out[2]: <class 'numpy.ndarray over GF(2^4)'> In [3]: print(bch.field) Galois Field: name: GF(2^4) characteristic: 2 degree: 4 order: 16 irreducible_poly: x^4 + x + 1 is_primitive_poly: True primitive_element: x
- property generator_poly : Poly¶
The generator polynomial
whose roots areroots
.Examples
In [1]: bch = galois.BCH(15, 7); bch Out[1]: <BCH Code: [15, 7, 5] over GF(2)> In [2]: bch.generator_poly Out[2]: Poly(x^8 + x^7 + x^6 + x^4 + 1, GF(2)) # Evaluate the generator polynomial at its roots in GF(2^m) In [3]: bch.generator_poly(bch.roots, field=bch.field) Out[3]: GF([0, 0, 0, 0], order=2^4)
- property is_narrow_sense : bool¶
Indicates if the BCH code is narrow sense, meaning the roots of the generator polynomial are consecutive powers of
starting at 1, i.e. .Examples
In [1]: bch = galois.BCH(15, 7); bch Out[1]: <BCH Code: [15, 7, 5] over GF(2)> In [2]: bch.is_narrow_sense Out[2]: True In [3]: bch.roots Out[3]: GF([2, 4, 8, 3], order=2^4) In [4]: bch.field.primitive_element**(np.arange(1, 2*bch.t + 1)) Out[4]: GF([2, 4, 8, 3], order=2^4)
- property is_primitive : bool¶
Indicates if the BCH code is primitive, meaning
.Examples
In [1]: bch = galois.BCH(15, 7); bch Out[1]: <BCH Code: [15, 7, 5] over GF(2)> In [2]: bch.is_primitive Out[2]: True
- property k : int¶
The message size
of the codeExamples
In [1]: bch = galois.BCH(15, 7); bch Out[1]: <BCH Code: [15, 7, 5] over GF(2)> In [2]: bch.k Out[2]: 7
- property n : int¶
The codeword size
of the codeExamples
In [1]: bch = galois.BCH(15, 7); bch Out[1]: <BCH Code: [15, 7, 5] over GF(2)> In [2]: bch.n Out[2]: 15
- property roots : FieldArray¶
The
roots of the generator polynomial. These are consecutive powers of , specifically .Examples
In [1]: bch = galois.BCH(15, 7); bch Out[1]: <BCH Code: [15, 7, 5] over GF(2)> In [2]: bch.roots Out[2]: GF([2, 4, 8, 3], order=2^4) # Evaluate the generator polynomial at its roots in GF(2^m) In [3]: bch.generator_poly(bch.roots, field=bch.field) Out[3]: GF([0, 0, 0, 0], order=2^4)
-
__init__(n, k, primitive_poly=