Kapitola 8

Samoopravné kódy

Teorie kódování se zabývá tím, jak rychle a spolehlivě přenášet informace z jednoho místa na druhé. Mezi její aplikace patří například minimalizace šumu při přehrávání kompaktních disků, přenos finančních informací po telefonních linkách, přenos informací mezi dvěma počítači, mezi pevným diskem a operační pamětí v jednom počítači, přenos informací z telekomunikačních, meteorologických nebo špionážních satelitů, přenos obrázků vzdálených planet a jejich měsíců ze sondy Voyager zpátky na Zem, atd.

Fyzikální prostření, ve kterém je informace přenášena, se nazývá kanál. Příkladem kanálů mohou být atmosféra, telefonní linky, elektromagnetické pole, atd. Při přenosu informace kanálem může dojít k jejímu poškození kvůli poruchám fyzikálního prostředí, ve kterém k přenosu dochází. Obecně jim říkáme šum. Šum může být způsobený například slunečními skvrnami, bleskem, přehnutím magnetické pásky, meteorickým rojem, přeslechem u telefonních linek, překlepy při psaní, špatnou artikulací, nedoslýchavostí, poškrábáním kompaktního disku, atd., atd. Šum může způsobit, že přijatá zpráva se liší od zprávy vyslané.

Teorie kódování se zabývá problémem jak odhalit a opravit chyby způsobené šumem v komunikačním kanálu. Schematicky můžeme znázornit systém pro přenos informací pomocí obrázku na následující straně. Z našeho pohledu je nejdůležitější částí diagramu šum. Bez něho by teorie kódování nebyla třeba.

Šum můžeme zmenšit pomocí volby vhodného komunikačního kanálu a použitím filtrů, které dokáží šum minimalizovat. Poté, co jsme už z dostupných možností vybrali vhodný komunikační kanál, můžeme obrátit pozornost na konstrukci kódovacího a dekódovacího zařízení. zdroj informace ↓ kódovací zařízení ↓

komunikační kanál ←

šum

↓ dekódovací zařízení ↓ příjemce informace

Konstrukce kódovacího a dekódovacího zařízení sleduje několik cílů:

1. rychlé kódování informace,

2. snadný přenos zakódované zprávy,

3. rychlé dekódování přijaté zprávy,

4. opravu chyb způsobených šumem v kanálu během přenosu zprávy,

5. maximalizaci množství informace přenesené za jednotku času.

Hlavní je čtvrtý z těchto cílů. Problém spočívá v tom, že dosažení čtvrtého cíle není v souladu s pátým cílem, a nemusí být ani příliš v souladu s prvními třemi cíly. Jakékoliv řešení tohoto problému je nutně kompromisem mezi těmito pěti cíly.

Nejběžnější způsob kódování informace je mluvená řeč. Každý přirozený jazyk má v sobě zabudovánu možnost opravy chyb způsobených šumem, kterým může být v tomto případě sbíječka za oknem, špatná artikulace, nedoslýchavost, překlepy, apod. Tato ochrana před šumem je tak přirozená, že si ji ani neuvědomujeme. Odolnost přirozeného jazyka vůči šumu je založena na redundanci, nadbytečnosti používaných hlásek pro přenos dané informace. Většině českých vět lze rozumět i když vynecháme všechny samohlásky: zkuste si sami domyslet, co jsem dělal v sobotu večer: “V sbt včr jsm šl s kmrdm n pv”. Obvykle se odhaduje, že redundance přirozeného jazyka je více než 50%. To znamená, že stejné množství informace je možné sdělit s méně než polovinou hlásek.

Nyní si řekneme několik základních předpokladů. Informace budeme přenášet pomocí posloupností složených z čísel 0 a 1. Budeme jim říkat cifry. Slovo je posloupnost cifer. Délka slova je počet cifer ve slově. Tak například 010010101 je slovo délky 9. Slovo přenášíme tak, že vysíláme cifry jednu po druhé binárním kanálem. Binární znamená, že používáme pouze dvě cifry – 0 a 1. Cifry lze přenášet mechanicky, elektricky, magneticky nebo nějak jinak pomocí dvou snadno rozlišitelných impulsů.

Binární kód je nějaká neprázdná množina C slov. Tak například kód tvořený všemi slovy délky 2 je množina

C = {00, 01, 10, 11}.

Blokový kód je kód, který obsahuje slova stejné délky. Délka těchto slov se nazývá délka kódu. Budeme se zabývat pouze blokovými kódy. Kód pro nás bude vždy binární blokový kód. Slova, která patří do daného kódu C, budeme nazývat kódová slova. Počet kódových slov v kódu C budeme označovat |C|.

Další předpoklady se týkají přenosového kanálu. První předpoklad je, že kódové slovo délky n je přijato jako slovo délky n. Žádné cifry se během přenosu neztratí ani nepřibydou. Cifry se mohou během přenosu pouze změnit.

Druhý předpoklad je, že umíme vždy poznat první cifru přenášených slov. To znamená, že pokud používáme kód délky 3 a přijmeme posloupnost 011011101, tak jsme přijali slova 011, 011 a 101.

Třetí a poslední předpoklad je, že šum je náhodný (random). To znamená, že pravděpodobnost, že se nějaká cifra během přenosu změní (poškodí), je stejná pro všechny cifry a není nijak ovlivněná chybami při přenosu sousedních cifer. Opakem náhodných chyb jsou shlukové chyby (burst errors). Shlukové chyby jsou způsobené například škrábnutím kompaktního disku, blýskáním, slunečními erupcemi, apod. Předpoklad náhodnosti chyb není příliš realistický. Teorie kódů odstraňujících náhodné chyby je ale jednodušší. Kódy pro odstraňování shlukových chyb jsou založené na kódech původně vytvořených pro odstraňování náhodných chyb.

