Codificação aritmética: diferenças entre revisões
Conteúdo apagado Conteúdo adicionado
Linha 1:
{{Wikificação|data=julho de 2010}}
[[Algoritmo]] para compressão de dados, não-baseado em tabelas de símbolos
A partir de um modelo estatístico, constrói-se uma tabela onde são listadas as probabilidades de o próximo símbolo lido ser cada um dos possíveis símbolos. Em geral esta probabilidade é simplesmente a contagem de todas as ocorrências do símbolo no arquivo dividida pelo tamanho do arquivo:
Linha 10:
onde <math>P(\sigma)</math> é a probabilidade de ocorrência do símbolo <math>\sigma</math>, <math>n_{\sigma}</math> é o número de ocorrências desse símbolo e <math>N</math> é o tamanho do arquivo. Em contextos específicos (ao associar a codificação aritmética com outros métodos de compressão como o [[BWT]] por exemplo) outros modelos mais apropriados podem ser adotados, que desprezam parte do contexto, ou usam probabilidades determinadas dinamicamente a medida que o arquivo é processado.
Esta tabela é expressa na forma de intervalos cumulativos, de tal forma que se ordenarmos os símbolos em uma ordem qualquer, o início do intervalo de um símbolo coincide com o final do intervalo do símbolo anterior. O primeiro símbolo tem seu intervalo começado em 0 e o último símbolo tem seu intervalo terminado em 1. Sejam os símbolos ordenados de 1 a N chamados
<math>
Linha 18:
[[Imagem:Arithmetic encoding.svg|thumb|300px|Diagrama representando a subdivisão dos intervalos na codificação aritmética, usando-se quatro símbolos de probabilidades 0.6, 0.2, 0.1, e 0.1. Os círculos negros representam a mensagem codificada, que pode ser decodificada para o primeiro símbolo, depois o terceiro, em seguida o quarto. A primeira linha mostra o intervalo completo [0,1) enquanto as linhas subsequentes mostram as subdivisões proporcionais do intervalo anterior.]]
O algoritmo de codificação aritmética consiste em representar a probabilidade de ocorrência de cada
A saída do algoritmo é então um valor que esteja contido neste intervalo e possa ser representado com o menor número possível de dígitos. Na prática não se tenta encontrar o menor número de dígitos, mas apenas um número razoável de dígitos.
Linha 27:
# Cria-se um intervalo corrente iniciado com [0,1)
# Para cada elemento da mensagem:
## Particiona-se o intervalo corrente em
## O
#Codifica-se a mensagem com o menor número de bits necessário para distinguir o intervalo corrente final de todos os outros possíveis intervalos correntes finais.
Linha 45:
'''low''' = 0000
Representando nosso intervalo inicial. Para cada
new_low = low + (high-low+1) * prob_inicial
new_high = low + (high-low+1) * prob_final - 1
onde '''new_low''' e '''new_high''' são os novos valores para '''low''' e '''high''', e '''prob_inicial''' e '''prob_final''' são
* Caso o primeiro dígito (o dígito mais a esquerda) dos dois valores, '''low''' e '''high''' venha a se tornar idêntico, sabemos que ele não mais mudará<ref name="prova" /> e com isso podemos eliminá-lo dos nossos cálculos e escrevê-lo na saída do nosso programa.
Linha 80:
Essa situação é chamada de ''underflow''. A solução para esse caso também é simples: mantemos um contador para as vezes onde ela acontece e eliminamos o segundo dígito de '''low''' e '''high'''. Quando o primeiro dígito dos dois números se igualarem, emitimos normalmente o dígito que se igualou e então verificamos:
* se ele se igualou "para cima", ou seja foi o primeiro dígito de '''low''' que cresceu para se igualar ao primeiro dígito de '''high''', então emitimos uma seqüência de dígitos 0 do tamanho do contador (se o contador for 3, emitimos 000, se for 4 emitimos 0000 e assim por diante).
* se ele se igualou "para baixo" emitimos a mesma
No momento da descompressão basta seguir o mesmo procedimento, ignorando os dígitos introduzidos pela técnica acima
== Exemplo ==
O quadro abaixo mostra um exemplo de codificação
{|
|