5 Kody liniowe

Transkrypt

5 Kody liniowe
5
Kody liniowe
Jak już wiemy, w celu przesłania zakodowanego tekstu dzielimy go na bloki
i do każdego z bloków dodajemy tak zwane bity sprawdzające. Bity te są
w ścisłej zależności z bitami informacyjnymi, czyli tymi, z których składał
się blok przed dodaniem do niego symboli sprawdzających. Wspomniana zależność najczęściej jest liniowa i dlatego odpowiadający kod nazwiemy kodem
liniowym. Poniżej, dokładnie omówimy znaczenie użytych słów.
5.1
Definicja
Alfabet kodowy składa się z zera i jedynki. Zapiszemy to F = {0, 1}. Na zbiorze F zdefiniujemy operację dodawania następująco:
0 + 0 = 0,
1 + 0 = 1,
0 + 1 = 1,
1 + 1 = 0.
Jak widzimy, dodawanie to różni się tylko tym od ,,zwykłego” dodawania,
że 1 + 1 = 0. Od razu widać, że zdefiniowane działanie jest przemienne
i ma element neutralny 0. Troszkę trudniejsze jest sprawdzenie, że nasze
dodawanie jest też łączne. Dodatkowo zauważmy, że 0 oraz 1 są liczbami
przeciwnymi do siebie. Oznacza to, że dodawanie i odejmowanie, to jest
jedno i to samo działanie.
Będziemy też używać mnożenia, które niczym się nie różni od dobrze
znanego mnożenia liczb. Jest, więc, to działanie łączne, przemienne, rozdzielne względem dodawania i ma element neutralny 1.
Rozważać będziemy zbiór wn (F) wszystkich słów n-bitowych. W zbiorze
tym określimy sumę słów a = a1 a2 . . . an oraz b = b1 b2 . . . bn następująco:
a + b = (a1 + b1 )(a2 + b2 ) . . . (an + bn ).
Ponownie, zdefiniowane działanie jest łączne, przemienne, ma element neutralny 0 = 00 . . . 0, oraz każde słowo a ma słowo przeciwne a.
Rozważmy podzbiór K zbioru wn (F) zamknięty ze względu na działanie
dodawania słów. Zamknięty, oznacza, że suma dwóch słów ze zbioru K
jest też słowem należącym do K. Taki zbiór nazywamy kodem liniowym
długości n. Jeżeli kod K ma k bitów informacyjnych, to ma on 2k słów
kodowych. Liczbę bitów informacyjnych nazywamy też wymiarem kodu K i
oznaczamy dim K.
27
5.2
Przykłady
Kod powtórzeń Kn jest kodem liniowym i dim Kn = 1 ponieważ ma on jeden
bit informacyjny. Kod K4∗ jest podzbiorem w4 (F), ma dwa bity informacyjne
i dwa sprawdzające, które są równe drugiemu bitowi informacyjnemu. Aby
sprawdzić, czy jest to kod liniowy, wystarczy wykonać poniższe działania:
0111 + 1000 = 1111,
0111 + 1111 = 1000,
1000 + 1111 = 0111.
Ponieważ wszystkie trzy wyniki są elementami K4∗ , więc kod K4∗ jest kodem
liniowym wymiaru 2. Podobnie sprawdzamy, że K6∗ jest kodem liniowy o
wymiarze 3.
5.3
Macierz generująca
Jak już wspominaliśmy, bity informacyjne są dowolne. Przyjmijmy, że mamy
dim K = k oraz u1 u2 . . . uk jest blokiem bitów informacyjnych. Zauważmy,
że dodając kilka z bloków
10 . . . 0,
010 . . . 0,
... ,
00 . . . 01
otrzymamy dowolny blok informacyjny. Zdefiniujmy słowa ei (1 ≤ i ≤ k)
następująco: blok bitów informacyjnych składa się z k − 1 zer i jedynki na
pozycji i. Bity sprawdzające, jak zwykle, zależą od informacyjnych. Zachodzi
wzór
k
X
v ∈ K ⇐⇒ v =
ui ei .
(1)
i=1
Macierzą generującą kodu K nazywamy macierz


