[1] O documento introduz os conceitos básicos de códigos convolucionais e corretores de erros, incluindo suas classificações, taxas de código, esquemas de codificação e decodificação. [2] É apresentada uma cronologia histórica dos principais desenvolvimentos dos códigos convolucionais, desde 1955 até 1967. [3] São descritos em detalhes códigos convolucionais para correção de erros em salva, definindo suas capacidades, espaço de guarda, interleaving e exemplos de códigos como Berlekamp-
Códigos convolucionais: correção de erros em salva
1. Códigos Convolucionais
Mauro Tapajós Santos (1/1996)
Introdução
Existem duas classificações básicas para codigos corretores de erro: códigos de
bloco e códigos de "árvore".
Um códigos de bloco é o mapeamento de k símbolos de entrada em n símbolos de
saída. O número n pode ser maior ou igual a k, se for maior, os símbolos a mais são
redundantes com finalidades de prover deteção e/ou correção de erros. Este codificador
não possue memória, pois a cada grupo de k símbolos é gerado um grupo de n símbolos
definido.
Códigos de árvore são caracterizados por serem gerados num codificador que
possua memória. Os códigos convolucionais são um subconjunto dos códigos de árvore.
O codificador convolucional aceita k símbolos na entrada e produz n símbolos na
saída que são gerados em função de v + k símbolos de entrada. O sistema possui memória
em função de v ser maior que zero. O valor R = k / n é definido como a taxa de código.
Esquema do codificador convolucional
Um exemplo é dado a seguir.
1
2. Exemplo: Codificador Convolucional com k = 1, n = 2 e memória de 3 símbolos (m = 3)
o código é gerado inserindo-se um bit de dado no circuito e o comutador da saída efetua
uma rotação completa. Este código apresenta taxa de R = k/n =½. A decodificação é feita
continuamente. Uma outra maneira de se entender a decodificação é o percurso através de
uma árvore de código. Cada ramo percorrido é associado a um bit ou grupo de bits. No
final, os bits decodificados estarão nas "folhas" da árvore.
A matriz "check" de paridade H de um código convolucional (mn0,mk0) com
distância mínima d pode ser associado com a matriz H de um código de blocos linear de
mesmo comprimento e com o mesmo número de símbolos.
Cronologia
1955 - Elias ("Coding for noisy channels"): primeira idéia sobre códigos
convolucionais.
1959 - Hagelbarger: primeira idéia sobre códigos convolucionais corretores de
erros em salva.
1961/63 - Wozencraft, Reiffen e Fano: desenvolveram e aprimoraram o
primeiro algoritmo decodificador para códigos convolucionais.
2
3. 1963 - Wyner e Ash: definiram códigos com capacidade de correção de erros
em salva B2 e seus limites.
1965 - Pinsker ("On the complexity of decoding"): refutou a hipótese de que,
para códigos com taxa maior que Rcomp (teórica taxa limite para se limitar a média
de computações), não se poderia desenvolver algoritmos que funcionassem
adequadamente no intervalo entre Rcomp e a capacidade do canal.
1967 - Viterbi ("Error bounds for convolutional codes and an
asymptotically optimum decoding algorithm"): desenvolveu um algoritmo
efetivo na decodificação de códigos convolucionais com pequeno K (constraint
length). Este algoritmo ficou conhecido como "algoritmo de Viterbi".
Códigos Convolucionais para Correção de Erros em Salva
Definições
Capacidade de correção de salvas tipo-B2 : um código convolucional (mn0,mk0)
é dito ter capacidade de correção de salvas tipo-B2 (B2 = rn0) se todas as salvas de
comprimento B2 confinadas em r blocos consecutivos são corrigíveis e pelo menos uma
salva de comprimento (r+1)n0 não é corrigível. A Capacidade de Correção de Salvas (b)
destes tipos de códigos respeita a relação b2 ( n0 1) b b2 ( n0 1) , o que pode ser
checado a partir da definição acima. Este valor está limitado a
( m 1)( n 0 k 0 )
b n0 1
k0
(1 )
n0
Quanto maior este número, maior será a capacidade de correção de erros em
salvas (salvas de maior comprimento).
Espaço de guarda do código (g) : uma salva de comprimento l < b é corrigível
desde que seja sucedida por um conjunto mínimo de símbolos. O maior número necessário
3
4. para corrigir qualquer salva corrigível é chamado de Espaço de guarda do Código. Este
valor é função de como o código é decodificado e é preferível minimizado ao máximo,
pois erros durante este período podem causar decodificação errada. Para qualquer código
(n,k), este número está limitado a g n 1 , para muitos códigos g = n - b.
Interleaving : os códigos normalmente são desenvolvidos para a correção de
erros isolados dentro de um certo bloco de símbolos. Alguns canais podem apresentar
ruídos que se traduzem em grandes sequências de erros seguidos (salvas), gerando
sequências de erros também na saída do decodificador. Uma forma de minimizar esta
situação é a técnica de Interleaving, onde os símbolos de um determinado bloco são
"embaralhados" dentro do fluxo de símbolos, de maneira que, no decodificador, estes
possam ser reagrupados. Desta maneira, os erros em salva produzidos pelo ruído do canal
se transformarão em vários erros isolados dentro de blocos de símbolos independentes, e
poderão ser corrigidos.
Grau de Interleaving (i) : é a quantidade de "subfluxos" no qual o fluxo de dados
real é efetivamente dividido. Existem dois tipos de Interleaving: de símbolos e de blocos.
No primeiro o 0 símbolo, o (i+1)-ésimo, o (2i+1)-ésimo, etc.. são codificados
independentemente dos outros símbolos. No caso por blocos, blocos de n0 símbolos
separados por i blocos formam um fluxo independente de dados. Note que se b < n0 será
impossível efetuar interleave de blocos, visto que, o código não terá capacidade de
corrigir salvas maiores que o tamanho do bloco.
Proceder "Interleaving" sobre um código convolucional (mn0,mk0) com capacidade
de correção de erros em salva b gerará um código (mn0(i-1)+n0 , mk0(i-1)+k0) com bi = bi.
A taxa de código antes e depois é exatamente a mesma.
Códigos Berlekamp-Preparata-Massey
Estes códigos apresentam 1 bit de paridade por bloco. Os códigos básicos
possuem capacidade de correção de salvas tipo-B2 com b2 = n0 para qualquer valor
escolhido de n0. Códigos com capacidades maiores podem ser construídos por meio de
"Interleaving".
4
5. Os códigos básicos tem relação ( 2 n0 ,2 n0 2n0 ) e matriz "check" de paridade na
2 2
forma:
H [ B0 B1 B2 ... B2 N 0 1 ]
onde Bi é relacionada com Bi-1 da seguinte forma:
0 0 0 ... 0
1 0 0 ... 0
0 1 0 ... 0
Bi Bi1
0 0 1 ... 0
0
0 0 0 1 0
Para este código ter b2 = n0, nenhuma palavra diferente de zero pode ter todos os
seus 1's confinados ao bloco 0 e outro bloco qualquer. Uma palavra deste tipo pode ser
representada por:
E = E0 0 0 0 ... Ei 0 0 ... 0
onde E0 é diferente de zero.
Se B0 pode ser escolhido de maneira que EHt seja não-zero para todos os valores
de E0 0, Ei e i, então o código terá b2 = n0.
Para que isto ocorra, devemos ter:
E0 Ei [B0 Bi]t 0 ; 1 i 2n0 1
Para n0 i 2n0 1 , o quadrante superior direito de [B0 Bi] é a matriz de zeros
de ordem n0. Assim, escolhemos a metade superior de B0 não-singular para a equação
acima valer. Para simplificação da decodificação escolhemos esta como a matriz
identidade, chamada de In0.
Para 1 i n0 1 , as matrizes [B0 Bi] devem ser simultaneamente não-singulares
para a equação acima valer. Procedimentos matriciais elementares reduzem esta matriz a:
I n0 Xi
0 Yi
5
6. Nesta forma, [B0 Bi] só será não-singular se, e somente se, Yi for não-singular. Já
existem matrizes Yi calculadas para vários valores de n0.
Note que, códigos deste tipo necessitam que o bit de paridade seja transmitido
antes dos bits de informação do bloco.
Os códigos com k0 = n0 - 1 construídos segundo acima chegam ao limite de b2.
Códigos com k0 < n0 - 1 podem ser construídos da mesma forma ou segundo um artifício:
fazendo "interleave" de bloco de dois códigos com capacidades b1 e b2 ,de forma a termos
um terceiro código com n03 = n01 + n02, k03 = k01 + k02 e m3 = max(m1,m2). Este artifício
constrói códigos onde nem k0, nem n0 - k0 sejam 1.
A decodificação de códigos BPM funciona da seguinte maneira: assuma uma salva
no 0-ésimo bloco, os primeiros n0 bits da síndrome serão iguais ao padrão de erro
adicionado ao bloco, por que a metade superior da matriz é a matriz identidade de ordem
n0. A segunda parte da síndrome deverá ser:
s2 = E0 [ B02 ]t
onde s2 é a segunda metade da síndrome, E0 é a salva e B02 é a metade inferior de B0.
Já que s1 é idêntica a E0, se for verdade:
s2 + s1 [ B02 ]t = 0
então a salva ocorreu no 0-ésimo bloco.
Procedendo "Interleave" sobre um código BPM básico, chega-se aos seguintes
parâmetros:
m = (2n0 - 1)i + 1
n = mn0 = (2n0 - 1)n0i + n0
k = mk0
b2 = in0
b = b2 - (n0 - 1) = n0(i - 1) + 1
6
7. g = n - 1 ou n - b2
Para grandes valores de m, a capacidade de correção de salvas destes códigos
aproximam do limite.
A decodificação básicas para códigos BPM "Interleave" é decodificar
independentemente os i fluxos de bits. O tempo de guarda é de n - 1 bits
Códigos Iwadare
Códigos deste tipo são definidos com k0 = n0 - 1. Comparados aos códigos BPM
são mais simples de serem implementados ao preço de um espaço de guarda maior. O
código Iwadare básico apresenta:
n0 ( n0 1)
m ( 2 n0 1)
2
k0 n0 1
b n0
g n 1
para qualquer escolha de n0 2. Estes códigos básicos corrigem todas as salvas de
comprimento n0.
A matriz "check" de paridade é especificada pela matriz B0:
7
8. 0 ... 0 0 0 1
0 ... 0 0 0 0
. . .
0 0 ... 0 0 0 0
0 ... 0 0 1 0
0 ... 0 0 1 0
0 ... 0 1 0 0
B0 0 ... 0 0 0 0
0 ... 0 1 0 0
0 1 ... 0 0 0 0
1 0 ... 0 0 0 0
0 0 ... 0 0 0 0
1 0 ... 0 0 0 0
a j-ésima coluna de B0 ( 1 j n0 1 ), tem 1's somente nas posições:
( n 0 j )( n0 j 1) ( n j )( n0 j 1)
n0 e n0 0 n0 j
2 2
A decodificação é feita de maneira diferenciada onde cada símbolo é decodificado
em tempos diferentes. A decodificação do (n0 - 1)-ésimo símbolo é feita depois de serem
recebidos n0 + 2 blocos; a decodificação do (n0 - 2)-ésimo símbolo é feita depois de serem
recebidos n0 + 2 + 3 blocos; e o primeiro símbolo depois de n0 + 2 + 3 + ... + n0 blocos.
Assim, a decodificação é efetuada em n0 - 1 passos.
Exemplo: n0 = 3, a matriz H para um código Idaware (24,16) com capacidade de
correção de erros em salva b = 3 será
8
9. 001
000 001
000 001
000 001
H
000 001
100 001
000 100 010 001
100 100 010 010 001
onde os vazios são preenchidos com zeros. O circuito decodificador para este
código é mostrado a seguir:
Circuito decodificador para o código Iwadare (24,16)
"Interleave" sobre um código Iwadare com grau i resulta na inserção de i - 1 linhas
nulas na matriz B0 imediatamente após sua segunda linha e suas linhas originais não-nulas
com exceção da última.
O código resultante do processo de "interleave" terá:
9
10. n 0 ( n0 1)
m ( 2n0 1)i
2
k0 n0 1
b in 0
g n 1
O espaço de guarda será o mesmo que o caso sem "interleave": n - 1.
Códigos de Baixa Taxa
Os melhores códigos corretores de salvas com taxas baixas possuem os seguintes
parâmetros:
m3
n n0 m 3n0
n 1 n 1
b[ ] n0 [ 0 ]
2 2
k0 1
g n 1
A matriz B0 para estes códigos tem a forma:
a I n 0 1
B0 b On0 1
c On0 1
onde a é a coluna nula de tamanho n0 - 1, b é a coluna de tamanho n0 - 1 formada por
zeros e um único 1 na posição n0 / 2 e c é formada de zeros exceto na posição n0 - 1.
A decodificação é direta: se ocorrer uma salva de comprimento b ou menor, os
dois "check" do bit de informação do primeiro bloco estarão errados. Caso contrário, um
dos, ou ambos estarão corretos. Se o bit de informação do segundo bloco estiver em erro,
10
11. ele será corrigido da mesma maneira depois que o primeiro bloco for deslocado para fora
do decodificador.
Se procedermos "Interleaving" nos códigos mostrados teremos:
m 2i 1
n n0 m
n 1 n 1
b[ ] in0 [ 0 ]
2 2
k0 1
g n 1
para qualquer escolha de n0 e i.
Códigos Para Correção de Erros em Salvas e Erros Aleatórios
Estes códigos visam a correção de erros não restritos a uma salva somente. As
técnicas utilizadas podem ser divididas em:
1. Proceder "interleaving" sobre um código corretor de erros de pequeno
comprimento.
2. Construir um código com certa capacidade de correção de erros em salva e
de erros randômicos.
3. decodificação "adaptativa", onde o decodificador tenta determinar o tipo
de erro que ocorreu e tenta corrigi-lo.
"Interleave" de blocos com grau i sobre um código convolucional com capacidade
t de correção de erros randômicos produz um código convolucional mais longo com
capacidade de corrigir salvas de comprimento até [t/n0]i além dos erros randômicos.
Um exemplo de código "misto" que combina ambas as capacidades são os códigos
auto-ortogonais difusos. Estes estão no meio termo entre os extremos dos códigos auto-
ortogonais que possuem capacidade de correção de erros randômicos t, porém com
capacidade de correção de salvas pouco maior que t; e os códigos Idaware que
apresentam grande capacidade de correção de salvas porém com t = 1.
11
12. Forney e outros apresentaram um procedimento "adaptativo" para correção de
erros mistos baseado num código com capacidade de correção de erros randômicos t. O
decodificador terá um circuito que detectará a ocorrência de uma salva de erros passando
para um modo "salva". Após este circuito ter notado o fim da salva de erros, ele chaveia o
decodificador para voltar ao seu "modo natural randômico". Para este esquema, a razão
da maior capacidade de correção de erros em salva com o espaço de guarda é :
b 2N
g 2N m
Note que, nem todas as salvas de comprimento menor ou igual a 2N são
corrigidas.
12