V naprosto spolehlivém kanálu, kde není žádný šum, je každá přijatá cifra stejná jako vyslaná cifra. V takových kanálech není třeba informaci kódovat.

Reálně existující kanály vždy nějaký šum obsahují. Binární kanál se nazývá symetrický, pokud pravděpodobnost, že vyslaná cifra je správně přijata, nezávisí na této cifře. Spolehlivost binárního symetrického kanálu je reálné číslo p ∈ [0, 1], kde p je pravděpodobnost, že vyslaná cifra je stejná jako cifra přijatá. Číslo 1 − p je potom pravděpodobnost, že přijatá cifra je různá od cifry vyslané. Hodnota p = 1 znamená, že kanál je absolutně spolehlivý. Hodnota p = 1/2 znamená, že přijmeme-li nějakou cifru, nemůžeme vůbec nic říct o tom, jaká cifra byla vyslána. Obě jsou stejně pravděpodobné. Takový kanál je naopak zcela nepoužitelný. U použitelných kanálů vždy je možné předpokládat, že p ∈ (1/2, 1). Přesnou hodnotu spolehlivosti kanálu je obvykle obtížné určit. Teorie kódování je ale na přesné znalosti spolehlivosti kanálu nezávislá.

Jaké možnosti máme pro odhalení (detekci) chyb během přenosu, a jaké pro opravu (korekci) těchto chyb? Pokud přijmeme slovo, které není kódovým slovem, tak poznáme, že během přenosu došlo k chybě, přijaté slovo je jiné, než které bylo vysláno. Chybu jsme odhalili. Pokud přijmeme kódové slovo, tak nemůžeme žádnou chybu odhalit, během přenosu nemuselo k žádné chybě dojít.

Pojem opravy chyby je o něco složitější. Tady se odvoláme na schopnost přirozeného jazyka opravovat chyby. Vidíme-li někde napsáno slovo “hospůrka”, tak si domyslíme, že to asi mělo být “hospůdka”. Dáme přednost slovu “hospůdka” před slovem “rozbuška”, protože “hospůdka” se od přijatého slova “hospůrka” liší pouze v jednom písmenu, zatímco “rozbuška” se liší ve čtyřech písmenech. Pokud můžeme předpokládat, že je pravděpodobnější, že písmeno je přijato správně, než že bylo během přenosu poškozeno, tak je náš výběr oprávněný. Pokud bychom přijali slovo “hoshůzka”, tak nemáme žádný důvod dát přednost slovu “hospůdka” před slovem “pochůzka”. Obě se od přijatého slova “hoshůzka” liší ve dvou písmenech.

Vrátíme-li se k binárním blokovým kódům, tak můžeme usoudit, že kód

C_{1} = {00, 01, 10, 00}

nedokáže odhalit žádnou chybu, protože všechna slova délky 2 jsou kódová slova. Nemůže ani žádnou chybu opravit, protože žádné přijaté slovo není třeba měnit, aby se stalo kódovým slovem.

Upravíme kód C_{1} tak, že každé slovo délky 2 zopakujeme třikrát. Dostaneme kód

C_{2} = {000000, 010101, 1010101, 111111}.

Takovému kódu se říká opakovací kód (repetition code). Pokud používáme kód C_{2} a přijmeme slovo 110101, tak odhalíme, že při přenosu došlo aspoň k jedné chybě – přijaté slovo není kódové slovo. Kódové slovo 010101 dostaneme z přijatého slova 110101 změnou jedné cifry, zatímco každé jiné kódové slovo vyžaduje změnu nejméně dvou cifer. Říkáme, že slovo 010101 je nejbližší kódové slovo k přijatému slovu 110101. Díky předpokladu, že spolehlivost kanálu je p > 1/2, lze dokázat, že vyslání kódového slova 010101 je pravděpodobnější, než vyslání kterékoliv jiného kódového slova. Ve skutečnosti, pokud je vysláno jakékoliv jiné slovo c ∈ C_{2} a při přenosu dojde k jedné chybě, pak je c jediné nejbližší kódové slovo k přijatému slovu. Kód C_{2} tak dokáže správně opravit jednu chybu.

Upravíme kód C_{1} ještě jiným způsobem. Ke každému slovu kódu C_{1} přidáme jednu cifru tak, aby byl počet cifer 1 v každém kódovém slově sudý. Dostaneme kód

C_{3} = {000, 011, 101, 110}.

Přidané cifře se říká cifra pro kontrolu parity (parity-check digit). Pokud přijmeme slovo 010 s lichým počtem jednotek, tak odhalíme, že při přenosu došlo k chybě. Každé z kódových slov 110, 000, 011 dostaneme z přijatého slova 010 změnou jedné cifry. Nemáme žádný důvod dát jednomu z těchto tří kódových slov přednost před ostatními. Každé z nich ale bylo vysláno pravděpodobněji, než kódové slovo 101. Kód C_{2} tak dokáže jednu chybu odhalit, nedokáže ji ale opravit.

Efekt kontroly parity

Efekt přidání cifry pro kontrolu parity na spolehlivost přenosu informace si ukážeme na příkladu. Budeme předpokládat, že pro přenos informace používáme kód D_{1}, který je tvořený všemi slovy délky 11. To znamená, že kód nedokáže odhalit žádnou chybu. Dále budeme předpokládat, že spolehlivost použitého kanálu je

