4. Adattömörítés 152
4.5. Aritmetikai kódolás
Az aritmetikai kódolás a Shannon–Fano-kód természetes kiterjesztése. Alapöt-lete, hogy a valószín˝uségeket intervallumokkal ábrázolja, amihez a valószín˝uségek pontos kiszámítása szükséges. Egyetlen kódszót rendel a bemeneti adathalmaz egy blokkjához, vagyis blokkonkénti kód. Egy kódszó a[0,1)intervallum egy jobbról nyílt részintervallumának felel meg, és megadása annyi bittel történik, amennyi már egyértelm˝uen megkülönböztethet ˝ové teszi bármely más részintervallumtól. A rövidebb kódszavak hosszabb intervallumokat, vagyis nagyobb valószín˝uség˝u be-meneti blokkokat kódolnak. A gyakorlatban a részintervallumokat fokozatosan finomítjuk a blokk szimbólumainak valószín˝uségei szerint, és mihelyt eld ˝ol a ki-menet egy bitje (elegend ˝oen kicsi lesz az intervallum aktuális hossza), továbbítjuk azt.
Az aritmetikai kódolást ideális, azaz végtelen pontosságú lebeg ˝opontos tikával mutatjuk be. A gyakorlatban természetesen csak véges pontosságú aritme-tikák léteznek, de a módszer ezeken is implementálható.
A kódoló m˝uködése a következ ˝o. Induláskor az aktuális[E0,V0) intervallum-nak a[0,1)intervallumot vesszük. Ezután minden egyes bemeneti szimbólumot két lépésben kódolunk. El ˝oször tovább osztjuk az aktuális[Ek,Vk)intervallumot disz-junkt részintervallumokra úgy, hogy ezek közül egy-egy a szimbólum lehetséges értékeinek feleljen meg. A részintervallumok hosszát a szimbólumértékek felté-teles valószín˝uségével arányosnak választjuk meg. Az ily módon partíciót alkotó részintervallumok közül azt választjuk, amelyik a szimbólum ténylegesen el ˝ofor-duló értékének felel meg, és ezután ez lesz az új aktuális[Ek+1,Vk+1)intervallum.
Valójában nem szükséges egy-egy szimbólum esetén az összes részinterval-lumot meghatároznunk, elegend ˝o a szimbólum tényleges értékének megfelel ˝ore szorítkoznunk. Ehhez kumulatív valószín˝uségeket vezetünk be, a k-adik bemeneti szimbólum feldolgozásához annak i-edik lehetséges értéke esetén a
wki := i-edik lehetséges szimbólumérték érkezik, akkor az új[Ek,Vk)intervallum a követ-kez ˝o:
Ek=Ek−1+wki(Vk−1−Ek−1), Vk=Ek−1+ (wki+p(xi))(Vk−1−Ek−1).
Látható, hogy a végül így kialakuló intervallum egyértelm˝uen meghatározza a tel-jes egymásba skatulyázott intervallumsorozatot, és emiatt bel ˝ole a teltel-jes blokk visszafejthet ˝o. Az intervallum hossza a bemeneten érkezett szimbólumok felté-teles valószín˝uségeinek szorzata, azaz a blokk valószín˝usége. Az utolsó interval-lumot kódoljuk tehát, de a gyakorlatban nem az intervallum alsó és fels ˝o határa, hanem annak egy tetsz ˝olegesen választott eleme adja a kódszót. Ebb ˝ol is visz-szaállítható ugyanis az üzenet. Célszer˝u az intervallumból a lehet ˝o legkevesebb bittel leírható elemet kiválasztanunk. Belátható, hogy az x üzenetblokkhoz tartozó intervallumból alkalmasan kiválasztott elem leírásához elegend ˝ol
logp(x)1 m +1 bit.
Ebb ˝ol megkapható, hogy egy m hosszú blokkhoz tartozó kódszó hosszának várható értékére, azaz az átlagos kódszóhosszra igaz a következ ˝o:
E|f(X)| ≤E
Az aritmerikai kód átlagos kódszóhosszára tehát rosszabb korlátunk van, mint a Shannon–Fano-kód esetén. Ennek az az oka, hogy nem rendezzük sorba minden lépésben a szimbólumokat a feltételes valószín˝uségeik szerint csökken ˝o módon.
Ha az X üzenetvektor komponensei független azonos eloszlásúak, akkor a wki valószín˝uségek nem függenek k-tól, és a kiszámításukhoz sem kell feltételes való-szín˝uségeket használnunk:
wi:=
0, ha i=0,
i−1 j=1∑
p(xj), ha 1≤i≤n
Ekkor H(X) =mH(X1), tehát a bet˝unkénti átlagos kódszóhosszra 1
mE|f(X)| ≤H(X1) + 2 m,
azaz az m blokkhossz növelésével tetsz ˝olegesen megközelíti H(X1)-et. Fontos, hogy ellentétben a blokkonkénti Huffman-kódolással itt a bonyolultság nem n ˝o a blokkok hosszának növelésével.
Az alábbiakban az aritmetikai kódoló független azonos eloszlású bemeneti szimbólumokra m˝uköd ˝o pszeudokódját adjuk meg. Annyiban egyszer˝usítjük a megoldást, hogy az algoritmus a végs ˝o intervallumból nem feltétlenül a lehet ˝o leg-kevesebb bittel ábrázolható elemet választja ki.
INPUT: x[ ]={tömörítend˝o blokk}
n={tömörítend˝o blokk hossza}
p[ ]={szimbólumok valószín˝uségei}
w[ ]={szimbólumok kumulált valószín˝uségei}
OUTPUT: c={kódszó}
E=0 hossz=1
FOR i=0 to n-1
E=E+hossz*w[x[i]]
hossz=hossz*p[x[i]]
ENDFOR
méret=Fels˝oEgészRész(-log(hossz))+1 c=Fels˝oEgészRész(E*Hatvány(2,méret)) RETURN c
A dekódoló pszeudokódja pedig a következ ˝o:
INPUT: c={kódszó}
n={dekódolandó blokk hossza}
p[ ]={szimbólumok valószín˝uségei}
w[ ]={szimbólumok kumulált valószín˝uségei}
F[ ]={forrásábécé}
0 12 56 1
4.5. ábra. Az intervallum felosztása aritmetikai kódolás során
OUTPUT: x[ ]={dekódolt blokk}
4.11. példa. Tegyük fel, hogy a bemeneti szimbólumok független azonos eloszlá-súak, és háromféle értéket vehetnek fel. Eloszlásuk és az ehhez tartozó kumulatív valószín˝uségek a következ ˝ok:
p(x1) =12, w1=0, p(x2) =13, w2=12, p(x3) =16, w3=56.
Kódoljuk aritmetikai kódolóval az x2,x1,x3sorozatot. A kezdeti intervallum az [E0,V0) = [0,1)
(alsó indexszel az eddig már feldolgozott szimbólumok számát jelöljük). Az els ˝o, vagyis az x2szimbólum után három részre vágjuk az intervallumot, és a középs ˝o részt választjuk ki (4.5. ábra), tehát
[E1,V1) =
Ismét három részre osztjuk az aktuális intervallumot, s mivel a második szimbólum az x1, így az els ˝o részintervallumot választjuk:
[E2,V2) =1
Végül a harmadik részintervallumokra bontás után az x3 szimbólumot a három közül az utolsó intervallummal kódoljuk, tehát
[E3,V3) =1
Láthatjuk, hogy az[E3,V3)intervallum hossza valóban megegyezik a szimbólumok valószín˝uségeinek szorzatával, azaz a p(x2)p(x1)p(x3) =361 értékkel. Ebb ˝ol rögtön fels ˝o becslést is adhatunk a kimenet hosszára:
−log361
+2=7 bit. A kimenet el˝oállításához írjuk fel az utolsó intervallumot bináris alakban:
[E3,V3) = [0.101000111. . .2, 0.101010101. . .2).
Mivel az összes, 0.101001. . .2 számjegyekkel kezd ˝od˝o bináris szám benne van ebben az intervallumban, és ez a legrövidebb ilyen tulajdonságú prefix, így a ki-menetre az 101001 sorozatot küldhetjük.
Az aritmetikai kódolás el ˝oz˝oekben ismertetett legegyszer˝ubb megvalósítása két problémát vet fel. Az egyre csökken ˝o méret˝u intervallumok kezelése igen nagy pontosságú aritmetikát tesz szükségessé, másrészt a teljes bemenet vagy bemeneti blokk beolvasásáig egyetlen bit sem jelenik meg a kimeneten. Mindkét problé-mára megoldást jelent, hogy a kódszó elején lév ˝o bitek (tehát a legutolsó interval-lum alkalmasan kiválasztott elemének bináris tört ábrázolásban vett els ˝o néhány bitje) már az els ˝o néhány forráskarakterb ˝ol meghatározhatók. Ennélfogva a kód-szó bitjeit, amint ismertté válnak, rögtön elküldhetjük a kimenetre. Ezzel együtt felskálázzuk az aktuális intervallum hosszát, amely így már csak a végs ˝o interval-lum eddig még ismeretlen részét fogja reprezentálni. Abban az esetben, amikor az aktuális intervallum teljes egészében az 12 bal vagy jobb oldalára esik, a megoldás viszonylag egyszer˝u. A bemutatott eljárás igazi ötlete annak kezelése, amikor az aktuális intervallum közrefogja az 12-et. Ehhez egy számlálót fogunk bevezetni.
A korábban ismertett algoritmusba az új aktuális[Ek,Vk)intervallum kiválasz-tása után be kell szúrnunk az alábbi lépéseket:
• Ha az aktuális intervallum a 0,12
szakaszra esik, akkor egy 0-t, majd a számláló értékének megfelel ˝o darab 1-est írunk a kimenetre. Ezután meg-duplázzuk az intervallum hosszát úgy, hogy a
0,12
szakaszt lineárisan ki-terjesztjük a[0,1)szakaszra.
• Ha az aktuális intervallum az1
2,1
szakaszra esik, akkor egy 1-est, majd a számláló értékének megfelel ˝o darab 0-t írunk a kimenetre. Ezután megdup-lázzuk az intervallum hosszát úgy, hogy az1
2,1
szakaszt lineárisan kiter-jesztjük a[0,1)szakaszra.
• Ha az aktuális intervallum az1
4,34
szakaszra esik, akkor nem írunk semmit a kimenetre, de megnöveljük a számláló értékét. Ezután megduplázzuk az intervallum hosszát úgy, hogy az 1
4,34
szakaszt lineárisan kiterjesztjük a [0,1)szakaszra.
Ezeket a lépéseket mindaddig ismételjük, ameddig már egyik feltétel sem teljesül az aktuális intervallumra.
INPUT: x[ ]={tömörítend˝o blokk}
n={tömörítend˝o blokk hossza}
p[ ]={szimbólumok valószín˝uségei}
w[ ]={szimbólumok kumulált valószín˝uségei}
OUTPUT: c={kódszó}
E=0 V=1 hossz=1 számláló=0 FOR i=0 to n-1
E=E+w(x[i])*hossz hossz=hossz*p(x[i]) V=E+hossz
WHILE V-E<0.5 && !(E<0.25 && V>=0.75) IF V<0.5 THEN
c=c,0,számláló db 1 számláló=0
E=E*2 V=V*2
ELSE IF E>=0.5 THEN c=c,1,számláló db 0 számláló=0
E=E*2-1 V=V*2-1
ELSE IF E>=0.25 && V<0.75 THEN számláló=számláló+1
E=E*2-0.5 V=V*2-0.5 ENDIF
ENDWHILE ENDFOR
IF számláló>0 THEN c=c,0,számláló db 1 ENDIF
RETURN c
Végezetül még egy dologra szeretnénk rámutatni. Az aktuális intervallum a már feldolgozott bemenetr ˝ol hordoz olyan információt, amely eddig még nem je-lent meg a kimeneten, ezért a kódoló állapotának is tekinthetjük. Egy h hosszú intervallum −log h bites állapotot jelent. A szakasz elején bemutatott legegysze-r˝ubb aritmetikai kódoló esetén az állapot az összes információt tartalmazza, hiszen a kimeneten egyetlen bit sem jelenik meg a bemenet teljes feldolgozásáig. A mó-dosított algoritmus esetén az állapot mindig kett ˝onél keveseb bit információt
tar-talmaz, ugyanis a szabály szerint az aktuális intervallum hossza mindig legalább
1