e1
 e2 

G=
 ... .
ek
Wzór (1) mówi, że dowolne
słowo kodowe możemy otrzymać mnożąc
macierze u1 u2 . . . uk oraz G.
5.4
Przykłady
Kod powtórzeń Kn ma macierz generującą
G = 1 1 ... 1 .
28
Rozważmy kod, o którym już wspominaliśmy jako ortogonalnym do Kn .
Jest to kod sprawdzający parzystość. Oznaczymy go przez Kn⊥ . Przypomnimy, że kod ten ma n − 1 bitów informacyjnych i jeden bit sprawdzający
równy sumie wszystkich bitów informacyjnych. Jego macierz generująca to


1
0 ... 0 1
 0
1 ... 0 1 


G=
.
 . . . . . . ... . . .

0
0 ... 1 1
Macierze generujące kodów K4∗ oraz K6∗ wyglądają następująco:


1 0 0 0 1 1
1 0 0 0
 0 1 0 1 0 1 .
0 1 1 1
0 0 1 1 1 0
Pokażemy, jak w kodzie K6∗ jest generowane słowo kodowe z bitów informacyjnych 011. Aby to słowo wygenerować, mnożymy macierze


1 0 0 0 1 1
0 1 1  0 1 0 1 0 1 = 0 1 1 0 1 1 .
0 0 1 1 1 0
Wygenerowanym słowem kodowym jest tu 011011.
Podamy teraz przykład kodu, który jeszcze się nie pojawił. Niech r > 1
i s > 1 będą ustalonymi liczbami naturalnymi i niech n = rs. Każde słowo
kodowe zapisujemy w postaci macierzy w następujący sposób:
• W każdym z wierszy 1, 2, . . . , s − 1 zapisujemy r − 1 bitów informacyjnych. W sumie daje to (r − 1)(s − 1) bitów informacyjnych.
• Ostatni bit w wierszu jest bitem, który sprawdza parzystość słowa w danym wierszu, tj. liczba jedynek w wierszu musi być parzysta, lub ostatni bit jest sumą wszystkich poprzednich.
• Ostatni wiersz składa się z bitów sprawdzających parzystości swoich
kolumn.
Ustalmy r = 4 i s = 3. Przykładem słowa kodowego jest


1 1 0 0
 0 1 1 0 .
1 0 1 0
29
Bitami informacyjnymi są tu (czytane wierszami) 110011. Jest to więc kod
wymiaru 6 i o długosci 12. Przyjmijmy, że słowa kodowe odczytujemy z
macierzy poprzez łączenie kolejnych wierszy. Macierzą generującą jest tu
więc


1 0 0 1 0 0 0 0 1 0 0 1
 0 1 0 1 0 0 0 0 0 1 0 1 


 0 0 1 1 0 0 0 0 0 0 1 1 


 0 0 0 0 1 0 0 1 1 0 0 1 .


 0 0 0 0 0 1 0 1 0 1 0 1 
0 0 0 0 0 0 1 1 0 0 1 1
5.5
Równania opisujące kody
Macierz generująca daje nam możliwość zakodowania bloku informacyjnego.
Jeżeli bity informacyjne mamy już zakodowane, możemy powstały kod opisać
stosując jednorodne układy równań liniowych. Na przykład, dla kodu powtórzeń Kn wiemy, że wszystkie bity są równe. Można więc to zapisać jako
x1 = x2 = · · · = xn lub, równoważnie, jako
x1 + xn = 0
x2 + xn = 0
.
· · · · · · ..
xn−1 + xn = 0.
Kod sprawdzający parzystość Kn⊥ opisuje natomiast równanie
x1 + x2 + · · · + xn = 0.
Powyższe równania możemy zapisać