p = 1 − 10^{−8},

a že cifry jsou vysílány rychlostí 10^{7} cifer za sekundu.

Pravděpodobnost, že nějaké slovo je přeneseno s jednou chybou, je

11p^{10}(1 − p),

pravděpodobnost, že je přeneseno se dvěma chybami, se rovná

\binom{11}{2}p^{9}(1 − p)^{2},

tři chyby mají pravděpodobnost

\binom{11}{3}p^{8}(1 − p)^{3},

a tak dále. Z těchto pravděpodobností je první řádově mnohem větší než součet všech ostatních. Můžeme tedy říct, že pravděpodobnost chybného přenosu slova je přibližně

11p^{10}(1 − p) ≈ \frac{11}{10^{8}}.

To znamená, že za jednu vteřinu se přenese chybně, aniž bychom si toho všimnuli, zhruba

\frac{11}{10^{8}} · \frac{10^{7}}{11} ≈ 0, 1 slov.

To je přibližně jedno slovo za 10 sekund, 6 slov za minutu, 360 za hodinu, atd.

Nyní změníme použitý kód D_{1} tak, že přidáme cifru kontrolující paritu. Dostaneme tak kód D_{2}, který je tvořený všemi slovy délky 12, které obsahují sudý počet cifer 1. Všimněte si, že kód D_{2} má stejný počet slov, jako původní kód D_{1}. Při použití tohoto kódu odhalíme každé slovo, které bylo přeneseno s jednou chybou. Chybně přenesené slovo tedy musí obsahovat aspoň dvě (a sudý počet) chybně přenesené cifry, abychom chybný přenos neodhalili. Pravděpodobnost, že slovo je přeneseno se dvěma chybami, je nyní

\binom{12}{2}p^{10}(1 − p)^{2},

čtyři chyby mají pravděpodobnost

\binom{12}{4}p^{8}(1 − p)^{4},

se šesti chybami je slovo přeneseno s pravděpodobností

\binom{12}{8}p^{6}(1 − p)^{6},

atd. Z těchto pravděpodobností je první řádově mnohem větší než ostatní. Pravděpodobnost, že při použití kódu D_{2} přijmeme slovo s chybami aniž bychom to odhalili, je tak přibližně

\binom{12}{2}p^{10}(1 − p)^{2} ≈ \frac{66}{10^{16}} .

Tentokrát za jednu sekundu přeneseme chybně, aniž bychom si toho všimnuli, přibližně

\frac{66}{10^{16}} · \frac{10^{7}}{12} = 5, 5 · 10^{−9} slov.

To je zhruba jedno neodhalené chybně přenesené slovo za 2000 dní, téměř 6 let. Cena, kterou jsme zaplatili za takto dramatické zvýšení spolehlivosti, je relativně malá. Přenos informace se zpomalí o 1/12, protože každá dvanáctá přenášená cifra je kontrolní. Nenese žádnou novou informaci, protože ji můžeme dopočítat z jedenácti předcházejících cifer.

Rychlost přenosu informace kódem C délky n se definuje jako číslo

\frac{1}{n} log_{2} |C|.

Binárních slov délky n je 2^{n}, proto 1 ≤ |C| ≤ 2^{n} pro každý binární kód délky n. Rychlost přenosu je tak vždy nějaké číslo mezi 0 a 1. Rovná se 1, pokud kód C obsahuje všechna slova délky n, a rovná se 0, pokud C obsahuje jediné slovo. Kód D_{1} tak přenáší informace rychlostí 1, kód D_{2} rychlostí 11/12. Tato rychlost odpovídá tomu, že z 12 cifer v každém slově kódu D_{2} pouze prvních 11 je informačních, zatímco dvanáctá cifra je kontrolní. Podobně rychlost přenosu informace kódy C_{1}, C_{2} a C_{3} je postupně 1, 1/3 a 2/3. Ve všech třech případech jsou pouze první dvě cifry v každém kódovém slově informační, zbývající jsou kontrolní. Rychlost přenosu informace kódem tak říká, jaká část cifer v průměru v každém slově tohoto kódu nese informaci.

Úprava kódu D_{1} přidáním cifry pro kontrolu parity sice umožní odhalit jednu chybu při přenosu slova, nepomůže ale poznat, která cifra ve slově byla špatně přenesena. Aby to bylo možné zjistit, může být nutné vyslat chybně přijaté slovo ještě jednou. To lze zařídit například tak, že vysílač po každém slově čeká, až dostane z přijímače potvrzení, že slovo bylo přijato správně. To je velmi náročné na čas. Druhou možností je, že přijímač ukládá celou zprávu do paměti a po skončení celého vysílání požádá o opětovné vyslání těch slov, ve kterých odhalil chybu. Tento způsob je zase hodně náročný na velikost pamětí přijímače a vysílače. V některých případech je opětovné vysílání některých slov navíc buď zcela nepoužitelné, například při poslechu hudby z kompaktního disku, nebo příliš nákladné jako třeba při vysílání fotografií vzdálených planet ze sondy Voyager.

Jednoduchým způsobem jak upravit kód tak, aby byl schopen jednu chybu nejen odhalit, ale i opravit, je použít opakovací kód, vyslat každé slovo třikrát po sobě tak, jako to dělá kód C_{2}. Délka kódových slov se tak prodlouží třikrát, rychlost přenosu informace se sníží na třetinu. Pokud v nějakém kódovém slově dojde k jedné chybě, tak ji opakovací kód nejen odhalí, ale i opraví. Nejméně dvě třetiny slova jsou přenesené správně a jejich porovnáním s třetinou, která se liší, poznáme chybně přijatou cifru v této třetině. Nicméně snížení rychlosti přenosu informace na jednu třetinu je příliš velké a stejné spolehlivosti lze dosáhnout lepším výběrem kódových slov než jak to dělá opakovací kód.

