In information theory and coding theory, Reed–Solomon codes are a group of error-correcting codes that were introduced by Irving S. Reed and Gustave Solomon in 1960.
They have many applications, including consumer technologies such as MiniDiscs, CDs, DVDs, Blu-ray discs, QR codes, Data Matrix, data transmission technologies such as DSL and WiMAX, broadcast systems such as satellite communications, DVB and ATSC, and storage systems such as RAID 6.
Reed–Solomon codes operate on a block of data treated as a set of finite-field elements called symbols. Reed–Solomon codes are able to detect and correct multiple symbol errors. By adding check symbols to the data, a Reed–Solomon code can detect (but not correct) any combination of up to erroneous symbols, or locate and correct up to erroneous symbols at unknown locations. As an erasure code, it can correct up to erasures at locations that are known and provided to the algorithm, or it can detect and correct combinations of errors and erasures. Reed–Solomon codes are also suitable as multiple-burst bit-error correcting codes, since a sequence of consecutive bit errors can affect at most two symbols of size . The choice of is up to the designer of the code and may be selected within wide limits.
There are two different Reed-Solomon encoding schemes, called original view and BCH view in this article. The history section explains the origins of this.
History
Reed–Solomon codes were developed in 1960 by Irving S. Reed and Gustave Solomon, who were then staff members of MIT Lincoln Laboratory. Their seminal article was titled "Polynomial Codes over Certain Finite Fields". The Gorenstein–Zierler decoder and the related work on BCH codes are described in a book "Error-Correcting Codes" by W. Wesley Peterson (1961). By 1963 (or possibly earlier), J.J. Stone (and others) recognized that Reed–Solomon codes could use the BCH scheme of using a fixed generator polynomial, making such codes a special class of BCH codes, but Reed–Solomon codes based on the original encoding scheme are not a class of BCH codes, and depending on the set of evaluation points, they are not even cyclic codes.
In 1969, an improved BCH scheme decoder was developed by Elwyn Berlekamp and James Massey and has since been known as the Berlekamp–Massey decoding algorithm.
In 1975, another improved BCH scheme decoder was developed by Yasuo Sugiyama, based on the extended Euclidean algorithm.
thumb|350px
In 1977, Reed–Solomon codes were implemented in the Voyager program in the form of concatenated error correction codes. The first commercial application in mass-produced consumer products appeared in 1982 with the compact disc, where two interleaved Reed–Solomon codes are used. Today, Reed–Solomon codes are widely implemented in digital storage devices and digital communication standards, though they are being slowly replaced by Bose–Chaudhuri–Hocquenghem (BCH) codes. For example, Reed–Solomon codes are used in the Digital Video Broadcasting (DVB) standard DVB-S, in conjunction with a convolutional inner code, but BCH codes are used with LDPC in its successor, DVB-S2.
In 1986, an original scheme decoder known as the Berlekamp–Welch algorithm was developed.
In 1996, variations of original scheme decoders called list decoders or soft decoders were developed by Madhu Sudan and others, and work continues on these types of decoders (see Guruswami–Sudan list decoding algorithm).
In 2002, another original scheme decoder was developed by Shuhong Gao, based on the extended Euclidean algorithm.
Around 2015 an original scheme syndrome like decoder was developed (author unkown).
Applications
Data storage
Reed–Solomon coding is very widely used in mass storage systems to correct
the burst errors associated with media defects.
Reed–Solomon coding is a key component of the compact disc. It was the first use of strong error correction coding in a mass-produced consumer product, and DAT and DVD use similar schemes. In the CD, two layers of Reed–Solomon coding separated by a 28-way convolutional interleaver yields a scheme called Cross-Interleaved Reed–Solomon Coding (CIRC). The first element of a CIRC decoder is a relatively weak inner (32,28) Reed–Solomon code, shortened from a (255,251) code with 8-bit symbols. This code can correct up to 2 byte errors per 32-byte block. More importantly, it flags as erasures any uncorrectable blocks, i.e., blocks with more than 2 byte errors. The decoded 28-byte blocks, with erasure indications, are then spread by the deinterleaver to different blocks of the (28,24) outer code. Thanks to the deinterleaving, an erased 28-byte block from the inner code becomes a single erased byte in each of 28 outer code blocks. The outer code easily corrects this, since it can handle up to 4 such erasures per block.
The result is a CIRC that can completely correct error bursts up to 4000 bits, or about 2.5 mm on the disc surface. This code is so strong that most CD playback errors are almost certainly caused by tracking errors that cause the laser to jump track, not by uncorrectable error bursts.
DVDs use a similar scheme, but with much larger blocks, a (208,192) inner code, and a (182,172) outer code.
Reed–Solomon error correction is also used in parchive files which are commonly posted accompanying multimedia files on USENET. The distributed online storage service Wuala (discontinued in 2015) also used Reed–Solomon when breaking up files.
Bar code
Almost all two-dimensional bar codes such as PDF-417, MaxiCode, Datamatrix, QR Code, Aztec Code and Han Xin code use Reed–Solomon error correction to allow correct reading even if a portion of the bar code is damaged. When the bar code scanner cannot recognize a bar code symbol, it will treat it as an erasure.
Reed–Solomon coding is less common in one-dimensional bar codes, but is used by the PostBar symbology.
Data transmission
Specialized forms of Reed–Solomon codes, specifically Cauchy-RS and Vandermonde-RS, can be used to overcome the unreliable nature of data transmission over erasure channels. The encoding process assumes a code of RS(N, K) which results in N codewords of length N symbols each storing K symbols of data, being generated, that are then sent over an erasure channel.
Any combination of K codewords received at the other end is enough to reconstruct all of the N codewords. The code rate is generally set to 1/2 unless the channel's erasure likelihood can be adequately modelled and is seen to be less. In conclusion, N is usually 2K, meaning that at least half of all the codewords sent must be received in order to reconstruct all of the codewords sent.
Reed–Solomon codes are also used in xDSL systems and CCSDS's Space Communications Protocol Specifications as a form of forward error correction.
Space transmission
350px|right|thumb| Deep-space concatenated coding system. Notation: RS(255, 223) + [[convolutional codes|CC ("constraint length" = 7, code rate = 1/2).]]
One significant application of Reed–Solomon coding was to encode the digital pictures sent back by the Voyager program.
Voyager introduced Reed–Solomon coding concatenated with convolutional codes, a practice that has since become very widespread in deep space and satellite (e.g., direct digital broadcasting) communications.
<!-- Unsourced image removed: thumb|600px|none|NASA's Deep Space Missions ECC Codes (code imperfectness) -->
Viterbi decoders tend to produce errors in short bursts. Correcting these burst errors is a job best done by short or simplified Reed–Solomon codes.
Modern versions of concatenated Reed–Solomon/Viterbi-decoded convolutional coding were and are used on the Mars Pathfinder, Galileo, Mars Exploration Rover and Cassini missions, where they perform within about 1–1.5 dB of the ultimate limit, the Shannon capacity.
These concatenated codes are now being replaced by more powerful turbo codes:
{| class="wikitable"
|+ Channel coding schemes used by NASA missions
|-
! Years !! Code !! Mission(s)
|-
| 1958–present || Uncoded || Explorer, Mariner, many others
|-
| 1968–1978 || convolutional codes (CC) (25, 1/2) || Pioneer, Venus
|-
| 1969–1975 || Reed–Muller code (32, 6) || Mariner, Viking
|-
| 1977–present || Binary Golay code || Voyager
|-
| 1977–present || RS(255, 223) + CC(7, 1/2) || Voyager, Galileo, many others
|-
| 1989–2003 || RS(255, 223) + CC(7, 1/3) || Voyager
|-
| 1989–2003 || RS(255, 223) + CC(14, 1/4) || Galileo
|-
| 1996–present || RS + CC (15, 1/6) || Cassini, Mars Pathfinder, others
|-
| 2004–present || Turbo codes{2^m-1}\frac{1}{n}\sum_{\ell=t+1}^n \ell {n\choose \ell}P_s^\ell(1-P_s)^{n-\ell}</math>
and for other modulation schemes:
<math display="block">P_b \approx \frac{1}{m}\frac{1}{n}\sum_{\ell=t+1}^n \ell {n\choose \ell} P_s^\ell(1-P_s)^{n-\ell}</math>
where <math display="inline">t = \frac{1}{2}(d_{\min}-1)</math>, <math>P_s = 1-(1-s)^h</math>, <math>h = \frac{m}{\log_2M}</math>, <math>s</math> is the symbol error rate in uncoded AWGN case and <math>M</math> is the modulation order.
For practical uses of Reed–Solomon codes, it is common to use a finite field <math>F</math> with <math>2^m</math> elements. In this case, each symbol can be represented as an <math>m</math>-bit value.
The sender sends the data points as encoded blocks, and the number of symbols in the encoded block is <math>n = 2^m - 1</math>. Thus a Reed–Solomon code operating on 8-bit symbols has <math>n = 2^8 - 1 = 255</math> symbols per block. (This is a very popular value because of the prevalence of byte-oriented computer systems.) The number <math>k</math>, with <math>k < n</math>, of data symbols in the block is a design parameter. A commonly used code encodes <math>k = 223</math> eight-bit data symbols plus 32 eight-bit parity symbols in an <math>n = 255</math>-symbol block; this is denoted as a <math>(n, k) = (255,223)</math> code, and is capable of correcting up to 16 symbol errors per block.
The Reed–Solomon code properties discussed above make them especially well-suited to applications where errors occur in bursts. This is because it does not matter to the code how many bits in a symbol are in error — if multiple bits in a symbol are corrupted it only counts as a single error. Conversely, if a data stream is not characterized by error bursts or drop-outs but by random single bit errors, a Reed–Solomon code is usually a poor choice compared to a binary code.
The Reed–Solomon code, like the convolutional code, is a transparent code. This means that if the channel symbols have been inverted somewhere along the line, the decoders will still operate. The result will be the inversion of the original data. However, the Reed–Solomon code loses its transparency when the code is shortened (see 'Remarks' at the end of this section). The "missing" bits in a shortened code need to be filled by either zeros or ones, depending on whether the data is complemented or not. (To put it another way, if the symbols are inverted, then the zero-fill needs to be inverted to a one-fill.) For this reason it is mandatory that the sense of the data (i.e., true or complemented) be resolved before Reed–Solomon decoding.
Whether the Reed–Solomon code is cyclic or not depends on subtle details of the construction. In the original view of Reed and Solomon, where the codewords are the values of a polynomial, one can choose the sequence of evaluation points in such a way as to make the code cyclic. In particular, if <math>\alpha</math> is a primitive root of the field <math>F</math>, then by definition all non-zero elements of <math>F</math> take the form <math>\alpha^i</math> for <math>i\in\{1,\dots,q-1\}</math>, where <math>q=|F|</math>. Each polynomial <math>p</math> over <math>F</math> gives rise to a codeword <math>(p(\alpha^1),\dots,p(\alpha^{q-1}))</math>. Since the function <math>a \mapsto p(\alpha a)</math> is also a polynomial of the same degree, this function gives rise to a codeword <math>(p(\alpha^2),\dots,p(\alpha^{q}))</math>; since <math>\alpha^{q}=\alpha^1</math> holds, this codeword is the cyclic left-shift of the original codeword derived from <math>p</math>. So choosing a sequence of primitive root powers as the evaluation points makes the original view Reed–Solomon code cyclic. Reed–Solomon codes in the BCH view are always cyclic because BCH codes are cyclic.
Remarks
Designers are not required to use the "natural" sizes of Reed–Solomon code blocks. A technique known as "shortening" can produce a smaller code of any desired size from a larger code. For example, the widely used (255,223) code can be converted to a (160,128) code by padding the unused portion of the source block with 95 binary zeroes and not transmitting them. At the decoder, the same portion of the block is loaded locally with binary zeroes.
The QR code, Ver 3 (29×29) uses interleaved blocks. The message has 26 data bytes and is encoded using two Reed-Solomon code blocks. Each block is a (255,233) Reed Solomon code shortened to a (35,13) code.
The Delsarte–Goethals–Seidel theorem illustrates an example of an application of shortened Reed–Solomon codes. In parallel to shortening, a technique known as puncturing allows omitting some of the encoded parity symbols.
BCH view decoders
The decoders described in this section use the BCH view of a codeword as a sequence of coefficients. They use a fixed generator polynomial known to both encoder and decoder.
Peterson–Gorenstein–Zierler decoder
Daniel Gorenstein and Neal Zierler developed a decoder that was described in a MIT Lincoln Laboratory report by Zierler in January 1960 and later in a paper in June 1961. The Gorenstein–Zierler decoder and the related work on BCH codes are described in the book Error Correcting Codes by W. Wesley Peterson (1961).
Find the roots of the error locator polynomial
Use the coefficients Λ<sub>i</sub> found in the last step to build the error location polynomial. The roots of the error location polynomial can be found by exhaustive search. The error locators X<sub>k</sub> are the reciprocals of those roots. The order of coefficients of the error location polynomial can be reversed, in which case the roots of that reversed polynomial are the error locators <math>X_k</math> (not their reciprocals <math>X_k^{-1}</math>). Chien search is an efficient implementation of this step.
Calculate the error values
Once the error locators X<sub>k</sub> are known, the error values can be determined. This can be done by direct solution for Y<sub>k</sub> in the error equations matrix given above, or using the Forney algorithm.
Calculate the error locations
Calculate i<sub>k</sub> by taking the log base <math>\alpha</math> of X<sub>k</sub>. This is generally done using a precomputed lookup table.
Fix the errors
Finally, e(x) is generated from i<sub>k</sub> and e<sub>i<sub>k</sub></sub> and then is subtracted from r(x) to get the originally sent message s(x), with errors corrected.
Example
Consider the Reed–Solomon code defined in with and (this is used in PDF417 barcodes) for a RS(7,3) code. The generator polynomial is
<math display="block">
g(x) = (x - 3)(x - 3^2)(x - 3^3)(x - 3^4) = x^4 + 809 x^3 + 723 x^2 + 568 x + 522.
</math>
If the message polynomial is , then a systematic codeword is encoded as follows:
<math display="block">
s_r(x) = p(x) \, x^t \bmod g(x) = 547 x^3 + 738 x^2 + 442 x + 455,
</math>
<math display="block">
s(x) = p(x) \, x^t - s_r(x) = 3 x^6 + 2 x^5 + 1 x^4 + 382 x^3 + 191 x^2 + 487 x + 474.
</math>
Errors in transmission might cause this to be received instead:
<math display="block">
r(x) = s(x) + e(x) = 3 x^6 + 2 x^5 + 123 x^4 + 456 x^3 + 191 x^2 + 487 x + 474.
</math>
The syndromes are calculated by evaluating r at powers of α:
<math display="block">
S_1 = r(3^1) = 3 \cdot 3^6 + 2 \cdot 3^5 + 123 \cdot 3^4 + 456 \cdot 3^3 + 191 \cdot 3^2 + 487 \cdot 3 + 474 = 732,
</math>
<math display="block">
S_2 = r(3^2) = 637,\quad S_3 = r(3^3) = 762,\quad S_4 = r(3^4) = 925,
</math>
yielding the system
<math display="block">
\begin{bmatrix}
732 & 637 \\
637 & 762
\end{bmatrix}
\begin{bmatrix}
\Lambda_2 \\ \Lambda_1
\end{bmatrix}
=
\begin{bmatrix}
-762 \\ -925
\end{bmatrix}
=
\begin{bmatrix}
167 \\ 004
\end{bmatrix}.
</math>
Using Gaussian elimination,
<math display="block">
\begin{bmatrix}
001 & 000 \\
000 & 001
\end{bmatrix}
\begin{bmatrix}
\Lambda_2 \\ \Lambda_1
\end{bmatrix}
=
\begin{bmatrix}
329 \\ 821
\end{bmatrix},
</math>
so
<math display="block">
\Lambda(x) = 329 x^2 + 821 x + 001,
</math>
with roots x<sub>1</sub> = 757 = 3<sup>−3</sup> and x<sub>2</sub> = 562 = 3<sup>−4</sup>.
The coefficients can be reversed:
<math display="block">
R(x) = 001 x^2 + 821 x + 329,
</math>
to produce roots 27 = 3<sup>3</sup> and 81 = 3<sup>4</sup> with positive exponents, but typically this isn't used. The logarithm of the inverted roots corresponds to the error locations (right to left, location 0 is the last term in the codeword).
To calculate the error values, apply the Forney algorithm:
<math display="block">
\Omega(x) = S(x) \Lambda(x) \bmod x^4 = 546 x + 732,
</math>
<math display="block">
\Lambda'(x) = 658 x + 821,
</math>
<math display="block">
e_1 = -\Omega(x_1)/\Lambda'(x_1) = 074,
</math>
<math display="block">
e_2 = -\Omega(x_2)/\Lambda'(x_2) = 122.
</math>
Subtracting <math>e_1 x^3 + e_2 x^4 = 74x^3 + 122x^4</math> from the received polynomial r(x) reproduces the original codeword s.
Berlekamp–Massey decoder
The Berlekamp–Massey algorithm is an alternate iterative procedure for finding the error locator polynomial. During each iteration, it calculates a discrepancy based on a current instance of Λ(x) with an assumed number of errors e:
<math display="block"> \Delta = S_{i} + \Lambda_1 \ S_{i-1} + \cdots + \Lambda_e \ S_{i-e}</math>
and then adjusts Λ(x) and e so that a recalculated Δ would be zero. The article Berlekamp–Massey algorithm has a detailed description of the procedure. In the following example, C(x) is used to represent Λ(x).
Example
Using the same data as the Peterson Gorenstein Zierler example above:
{| class="wikitable"
|-
! n !! S<sub>n+1</sub> !! d !! C !! B !! b !! m
|-
| 0 || 732 || 732 || 197 x + 1 || 1 || 732 || 1
|-
| 1 || 637 || 846 || 173 x + 1 || 1 || 732 || 2
|-
| 2 || 762 || 412 || 634 x<sup>2</sup> + 173 x + 1 || 173 x + 1 || 412 || 1
|-
| 3 || 925 || 576 || 329 x<sup>2</sup> + 821 x + 1 || 173 x + 1 || 412 || 2
|}
The final value of C is the error locator polynomial, Λ(x).
Sugiyama decoder <span class="anchor" id="Euclidean decoder"></span>
Another iterative method for calculating both the error locator polynomial and the error value polynomial is based on Sugiyama's adaptation of the extended Euclidean algorithm.
Define S(x), Λ(x), and Ω(x) for t syndromes and e errors:
<math display="block"> \begin{align}
S(x) &= S_{t} x^{t-1} + S_{t-1} x^{t-2} + \cdots + S_2 x + S_1 \\[1ex]
\Lambda(x) &= \Lambda_{e} x^{e} + \Lambda_{e-1} x^{e-1} + \cdots + \Lambda_{1} x + 1 \\[1ex]
\Omega(x) &= \Omega_{e} x^{e} + \Omega_{e-1} x^{e-1} + \cdots + \Omega_{1} x + \Omega_{0}
\end{align} </math>
The key equation is:
<math display="block"> \Lambda(x) S(x) = Q(x) x^{t} + \Omega(x) </math>
For t = 6 and e = 3:
<math display="block">\begin{bmatrix}
\Lambda_3 S_6 & x^8 \\
\Lambda_2 S_6 + \Lambda_3 S_5 & x^7 \\
\Lambda_1 S_6 + \Lambda_2 S_5 + \Lambda_3 S_4 & x^6 \\
S_6 + \Lambda_1 S_5 + \Lambda_2 S_4 + \Lambda_3 S_3 & x^5 \\
S_5 + \Lambda_1 S_4 + \Lambda_2 S_3 + \Lambda_3 S_2 & x^4 \\
S_4 + \Lambda_1 S_3 + \Lambda_2 S_2 + \Lambda_3 S_1 & x^3 \\
S_3 + \Lambda_1 S_2 + \Lambda_2 S_1 & x^2 \\
S_2 + \Lambda_1 S_1 & x \\
S_1
\end{bmatrix}
=
\begin{bmatrix}
Q_2 x^8 \\
Q_1 x^7 \\
Q_0 x^6 \\
0 \\
0 \\
0 \\
\Omega_2 x^2 \\
\Omega_1 x \\
\Omega_0
\end{bmatrix}
</math>
The middle terms are zero due to the relationship between Λ and syndromes.
The extended Euclidean algorithm can find a series of polynomials of the form
where the degree of R decreases as i increases. Once the degree of R<sub>i</sub>(x) < t/2, then
B(x) and Q(x) don't need to be saved, so the algorithm becomes:
R<sub>−1</sub> := x<sup>t</sup>
R<sub>0</sub> := S(x)
A<sub>−1</sub> := 0
A<sub>0</sub> := 1
i := 0
while degree of R<sub>i</sub> ≥ t/2
i := i + 1
Q := R<sub>i-2</sub> / R<sub>i-1</sub>
R<sub>i</sub> := R<sub>i-2</sub> - Q R<sub>i-1</sub>
A<sub>i</sub> := A<sub>i-2</sub> - Q A<sub>i-1</sub>
to set low order term of Λ(x) to 1, divide Λ(x) and Ω(x) by A<sub>i</sub>(0):
A<sub>i</sub>(0) is the constant (low order) term of A<sub>i</sub>.
Example
Using the same data as the Peterson–Gorenstein–Zierler example above:
{| class="wikitable"
|-
! i
! R<sub>i</sub>
! A<sub>i</sub>
|-
| −1
| 001 x<sup>4</sup> + 000 x<sup>3</sup> + 000 x<sup>2</sup> + 000 x + 000
| 000
|-
| 0
| 925 x<sup>3</sup> + 762 x<sup>2</sup> + 637 x + 732
| 001
|-
| 1
| 683 x<sup>2</sup> + 676 x + 024
| 697 x + 396
|-
| 2
| 673 x + 596
| 608 x<sup>2</sup> + 704 x + 544
|}
Decoder using discrete Fourier transform
A discrete Fourier transform can be used for decoding. To avoid conflict with syndrome names, let c(x) = s(x) the encoded codeword. r(x) and e(x) are the same as above. Define C(x), E(x), and R(x) as the discrete Fourier transforms of c(x), e(x), and r(x). Since r(x) = c(x) + e(x), and since a discrete Fourier transform is a linear operator, R(x) = C(x) + E(x).
Transform r(x) to R(x) using discrete Fourier transform. Since the calculation for a discrete Fourier transform is the same as the calculation for syndromes, t coefficients of R(x) and E(x) are the same as the syndromes:
<math display="block">R_j = E_j = S_j = r(\alpha^j) \qquad \text{for } 1 \le j \le t</math>
Use <math>R_1</math> through <math>R_t</math> as syndromes (they're the same) and generate the error locator polynomial using the methods from any of the above decoders.
Let v = number of errors. Generate E(x) using the known coefficients <math>E_1</math> to <math>E_t</math>, the error locator polynomial, and these formulas
<math display="block">\begin{align}
E_0 &= - \frac{1}{\Lambda_v}(E_{v} + \Lambda_1 E_{v-1} + \cdots + \Lambda_{v-1} E_{1}) \\
E_j &= -(\Lambda_1 E_{j-1} + \Lambda_2 E_{j-2} + \cdots + \Lambda_v E_{j-v})
& \text{for } t < j < n
\end{align}</math>
Then calculate C(x) = R(x) − E(x) and take the inverse transform (polynomial interpolation) of C(x) to produce c(x).
Decoding beyond the error-correction bound
The Singleton bound states that the minimum distance of a linear block code of size (,) is upper-bounded by . The distance was usually understood to limit the error-correction capability to . The Reed–Solomon code achieves this bound with equality, and can thus correct up to errors. However, this error-correction bound is not exact.
In 1999, Madhu Sudan and Venkatesan Guruswami at MIT published "Improved Decoding of Reed–Solomon and Algebraic-Geometry Codes" introducing an algorithm that allowed for the correction of errors beyond half the minimum distance of the code. It applies to Reed–Solomon codes and more generally to algebraic geometric codes. This algorithm produces a list of codewords (it is a list-decoding algorithm) and is based on interpolation and factorization of polynomials over and its extensions.
In 2023, coding theorists showed that Reed-Solomon codes defined over random evaluation points can achieve achieve list decoding capacity (up to errors) over linear size alphabets with high probability. These results do not provide an algorithm for performing the decoding.
Soft-decoding
The algebraic decoding methods described above are hard-decision methods, which means that for every symbol a hard decision is made about its value. For example, a decoder could associate with each symbol an additional value corresponding to the channel demodulator's confidence in the correctness of the symbol. The advent of LDPC and turbo codes, which employ iterated soft-decision belief propagation decoding methods to achieve error-correction performance close to the theoretical limit, has spurred interest in applying soft-decision decoding to conventional algebraic codes. In 2003, Ralf Koetter and Alexander Vardy presented a polynomial-time soft-decision algebraic list-decoding algorithm for Reed–Solomon codes, which was based upon the work by Sudan and Guruswami.
In 2016, Steven J. Franke and Joseph H. Taylor published a novel soft-decision decoder.
Reed Solomon original view decoders
The decoders described in this section use the Reed Solomon original view of a codeword as a sequence of polynomial values where the polynomial is based on the message to be encoded. The same set of fixed values are used by the encoder and decoder, and the decoder recovers the encoding polynomial (and optionally an error locating polynomial) from the received message.
Theoretical decoder
Reed and Solomon described a theoretical decoder that corrected errors by finding the most popular message polynomial.
Example
- <math>R_{-1} = \prod_{i=1}^n (x - a_i)</math>
- <math>R_0 = </math> Lagrange interpolation of <math>(a_i, b(a_i))</math> for <math>i = 1</math> to <math>n</math>
- <math>A_{-1} = 0</math>
- <math>A_{0} = 1</math>
- generate <math>R_{i}</math> and <math>A_{i}</math> until degree of <math>R_{i} < (n+k)/2</math>, for this example <math> (n+k)/2 = (7+3)/2 = 5</math>
{| class="wikitable"
|-
! i
! R
! A
|-
| −1
| 001x + 908x + 175x + 194x + 695x + 094x + 720x + 000
| 000
|-
| 0
| 055x + 440x + 497x + 904x + 424x + 472x + 001
| 001
|-
| 1
| 702x + 845x + 691x + 461x + 327x + 237
| 152 x + 237
|-
| 2
| 266x + 086x + 798x + 311x + 532
| 708x + 176x + 532
|}
:
:
To duplicate the polynomials generated by Berlekamp Welsh,
divide Q(x) and E(x) by most significant coefficient of E(x) = 708.
:
:
:
Recalculate where to correct resulting in the corrected codeword:
:
Syndrome decoder
Around 2015, an improved decoder was developed. The decoder generates syndromes, and similar to BCH view, the key equation between the error locator polynomial and syndromes is the same, but the error locator polynomial has roots corresponding to <math>(1/\alpha_i)</math>, and a look up table is used to convert the roots into codeword offsets.
Initialization:<br>
A polynomial is defined: <math>L = \Pi_{i=0}^{n-1} (x - \alpha_i)</math>.<br>
A set of <math>n</math> polynomials is defined: <math>L_i = L/(x - \alpha_i)</math>.<br>
A set of <math>n</math> values is generated <math>u_i = L_i(\alpha_i)</math>.<br>
A set of <math>n</math> polynomials is generated: <math>P_i = (u_i / (1 - \alpha_i z)) \mod (z^{n-k})</math><br>
Decoding - A codeword with possible errors is received <math>r = \{r_0, r_1, \dots, r_{n-1}\}</math>.<br>
A syndrome polynomial is generated <math>S = \Sigma_{i=0}^{n-1} r_i P_i </math>.<br>
If <math>S = 0</math> then no errors are detected, otherwise extended Euclid starts off with<br>
<math>R_{-1} = z^{n-k}</math>, <math>R_{0} = S</math>, <math>A_{-1} = 0</math>, <math>A_{0} = 1</math><br>
and continues until degree of <math>R_i < (n-k)/2</math><br>
The error locator polynomial is <math>\sigma = A_i</math><br>
and the error value polynomial is <math>\omega = R_i</math><br>
<math>\sigma</math> and <math>\omega</math> are divided by the least significant term of <math>\sigma</math><br>
The formal derivative of <math>\sigma</math> is generated: <math>\sigma'</math><br>
The offsets <math>o</math> of the errors correspond to the roots of <math>\sigma</math><br>
for root = <math>1/\alpha_i</math>, <math>o_i = i</math><br>
The error value for <math>o_i</math> is <br>
<math> e_i = (-\alpha_i \ \omega(1/\alpha_i)) / (u_i \ \sigma'(1/\alpha_i))</math>.
If <math>deg(\omega) = deg(\sigma)</math> then an error value corresponding to <math>\alpha_b = 0</math><br>
has been detected at offset <math>o_b = b</math>, and a separate error value is calculated:<br>
<math>B = \{ b | \sigma(1/\alpha_i) = 0 \} </math>, the set of <math>\alpha_i</math> corresponding to roots of <math>\sigma</math><br>
<math>w = </math> most significant coefficient of <math>\omega</math><br>
<math>e_b = w \ u_b^{-1} \ (\Pi_{\alpha \in B} \ (-\alpha) )^{-1}</math><br>
Example
Using the same data as the Berlekamp Welch example
Initialization:<br />
<math>a = \{000, 001, 002, 003, 004, 005, 006\}</math><br>
<math>u = \{040, 689, 600, 129, 600, 689, 040\}</math>
{| class="wikitable"
|-
! i
! P<sub>i</sub>
|-
| 0
| align="right" | 040
|-
| 1
| 689 z<sup>3</sup> + 689 z<sup>2</sup> + 689 z + 689
|-
| 2
| 155 z<sup>3</sup> + 542 z<sup>2</sup> + 271 z + 600
|-
| 3
| 696 z<sup>3</sup> + 232 z<sup>2</sup> + 387 z + 129
|-
| 4
| 311 z<sup>3</sup> + 310 z<sup>2</sup> + 542 z + 600
|-
| 5
| 657 z<sup>3</sup> + 503 z<sup>2</sup> + 658 z + 689
|-
| 6
| 279 z<sup>3</sup> + 511 z<sup>2</sup> + 240 z + 040
|}
Decoding:<br />
<math>r = \{001, 006, 123, 456, 057, 086, 121\}</math><br>
<math> S = 785 \ z^3 + 213 \ z^2 + 666 \ z + 055</math><br>
Euclid:
{| class="wikitable"
|-
! i
! R<sub>i</sub>
! A<sub>i</sub>
|-
| -1
| 001 z<sup>4</sup> + 000 z<sup>3</sup> + 000 z<sup>2</sup> + 000 z + 000
| align="right" |000
|-
| 0
| align="right" | 785 z<sup>3</sup> + 213 z<sup>2</sup> + 666 z + 055
| align="right" | 001
|-
| 1
| align="right" | 658 z<sup>2</sup> + 858 z + 323
| align="right" | 200 z + 141
|-
| 2
| align="right" | 294 z + 709
| align="right" | 905 z<sup>2</sup> + 020 z + 925
|}
<math>\sigma = 905 \ z^2 + 020 \ z + 925</math><br>
<math>\omega = 294 \ z + 709</math><br>
divide <math>\sigma</math> and <math>\omega</math> by 925<br />
<math>\sigma = 006 \ z^2 + 924 \ z + 1</math><br>
<math>\omega = 391 \ z + 55</math><br>
<math>\sigma' = 012 \ z + 924</math><br>
<math>o = \{002, 003\}</math><br>
<math>e = \{000, 000, 106, 422, 000, 000, 000\}</math><br>
<math>c = \{001, 006, 017, 034, 057, 086, 121\} = r-e</math><br>
See also
- BCH code
- Berlekamp–Massey algorithm
- Berlekamp–Welch algorithm
- Chien search
- Cyclic code
- Folded Reed–Solomon code
- Forward error correction
Notes
References
External links
Information and tutorials
- Introduction to Reed–Solomon codes: principles, architecture and implementation (CMU)
Implementations
- FEC library in C by Phil Karn (aka KA9Q) includes Reed–Solomon codec, both arbitrary and optimized (223,255) version
- Open Source C++ Reed–Solomon Soft Decoding library
- Matlab implementation of errors and-erasures Reed–Solomon decoding