1
0 ... 0
 0
1
... 0


 . . . . . . ... . . .
0
0 ... 1
oraz
w postaci macierzowej:
   
1
0
x1
 x2  0
1 
   
  ..  =  .. 
  .  .
1
xn
0
(2)

1 1 ...
  
x1
0



 x2  0

1  ..  =  .. 
 .  .
xn
(3)
0
Zauważmy, że macierz generująca kod sprawdzający parzystość jest macierzą układu (2), czyli układu opisującego kod powtórzeń. Natomiast macierz układu opisującego kod sprawdzający parzystość (3) jest macierzą generującą kod powtórzeń.
30
Każdy jednorodny układ równań (tj. taki, gdzie wyrazy wolne są równe
zeru) opisuje pewien kod liniowy i odwrotnie, każdy kod liniowy może być
opisany za pomocą układu równań jednorodnych. Niech dane będą dwa kody
liniowe K oraz K 0 . Jeżeli istnieje taki układ równań jednorodnych opisujący
kod K, że macierz tego układu jest macierzą generującą kod K 0 , to kody K i
K 0 nazywamy ortogonalnymi lub dualnymi. Zatem kod powtórzeń oraz kod
sprawdzający parzystość są ortogonalne.
5.6
Macierz sprawdzająca parzystość.
Mając dany kod K oraz układ równań jednorodnych opisujący K, macierzą
sprawdzającą parzystość nazywamy macierz tego układu. Macierz tę oznaczać
będziemy przez H. Dla kodu sprawdzającego parzystość mamy H =
1 1 . . . 1 , a dla kodu powtórzeń mamy


1
0 ... 0 1
 0
1 . . . 0 1


