galois.ReedSolomon

class galois.ReedSolomon(n, k, c=1, primitive_poly=None, primitive_element=None, systematic=True)

Constructs a \(\textrm{RS}(n, k)\) code.

A \(\textrm{RS}(n, k)\) code is a \([n, k, d]_q\) linear block code.

To create the shortened \(\textrm{RS}(n-s, k-s)\) code, construct the full-sized \(\textrm{RS}(n, k)\) code and then pass \(k-s\) symbols into encode() and \(n-s\) symbols into decode(). Shortened codes are only applicable for systematic codes.

Parameters
  • n (int) – The codeword size \(n\), must be \(n = q - 1\).

  • k (int) – The message size \(k\). The error-correcting capability \(t\) is defined by \(n - k = 2t\).

  • c (int, optional) – The first consecutive power of \(\alpha\). The default is 1.

  • primitive_poly (galois.Poly, optional) – Optionally specify the primitive polynomial that defines the extension field \(\mathrm{GF}(q)\). The default is None which uses Matlab’s default, see galois.matlab_primitive_poly(). Matlab tends to use the lexicographically-minimal primitive polynomial as a default instead of the Conway polynomial.

  • primitive_element (int, galois.Poly, optional) – Optionally specify the primitive element \(\alpha\) of \(\mathrm{GF}(q)\) whose powers are roots of the generator polynomial \(g(x)\). The default is None which uses the lexicographically-minimal primitive element in \(\mathrm{GF}(q)\), i.e. galois.primitive_element(p, m).

  • systematic (bool, optional) – Optionally specify if the encoding should be systematic, meaning the codeword is the message with parity appended. The default is True.

Examples

In [1]: rs = galois.ReedSolomon(15, 9)

In [2]: GF = rs.field

In [3]: m = GF.Random(rs.k); m
Out[3]: GF([ 7,  6, 15,  1,  6, 10, 14,  4,  1], order=2^4)

In [4]: c = rs.encode(m); c
Out[4]: 
GF([ 7,  6, 15,  1,  6, 10, 14,  4,  1,  8,  6,  5, 11,  2,  5],
   order=2^4)

# Corrupt the first symbol in the codeword
In [5]: c[0] ^= 13

In [6]: dec_m = rs.decode(c); dec_m
Out[6]: GF([ 7,  6, 15,  1,  6, 10, 14,  4,  1], order=2^4)

In [7]: np.array_equal(dec_m, m)
Out[7]: True

# Instruct the decoder to return the number of corrected symbol errors
In [8]: dec_m, N = rs.decode(c, errors=True); dec_m, N
Out[8]: (GF([ 7,  6, 15,  1,  6, 10, 14,  4,  1], order=2^4), 1)

In [9]: np.array_equal(dec_m, m)
Out[9]: True

Constructors

Methods

decode(codeword[, errors])

Decodes the Reed-Solomon codeword \(\mathbf{c}\) into the message \(\mathbf{m}\).

detect(codeword)

Detects if errors are present in the Reed-Solomon codeword \(\mathbf{c}\).

encode(message[, parity_only])

Encodes the message \(\mathbf{m}\) into the Reed-Solomon codeword \(\mathbf{c}\).

Attributes

G

The generator matrix \(\mathbf{G}\) with shape \((k, n)\).

H

The parity-check matrix \(\mathbf{H}\) with shape \((2t, n)\).

c

The degree of the first consecutive root.

d

The design distance \(d\) of the \([n, k, d]_q\) code.

field

The Galois field \(\mathrm{GF}(q)\) that defines the Reed-Solomon code.

generator_poly

The generator polynomial \(g(x)\) whose roots are ReedSolomon.roots.

is_narrow_sense

Indicates if the Reed-Solomon code is narrow sense, meaning the roots of the generator polynomial are consecutive powers of \(\alpha\) starting at 1, i.e. \(\alpha, \alpha^2, \dots, \alpha^{2t - 1}\).

k

The message size \(k\) of the \([n, k, d]_q\) code.

n

The codeword size \(n\) of the \([n, k, d]_q\) code.

roots

The roots of the generator polynomial.

systematic

Indicates if the code is configured to return codewords in systematic form.

t

The error-correcting capability of the code.

decode(codeword, errors=False)[source]

Decodes the Reed-Solomon codeword \(\mathbf{c}\) into the message \(\mathbf{m}\).