Hammingův kód (7, 4, 3)

První samoopravné kódy navrhnul americký matematik Richard W. Hamming krátce po druhé světové válce. Jeho návrh spočíval v kombinaci několika testů na paritu. Ukážeme si to na nejjednodušším případu Hammingových kódů, který se označuje (7, 4, 3).

Tento kód má čtyři informační a tři kontrolní cifry, jeho délka je tedy 7. Kontrolní cifry jsou na prvním, druhém a čtvrtém místě kódového slova, informační cifry jsou na místech 3,5,6,7. Nejdříve si místa cifer ve slově vyjádříme ve dvojkové soustavě:

1 = 001
2 = 010
3 = 011
4 = 100
5 = 101
6 = 110
7 = 111.

Jsou-li nyní dány informační cifry a_{3}, a_{5}, a_{6}, a_{7}, potřebujeme v kódovém slově

. . a_{3} . a_{5}a_{6}a_{7}

dopočítat kontrolní cifry a_{1}, a_{2} a a_{4}. Kontrolní cifra a_{1} zajistí, aby byl v kódovém slově sudý počet cifer 1 na místech, která mají ve dvojkovém vyjádření jednotku na místě jednotek, tj. vpravo. To znamená, že

a_{1} + a_{3} + a_{5} + a_{7} = 0, neboli a_{1} = a_{3} + a_{5} + a_{7}.

Podobně kontrolní cifra a_{2} zajistí, aby byl v každém kódovém slově sudý počet cifer 1 na místech, která mají ve dvojkovém vyjádření jednotku namístě desítek, tj. uprostřed. Proto

a_{2} + a_{3} + a_{6} + a_{7} = 0, neboli a_{2} = a_{3} + a_{6} + a_{7}.

A nakonec dopočítáme kotrolní cifru a_{4} tak, aby byl v každém slově sudý počet cifer 1 na místech, která mají ve dvojkovém vyjádření jednotku na místě stovek, tj. vlevo:

a_{4} + a_{5} + a_{6} + a_{7} = 0, neboli a_{4} = a_{5} + a_{6} + a_{7}.

Ve všech třech rovnostech je vždy jediná kontrolní cifra a zbývající tři jsou informační. Každá rovnost tak umožňuje jednoznačně vypočítat kontrolní cifru.

Každé kódové slovo a_{1}a_{2}a_{3}a_{4}a_{5}a_{6}a_{7} Hammingova kódu H je tak řešením následující soustavy tří rovnic o sedmi neznámých nad dvouprvkovým tělesem Z_{2}:

a_{1} + a_{3} + a_{5} + a_{7} = 0
a_{2} + a_{3} + a_{6} + a_{7} = 0
a_{4} + a_{5} + a_{6} + a_{7} = 0.

A naopak, každé řešení této soustavy je prvkem kódu H. Hammingův kód tak můžeme definovat jako množinu všech řešení této soustavy. Matice této homogenní soustavy

( \begin{matrix}1 & 0 & 1 & 0 & 1 & 0 & 1 \\ 0 & 1 & 1 & 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 1 & 1 & 1 & 1 \end{matrix} ) .

má hodnost 3, protože je v redukovaném řádkově odstupňovaném tvaru.

A jak je to se schopností Hammingova kódu odhalit a opravit jednu chybu? Pokud přijmeme slovo b_{1}b_{2}b_{3}b_{4}b_{5}b_{6}b_{7}, dosadíme cifry b_{1}, …, b_{7} do rovnic definujících Hammingův kód a spočítáme čísla e_{1}, e_{2}, e_{3} ∈ Z_{2}

b_{1} + b_{3} + b_{5} + b_{7} = e_{1}
b_{2} + b_{3} + b_{6} + b_{7} = e_{2}
b_{4} + b_{5} + b_{6} + b_{7} = e_{3}.

Pokud je e_{1} = e_{2} = e_{3} = 0, je slovo b_{1}b_{2}b_{3}b_{4}b_{5}b_{6}b_{7} kódovým slovem. Pokud je aspoň jedno z čísel e_{1}, e_{2}, e_{3} různé od 0, tak při přenosu došlo k chybě. Je-li e_{1} = 1, pak k chybě došlo na některém z míst, která mají ve vyjádření ve dvojkové soustavě 1 na místě jednotek, tj. u jedné z cifer b_{1}, b_{3}, b_{5}, b_{7}. Je-li rovněž e_{2} = 1, pak je chyba také u jedné z cifer na místech, která mají ve dvojkové soustavě 1 na místě desítek, tj. u cifer b_{2}, b_{3}, b_{6}, b_{7}. Pokud je naopak e_{3} = 0, tak víme, že k chybě nedošlo na žádném z míst, která mají ve dvojkové soustavě 1 na místě stovek, tj. chyba musí být u některé z cifer na místech, která mají cifru 0 na místě stovek, tj. u některé z cifer b_{1}, b_{2}, b_{3}. Chybně přenesená je tedy cifra b_{3}. Všimněte si, že místo 3 = e_{3}e_{2}e_{1} = 011 při vyjádření ve dvojkové soustavě. Změníme-li cifru b_{3}, bude nové slovo vyhovovat všem třem rovnicím definujícím Hammingův kód, bude tedy kódovým slovem.

