Vejamos uma maneira um pouco diferente de pensar sobre a codificação de Huffman.
Suponha que você tenha um alfabeto de três símbolos, A, B e C, com probabilidades 0,5, 0,25 e 0,25. Como as probabilidades são todas as potências inversas de dois, esse código Huffman é ideal (ou seja, é idêntico à codificação aritmética). Usaremos o código canônico 0, 10, 11 para este exemplo.
Suponha que nosso estado seja um número inteiro grande, que chamaremos de . Você pode pensar em codificação como uma função que pega o estado atual e um símbolo para codificar e retorna o novo estado:s
codificar ( s , A )codificar ( s , B )codificar (s) , C)= 2 s= 4 s + 2= 4 s + 3
Então, vamos começar com o estado 11 (que é 1011 em binário), codifique o símbolo B. O novo estado é 46, que é 101110 em binário. Como você pode ver, esse é o estado "antigo", com a sequência 10 adicionada ao final. Temos essencialmente "saída" da sequência de bits 10.
Por enquanto, tudo bem.
Agora pense por um momento sobre como a codificação aritmética funciona. Se você colocar as probabilidades sobre um denominador comum, o símbolo A realmente representa o intervalo , o símbolo B representa o intervalo[2[ 04, 24)e o símbolo C representa o intervalo[3[ 24, 34).[ 34, 44)
Basicamente, o que estamos fazendo aqui é multiplicar tudo pelo denominador comum. Imagine que o estado estava realmente na base 4. A codificação de um símbolo B está realmente gerando o dígito 2 nessa base, e a codificação de um símbolo C está gerando o dígito 3 nessa base.
No entanto, o símbolo A é um pouco diferente, porque não é um dígito inteiro na base 4.
Em vez disso, podemos pensar no alfabeto como o conjunto de símbolos A_0, A_1, B, C, com igual probabilidade. Isso, novamente, possui um código Huffman ideal 00, 01, 10, 11. Ou, novamente, podemos pensar nisso na base 4. Para codificar um símbolo, basta:
codificar (s, A0 0)codificar (s, A1 1)codificar ( s , B )codificar (s,C)= 4 s + 0= 4 s + 1= 4 s + 2= 4 s + 3
UMA0 0UMA1 1
s
s′= ⌊ s2⌋
i = s mod 2
codificar ( s)′, AEu)
s = 11s′= 5i = 1codificar (5, A1 1) = 4 × 5 + 1 = 21
Agora isso não produz exatamente a mesma saída de bits da codificação Huffman, mas gera uma saída que tem o mesmo comprimento. E o que eu espero que você possa ver é que isso também é decodificável. Para decodificar um símbolo, pegamos o restante quando dividido por 4. Se o valor for 2 ou 3, o símbolo será B ou C, respectivamente. Se for 0 ou 1, o símbolo é A e, em seguida, podemos colocar o bit de informações de volta multiplicando o estado por 2 e adicionando 0 ou 1.
3525
codificar (s, A0 0)codificar (s, A1 1)codificar (s, A2)codificar (s, B0 0)codificar (s, B1 1)= 5 s + 0= 5 s + 1= 5 s + 2= 5 s + 3= 5 s + 4
s′= ⌊ s3⌋i = s mod 3codificar ( s)′, AEu)
pq
A razão pela qual é uma família de métodos de codificação é que o que vimos aqui é impraticável por si só; ele precisa de algumas modificações para lidar com o fato de que você provavelmente não possui números inteiros de precisão infinita para manipular a variável state com eficiência, e existem várias maneiras de conseguir isso. A codificação aritmética, é claro, tem um problema semelhante com a precisão de seu estado.
As variantes práticas incluem rANS (o "r" significa "proporção") e tANS ("orientado a tabelas").
O ANS tem algumas vantagens interessantes sobre a codificação aritmética, tanto práticas quanto teóricas:
- Ao contrário da codificação aritmética, o "estado" é uma única palavra, e não um par de palavras.
- Não apenas isso, mas um codificador ANS e seu decodificador correspondente têm estados idênticos e suas operações são completamente simétricas. Isso levanta algumas possibilidades interessantes, como a possibilidade de intercalar diferentes fluxos de símbolos codificados e tudo sincronizar perfeitamente.
- As implementações práticas precisam, é claro, de "produzir" informações à medida que você avança, e não apenas coletá-las em um grande número inteiro para serem gravadas no final. No entanto, o tamanho da "saída" pode ser configurado em troca da perda de compactação (geralmente modesta). Portanto, onde os codificadores aritméticos devem produzir um pouco de cada vez, o ANS pode produzir um byte ou um nybble por vez. Isso oferece uma troca direta entre velocidade e compactação.
- Parece ser tão rápido no hardware da geração atual quanto a codificação aritmética binária e, portanto, competitiva com a codificação Huffman. Isso o torna muito mais rápido que a codificação aritmética de alfabeto grande e suas variantes (por exemplo, codificação por faixa).
- Parece estar livre de patentes.
Acho que nunca mais vou fazer codificação aritmética.