Podręcznik

4. Kody wykrywające i korygujące błędy

4.3. Podstawowe twierdzenia o kodach wykrywających i korygujących błędy

Definicja (m,n) kodu i kodu liniowego. Zakładamy, że chcemy przesyłać słowa nad alfabetem GF(pk) (alfabetem jest ciało skończone mające  pelementów, gdzie p jest liczbą pierwszą w szczególności może to być ciało GF(2) = Z2 = {0,1}. Słowa przesyłane mają długość m, chcemy więc przesyłać słowa z (GF(pk))m. Koncepcja kodu wykrywającego lub korygującego błędy polega na wykorzystaniu kodu redundancyjnego \(f\)smutnyGF(pk))→ (GF(pk))n, gdzie n > m. Taki kod nazywamy (m,n) kodem. Obiektami kodowanymi są tu słowa o długości m nad alfabetem GF(pk) a słowami kodowymi słowa z (GF(pk))m. Zbiory (GF(pk))m i (GF(pk))n są przestrzeniami liniowymi nad ciałem GF(pk). Jeśli odwzorowanie \(f\)smutnyGF(pk))→ (GF(pk))n jest liniowe to kod nazywamy kodem liniowym

Liniowość odwzorowania oznacza, że istnieje taka macierz A o współczynnikach w ciele GF(pk) mająca n wierszy i m kolumn, że dla wektora a ∈ (GF(pk))mamy

\(f\)(a) = Aa

gdzie wektor a jest traktowany jako macierz kolumnowa.

Kod wykrywający błędy powinien zachowywać się tak, że gdy odbieramy zamiast słowa kodowego \(f\)(a) słowo z przekłamaniami na pewnej niewielkiej liczbie co najwyżej r pozycji (oznaczmy to słowo z przekłamaniami przez br(\(f\)(a))) to oglądając br(\(f\)(a)) będziemy mogli stwierdzić czy nastąpiły przekłamania.

Powiemy, że kod \(f\)smutnyGF(pk))→ (GF(pk))wykrywa fakt popełnienia co najwyżej r błędów jeśli dla każdego a ∈ (GF(pk))zmiana cyfr na co najwyżej r pozycjach w słowie kodowym \(f\)(a) nie powoduje przejścia słowa kodowego w słowo \(f\)(b) dla pewnego b ∈ (GF(pk))m,  ab.

Praktycznie więc wykrywanie błędu może polegać na porównaniu br(\(f\)(a)) z wszystkimi możliwymi słowami kodującymi \(f\)(c) dla c ∈ (GF(pk))m. Jeśli nie stwierdzamy zgodności, to stwierdzamy, że słowo br(\(f\)(a)) zawiera przekłamanie.

Kod korygujący błędy powinien zachowywać się tak, że gdy odbieramy zamiast słowa kodowego \(f\)(a) słowo z przekłamaniami na pewnej niewielkiej liczbie co najwyżej r pozycji (tzn. słowo br(\(f\)(a))) to oglądając  br(\(f\)(a)) będziemy mogli skorygować błędy (stosując pewien algorytm) uzyskując słowo \(f\)(a) a więc w konsekwencji stwierdzamy, że zostało nadane słowo a.

Zasadnicza koncepcja na jakiej opierają się kody korekcyjne jest taka: Niech \(f\)smutnyGF(pk))→ (GF(pk))będzie (m,n) kodem kodującym słowa o długości m za pomocą słów o długości n, gdzie nm. Zakładamy, że podczas transmisji słowa \(f\)(a) o długości m może powstać co najwyżej r błędów. Dla każdego a ∈ (GF(pk))kodujemy przy tym słowo a takim ciągiem a ∈ (GF(pk)), że

\(\underset{a,b \in (GF(p^k))^m, a \neq b}{\forall}\) = K(\(f\)(a),r) ∩ K(\(f\)(b),r) = ∅\(\qquad\)(1)

gdzie K(x,r) oznacza kulę o promieniu r w przestrzeni metrycznej GF(pk)) z metryką Hamminga dH. Warunek (1) oznacza, że każde dwie kule rodziny kul K(\(f\)(x),r);  GF(pk))są rozłączne. Jeśli tak jest to aby stwierdzić jaka informacja została nadana wystarczy zastosować do słowa odebranego bk(\(f\)(a));  (GF(pk))regułę decyzyjną d: GF(pk))nGF(pk)) zdefiniowaną wzorem