Postup z předchozího odstavce vede k odhalení chybně přeneseného místa zcela obecně. Přijmeme-li slovo b_{1}b_{2}b_{3}b_{4}b_{5}b_{6}b_{7}, spočítáme cifry e_{1}, e_{2}, e_{3}. Pokud jsou všechny rovné 0, je b_{1}b_{2}b_{3}b_{4}b_{5}b_{6}b_{7} kódové slovo. Pokud nejsou všechny tři cifry e_{1}, e_{2}, e_{3} rovné 0, pak číslo e_{3}e_{2}e_{1} vyjadřuje ve dvojkové soustavě jednoznačně určenou polohu cifry, jejíž změna udělá z přijatého slova b_{1}b_{2}b_{3}b_{4}b_{5}b_{6}b_{7} kódové slovo. Hammingův kód tak nejenom odhalí, ale také opraví jednu chybu. Rychlost přenosu informace Hammingovým kódem je 4/7. To je výrazné zrychlení oproti rychlosti 1/3, které lze dosáhnout při použití opakovacího kódu, který také dokáže správně opravit jednu chybu.

Nyní začneme budovat souvislosti mezi lineární algebrou a teorií samoopravných kódů. Binární slova b_{1} ⋯ b_{n} délky n budeme považovat za prvky aritmetického vektorového prostoru Z_{2}^{n} dimenze n nad dvouprvkovým tělesem Z_{2} = {0, 1}. Blokový binární kód délky n je potom podmnožina C ⊆ Z_{2}^{n}.

Definice 8.1 Kód C ⊆ Z_{2}^{n} délky n se nazývá lineární, jestliže C je podprostor prostoru Z_{2}^{n}. Dimenze lineárního kódu je dimenze dim C podprostoru C.

Protože počet prvků vektorového prostoru dimenze k nad dvouprvkovým tělesem Z_{2} se rovná 2^{k}, rychlost přenosu informace lineárním kódem dimenze k a délky n se rovná k/n.

Prakticky všechny používané kódy jsou lineární. Lineární kód je jednoduché popsat, stačí zadat nějakou jeho bázi. Bázi lineárního kódu zapisujeme do řádků matice.

Definice 8.2 Je-li dán lineární kód C ⊆ Z_{2}^{n} dimenze k, pak matice C = (a_{ij}) tvaru k × n s prvky z tělesa Z_{2} se nazývá generující matice kódu C, jestliže C = R(C).

V generující matici kódu jsou tedy řádky lineárně nezávislé. Matice

H = ( \begin{matrix}1 & 1 & 1 & 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 1 & 1 & 0 & 0 \\ 0 & 1 & 0 & 1 & 0 & 1 & 0 \\ 1 & 1 & 0 & 1 & 0 & 0 & 1 \end{matrix} )

je generující maticí Hammingova kódu (7, 4, 3). Sestrojili jsme ji tak, že jsme postupně zakódovali posloupnosti 1000, 0100, 0010 a 0001. Kvůli třetímu, pátému, šestému a sedmému sloupci jsou řádky matice H lineárně nezávislé. Dimenze Hammingova kódu (7, 4, 3) je 4, neboť jsme si uvedli, že jeho prvky jsou všechna řešení soustavy tří rovnic o 7 neznámých a matice této soustavy má hodnost 3. Podle Důsledku 6.16 má podprostor všech řešení takové soustavy dimenzi rovnou 4. Vynásobíme-li generující matici C nějakého lineárního kódu C dimenze k zleva nějakou regulární maticí P řádu k, pak součin PC je také generující matice kódu C podle Úlohy 6.4. Každý lineární kód má tak mnoho různých generujících matic.

To, patří-li nějaký vektor v ∈ Z_{2}^{7} do Hammingova kódu H, můžeme ověřit dvěma způsoby. Protože H = R(H), stačí ověřit, že v ∈ R(H) = L(H_{1∗}, H_{2∗}, H_{3∗}, H_{4∗}). Musíme tedy ověřit, že vektor v je lineární kombinací řádků generující matice kódu H, tj. že v = uH pro nějaký vektor u ∈ Z_{2}^{4}. Souřadnice vektoru u ∈ Z_{2}^{4} najdeme jako řešení vhodné soustavy lineárních rovnic o čtyřech neznámých.

Máme-li nyní dány čtyři informační cifry a_{3}, a_{5}, a_{6}, a_{7} a chceme-li dopočítat kontrolní cifry a_{1}, a_{2}, a_{4}, označíme u = (a_{3}, a_{5}, a_{6}, a_{7}) ∈ Z_{2}^{4} a spočítáme součin

uH = (b_{1}, b_{2}, b_{3}, b_{4}, b_{5}, b_{6}, b_{7}).

Z tvaru matice H ihned dostaneme, že b_{3} = a_{3}, b_{5} = a_{5}, b_{6} = a_{6} a b_{7} = a_{7}. Protože uH ∈ H, je vektor uH kódovým slovem, jehož informační symboly se rovnají pořadě a_{3}, a_{5}, a_{6}, a_{7}.

To, je-li vektor v = (a_{1}, a_{2}, …, a_{7}) ∈ H, můžeme ověřit také tak, že zjistíme, vyhovuje-li rovnicím definujícím Hammingův kód. Označíme-li

D = ( \begin{matrix}0 & 0 & 1 \\ 0 & 1 & 0 \\ 0 & 1 & 1 \\ 1 & 0 & 0 \\ 1 & 0 & 1 \\ 1 & 1 & 0 \\ 1 & 1 & 1 \end{matrix} )