H=
.
.
.
. . . . . .
. ... 
0
0 ... 1 1
Wprost z definicji wynika, że jeśli v ∈ K, to
HvT = 0T .
Dla dowolnej macierzy A, symbol AT oznacza transpozycje tej macierzy, czyli
zamianę wierszy i kolumn. W powyższym równaniu, vT oznacza zapis słowa
v jako kolumnę.
Następujące twierdzenie mówi jak otrzymać macierz sprawdzającą parzystość z macierzy generującej.
Twierdzenie. Kod o macierzy
generującej
G = [Ik |B] ma macierz spra
wdzającą parzystość H = B T |In−k .
Symbol Ik oznacza tu macierz jednostkową stopnia k. Bezpośrednio
z twierdzenia otrzymujemy następujący wniosek.
Wniosek. Każdy kod liniowy długości n i wymiaru k ma macierz sprawdzającą parzystość o wymiarach (n − k) × n.
5.7
Waga Hamminga
Do tej pory mówiliśmy jak opisać dany kod liniowy oraz jak zakodować
blok bitów informacyjnych. Zajmiemy się teraz dekodowaniem pamiętając, że przy tej czynności musimy też korygować lub wykrywać ewentualne
31
błędy powstałe w wyniku transmisji. Okazuje się, że w przypadku kodów
liniowych zasadę MLD łatwiej jest zastosować niż w przypadku ogólnym.
Przede wszystkim, dzięki strukturze liniowej, możemy uprościć koncepcję
odległości Hamminga wprowadzając wielkość, którą jest zdefiniowana poniżej
waga Hamminga.
Wagą Hamminga binarnego słowa kodowego a = a1 a2 . . . an nazywamy
liczbę różnych od zera symboli w tym słowie, tj.
||a|| = # {i : ai 6= 0} .
Twierdzenie. Dla dowolnych słów a, b ∈ wn (F) zachodzą następujące własności:
(i) ||a|| = 0 ⇐⇒ a = 0;
(ii) ||a + b|| ≤ ||a|| + ||b||.
(iii) Jeśli określimy d(a, b) = ||a + b||, to d jest odległością Hamminga.
Podobnie jak dla odległości Hamminga zdefiniowaliśmy odległość minimalną, tak teraz zdefiniujemy wagę minimalną. Wagą minimalną kodu K
nazywamy najmniejszą wagę Hamminga niezerowego słowa a ∈ K.
W celu obliczenia minimalnej wagi rozważamy tylko odległości Hamminga
słów kodowych od słowa 0, a nie wszystkie możliwe odległości. Na przykład,
waga minimalna kodu sprawdzającego parzystość wynosi 2, natomiast kodu
powtórzeń – n.
Okazuje się, że waga minimalna to jest dokładnie odległość minimalna,
o czym mówi następujące twierdzenie.
Twierdzenie. Dla dowolnego nietrywialnego kodu dwójkowego, waga minimalna jest równa odległości minimalnej.
Używając tego twierdzenia oraz twierdzeń o wykrywaniu i poprawianiu
błędów możemy wydedukować następujący wniosek.
Wniosek. Kod liniowy poprawia (wykrywa) t błędów wtedy i tylko wtedy,
gdy jego waga minimalna jest większa od 2t (t).
5.8
Syndrom
Zajmiemy się teraz metodami dekodowania kodów liniowych. Stosować będziemy przy tym zasadę MLD. Załóżmy, że w wyniku wysłania słowa v
otrzymaliśmy słowo w. Sytuacją błędu ∗ nazywamy słowo e = w + v. Aby
∗
ang. error pattern
32
rozkodować słowo w musimy więc znać sytuację błędu e. Wówczas v =
w + e. Oczywiście, szukamy słowa e, które ma najmniejszą wagę Hamminga, ponieważ prowadzi to, zgodnie z MLD, do najbliższego od w, w sensie
odległości Hamminga, słowa kodowego.
Dużo informacji na temat sytuacji błędu daje nam łatwo obliczalny syndrom. Dokładnie, przypuśćmy, że kod liniowy K ma macierz sprawdzającą
parzystość H. Syndromem słowa w nazywamy iloczyn s = HwT . Zatem,
jeśli K jest k wymiarowym kodem liniowy długości n, macierz sprawdzająca
parzystość H ma n kolumn i k wierszy. Stąd syndrom s ∈ wk (F).
Twierdzenie. Sytuacja błędu ma ten sam syndrom, co otrzymane słowo, tj.
dla dowolnego słowa kodowego v i sytuacji błędu e,
HeT = H(v + e)T .
Powyższe twierdzenie stanowi podstawę dekodowania kodów liniowych:
otrzymujemy słowo, liczymy jego syndrom i szukamy słowa o najmniejszej
wadze Hamminga, które posiada taki sam syndrom.
5.9
Wykrywanie i poprawianie błędów
Przypomnijmy, że kod K wykrywa t błędów, jeśli jego waga minimalna
jest większa od t. Zatem kod liniowy jest tym lepszy im większa jest jego
waga minimalna i im większa jest liczba bitów informacyjnych. Niestety te
dwa warunki stoją ze sobą w jawnej sprzeczności, o czym mówi następujące
twierdzenie.
Twierdzenie. Waga minimalna w k wymiarowego kodu liniowego długości
n spełnia nierówność
w ≤ n − k + 1.
Ponieważ syndrom każdego słowa kodowego jest równy 0, więc błąd jest
wykryty, jeśli syndrom otrzymanego słowa jest różny od zera. Używając
syndromu możemy też dekodować kod, albo poprawiać ewentualne błędy
transmisji.
Opiszemy procedurę dekodowania przez syndrom. Załóżmy, że K jest
liniowym kodem długości n o wymiarze k z macierzą sprawdzającą parzystość H. Tworzymy zbiory
e + K = {e + v : v ∈ K} .
Zbiory tej postaci nazywamy warstwami kodu K. Element warstwy o najmniejszej wadze Hamminga nazywamy liderem warstwy. Wszystkie elementy
33
T
warstwy e + K mają ten sam syndrom. Słowo s = HeT nazywamy syndromem warstwy. Załóżmy, że otrzymaliśmy słowo w. Dekodowanie wygląda
następująco:
1. Liczymy syndrom s = HwT
T
;
2. Znajdujemy lidera e warstwy o syndromie s;
3. Zakładamy, że wysłanym słowem jest v = w + e.
Oczywiście, przed rozpoczęciem opisanej procedury, warto sporządzić jest
tablicę syndromów i odpowiadających im liderów.
5.10
Przykłady
Rozważmy kody K4∗ oraz K6∗ . Ich macierzami generującymi są, odpowiednio,


