Zalety o prosty o szybki Wady o nieefektywny, gdy

Transkrypt

Zalety o prosty o szybki Wady o nieefektywny, gdy

Zalety
o prosty
o szybki
 Wady
o nieefektywny, gdy
prawdopodobieństwo wystąpienia
jednego z symboli alfabetu źródła
jest duże (ale można kodować ciągi
symboli)
o dwuprzebiegowy (koszt transmisji
modelu może być duży, nie do
zastosowania wprost do kodowania
on-line)

Użycie algorytmu Huffmana w adaptacyjnym
modelu jest możliwe
Metoda brute-force – każdorazowo po zakodowniu symbolu buduj
od nowa drzewo Huffmana
( Uwaga na Zero Frequency Problem )
... ale w praktyce zbyt kosztowne
Ale mamy algorytm generujący kod zbliżony do kodu Huffmana,
nadający się do zastosowania w algorytmie adaptacyjnym.
Drzewo Huffmana budowane jest przyrostowo – możliwa jest
„aktualizacja modelu”
•został wynaleziony niezależnie przez Fallera i Gallagera
• udoskonalony przez Cormacka i Horspoola oraz (niezależnie) przez
Knutha
• następnie udoskonalony przez Vittera
Na czym polega?
Budujemy przyrostowo drzewo
binarne, którego węzły zawierają
liczniki częstości, a liście są
dodatkowo skojarzone z symbolami
alfabetu źródła
Drzewo ma własność rodzeństwa, gdy:
1.
każdy węzeł nie będący liściem ma 2 potomków;
2.
przechodząc węzły w kolejności z góry do dołu, a na danym
poziomie od prawej do lewej, otrzymamy ciąg węzłów o
nierosnących licznikach.
Drzewo mające własność rodzeństwa
jest drzewem Huffmana (tw. FalleraGallagera)
Przykład: drzewo mające własność rodzeństwa
11
6
5
a
2
4
r
2
2
b
1
1
c
d


Budowane drzewo zawiera liść (0-węzeł) reprezentujący wszystkie
symbole, które jeszcze nie wystąpiły w kodowanym ciągu
Kodowanie rozpoczynamy od drzewa składającego się wyłącznie z 0-
węzła


Używamy pomocniczej struktury węzły, listy dwukierunkowej
zawierającej węzły drzewa uporządkowane w kolejności przeglądania
drzewa z góry do dołu, a na danym poziomie od prawej do lewej
Podlistę listy węzły składającą się z wszystkich węzłów o wartości
licznika i nazywamy blokiem-i , a pierwszy węzeł takiego bloku liderem
DynamiczneKodowanieHuffmanaFGK(symbol s)
p = liść zawierający symbol s;
wyprowadź słowo kodowe dla s (*);
if p jest 0-węzłem
utwórz nowy węzeł q dla symolu s;
q.licznik = 1;
p = nowy węzeł w miejscu 0-węzła
będący rodzicem 0-węzła i
węzła q;
p.licznik = 1;
else
p.licznik++;
endif
while p nie jest korzeniem
if p narusza własność rodzeństwa
if lider bloku-i
zawierającego p nie jest
rodzicem p
zamień p z liderem;
endif
endif
p = rodzic(p);
p.licznik++;
endwhile
a
p
r
b
0
1
1
2
p
0
1
1
q
1
1
a
1
a
0
1
q
b
Przykład: kodujemy ciąg abrr, wstawienie symbolu b
a
0
1
b
r
2
2
2
p
1
a
0
2
1
2
1
1
a
p
1
a
1
1
b
1
1
b
0
1
b
0
r
wstawienie symbolu r (przywróć własność rodzeństwa)
1
r
r
2
3
2
p
p
2
1
1
a
a
1
1
1
r
wstawienie symbolu r
2
a
1
1
1
1
b
0
1
2
b
b
0
1
r
0
1
r
r
3
1
3
1
2
a
3
a
1
1
b
1
r
2
a
1
1
0
1
2
1
1
b
0
2
p
r
b
0
2
p
r
ponowne wstawienie symbolu r (przywróć własność rodzeństwa)
3
4
p
1
2
2
a
2
r
1
1
1
1
b
0
2
p
r
b
0
1
a
ponowne wstawienie symbolu r (przywróć własność rodzeństwa)
4
2
2
r
1
1
b
0
1
a
postać drzewa po przetworzeniu ciągu abrr
Dodatkowe założenie: w bloku-i węzłów najpierw znajdują się węzły
wewnętrzne, później liście

minimalizujemy głębokość drzewa

bardziej złożone staje się przywracanie własności rodzeństwa

ciąg o długości s zakodujemy na nie więcej niż h+s bitach,
gdzie h to liczba bitów dla kodowania statycznego Huffmana

Algorytm adaptacyjny można zbudować z kilku
stałych modeli