matici transponovanou k matici soustavy definující Hammingův kód, pak platí

v ∈ H právě když vD = 0.

Druhý způsob je mnohem jednodušší. Stačí spočítat součin vD, namísto řešení soustavy lineárních rovnic. Zkuste si spočítat, kolik operací každá z těchto dvou metod vyžaduje. Matice D umožňuje nejen ověřit, platí-li pro přijaté slovo v ∈ H, ale také najít chybně přenesenou cifru, pokud vD ≠ 0. V takovém případě je chybně přenesená cifra na místě i ∈ {1, 2, …, 7} právě když vektor vD se rovná i-tému řádku matice D. Rozmyslete si proč. Všimněte si, že řádky matice D tvoří všechny nenulové vektory prostoru Z_{2}^{3}. Matice D se nazývá kontrolní matice Hammingova kódu (7, 4, 3). Tyto úvahy vedou k následující definici.

Definice 8.3 Je-li C lineární kód dimenze k a délky n, pak matici D tvaru n × (n − k) nazýváme kontrolní matice kódu C, platí-li

v ∈ C právě když vD = 0, tj. platí-li C = M(D),

kde M(D) je levý nulový prostor matice D.

Úloha 8.1 Předpokládáme, že C je lineární kód dimenze k a délky n a D je kontrolní matice kódu C. Dokažte, že

• hodnost matice D je n − k, tj. sloupce kontrolní matice jsou lineárně nezávislé,

• je-li Q regulární matice řádu n − k, pak součin DQ je také kontrolní matice kódu C.

Řešení. Z Definice 8.3 vyplývá, že C = M(D). Podle Tvrzení 6.17 pak platí

k = dim C = dim M(D) = n − r(D), tj. r(D) = n − k.

Abychom dokázali druhou část úlohy, stačí si připomenout, že elementární řádkové úpravy nemění nulový prostor matice. Přechodem k transponovaným maticím dostaneme, že elementární sloupcové úpravy nemění levý nulový prostor matice. Vynásobit nějakou matici zprava regulární maticí znamená provést posloupnost elementárních sloupcových úprav. Proto

C = M(D) = M(DQ).

□

Každý lineární kód má proto také mnoho různých kontrolních matic. Následující tvrzení udává nutnou a postačující podmínku pro to, aby dvě matice C a D byly generující a kontrolní maticí nějakého lineárního kódu.

Tvrzení 8.4 Předpokládáme, že C je matice tvaru k×n a D je matice tvaru n × (n − k), obě s prvky z dvouprvkového tělesa Z_{2}. Potom je ekvivalentní

• matice C a D jsou generující a kontrolní matice nějakého lineárního kódu C dimenze k a délky n, • platí r(C) = k, tj. řádky matice C jsou lineárně nezávislé, r(D) =

n − k, tj. sloupce matice D jsou lineárně nezávislé, a CD = 0.

Důkaz. Je-li C generující matice kódu C dimenze k, tvoří řádky matice C bázi podprostoru C ⊆ Z_{2}^{n}, který má dimenzi k. Proto jsou řádky matice C lineárně nezávislé a tedy r(C) = k. Rovnost r(D) = n − k pro libovolnou kontrolní matici D lineárního kódu dimenze k a délky n jsme dokázali v Úloze 8.1. Protože D je kontrolní matice kódu C a C_{i∗} ∈ R(C) = C pro každé i = 1, …, k, plyne odtud podle Tvrzení 3.7, že (CD)_{i∗} = C_{i∗}D = 0 pro každé i = 1, …, k, tj. CD = 0.

Abychom dokázali opačnou implikaci, definujeme lineární kód C = R(C). Protože r(C) = k, jsou řádky matice C lineárně nezávislé, tvoří proto bázi kódu C a matice C je proto generující maticí kódu C. Vzhledem k předpokladu CD = 0 platí C_{i∗} ∈ M(D) pro každé i = 1, …, k a proto také C = L(C_{1∗}, …, C_{k∗}) ⊆ M(D). Protože r(D) = n − k, platí podle Tvrzení 6.17, že r(M(D)) = n − r(D) = k. Každá báze podprostoru C je proto také bází levého nulového prostoru matice D, a proto C = M(D). Matice D je tak kontrolní maticí lineárního kódu C. □

Každý lineární kód C ⊆ Z_{2}^{n} můžeme zadat dvěma způsoby – buď pomocí generující matice nebo pomocí kontrolní matice. Tyto matice nejsou kódem C jednoznačně určené. Stejně tak ani jedna z těchto matic neurčuje jednoznačně tu druhou. Budeme se nyní zabývat otázkou, jak rychle najít kontrolní matici D kódu C, známe-li jeho generující matici C, a naopak jak najít generující matici C, známe-li kontrolní matici D.

Nejjednodušší případ nastává, je-li generující matice ve speciálním tvaru.

Definice 8.5 Generující matice C lineárního kódu C dimenze k a délky n je ve standardním tvaru, platí-li

C = ( I_{k} X ) ,

kde X je nějaká matice tvaru k × (n − k) s prvky z tělesa Z_{2}. Kód C se nazývá systematický kód, pokud má nějakou generující matici ve standardním tvaru.

Cvičení 8.1 Dokažte, že je-li C = ( I_{k} X ) generující matice systematického kódu C dimenze k a délky n ve standardním tvaru a u ∈ Z_{2}^{k}, pak

uC = ( u uX ) .