d(br(f(a))) = a 

wtedy i tylko wtedy, gdy

 dH(\(f\)(a),br,\(f\)(a)) = \(\underset{x \in (GF(p^k))^m}{min}\){<d<sub><em>d<sub>H</sub></em>(<span class="equation">\(f\)</span>(<em>x</em>),<em>b<sub>r</sub></em>(<span class="equation">\(f\)</span>(<em>a</em>)) }\(\qquad\)(2)

Innymi słowy jako informację nadaną przyjmujemy takie a (GF ( pk ))m , że odebrane słowo br (f(a)) (GF( pk ))n jest najbliższe f(a) tzn.

\(\underset{a,b \in (GF(p^k))^m, a \neq b}{\forall}\) dH (f(a), b) dH ( f(x), b)\(\qquad\) (3)

Jest oczywiste, że powyższa reguła decyzyjna przy warunku (1) jest poprawna w tym sensie, że pozwala na odtworzenie wiadomości nadanej przy ograniczonej do r ilości błędów transmisji.

Warto zauważyć, że istotą powyższego pomysłu na kod korekcyjny jest to, że wokół każdego słowa kodującego f(a) (gdzie a (GF ( pk ))m ) tworzymy otoczenie (w metryce Hamminga), którego elementy (oprócz f(a)) nie są wykorzystywane do kodowania słów z a (GF ( pk ))m . Możemy jednak odebrać (w wyniku wprowadzenia błędów podczas przesyłania słowa f(a)) dowolny element z tego otoczenia a mimo to nie tracimy orientacji w sytuacji, potrafimy wykryć i skorygować przekłamania.

Niech będzie dany (m,n) kod f : (GF ( pk ))m (GF ( pk ))n i ustalona liczba r  0, n . Kod f wykrywa fakt popełnienia co najwyżej r błędów wtedy i tylko wtedy gdy dla każdego a, b (GF ( pk )m , a b mamy f (a) K ( f (b), r) (czyli dH ( f (a), f (b)) r ).
Kod f : (GF ( pk ))m (GF ( pk ))n koryguje popełnienia co najwyżej r błędów wtedy i tylko wtedy, gdy dla każdego a, b (GF ( pk ))m , a b mamy dH ( f (a), f (b)) 2r 1 (lub równoważnie spełniony jest warunek (1)).
Klasycznym przykładem kodu korekcyjnego jest kod s krotnie powtórzony. Powstaje on przez przyporządkowanie słowu kodowanemu a (GF ( pk ))m słowa kodowego \(\underset{s}{\underbrace{aa...aa}}\) (GF ( pk ))ms . Zdolności korekcyjne tak zdefiniowanego kodu są oczywiste. Widać s od razu, że popełnienie co najwyżej r błędów w słowie kodowym (gdzie \(r < \frac{s}{2}\) ) nie przeszkadza w poprawnym odczytaniu takiego słowa kodowego. Kod s krotnie powtórzony jest (m, s m) kodem.

Kod blokowy. Niech V będzie ustalonym alfabetem. Kodem blokowym nazywamy kod f : Vm Vn , w którym słowom o długości m (obiektom kodowanym) przyporządkowujemy słowa o długości n, gdzie n m .

(m,n) kod jest kodem blokowym.

Kod blokowy nazywamy kodem grupowym, jeśli słowa kodowe kodu tworzą grupę addytywną.

Różnych typów kodów korekcyjnych (ang. ECC od Error Correcting Codes) jest dosyć dużo. Z bardziej znanych warto wymienić:

  • kody cykliczne (kody CRC - ang. Cyclic Redundancy Check)
  • kody Hamminga
  • kody Reeda-Solomona
  • kody Bose-Chaudhuri-Hocquenghema (kody BCH)
Kodowanie stosowane w płytach kompaktowych (płytach CD) to kod Reeda-Solomona, a ściślej CIRC (CIRC - ang. cross interleaved Reed-Solomon code).