The codeword vector \(\mathbf{c}\) is defined as \(\mathbf{c} = [c_{n-1}, \dots, c_1, c_0] \in \mathrm{GF}(q)^n\), which corresponds to the codeword polynomial \(c(x) = c_{n-1} x^{n-1} + \dots + c_1 x + c_0\). The message vector \(\mathbf{m}\) is defined as \(\mathbf{m} = [m_{k-1}, \dots, m_1, m_0] \in \mathrm{GF}(q)^k\), which corresponds to the message polynomial \(m(x) = m_{k-1} x^{k-1} + \dots + m_1 x + m_0\).

In decoding, the syndrome vector \(s\) is computed by \(\mathbf{s} = \mathbf{c}\mathbf{H}^T\), where \(\mathbf{H}\) is the parity-check matrix. The equivalent polynomial operation is \(s(x) = c(x)\ \textrm{mod}\ g(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.

For the shortened \(\textrm{RS}(n-s, k-s)\) code (only applicable for systematic codes), pass \(n-s\) symbols into decode() to return the \(k-s\)-symbol message.

Parameters
  • codeword (numpy.ndarray, galois.FieldArray) – The codeword as either a \(n\)-length vector or \((N, n)\) matrix, where \(N\) is the number of codewords. For systematic codes, codeword lengths less than \(n\) may be provided for shortened codewords.

  • errors (bool, optional) – Optionally specify whether to return the nubmer of corrected errors.

Returns

  • numpy.ndarray, galois.FieldArray – The decoded message as either a \(k\)-length vector or \((N, k)\) matrix.

  • int, np.ndarray – Optional return argument of the number of corrected symbol errors as either a scalar or \(n\)-length vector. Valid number of corrections are in \([0, t]\). If a codeword has too many errors and cannot be corrected, -1 will be returned.

Examples

Decode a single codeword.

In [1]: rs = galois.ReedSolomon(15, 9)

In [2]: GF = rs.field

In [3]: m = GF.Random(rs.k); m
Out[3]: GF([ 4, 12,  5,  5,  5,  2,  1,  4, 14], order=2^4)

In [4]: c = rs.encode(m); c
Out[4]: 
GF([ 4, 12,  5,  5,  5,  2,  1,  4, 14, 10,  4, 13,  0,  4, 15],
   order=2^4)

# Corrupt the first symbol in the codeword
In [5]: c[0] += GF(13)

In [6]: dec_m = rs.decode(c); dec_m
Out[6]: GF([ 4, 12,  5,  5,  5,  2,  1,  4, 14], order=2^4)

In [7]: np.array_equal(dec_m, m)
Out[7]: True

# Instruct the decoder to return the number of corrected symbol errors
In [8]: dec_m, N = rs.decode(c, errors=True); dec_m, N
Out[8]: (GF([ 4, 12,  5,  5,  5,  2,  1,  4, 14], order=2^4), 1)

In [9]: np.array_equal(dec_m, m)
Out[9]: True

Decode a single, shortened codeword.

In [10]: m = GF.Random(rs.k - 4); m
Out[10]: GF([ 0, 14,  0,  4,  8], order=2^4)

In [11]: c = rs.encode(m); c
Out[11]: GF([ 0, 14,  0,  4,  8,  7, 14,  2, 15,  3, 10], order=2^4)

# Corrupt the first symbol in the codeword
In [12]: c[0] += GF(13)

In [13]: dec_m = rs.decode(c); dec_m
Out[13]: GF([ 0, 14,  0,  4,  8], order=2^4)

In [14]: np.array_equal(dec_m, m)
Out[14]: True

Decode a matrix of codewords.

In [15]: m = GF.Random((5, rs.k)); m
Out[15]: 
GF([[ 6,  3,  6,  8,  0,  3,  1, 12,  9],
    [14,  1,  1,  6,  8,  9,  9,  3,  6],
    [ 1, 15,  3,  7,  1,  6,  1,  2,  1],
    [15, 10, 15,  4,  4, 15,  7,  4, 14],
    [ 2,  6, 15, 11,  5, 12,  3,  2,  5]], order=2^4)

In [16]: c = rs.encode(m); c
Out[16]: 
GF([[ 6,  3,  6,  8,  0,  3,  1, 12,  9,  0, 11,  2,  3,  7,  6],
    [14,  1,  1,  6,  8,  9,  9,  3,  6, 10,  3, 15, 10,  9,  6],
    [ 1, 15,  3,  7,  1,  6,  1,  2,  1,  1, 10,  0, 13,  7,  6],
    [15, 10, 15,  4,  4, 15,  7,  4, 14, 14, 15,  2,  9,  4, 14],
    [ 2,  6, 15, 11,  5, 12,  3,  2,  5, 11, 11, 11, 10, 15,  4]],
   order=2^4)

# Corrupt the first symbol in each codeword
In [17]: c[:,0] += GF(13)

In [18]: dec_m = rs.decode(c); dec_m
Out[18]: 
GF([[ 6,  3,  6,  8,  0,  3,  1, 12,  9],
    [14,  1,  1,  6,  8,  9,  9,  3,  6],
    [ 1, 15,  3,  7,  1,  6,  1,  2,  1],
    [15, 10, 15,  4,  4, 15,  7,  4, 14],
    [ 2,  6, 15, 11,  5, 12,  3,  2,  5]], order=2^4)

In [19]: np.array_equal(dec_m, m)
Out[19]: True

# Instruct the decoder to return the number of corrected symbol errors
In [20]: dec_m, N = rs.decode(c, errors=True); dec_m, N
Out[20]: 
(GF([[ 6,  3,  6,  8,  0,  3,  1, 12,  9],
     [14,  1,  1,  6,  8,  9,  9,  3,  6],
     [ 1, 15,  3,  7,  1,  6,  1,  2,  1],
     [15, 10, 15,  4,  4, 15,  7,  4, 14],
     [ 2,  6, 15, 11,  5, 12,  3,  2,  5]], order=2^4),
 array([1, 1, 1, 1, 1]))

In [21]: np.array_equal(dec_m, m)
Out[21]: True
detect(codeword)[source]

Detects if errors are present in the Reed-Solomon codeword \(\mathbf{c}\).

The \([n, k, d]_q\) Reed-Solomon code has \(d_{min} = d\) minimum distance. It can detect up to \(d_{min}-1\) errors.

Parameters

codeword (numpy.ndarray, galois.FieldArray) – The codeword as either a \(n\)-length vector or \((N, n)\) matrix, where \(N\) is the number of codewords. For systematic codes, codeword lengths less than \(n\) may be provided for shortened codewords.

Returns

A boolean scalar or array indicating if errors were detected in the corresponding codeword True or not False.

Return type

bool, numpy.ndarray

Examples

Detect errors in a valid codeword.

In [1]: rs = galois.ReedSolomon(15, 9)

In [2]: GF = rs.field

# The minimum distance of the code
In [3]: rs.d
Out[3]: 7

In [4]: m = GF.Random(rs.k); m
Out[4]: GF([13,  1,  5,  1, 10,  8, 13, 11,  8], order=2^4)

In [5]: c = rs.encode(m); c
Out[5]: 
GF([13,  1,  5,  1, 10,  8, 13, 11,  8,  2,  7, 15,  1,  3, 15],
   order=2^4)

In [6]: rs.detect(c)
Out[6]: False

Detect \(d_{min}-1\) errors in a received codeword.

# Corrupt the first `d - 1` symbols in the codeword
In [7]: c[0:rs.d - 1] += GF(13)

In [8]: rs.detect(c)
Out[8]: True
encode(message, parity_only=False)[source]

Encodes the message \(\mathbf{m}\) into the Reed-Solomon codeword \(\mathbf{c}\).

The message vector \(\mathbf{m}\) is defined as \(\mathbf{m} = [m_{k-1}, \dots, m_1, m_0] \in \mathrm{GF}(q)^k\), which corresponds to the message polynomial \(m(x) = m_{k-1} x^{k-1} + \dots + m_1 x + m_0\). The codeword vector \(\mathbf{c}\) is defined as \(\mathbf{c} = [c_{n-1}, \dots, c_1, c_0] \in \mathrm{GF}(q)^n\), which corresponds to the codeword polynomial \(c(x) = c_{n-1} x^{n-1} + \dots + c_1 x + c_0\).

The codeword vector is computed from the message vector by \(\mathbf{c} = \mathbf{m}\mathbf{G}\), where \(\mathbf{G}\) is the generator matrix. The equivalent polynomial operation is \(c(x) = m(x)g(x)\). For systematic codes, \(\mathbf{G} = [\mathbf{I}\ |\ \mathbf{P}]\) such that \(\mathbf{c} = [\mathbf{m}\ |\ \mathbf{p}]\). And in polynomial form, \(p(x) = -(m(x) x^{n-k}\ \textrm{mod}\ g(x))\) with \(c(x) = m(x)x^{n-k} + p(x)\). For systematic and non-systematic codes, each codeword is a multiple of the generator polynomial, i.e. \(g(x)\ |\ c(x)\).

For the shortened \(\textrm{RS}(n-s, k-s)\) code (only applicable for systematic codes), pass \(k-s\) symbols into encode() to return the \(n-s\)-symbol codeword.

Parameters
  • message (numpy.ndarray, galois.FieldArray) – The message as either a \(k\)-length vector or \((N, k)\) matrix, where \(N\) is the number of messages. For systematic codes, message lengths less than \(k\) may be provided to produce shortened codewords.

  • parity_only (bool, optional) – Optionally specify whether to return only the parity symbols. This only applies to systematic codes. The default is False.

Returns

The codeword as either a \(n\)-length vector or \((N, n)\) matrix. The return type matches the message type. If parity_only=True, the parity symbols are returned as either a \(n - k\)-length vector or \((N, n-k)\) matrix.

Return type

numpy.ndarray, galois.FieldArray

Examples

Encode a single codeword.

In [1]: rs = galois.ReedSolomon(15, 9)

In [2]: GF = rs.field

In [3]: m = GF.Random(rs.k); m
Out[3]: GF([ 0, 10, 14, 10,  3,  4, 14,  3, 13], order=2^4)

In [4]: c = rs.encode(m); c
Out[4]: 
GF([ 0, 10, 14, 10,  3,  4, 14,  3, 13,  3, 13,  8,  4,  5, 10],
   order=2^4)

In [5]: p = rs.encode(m, parity_only=True); p
Out[5]: GF([ 3, 13,  8,  4,  5, 10], order=2^4)

Encode a single, shortened codeword.

In [6]: m = GF.Random(rs.k - 4); m
Out[6]: GF([ 7,  1,  7,  7, 11], order=2^4)

In [7]: c = rs.encode(m); c
Out[7]: GF([ 7,  1,  7,  7, 11, 13, 10,  7,  2,  1, 15], order=2^4)

Encode a matrix of codewords.

In [8]: m = GF.Random((5, rs.k)); m
Out[8]: 
GF([[ 5, 13,  7, 13,  7,  1,  5,  0, 10],
    [ 6, 14,  2, 15, 13, 14,  6,  0, 14],
    [ 2,  7,  2, 13, 13,  6, 14,  5, 12],
    [10,  7, 10,  3,  2,  0,  0,  4,  3],
    [ 9,  4,  7, 12,  9,  5,  8,  4, 11]], order=2^4)

In [9]: c = rs.encode(m); c
Out[9]: 
GF([[ 5, 13,  7, 13,  7,  1,  5,  0, 10,  6,  3,  6, 15,  4, 13],
    [ 6, 14,  2, 15, 13, 14,  6,  0, 14, 12,  7,  1, 13, 13, 12],
    [ 2,  7,  2, 13, 13,  6, 14,  5, 12, 15, 12, 12,  3,  3,  1],
    [10,  7, 10,  3,  2,  0,  0,  4,  3,  2,  3, 10,  6, 15, 14],
    [ 9,  4,  7, 12,  9,  5,  8,  4, 11, 11, 14, 14,  4,  2,  4]],
   order=2^4)

In [10]: p = rs.encode(m, parity_only=True); p
Out[10]: 
GF([[ 6,  3,  6, 15,  4, 13],
    [12,  7,  1, 13, 13, 12],
    [15, 12, 12,  3,  3,  1],
    [ 2,  3, 10,  6, 15, 14],
    [11, 14, 14,  4,  2,  4]], order=2^4)
property G

The generator matrix \(\mathbf{G}\) with shape \((k, n)\).

Type

galois.FieldArray

property H

The parity-check matrix \(\mathbf{H}\) with shape \((2t, n)\).

Type

galois.FieldArray

property c

The degree of the first consecutive root.

Type

int

property d

The design distance \(d\) of the \([n, k, d]_q\) code. The minimum distance of a Reed-Solomon code is exactly equal to the design distance, \(d_{min} = d\).

Type

int

property field

The Galois field \(\mathrm{GF}(q)\) that defines the Reed-Solomon code.

Type

galois.FieldClass

property generator_poly

The generator polynomial \(g(x)\) whose roots are ReedSolomon.roots.

Type

galois.Poly

property is_narrow_sense

Indicates if the Reed-Solomon code is narrow sense, meaning the roots of the generator polynomial are consecutive powers of \(\alpha\) starting at 1, i.e. \(\alpha, \alpha^2, \dots, \alpha^{2t - 1}\).

Type

bool

property k

The message size \(k\) of the \([n, k, d]_q\) code.

Type

int

property n

The codeword size \(n\) of the \([n, k, d]_q\) code.

Type

int

property roots

The roots of the generator polynomial. These are consecutive powers of \(\alpha\).

Type

galois.FieldArray

property systematic

Indicates if the code is configured to return codewords in systematic form.

Type

bool

property t

The error-correcting capability of the code. The code can correct \(t\) symbol errors in a codeword.

Type

int