To znamená, že v systematickém kódu dimenze k a délky n je v každém kódovém slově prvních k cifer informačních a po nich následují kontrolní cifry.

Tvrzení 8.6 Je-li C = ( I_{k} X ) generující matice systematického kódu C dimenze k a délky n ve standardním tvaru, pak matice

D = ( \begin{matrix}X \\ I_{n−k} \end{matrix} )

je kontrolní matice kódu C.

Naopak, je-li

D = ( \begin{matrix}X \\ I_{n−k} \end{matrix} )

kontrolní matice lineárního kódu D dimenze k a délky n, pak matice C = ( I_{k} X ) je generující matice kódu D.

Důkaz. Přímým výpočtem dostaneme, že

CD = ( I_{k} X ) ( \begin{matrix}X \\ I_{n−k} \end{matrix} ) = I_{k}X + XI_{n−k} = X + X = 0,

protože těleso Z_{2} má charakteristiku 2.

Vzhledem k přítomnosti bloku I_{n−k} v matici D je hodnost r(D) = n−k. Podle Tvrzení 8.4 je tak D kontrolní matice kódu generovaného maticí C, tj. kódu C.

Tvrzení z druhého odstavce dokážeme stejně. Protože r(C) = k, je C generující maticí kódu, jehož kontrolní maticí je D, tj. kódu D. □

Ne každý kód je ovšem systematický a má generující matici ve standardním tvaru. Z hlediska teorie kódování je ale možné omezit se pouze na systematické kódy. V libovolném lineárním kódu stačí změnit pořadí cifer v kódových slovech tak, aby informační cifry byly na počátku kódových slov a informační cifry až po nich.

Definice 8.7 Dva lineární kódy C a C′ dimenze k a délky n se nazývají ekvivalentní, pokud existuje generující matice C kódu C taková, že změnou pořadí sloupců v matici C dostaneme generující matici C′ kódu C′.

Tvrzení 8.8 Každý lineární kód C je ekvivalentní nějakému systematickému kódu.

Důkaz. Vezmeme libovolnou generující matici kódu C a pomocí elementárních řádkových úprav ji převedeme do redukovaného řádkově odstupňovaného tvaru C. Poté přeházíme sloupce v matici C tak, aby první pivot ležel v prvním sloupci, druhý pivot ve druhém sloupci, atd. Dostaneme tak matici C′ = ( I_{k} X ), která je ve standardním tvaru a je proto generující maticí systematického kódu, který je ekvivalentní kódu C. □

Hammingova vzdálenost

Důkazy schopnosti kódů odhalovat a opravovat některé chyby jsou založené na následující jednoduché, ale důležité definici.

Definice 8.9 Jsou-li u, v ∈ Z_{2}^{n} dvě binární slova stejné délky n, pak definujeme jejich Hammingovu vzdálenost d(u, v) jako počet souřadnic, ve kterých se oba vektory liší. Hammingova váha wt(u) slova u ∈ Z_{2}^{n} se rovná počtu souřadnic ve slově u rovných 1. Je-li C kód obsahující aspoň dvě slova, pak definujeme Hammingovu vzdálenost d(C) kódu C jako nejmenší ze vzdáleností d(u, v), kde u ≠ v jsou libovolné dva různé prvky kódu C.

Tak například d(01011, 00111) = 2 a d(00111, 00111) = 0. Podobně wt(10101) = 3 a wt(00000) = 0. Snadno si sami dokážete jednoduchou ale důležitou rovnost

d(u, v) = wt(u + v)

pro libovolné dva vektory u, v ∈ Z_{2}^{n}. Také všechny důkazy v následujícím cvičení jsou jednoduché.

Cvičení 8.2 Dokažte, že pro každé tři vektory u, v, w ∈ Z_{2}^{n} a libovolný skalár a ∈ Z_{2} platí

1. 0 ≤ wt(v) ≤ n,

2. wt(0) = 0,

3. je-li wt(v) = 0, pak v = 0,

4. d(v, v) = 0,

5. je-li d(v, w) = 0, pak v = w,

6. d(v, w) = d(w, v),

7. wt(v + w) ≤ wt(v) + wt(w), 8. d(u, w) ≤ d(u, v) + d(v, w) (trojúhelníková nerovnost),

9. wt(av) = a · wt(v),

10. d(av, aw) = a · d(v, w),

11. je-li C lineární kód, pak d(C) = min{wt(v) : 0 ≠ v ∈ C}.

S použitím definice Hammingovy vzdálenosti můžeme formálně definovat, co to znamená, že nějaký kód odhalí nebo opraví nějakou chybu.

Definice 8.10 Libovolné binární slovo e ∈ Z_{2}^{n} délky n nazýváme typ chyby. Je-li C ⊆ Z_{2}^{n} kód délky n, pak říkáme, že kód C dokáže odhalit chybu typu e ≠ 0, jestliže pro každé kódové slovo v ∈ C platí v + e ∉ C.

Říkáme, že kód C dokáže odhalit t chyb, jestliže dokáže odhalit každou chybu e ≠ 0 s váhou wt(e) ≤ t.

Dále říkáme, že C dokáže opravit chybu typu e ≠ 0 jestliže pro každé slovo v ∈ C platí

d(v, v + e) < d(v + e, w) pro libovolné slovo w ∈ C různé od v.

Konečně říkáme, že kód C dokáže opravit t chyb, jestliže dokáže opravit každou chybu e ≠ 0 s váhou wt(e) ≤ t.