Ale po kolei ...
◦
◦
◦
◦
Zmodyfikowane kody binarne
Rodzina kodów Golomba
Rodzina kodów Golomba-Rice’a
Model danych dla parametrycznej rodziny kodów
(model algorytmu FELICS)
Prefiksowy kod dla skończonego alfabetu, np. dla liczb 0 .. j-1
◦ słowa kodowe o długości  log(j)  lub  log (j)  bitów,
gdzie j to rozmiar alfabetu
◦ właściwie to rodzina kodów
Symbol
(długość słowa kodowego
kodu binarnego dla alfabetu j
symboli to  log(j)  )
Alfabet
0 .. 4
0 .. 5
0 .. 6
0 .. 7
0
.00
.00
.00
.000
1
.01
.01
.010
.001
2
.10
.100
.011
.010
3
.110
.101
.100
.011
4
.111
.110
.101
.100
.111
.110
.101
.111
.110
5
6
7
.111
Generowanie słowa kodowego
kodujemy liczbę i zmodyfikowanym kodem binarnym dla liczb 0 .. j – 1,
przyjmijmy N =  log(j)  i n = 2 N
jeżeli i < n – j
zakoduj i za pomocą N – 1 -bitowego kodu binarnego
else
zakoduj i + n – j za pomocą N -bitowego kodu binarnego
Własności zmodyfikowanego kodu binarnego
◦ długość słowa kodowego:  log(j)  lub  log (j) 
◦ dla j = 2
N
kod staje się N -bitowym kodem binarnym
◦ liczba dłuższych słów kodowych jest zawsze parzysta
◦
parametryczna rodzina kodów
przeznaczona do kodowania nieujemnych liczb całkowitych
nieskończona
parametrem kodu jest całkowite m, m > 0
◦
zawiera kody optymalne dla wykładniczego rozkładu
prawdopodobieństwa symboli
(dla niektórych parametrów rozkładu)
(nadaje się do źródeł o rozkładzie nierosnącym)
◦
słowa kodowe łatwe w generacji i dekodowaniu
Generowanie słowa kodowego
kodujemy liczbę x kodem
Golomba z parametrem m
prefiks słowa:
 x/ m 
zakodowane unarnie (kod α Eliasa)
sufiks słowa: x mod m
zakodowane zmodyfikowanym
kodem binarnym dla przedziału
[0, m – 1]
np. 8 kodem Golomba z parametrem 3
 8/3  = 2
110
8 mod 3 = 2
11
Jest to szczególny przypadek kodu Golomba zauważony już przez
Golomba i niezależnie od niego odkryty przez Rice’a.
Kody Golomba są szczególnie proste, gdy m = 2 k
kodujemy liczbę x kodem Golomba-Rice’a z parametrem k
prefiks słowa:  x/ 2 k 
sufiks słowa:
x mod 2 k
zakodowane unarnie (kod α Eliasa)
x >> k
zakodowane zmodyfikowanym kodem
binarnym dla przedziału [0, m – 1]
k najmniej znaczących bitów x
Dla skończonego alfabetu używamy tylko części nieskończonej
rodziny.
Przyjmijmy rozmiar alfabetu 2 N
• dla rodziny Golomba
kody o m > 2 N-1 mają
słowa kodowe
wszystkich symboli
alfabetu dłuższe od
kodu o m = 2 N-1
• dla kodów GolombaRice’a kody o k > N – 1
mają słowa wszystkich
symboli alfabetu dłuższe
od kodu o k = N – 1
• sensowne jest używanie
początkowych 2 N-1
kodów
• sensowne jest używanie
początkowych N kodów
(k = 0 .. N – 1 )

Rodziny Golomba-Rice’a można użyć do kodowania ciągów symboli
o wykładniczym rozkładzie prawdopodobieństwa.
(rozkład często spotykany w kompresji obrazów, dźwięków ... )

Jeżeli parametr rozkładu jest nieznany, lub zmienia się w trakcie
pracy źródła to parametr kodu Golomba-Rice’a trzeba dobierać
adaptacyjnie.
Jak to zrobić?
Wybierajmy ten kod, który jest najlepszy dla już przetworzonych symboli
Jak to zrobić?
Algorytm modelowania zastosowany przez Howarda i Vittera w
algorytmie bezstratnej kompresji obrazów FELICS.
Idea
Dla każdego kodu z rodziny utrzymuj licznik (tablica liczników)
◦ licznik liczby bitów, którą by uzyskano, kodując dotychczas
przetworzoną część ciągu tym kodem.
Po zakodowaniu symbolu zwiększ licznik każdego z kodów
o długość słowa kodowego właśnie zakodowanego symbolu
w kodzie odpowiadającym licznikowi
Do kodowania symbolu użyj kodu o najmniejszym liczniku
◦ Udoskonalenie: okresowo, gdy wartość najmniejszego z liczników
przekroczy pewien próg, podziel wszystkie liczniki przez 2
 unikniemy przepełnienia
 zwiększymy znaczenie symboli kodowanych niedawno
◦ Ww. metoda to tylko część całego algorytmu
(i tylko część modelu)
◦ Metoda z FELICS nadaje się do każdej rodziny
◦ Jeszcze prostsza metoda istnieje dla rodziny Golomba-Rice’a
 zastosowana przez Weinberger, Seroussi, Sapiro w algorytmie
LOCO(JPEG-LS)
 niezależnie od rozmiaru alfabetu mamy 2 liczniki (licznik
zakodowanych symboli i licznik sumy wartości tych symboli)
Warto się zapoznać

Idea kodowania arytmetycznego

Koncepcja implementacji dla liczb o ograniczonej
precyzji

Wybrane algorytmy
◦ MQ-Coder
◦ Range-Coder
◦ Szybki model dla kodera arytmetycznego