1 0 0 0 1 1
1 0 0 0
0 1 0 1 0 1 .
oraz
0 1 1 1
0 0 1 1 1 0
Zatem macierzami sprawdzającymi parzystość są,

0
0 1 1 0
H4 =
oraz
H6 = 1
0 1 0 1
1
odpowiednio,

1 1 1 0 0
0 1 0 1 0 .
1 0 0 0 1
Kod K4∗ ma 4 elementy, a w4 (F) ma 16 elementów. Dlatego mamy 4 warstwy:
kod (warstwa 0),
warstwa 1,
warstwa 2,
warstwa 3,
s = 00:
s = 01:
s = 10:
s = 11:
0000
0001
0010
0100
1000
1001
1010
1100
0111
0110
0101
0011
Bez trudu wybieramy tu liderów warstw i otrzymujemy:
lider syndrom
0000
00
0001
01
0010
10
0100
11
34
1111
1110
1101
1011.
Jeśli otrzymaliśmy słowo 1010, to jego syndromem jest 10, któremu odpowiada
lider 0010, więc wysłane było prawdopodobnie 1000. Zwróćmy uwagę, że
błąd w pierwszym bicie jest niezauważony przez naszą procedurę: syndromem
słów 1bbb oraz 0bbb jest zero, bez względu na to, czy b jest równe 1, czy 0.
Jest tak, ponieważ bity sprawdzające sprawdzają tylko drugi bit.
Kod K6∗ ma 8 elementów, a cała przestrzeń 64 elementy, więc mamy tu 8
warstw:
kod (warstwa 0), s = 000: 000000
011011
warstwa 1, s = 001: 000001
011010
warstwa 2, s = 010: 000010
011001
warstwa 3, s = 011: 100000
111011
warstwa 4, s = 100: 000100
011111
warstwa 5, s = 101: 010000
001011
warstwa 6, s = 110: 001000
010011
warstwa 7, s = 111: 010010
001001
100011
101101
100010
101100
100001
101111
000011
001101
100111
101001
110011
111101
101011
100101
110001
111111
010101
110110
010100
110111
010111
110100
110101
010110
010001
110010
000101
100110
011101
111110
000111
100100
001110
111000
001111
111001
001100
111010
101110
011000
001010
111100
011110
101000
000110
110000
011100
101010.
Dla każdej warstwy wybieramy lidera i obliczamy jego syndrom. Wątpliwości
mogą być przy wyborze lidera warstwy siódmej, ponieważ aż trzy elementy tej
warstwy mają wagę Hamminga równą 2. Zgodnie z zasadą MLD, wybieramy
losowo.
lider
syndrom
000000
000
000001
001
000010
010
100000
011
000100
100
010000
101
001000
110
010010
111
35
Załóżmy, że otrzymaliśmy słowo 111111. Jego syndrom, to 111. Z powyższej
tabeli odczytujemy lidera, którym jest 010010. Zatem otrzymane słowo
rozkodowujemy jako 101101. Jeśli otrzymanym słowem jest 001101, to syndromem jest 011, czyli zakładamy, że wysłane zostało 101101. Jeżeli otrzymamy 010101, to syndrom tego słowa wynosi 000, więc jest to słowo kodowe
i zakładamy, że takowe zostało wysłane.
36