Věta 8.11 Má-li kód C délky n vzdálenost d(C) = d, pak dokáže odhalit všechny chyby typu e ≠ 0 s váhou d − 1 a existuje aspoň jedna chyba s váhou d, kterou odhalit nedokáže. Takový kód tak dokáže odhalit d − 1 chyb a nedokáže odhalit d chyb.

Důkaz. Je-li 0 < wt(e) < d pro nenulový vektor e ∈ Z_{2}^{n} a v ∈ C, pak d(v, v + e) = wt(e) < d. Protože d = d(C), není vektor v + e prvkem kódu C.

Jsou-li v, w ∈ C dvě kódová slova taková, že d(v, w) = d = d(C), pak definujeme e = v + w. Platí wt(e) = wt(v + w) = d a kód C neodhalí chybu typu e, neboť v + e = w ∈ C. □

Ve formulaci následující věty se objevuje označení ⌊x⌋ pro reálné číslo x. Symbol ⌊x⌋ označuje celou část čísla x, tj. největší celé číslo menší nebo rovné x. Například ⌊3/2⌋ = ⌊1⌋ = 1, ⌊−(3/2⌋ = −2, atd.

Věta 8.12 Má-li kód C délky n vzdálenost d(C) = d, pak dokáže opravit všechny chyby s váhou menší nebo rovnou ⌊(d−1)/2⌋ a existuje aspoň jedna chyba s váhou 1 + ⌊(d − 1)/2⌋, kterou kód C odhalit nedokáže. Kód C tak dokáže opravit ⌊(d − 1)/2⌋ chyb a nedokáže opravit 1 + ⌊(d − 1)/2⌋ chyb.

Důkaz. Předpokládáme, že e ≠ 0 je typ chyby s váhou wt(e) ≤ (d−1)/2. Nyní vezmeme libovolná dvě různá kódová slova v, w ∈ C. Potom platí

d(w, v + e) + d(v + e, v) ≥ d(w, v) ≥ d.

Dále platí

d(w, v + e) + wt(e) ≥ 2wt(u) + 1
d(w, v + e) ≥ wt(u) + 1
≥ d(v, v + e) + 1,

neboť wt(e) = d(v + e, v) a 2wt(e) + 1 ≤ d. Tím je dokázáno, že kód C opraví chybu typu e.

Existují dvě kódová slova v, w ∈ C, pro která platí d(v, w) = d. Vytvoříme typ chyby e tak, že v součtu v + w změníme d − 1 − ⌊(d − 1)/2⌋ souřadnic 1 na 0. Potom

d(v, v + e) = wt(e) = 1 + ⌊(d − 1)/2⌋, a
d(w, v + e) = wt(w + v + e) = d(v + w, e)
= d − (1 + ⌊(d − 1)/2⌋).

Je-li d liché číslo, tj. d = 2t + 1, potom

d(v, v + e) = wt(e) = 1 + (2t)/2 = 1 + t, a

d(w, v + e) = 2t + 1 − (1 + t) = t,

takže d(v, v + e) > d(w, v + e). A je-li d sudé číslo, tj. d = 2t, pak

d(v, v + e) = 1 + ⌊t − 1/2⌋ = t a
d(w, v + e) = 2t − t = t.

V obou případech platí d(v, v + e ≥ d(w, v + e) a proto v + e není blíže ke kódovému slovu v než ke kódovému slovu w. Kód C tak nedokáže opravit chybu typu e.

Proto kód C (jehož vzdálenost je d) nedokáže opravit 1 + ⌊(d − 1)/2⌋ chyb, dokáže ale opravit ⌊(d − 1)/2⌋ chyb. □

Vzdálenost lineárního kódu C můžeme velmi dobře zjistit pomocí kontrolní matice D.

Věta 8.13 Je-li D kontrolní matice lineárního kódu C, pak platí, že vzdálenost kódu C se roná d právě tehdy když je libovolných d − 1 různých řádků matice D lineárně nezávislých a existuje d řádků v matici D, které jsou lineárně závislé.

Důkaz. Je-li v libovolné slovo, pak vD je lineární kombinací přesně wt(v) řádků matice D. Je-li tedy 0 ≠ v ∈ C, pak platí vD = 0 a proto existuje wt(v) řádků matice D, které jsou lineárně závislé.

Pokud je vzdálenost kódu C rovna d, pak existuje vektor 0 ≠ v ∈ C, který má váhu wt(v) = d a proto také existuje d lineárně závislých řádků matice D. Kromě toho pro každý nenulový vektor w s váhou wt(w) ≤ d − 1 platí w ∉ C, tj. wD ≠ 0, tj. každých d − 1 řádků matice D je lineárně nezávislých.

Opačná implikace se dokáže podobně □

Nyní si řekneme, jak jsou definovány obecné Hammingovy kódy.

Definice 8.14 Pro přirozené číslo r ≥ 2 definujeme Hammingův kód délky 2^{r} − 1 jako lineární kód, jehož kontrolní matice D je tvořena všemi nenulovými vektory délky r. Délka tohoto kódu je zřejmě 2^{r} − 1.

Věta 8.15 Hammingův kód délky 2^{r} − 1 dokáže opravit jednu chybu.

Důkaz. Stačí ukázat, že vzdálenost Hammingova kódu je 3, tj. libovolné dva řádky kontrolní matice D jsou lineárně nezávislé, a dále že existují tři řádky, které lineárně závislé jsou. To je ale zřejmé, protože libovolné dva různé nenulové vektory v, w téže délky nad dvouprvkovým tělesem jsou lineárně nezávislé. Tři vektory v, w, v + w lineárně závislé jsou. □