Obcięte kodowanie binarne

Obcięte kodowanie binarne to kodowanie entropijne, zwykle używane do jednolitych rozkładów prawdopodobieństwa ze skończonym alfabetem. Jest sparametryzowany alfabetem o łącznej wielkości liczby n . Jest to nieco bardziej ogólna forma kodowania binarnego , gdy n nie jest potęgą dwójki .

Jeśli n jest potęgą dwójki, to zakodowana wartość dla 0 ≤ x < n jest prostym kodem binarnym dla x o długości log 2 ( n ). W przeciwnym razie niech k = podłoga(log 2 ( n )), tak że 2 k < n < 2 k +1 i niech u = 2 k +1 n .

Skrócone kodowanie binarne przypisuje pierwszym symbolom u słów kodowych o długości k , a następnie przypisuje pozostałym symbolom n - u ostatnie słowa kodowe n - u o długości k + 1. Ponieważ wszystkie słowa kodowe o długości k + 1 składają się z nieprzypisanego słowa kodowego o długości k z dodaną cyfrą „0” lub „1” wynikowy kod jest kodem prefiksu .

Historia

Używane od co najmniej 1984 r. kody fazowe , znane również jako kody ekonomiczne , są również znane jako obcięte kodowanie binarne.

Przykład z n = 5

Na przykład dla alfabetu {0, 1, 2, 3, 4} n = 5 i 2 2 n < 2 3 , stąd k = 2 i u = 2 3 − 5 = 3. Skrócone kodowanie binarne przypisuje pierwsze u symbolizuje słowa kodowe 00, 01 i 10, wszystkie o długości 2, a następnie przypisuje ostatnie n - symbole u symboli słów kodowych 110 i 111, dwa ostatnie słowa kodowe o długości 3.

Na przykład, jeśli n wynosi 5, zwykłe kodowanie binarne i obcięte kodowanie binarne przydziela następujące słowa kodowe . Cyfry pokazane jako przekreślone nie są przesyłane w obciętym formacie binarnym.


Obcięty plik binarny
Kodowanie
Standardowy plik binarny
0 0 0 0 0
1 0 0 1 1
2 0 1 0 2
NIE UŻYWANY 0 1 1 3
NIE UŻYWANY 1 0 0 4
NIE UŻYWANY 1 0 1 5/NIEUŻYWANE
3 1 1 0 6/NIEUŻYWANE
4 1 1 1 7/NIEUŻYWANE

Zakodowanie n przy użyciu prostego kodowania binarnego zajmuje 3 bity, stąd 2 3 n = 8 − 5 = 3 są nieużywane.

W kategoriach liczbowych, aby wysłać wartość x , gdzie 0 ≤ x < n , i gdzie jest 2 k n < 2 k +1 symboli, istnieje u = 2 k +1 n niewykorzystanych wpisów, gdy rozmiar alfabetu jest zaokrąglony do najbliższej potęgi dwójki. Proces kodowania liczby x w obciętym systemie binarnym jest następujący: jeśli x jest mniejsze niż u , zakoduj ją w k bitach binarnych; jeśli x jest większe lub równe u , zakoduj wartość x + u w k + 1 bitach binarnych.

Przykład z n = 10

Inny przykład, kodowanie alfabetu o rozmiarze 10 (między 0 a 9) wymaga 4 bitów, ale jest 2 4 - 10 = 6 niewykorzystanych kodów, więc wartości wejściowe mniejsze niż 6 mają pierwszy bit odrzucony, podczas gdy wartości wejściowe większe lub równe do 6 są przesunięte o 6 do końca przestrzeni binarnej. (Niewykorzystane wzory nie są pokazane w tej tabeli).


Wprowadź wartość
Zrównoważyć Wartość przesunięcia

Standardowy plik binarny

Obcięty plik binarny
0 0 0 0000 000
1 0 1 0001 001
2 0 2 0010 010
3 0 3 0011 011
4 0 4 0100 100
5 0 5 0101 101
6 6 12 0110 1100
7 6 13 0111 1101
8 6 14 1000 1110
9 6 15 1001 1111

Aby zdekodować, przeczytaj pierwsze k bitów. Jeśli zakodują wartość mniejszą niż u , dekodowanie jest zakończone. W przeciwnym razie przeczytaj dodatkowy bit i odejmij u od wyniku.

Przykład z n = 7

Oto bardziej ekstremalny przypadek: przy n = 7 następną potęgą 2 jest 8, więc k = 2 i u = 2 · 3 - 7 = 1:


Wprowadź wartość
Zrównoważyć Wartość przesunięcia

Standardowy plik binarny

Obcięty plik binarny
0 0 0 000 00
1 1 2 001 010
2 1 3 010 011
3 1 4 011 100
4 1 5 100 101
5 1 6 101 110
6 1 7 110 111

Ten ostatni przykład pokazuje, że wiodący bit zerowy nie zawsze oznacza krótki kod; jeśli u < 2 k , niektóre długie kody będą zaczynać się od bitu zerowego.

Prosty algorytm

Wygeneruj skrócone kodowanie binarne dla wartości x , 0 ≤ x < n , gdzie n > 0 to rozmiar alfabetu zawierającego x . n nie musi być potęgą dwójki.

     

	
	   0   
	          

	
	    string  TruncatedBinary  (  int  x  ,  int  n  )  {  // Ustaw k = floor(log2(n)), tj. k takie, że 2^k <= n < 2^(k+1).  int  k  =  ,  t  =  n  ;  podczas gdy  (  t  >  1  )  {  k  ++  ;  t  >>=  1  ;  }  // Ustaw u na liczbę nieużywanych słów kodowych = 2^(k+1) - n.  int  u  =  (  1       

	   
           
    
              
 <<  k  +  1  )  -  n  ;  if  (  x  <  u  )  powrót  Binarny  (  x  ,  k  );  w przeciwnym razie  zwróć  Binarny  (  x  +  u  ,  k  +  1  ));  } 

Rutynowy plik binarny ma charakter ekspozycyjny; zwykle pożądane są tylko skrajne prawe bity długości zmiennej x . Tutaj po prostu wyprowadzamy kod binarny dla x za pomocą len bitów, dopełniając zerami wysokiego rzędu, jeśli to konieczne.

     

	   
	   0 
		 
                
		      
		
		  
	
	  string  Binarny  (  int  x  ,  int  len  )  {  string  s  =  ""  ;  podczas gdy  (  x  ! =  )  {  jeśli  (  parzyste  (  x  ))  s  =  '0'  +  s  ;  inaczej  s  =  '1'  +  s  ;  x  >>=  1  ;  }  podczas  (   
            
	 
 s  .  Długość  <  długość  )  s  =  '0'  +  s  ;  zwróć  s  ;  } 

O wydajności

Jeśli n nie jest potęgą dwójki, a symbole k -bitowe są obserwowane z prawdopodobieństwem p , to symbole ( k + 1)-bitowe są obserwowane z prawdopodobieństwem 1 − p . Możemy obliczyć oczekiwaną liczbę bitów na symbol

Surowe kodowanie symbolu ma bity Wtedy względna oszczędność miejsca s (patrz Współczynnik kompresji danych ) kodowania może być zdefiniowana jako

W uproszczeniu to wyrażenie prowadzi do

że względna wydajność obciętego kodowania binarnego wzrasta wraz ze wzrostem prawdopodobieństwa p k -bitowych symboli , a symbolu kodowania surowego maleje.

Zobacz też