En telecomunicaciones , un código convolucional es un tipo de código de corrección de errores que genera símbolos de paridad mediante la aplicación deslizante de una función polinómica booleana a un flujo de datos. La aplicación deslizante representa la "convolución" del codificador sobre los datos, lo que da lugar al término "codificación convolucional". La naturaleza deslizante de los códigos convolucionales facilita la decodificación de enrejado mediante un enrejado invariante en el tiempo. La decodificación de enrejado invariante en el tiempo permite que los códigos convolucionales se decodifiquen mediante decisión suave de máxima verosimilitud con una complejidad razonable.
La capacidad de realizar una decodificación económica de decisión suave de máxima verosimilitud es uno de los principales beneficios de los códigos convolucionales. Esto contrasta con los códigos de bloque clásicos, que generalmente se representan mediante un enrejado variable en el tiempo y, por lo tanto, se decodifican típicamente mediante decisión dura. Los códigos convolucionales a menudo se caracterizan por la tasa de código base y la profundidad (o memoria) del codificador . La tasa de código base generalmente se da como , donde n es la tasa de datos de entrada sin procesar y k es la tasa de datos del flujo codificado del canal de salida. n es menor que k porque la codificación del canal inserta redundancia en los bits de entrada. La memoria a menudo se denomina "longitud de restricción" K , donde la salida es una función de la entrada actual y de las entradas anteriores. La profundidad también se puede dar como el número de elementos de memoria v en el polinomio o el número máximo posible de estados del codificador (normalmente: ).
Los códigos convolucionales suelen describirse como continuos. Sin embargo, también se puede decir que los códigos convolucionales tienen una longitud de bloque arbitraria, en lugar de ser continuos, ya que la mayor parte de la codificación convolucional del mundo real se realiza en bloques de datos. Los códigos de bloque codificados convolucionalmente suelen emplear terminación. La longitud de bloque arbitraria de los códigos convolucionales también se puede contrastar con los códigos de bloque clásicos , que generalmente tienen longitudes de bloque fijas que están determinadas por propiedades algebraicas.
La tasa de código de un código convolucional se modifica comúnmente mediante la perforación de símbolos . Por ejemplo, un código convolucional con una tasa de código "madre" se puede perforar a una tasa más alta, por ejemplo, simplemente al no transmitir una parte de los símbolos de código. El rendimiento de un código convolucional perforado generalmente se escala bien con la cantidad de paridad transmitida. La capacidad de realizar una decodificación de decisión suave económica en códigos convolucionales, así como la longitud de bloque y la flexibilidad de la tasa de código de los códigos convolucionales, los hace muy populares para las comunicaciones digitales.
Los códigos convolucionales fueron introducidos en 1955 por Peter Elias . Se pensaba que los códigos convolucionales podían ser decodificados con una calidad arbitraria a expensas del cálculo y el retraso. En 1967, Andrew Viterbi determinó que los códigos convolucionales podían ser decodificados con máxima verosimilitud con una complejidad razonable utilizando decodificadores basados en enrejados invariantes en el tiempo: el algoritmo de Viterbi . Más tarde se desarrollaron otros algoritmos de decodificación basados en enrejados, incluido el algoritmo de decodificación BCJR .
Los códigos convolucionales sistemáticos recursivos fueron inventados por Claude Berrou alrededor de 1991. Estos códigos resultaron especialmente útiles para el procesamiento iterativo, incluido el procesamiento de códigos concatenados como los códigos turbo . [1]
Usando la terminología "convolucional", un código convolucional clásico podría considerarse un filtro de respuesta de impulso finito (FIR), mientras que un código convolucional recursivo podría considerarse un filtro de respuesta de impulso infinito (IIR).
Los códigos convolucionales se utilizan ampliamente para lograr una transferencia de datos confiable en numerosas aplicaciones, como video digital , radio, comunicaciones móviles (por ejemplo, en redes GSM, GPRS, EDGE y 3G (hasta 3GPP Release 7) [3] [4] ) y comunicaciones satelitales . [5] Estos códigos a menudo se implementan en concatenación con un código de decisión difícil, particularmente Reed–Solomon . Antes de los códigos turbo, tales construcciones eran las más eficientes y se acercaban más al límite de Shannon .
Para codificar datos de forma convolucional, comience con k registros de memoria , cada uno con un bit de entrada. A menos que se especifique lo contrario, todos los registros de memoria comienzan con un valor de 0. El codificador tiene n sumadores módulo 2 (un sumador módulo 2 se puede implementar con una única compuerta XOR booleana , donde la lógica es: 0+0 = 0 , 0+1 = 1 , 1+0 = 1 , 1+1 = 0 ) y n polinomios generadores , uno para cada sumador (consulte la figura siguiente). Un bit de entrada m 1 se alimenta al registro más a la izquierda. Usando los polinomios generadores y los valores existentes en los registros restantes, el codificador genera n símbolos. Estos símbolos se pueden transmitir o perforar según la tasa de código deseada. Ahora desplace bits todos los valores de registro hacia la derecha ( m 1 se mueve a m 0 , m 0 se mueve a m −1 ) y espere el siguiente bit de entrada. Si no quedan bits de entrada restantes, el codificador continúa desplazándose hasta que todos los registros hayan regresado al estado cero (terminación de bit de descarga).
La figura siguiente es un codificador de tasa 1 ⁄ 3 ( m ⁄ n ) con una longitud de restricción ( k ) de 3. Los polinomios generadores son G 1 = (1,1,1), G 2 = (0,1,1) , y G 3 = (1,0,1) . Por lo tanto, los bits de salida se calculan (módulo 2) de la siguiente manera:
Los códigos convolucionales pueden ser sistemáticos y no sistemáticos:
Los códigos convolucionales no sistemáticos son más populares debido a su mejor inmunidad al ruido. Esto se relaciona con la distancia libre del código convolucional. [6]
El codificador de la imagen de arriba es un codificador no recursivo . A continuación se muestra un ejemplo de uno recursivo y, como tal, admite una estructura de retroalimentación:
El codificador de ejemplo es sistemático porque los datos de entrada también se utilizan en los símbolos de salida (Salida 2). Los códigos con símbolos de salida que no incluyen los datos de entrada se denominan no sistemáticos.
Los códigos recursivos suelen ser sistemáticos y, a la inversa, los códigos no recursivos suelen ser no sistemáticos. No es un requisito estricto, pero sí una práctica habitual.
El codificador de ejemplo de la imagen 2 es un codificador de 8 estados porque los 3 registros crearán 8 estados posibles del codificador (2 3 ). Un enrejado de decodificador correspondiente normalmente también utilizará 8 estados.
Los códigos convolucionales sistemáticos recursivos (RSC) se han vuelto más populares debido a su uso en códigos Turbo. Los códigos sistemáticos recursivos también se conocen como códigos pseudosistemáticos.
Otros códigos RSC y aplicaciones de ejemplo incluyen:
Útil para la implementación de código LDPC y como código constituyente interno para códigos convolucionales concatenados en serie (SCCC).
Útil para SCCC y códigos turbo multidimensionales.
Útil como código constituyente en códigos turbo con baja tasa de error para aplicaciones como enlaces satelitales. También es adecuado como código externo SCCC.
Un codificador convolucional se llama así porque realiza una convolución del flujo de entrada con las respuestas de impulso del codificador :
donde x es una secuencia de entrada, y j es una secuencia de la salida j , h j es una respuesta al impulso para la salida j y denota convolución.
Un codificador convolucional es un sistema lineal discreto e invariante en el tiempo . Cada salida de un codificador se puede describir mediante su propia función de transferencia , que está estrechamente relacionada con el polinomio generador . Una respuesta al impulso está conectada con una función de transferencia a través de la transformada Z.
Las funciones de transferencia para el primer codificador (no recursivo) son:
Las funciones de transferencia para el segundo codificador (recursivo) son:
Definir m por
donde, para cualquier función racional ,
Entonces m es el máximo de los grados del polinomio
, y la longitud de la restricción se define como . Por ejemplo, en el primer ejemplo la longitud de la restricción es 3 y en el segundo es 4.
Un codificador convolucional es una máquina de estados finitos . Un codificador con n celdas binarias tendrá 2 n estados.
Imaginemos que el codificador (que se muestra en la imagen 1, arriba) tiene '1' en la celda de memoria izquierda ( m 0 ), y '0' en la derecha ( m −1 ). ( m 1 no es realmente una celda de memoria porque representa un valor actual). Designaremos dicho estado como "10". Según un bit de entrada, el codificador en el siguiente giro puede convertirse al estado "01" o al estado "11". Se puede ver que no todas las transiciones son posibles (por ejemplo, un decodificador no puede convertirse del estado "10" al "00" o incluso permanecer en el estado "10").
Todas las transiciones posibles se pueden mostrar a continuación:
En este gráfico, se puede representar una secuencia codificada real como una ruta. Se muestra una ruta válida en rojo como ejemplo.
Este diagrama nos da una idea sobre la decodificación : si una secuencia recibida no se ajusta a este gráfico, entonces se recibió con errores y debemos elegir la secuencia correcta más cercana (que se ajuste al gráfico). Los algoritmos de decodificación reales explotan esta idea.
La distancia libre [7] ( d ) es la distancia mínima de Hamming entre diferentes secuencias codificadas. La capacidad de corrección ( t ) de un código convolucional es el número de errores que puede corregir el código. Puede calcularse como
Dado que un código convolucional no utiliza bloques, sino que procesa un flujo de bits continuo, el valor de t se aplica a una cantidad de errores ubicados relativamente cerca unos de otros. Es decir, normalmente se pueden corregir varios grupos de t errores cuando están relativamente alejados.
La distancia libre puede interpretarse como la longitud mínima de una "ráfaga" errónea en la salida de un decodificador convolucional. El hecho de que los errores aparezcan como "ráfagas" debe tenerse en cuenta al diseñar un código concatenado con un código convolucional interno. La solución popular para este problema es intercalar los datos antes de la codificación convolucional, de modo que el código del bloque externo (generalmente Reed–Solomon ) pueda corregir la mayoría de los errores.
Existen varios algoritmos para decodificar códigos convolucionales. Para valores relativamente pequeños de k , el algoritmo de Viterbi se utiliza universalmente, ya que proporciona un rendimiento de máxima verosimilitud y es altamente paralelizable. Por lo tanto, los decodificadores de Viterbi son fáciles de implementar en hardware VLSI y en software en CPU con conjuntos de instrucciones SIMD .
Los códigos de longitud de restricción más larga se decodifican de manera más práctica con cualquiera de los diversos algoritmos de decodificación secuencial , de los cuales el algoritmo Fano es el más conocido. A diferencia de la decodificación de Viterbi, la decodificación secuencial no es de máxima verosimilitud, pero su complejidad aumenta solo ligeramente con la longitud de restricción, lo que permite el uso de códigos fuertes de longitud de restricción larga. Dichos códigos se utilizaron en el programa Pioneer de principios de la década de 1970 para Júpiter y Saturno, pero dieron paso a códigos decodificados por Viterbi más cortos, generalmente concatenados con grandes códigos de corrección de errores Reed-Solomon que hacen más pronunciada la curva de tasa de error de bits general y producen tasas de error residual no detectado extremadamente bajas.
Tanto los algoritmos de decodificación secuencial como los de Viterbi devuelven decisiones difíciles: los bits que forman la palabra clave más probable. Se puede añadir una medida de confianza aproximada a cada bit mediante el uso del algoritmo de Viterbi de salida suave . Se pueden obtener decisiones suaves a posteriori máximas (MAP) para cada bit mediante el uso del algoritmo BCJR .
De hecho, en la industria se utilizan estructuras de códigos convolucionales predefinidas obtenidas durante investigaciones científicas. Esto se relaciona con la posibilidad de seleccionar códigos convolucionales catastróficos (que provocan un mayor número de errores).
Un código convolucional decodificado por Viterbi especialmente popular, utilizado al menos desde el programa Voyager , tiene una longitud de restricción K de 7 y una tasa r de 1/2. [12]
Mars Pathfinder , Mars Exploration Rover y la sonda Cassini a Saturno utilizan un K de 15 y una tasa de 1/6; este código funciona aproximadamente 2 dB mejor que el código más simple a un costo de 256× en complejidad de decodificación (en comparación con los códigos de la misión Voyager).
El código convolucional con una longitud de restricción de 2 y una tasa de 1/2 se utiliza en GSM como técnica de corrección de errores. [13]
Se puede diseñar un código convolucional con cualquier tasa de código basándose en la selección polinómica; [15] sin embargo, en la práctica, a menudo se utiliza un procedimiento de perforación para lograr la tasa de código requerida. La perforación es una técnica utilizada para crear un código de tasa m / n a partir de un código de tasa baja "básica" (por ejemplo, 1/ n ). Se logra eliminando algunos bits en la salida del codificador. Los bits se eliminan de acuerdo con una matriz de perforación . Las siguientes matrices de perforación son las más utilizadas:
Por ejemplo, si queremos generar un código con una tasa de 2/3 utilizando la matriz adecuada de la tabla anterior, debemos tomar la salida de un codificador básico y transmitir cada bit inicial de la primera rama y cada bit de la segunda. El orden específico de transmisión está definido por el estándar de comunicación respectivo.
Los códigos convolucionales perforados se utilizan ampliamente en las comunicaciones por satélite , por ejemplo, en los sistemas Intelsat y en la radiodifusión de vídeo digital .
Los códigos convolucionales perforados también se denominan "perforados".
Los códigos convolucionales simples decodificados por Viterbi están dando paso a los códigos turbo , una nueva clase de códigos convolucionales cortos iterados que se acercan mucho a los límites teóricos impuestos por el teorema de Shannon con mucha menos complejidad de decodificación que el algoritmo de Viterbi en los códigos convolucionales largos que serían necesarios para el mismo rendimiento. La concatenación con un código algebraico externo (por ejemplo, Reed–Solomon ) aborda el problema de los niveles de error inherentes a los diseños de códigos turbo.