1 / 31

Algorytm kodowania arytmetycznego

Algorytm kodowania arytmetycznego. Algorytmy Kompresji Danych wykład 4 Roman Starosolski. Plan wykładu. Historia kodowania arytmetycznego Idea kodowania arytmetycznego Koncepcja implementacji dla liczb o ograniczonej precyzji Wybrane algorytmy MQ-Coder Range-Coder

walden
Download Presentation

Algorytm kodowania arytmetycznego

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Algorytm kodowania arytmetycznego Algorytmy Kompresji Danychwykład 4Roman Starosolski

  2. Plan wykładu • Historia kodowania arytmetycznego • Idea kodowania arytmetycznego • Koncepcja implementacji dla liczb o ograniczonej precyzji • Wybrane algorytmy • MQ-Coder • Range-Coder • Szybki model dla kodera arytmetycznego

  3. Historia kodowania arytmetycznego • Historia • Shannon (1948) ― „Podstawowe twierdzenie ...”, wzmianka o możliwości kodowania arytmetycznego • Elias (196x) ― dalsze prace • Jelinek (1968) ― dalsze prace • Rissanen i Pascoe (1976, niezależnie) ― idea implementacji w arytmetyce stałopozycyjnej • IBM (198x) ― algorytmy zorientowane na sprzętowe kodowanie alfabetu binarnego (w większości opatentowane) • Witten (1987) i inni ― implementacje programowe dla alfabetów binarnych i nie-binarnych

  4. „Podstawowe twierdzenie Shannona o kodowaniu bezszumowym” (jedna z postaci twierdzenia, wg.: Drozdek: „Wprowadzenie do kompresji danych”) Dla bezpamięciowego źródła S o entropii H(S) możliwe jest przypisanie ciągom k symboli źródła, słów kodu przedrostkowego tak, że spełnione jest H(S) ≤ Lk / k < H(S) + 1/k • asymptotycznie, możliwe jest uzyskanie średniej długości kodu (w przeliczeniu na pojedynczy symbol) równej entropii źródła • optymalna długość słowa kodowego dla symbolu o prawdopodobieństwie p równa jest –log(p) (czyli autoinformacji dla tego symbolu) • można zbudować koder entropijny o efektywności bliskiej 100%

  5. Idea kodowania arytmetycznego • Cały ciąg zostanie zakodowany za pomocą jednej liczby rzeczywistej z lewostronnie domkniętego przedziału zawartego w przedziale [0, 1) • (Jeżeli długość ciągu nie jest znana dekoderowi, to należy ją przetransmitować, bądź uzupełnić alfabet źródła o symbol oznaczający koniec ciągu.) • Zaczynamy od przedziału [0, 1) • Czytając kolejne symbole ciągu zawężamy stopniowo początkowy przedział;dla kolejnego symbolu pobranego z ciągu • przedział dzieli się na lewostronnie domknięte podprzedziały o długościach wprost proporcjonalnych do prawdopodobieństw poszczególnych symboli alfabetu źródła • wybiera się przedział odpowiadający odczytanemu symbolowi. • Wyprowadzamy dowolną liczbę z przedziału wyznaczonego dla ciągu

  6. Przykład • komdujemy ciąg abaca, • alfabet źródła to {a, b, c} • Używamy stałego modelu danych • P(a)=0.6, P(b)=0.2, P(c)=0.2 • Przyjmujemy, iż długość ciągu jest znana dekoderowi.

  7. 0.6 1 c 0.8 b 0.6  a  0 0 • Zaczynamy od przedziału [0, 1). Dla kolejnego symbolu z ciągu odczytaliśmy a • ... przedział dzieli się na lewostronnie domknięte podprzedziały o długościach wprost proporcjonalnych do prawdopodobieństw poszczególnych symboli alfabetu źródła, a: [0, 0.6) b: [0.6, 0.8) c: [0.8, 1) • ... wybiera się przedział odpowiadający temu symbolowi. przedział dla ciągu a: [0, 0.6)

  8. 0.6 0.48 1 c c 0.8 0.48  b  b 0.6 0.36  a  a 0 0 0.36 • przedział dla ciągu a: [0, 0.6). Dla kolejnego symbolu z ciągu odczytaliśmy b • ... przedział dzieli się na lewostronnie domknięte podprzedziały o długościach wprost proporcjonalnych do prawdopodobieństw poszczególnych symboli alfabetu źródła, aa: [0, 0.36) ab: [0.36, 0.48) ac: [0.48, 0.6) • ... wybiera się przedział odpowiadający temu symbolowi. przedział dla ciągu ab: [0.36, 0.48)

  9. 0.6 0.432 0.36 1 0.48 c c c 0.48 0.456 0.8  b  b b 0.432 0.36 0.6 a  a  a  0.36 0 0 • przedział dla ciągu ab: [0.36, 0.48). Dla kolejnego symbolu z ciągu odczytaliśmy a • ... przedział dzieli się na lewostronnie domknięte podprzedziały o długościach wprost proporcjonalnych do prawdopodobieństw poszczególnych symboli alfabetu źródła, aba: [0.36, 0.432)abb: [0.432, 0.456)abc: [0.456, 0.48) • ... wybiera się przedział odpowiadający temu symbolowi. przedział dla ciągu aba: [0.36, 0.432)

  10. 0.6 0.42624 1 0.48 0.432 0.432 c  c  c  c c 0.48 0.42912 0.4176 0.456 0.8 b b b b   b  0.4032 0.6 0.432 0.36 0.42624 a a   a   a  a  0.4176 0.36 0 0 0.36 0.4176 ... po przetworzeniu całego ciągu abaca • otrzymujemy przedział dla ciągu abaca: [0.4176, 0.432) • Wyprowadzamy dowolną liczbę z przedziału wyznaczonego dla ciągu • np. 0.42 • (a wiedząc, że liczba jest z [0, 1), wystarczy wyprowadzić znaczące cyfry mantysy: 42)

  11. Przedziału uzyskany po wykonaniu algorytmu • długość przedziału równa jest prawdopodobieństwu wygenerowania odczytanego ciągu • dla każdego możliwego ciągu o długości n symboli otrzymamy inny przedział • przedziały te nie pokrywają się • ich suma jest przedziałem [0, 1) • dla podprzedziału o długości p można znaleźć taką liczbę, że binarne zakodowanie jej mantysy wymagać będzie nie więcej niż  –log(p)  + 1 bitów

  12. 0.6 0.42 0.42 0.42 0.42 0.42 0.42624 0.432 0.432 1 0.48  c  c  c c c 0.456 0.48 0.4176 0.8 0.42912  b  b b b b  0.42624 0.6 0.4032 0.432 0.36  a  a   a  a a  0.4176 0 0.4176 0.36 0.36 0 • Dekodowanie • Znając rozkład prawdopodobieństwa symboli alfabetu i długość ciągu, • pobieramy zakodowany ciąg, czyli kod 42 → liczba 0.42 • zaczynamy od przedziału [0, 1) • cyklicznie, aż nie zdekodujemy ciągu o danej długości: • analogicznie do kodowania, dzielimy przedział na podprzedziały dla wszystkich symboli alfabetu • wybieramy podprzedział który zawiera liczbę 0.42 • wyprowadzamy symbol odpowiadający temu podprzedziałowi

  13. Cechy kodowania arytmetycznego • efektywność bliska 100%, asymptotycznie 100% • bez ograniczeń co do rozkładu prawdopodobieństwa symboli (ani co do rozmiaru alfabetu) • niezależność kodera od modelu • można stosować różne modele probabilistyczne • można stosować wiele modeli • nadaje się do algorytmów adaptacyjnych • (trzeba uzupełnić alfabet o symbol EOF) • nie da się go zaimplementować wprost dla liczb o ograniczonej precyzji

  14. 0.6 0.42624 1 0.48 0.432 0.432 c  c  c  c c 0.48 0.42912 0.4176 0.456 0.8 b b b b   b  0.4032 0.6 0.432 0.36 0.42624 a a   a   a  a  0.4176 0.36 0 0 0.36 0.4176 Koncepcja implementacji dla liczb o ograniczonej precyzji • Część cyfr liczby z wnętrza przedziału można wyprowadzać już w trakcie kodowania • gdy początkowe cyfry górnego i dolnego kresu przedziału są takie same,to takie będą również cyfry każdej liczby wewnątrz przedziału • można więc te cyfry wyprowadzić • (i odpowiednio przeskalować przedział aby korzystać z pełnej dostępnej dokładności)

  15. Koncepcja implementacji dla liczb o ograniczonej precyzji • Model danych • model oparty o liczby całkowite zamiast prawdopodobieństw zlicza liczby wystąpień symboli • do wyznaczenia podprzedziału dla kolejnego symbolu wystarczy znać jego prawdopodobieństwo oraz łączne prawdopodobieństwo wszystkich symboli poprzedzających go w alfabecie • ponieważ łatwiej to robić w modelu, zazwyczaj to model wyznacza skumulowane prawdopodobieństwa Pi = ∑ki= 1 pi , gdzie pi to prawdopodobieństwo symbolu si , tj. i-tego symbolu alfabetu; tu symbole numerujemy od 1

  16. Koncepcja implementacji dla liczb o ograniczonej precyzji • Reprezentacja przedziału • kresy pamiętamy na m-bitowych liczbach całkowitych, M=2m –1 • przedziały traktujemy jako obustronnie domknięte, • kres górny danego podprzedziału jest o 1 mniejszy od kresu dolnego następnego podprzedziału • w przypadku skalowania przedziału trzeba zadbać aby powyższa własność została zachowana (po pomnożeniu kresów przez 2 odległość między nimi wzrośnie do 2) • zaczynamy od przedziału [0, M], tj. [0000...0 i 1111...1] • prawdopodobieństwo symbolu wyznaczone przez model nie może spowodować wyznaczenia przedziału o długości 0

  17. Normalizacja podprzedziału zawartego całkowicie w górnej lub dolnej połówce przedziału [0, M] • wyprowadź 1 (górna), lub 0 (dolna) i przeskaluj • co zrobić gdy podprzedział zawiera środek przedziału [0, M]?

  18. Normalizacja podprzedziału zawierającego środek przedziału [0, M] • koduj alfabet binarny, to nie będzie takich problemów (przy odpowiedniej normalizacji), albo • gdy długość podprzedziału będzie mniejsza od M/2 • przeskaluj • zliczaj przeskalowania, ale nie wyprowadzaj bitów

  19. (na podstawie: A. Drozdek, Wprowadzenie do kompresji danych, WNT, Warszawa, 1999) • Kodujemy symbol si (i-ty symbolu alfabetu), aktualny przedział to [L, R] bieżącyPrzedział = [ L + Pi-1(R – L + 1) , L + Pi (R – L + 1) ] • Normalizacja przedziału (gdy przedział jest mały wykonywana kilkakrotnie) while(1) if bieżącyPrzedział  [0, M/2] zwróc 0 i licznikBitów jedynek licznikBitów = 0 elseif bieżącyPrzedział  [M/2, M] zwróc 1 i licznikBitów zer licznikBitów = 0 odejmijM/2 od obu kresów bieżącegoPrzedziału elseif bieżącyPrzedział  [M/4, 3M/4] licznikBitów ++ // tylko tu możliwe przepełnienie odejmijM/4 od obu kresów bieżącegoPrzedziału else break endif pomnóż przez 2 oba kresy bieżącegoPrzedziału dodaj 1 do górnego kresu bieżącegoPrzedziału endwhile

  20. (na podstawie: A. Drozdek, Wprowadzenie do kompresji danych, WNT, Warszawa, 1999) • Zakończenie kodowania (wyprowadź resztę „stanu” kodera arytmetycznego, czyli końcówkę rozwinięcia binarnego liczby z bieżącego przedeziału) licznikBitów ++ ifkres dolny bieżącegoPrzedziału < M/4 zwróc 0 i licznikBitów jedynek else zwróc 1 i licznikBitów zer endif

  21. Wybrane Implementacje • Witten, Neal, Cleary (1987) (tzw. CACM, zasada działania pokazana na poprzednich slajdach)ftp://ftp.cpsc.ucalgary.ca/pub/projects/ar.cod/cacm-87.shar • Moffat, Neal, Witten (1998) (udoskonalony CACM, bez dzielenia, mniej mnożeń, shift, +, –) http://www.cs.mu.oz.au/~alistair/arith_coder/ • MQ Coder (binarny, opatentowany /IBM i in./, użyty w JBIG2, JPEG2000 i innych) • Range Coder (szybki, prosty, alfabety wielosymbolowe) http://www.compressconsult.com/rangecoder/

  22. Binarny koder arytmetycznyMQ Coder • Kodujemy symbole alfabetu binarnego • bardzo proste modelowanie, • nie trzeba liczyć prawdopodobieństwa kumulatywnego • wystarczy szacować prawdopodobieństwo tylko jednego symbolu • bardzo proste kodowanie • nowy symbol to zmiana tylko jednego kresu przedziału • podprzedział o długości M/2 zawsze jest całkowicie zawarty w górnej lub dolnej połówce przedziału [0, M] (przy odpowiedniej normalizacji)

  23. MQ Coder – dalsze uproszczenia • normalizacja utrzymuje długość podprzedziału między 0.75 a 1.5, średnio 1.0 • unikamy mnożenia; nowa długość podprzedziału dla prawdopodobieństwa p, to nie p * stara_długość, a po prostu p • faktycznie kodujemy alfabet {MPS, LPS} – czyli bardziej i mniej prawdopodobny symbol; to, czy MPS to 0 czy 1 jest określa flaga uaktualniana po każdym symbolu • pojawienie się LPS to zawsze skalowanie i wyprowadzenie bitu • MPS może, ale nie musi powodować skalowania i wyprowadzania bitów • model szacuje tylko prawdopodobieństwo LPS • jest ściśle powiązany z koderem i jest aktualizowany tylko w razie normalizacji • prawdopodobieństwo LPS pamiętane z niewielką precyzją (np. 7 bitów)precyzja jednocześnie odpowiada za adaptacyjność modelu (szybkość zapominania) • aktualizacja modelu również bez mnożeń, stablicowane prawdopodobieństwa po normalizacji wywołanej przez LPS/MPS (2 tablice indeksowane prawdopodobieństwem LPS)

  24. MQ Coder • bardzo szybki • dla większych alfabetów symbol kodowany jest jako ciąg bitów • co nadal jest szybkie • niewielkie wymagania pamięciowe • szczególnie istotne dla modelu; model dla kontekstu pamięta jedynie: • prawdopodobieństwo LPS (np. 7 bitów) • który bit jest LPS (1 bit) • można stosować złożone modele z wielką liczbą kontekstów • mimo uproszczeń, efektywność kodowania bliska 100%

  25. Range Coder – koncepcja • Martin (1979) • Koncepcja opracowana niezależnie od klasycznego kodowania arytmetycznego • podział pewnego przedziału liczb analogicznie jak w kodowaniu arytmetycznym, ale • przedział liczb całkowitych • odpowiednio duży przedział, np. [0, 1000000] • po przetworzeniu ciągu wyprowadzamy najbardziej znaczące cyfry pewnej liczby z wnętrza przedziału(nie wszystkie, wystarczające do jednoznacznego określenia przedziału)

  26. Range Coder – realizacja • Zakodowanie ciągów dłuższych niż bardzo krótkie, wymagałoby przedziału zbyt wielkiego by jego krańce reprezentować wprost jako liczby • używamy przedziału reprezentowalnego jako liczba o stałej precyzji w systemie n-arnym; gdy aktualna długość przedziału spada • wyprowadzamy pokrywające się najbardziej znaczące cyfry kresów • odpowiednio skalujemy przedział mnożąc jego kresy przez podstawę systemu liczbowego • wygląda znajomo? • Otrzymujemy koder podobny do kodera CACM • inna (szybsza) operacja normalizacji • nadal nie trywialna, mogą wystąpić niedomiary, zliczmy je (analogia do licznikaBitów) • alfabet kodu to cyfra w systemie n-arnym • n=256, a więc we/wy bajtowe, prostsze i szybsze niż bitowe w CACM • precyzja podziału przedziału na podprzedziały typowo mniejsza niż np. w CACM • Shindler: http://www.compressconsult.com/rangecoder(koder, dekoder, prosty model bezpamięciowy, przykłady)

  27. Szybki model dla kodera arytmetycznego • Potrzebne operacje • dla si wyznacz Pi-1 • dla si wyznacz pi • dla Pi-1 wyznacz si (dekodowanie) powyższe łatwe do zrealizowania, gdy potrafimy szybko wyznaczyć Ci– łączną liczbę wystąpień symboli sx, x≤i • uaktualnij model (po przetworzeniu si) • podziel liczniki w modelu (zwykle przez 2)

  28. Struktura Fenwicka • dla alfabetu n symboli, tablica T [0..n-1] • komórka o indeksie i zawiera sumę liczb wystąpień symboli od i – 2j + 1 do i gdzie j to pozycja najmniej znaczącej jedynki w binarnie zakodowanym i • np. i = 6 = 110b, j = 1 • 2j = i & – i

  29. Struktura Fenwicka

  30. Struktura Fenwicka • Fenwick • złożoność pamięciowa: n • złożoność czasowa • dla si wyznacz Pi-1 O(log2n) • dla si wyznacz pi O(1) • dla Pi-1 wyznacz siO(log2n) • uaktualnij model O(log2n) • podziel liczniki w modelu O(log2n)

  31. Struktura Moffata • W tablicy sumowanie „w przód” • złożoność pamięciowa: n (z sortowaniem 3n) • złożoność czasowa • dla si wyznacz Pi-1 O(log2i) • dla si wyznacz pi O(1) • dla Pi-1 wyznacz siO(log2i) • uaktualnij model O(log2i) • podziel liczniki w modelu O(log2n) (w praktyce struktury podobnie szybkie, Moffata będzie szybsza gdy alfabet będzie naturalnie posortowany wg rosnących częstości występowania symboli)

More Related