Seção 22.2 Códigos Polinomiales
Sabiendo sobre anillos de polinomios y cuerpos finitos, es posible derivar códigos más sofisticados que los del Capítulo 8. En primer lugar recordemos que un código de bloques \((n, k)\) consiste de una función codificadora inyectiva \(E:{\mathbb Z}^{k}_{2} \rightarrow {\mathbb Z}^{n}_{2}\) y una función decodificadora \(D:{\mathbb Z}^{n}_{2} \rightarrow {\mathbb Z}^{k}_{2}\text{.}\) El código es corrector de errores si \(D\) es sobreyectivo. Un código es lineal si es el espacio nulo de una matriz \(H \in {\mathbb M}_{k \times n}({\mathbb Z}_2)\text{.}\)
Estamos interesados en una clase de códigos conocidos como códigos cíclicos. Sea \(\phi : {\mathbb Z}_2^k \rightarrow {\mathbb Z}_2^n\) un código de bloques \((n,k)\) binario. Entonces \(\phi\) es un código cíclico si para cada palabra \((a_1, a_2, \ldots, a_n )\) en el código, la palabra formada por desplazamiento cíclico, la \(n\)-tupla \((a_n, a_1, a_2, \ldots, a_{n - 1} )\) también está en el código. Los códigos cíclicos son fáciles de implementar en un computador usando registro de shift [2, 3].
Exemplo 22.2.1.
Considere los código lineales \((6,3)\)generados por las dos matrices
Los mensajes del primero se codifican como sigue:
Es fácil ver que las palabras del código forman un código cíclico. En el segundo, las 3-tuplas se codifican de la siguiente manera:
Este código no es cíclico, pues \((101101)\) es una palabra del código pero \((011011)\) no lo es.
Subseção 22.2.1 Códigos Polinomiales
Nos gustaría encontrar un método fácil para obtener códigos cíclicos lineales. Para lograr esto, podemos usar lo que sabemos de cuerpos finitos y anillos de polinomios sobre \({\mathbb Z}_2\text{.}\) Cualquier \(n\)-tupla binaria se puede interpretar como un polinomio en \({\mathbb Z}_2[x]\text{.}\) Dicho de otra forma, la \(n\)-tupla \((a_0, a_1, \ldots, a_{n - 1} )\) corresponde al polinomio
donde el grado de \(f(x)\) es a lo más \(n - 1\text{.}\) Por ejemplo, el polinomio correspondiente a la 5-tupla \((10011)\) es
Recíprocamente, dado cualquier polinomio \(f(x) \in {\mathbb Z}_2[x]\) con \(\deg f(x) \lt n\) le podemos asociar una \(n\)-tupla binaria. El polinomio \(x + x^2 + x^4\) corresponde a la 5-tupla \((01101)\text{.}\)
Fijemos un polinomio no constante \(g(x)\) en \({\mathbb Z}_2[x]\) de grado \(n - k\text{.}\) Podemos definir un \((n,k)\)-código \(C\) de la siguiente manera. Si \((a_0, \ldots, a_{k - 1})\) es una \(k\)-tupla a codificar, entonces \(f(x) = a_0 + a_1 x + \cdots + a_{k - 1} x^{k - 1}\) es el correspondiente polinomio en \({\mathbb Z}_2[x]\text{.}\) Para codificar \(f(x)\text{,}\) lo multiplicamos por \(g(x)\text{.}\) Las palabras en \(C\) son todos aquellos polinomios en \({\mathbb Z}_2[x]\) de grado menor a \(n\) que son divisibles por \(g(x)\text{.}\) Los Códigos obtenidos de esta manera se llaman códigos polinomiales.
Exemplo 22.2.2.
Si \(g(x)= 1 + x^3\text{,}\) podemos definir un \((6,3)\)-código \(C\) como sigue. Para codificar una 3-tupla \(( a_0, a_1, a_2 )\text{,}\) multiplicamos el correspondiente polinomio \(f(x) = a_0 + a_1 x + a_2 x^2\) por \(1 + x^3\text{.}\) Estamos definiendo una función \(\phi : {\mathbb Z}_2^3 \rightarrow {\mathbb Z}_2^6\) como \(\phi : f(x) \mapsto g(x) f(x)\text{.}\) Es fácil verificar que esta función es un homomorfismo de grupos. De hecho, si consideramos \({\mathbb Z}_2^n\) como un espacio vectorial sobre \({\mathbb Z}_2\text{,}\) \(\phi\) es una transformación lineal de espacios vectoriales (vea el Ejercicio 20.4.15, Capítulo 20). Calculemos el núcleo de \(\phi\text{.}\) Observe que \(\phi ( a_0, a_1, a_2 ) = (000000)\) exactamente cuando
Como los polinomios sobre un cuerpo forman un dominio integral, \(a_0 + a_1 x + a_2 x^2\) debe ser el polinomio cero. Por lo tanto, \(\ker \phi = \{ (000) \}\) y \(\phi\) es 1-1.
Para calcular una matriz generadora para \(C\text{,}\) solo debemos examinar cómo se codifican los polinomios \(1\text{,}\) \(x\text{,}\) y \(x^2\text{:}\)
Obtenemos el código correspondiente a la matriz generadora \(G_1\) en el Ejemplo 22.2.1. la matriz de verificación de paridad para este código es
Como el menor peso de cualquier palabra no nula del código es 2, este código es capaz de detectar cualquier error único.
Los anillos de Polinomios tienen una estructura muy rica; por lo tanto, nuestro objetivo inmediato es establecer una relación entre los códigos polinomiales y la teoría de anillos. Recuerde que \(x^n - 1 = (x - 1)( x^{n-1} + \cdots + x + 1)\text{.}\) El anillo cociente
puede ser considerado como el anillo de polinomios de la forma
que satisfacen la condición \(t^n = 1\text{.}\) Es un ejercicio sencillo mostrar que \({\mathbb Z}_2^n\) y \(R_n\) son isomorfos como espacios vectoriales. Frecuentemente interpretaremos los elementos en \({\mathbb Z}_2^n\) con elementos en \({\mathbb Z_2}[x] / \langle x^n - 1 \rangle\text{.}\) De esta forma podemos interpretar un código lineal como un subconjunto de \({\mathbb Z_2}[x] / \langle x^n - 1 \rangle\text{.}\)
La estructura adicional de anillo en los códigos polinomiales es muy poderosa para describir códigos cíclicos. Un shift cíclico de una \(n\)-tupla puede ser descrito por una multiplicación polinomial. Si \(f(t) = a_0 + a_1 t + \cdots + a_{n-1} t^{n-1}\) es un código polinomial en \(R_n\text{,}\) entonces
es la palabra desplazada cíclicamente obtenida de multiplicar \(f(t)\) por \(t\text{.}\) El siguiente teorema entrega una hermosa clasificación de los códigos cíclicos en términos de los ideales de \(R_n\text{.}\)
Teorema 22.2.3.
Un código lineal \(C\) en \({\mathbb Z}_2^n\) es cíclico si y solo si es un ideal en \(R_n = {\mathbb Z_2}[x] / \langle x^n - 1 \rangle\text{.}\)
Demonstração.
Sea \(C\) un código cíclico lineal y supongamos que \(f(t)\) está en \(C\text{.}\) Entonces \(t f(t)\) también está en \(C\text{.}\) Así, \(t^k f(t)\) está en \(C\) para todo \(k \in {\mathbb N}\text{.}\) Como \(C\) es un código lineal, cualquier combinación lineal de las palabras \(f(t), tf(t), t^2f(t), \ldots, t^{n-1}f(t)\) también es una palabra del código; por lo tanto, para cada polinomio \(p(t)\text{,}\) \(p(t)f(t)\) está en \(C\text{.}\) Luego, \(C\) es un ideal.
Recíprocamente, sea \(C\) un ideal en \({\mathbb Z}_2[x]/\langle x^n + 1\rangle\text{.}\) Supongamos que \(f(t) = a_0 + a_1 t + \cdots + a_{n - 1} t^{n - 1}\) es una palabra en \(C\text{.}\) Entonces \(t f(t)\) es una palabra en \(C\text{;}\) es decir, \((a_1, \ldots, a_{n-1}, a_0)\) está en \(C\text{.}\)
El Teorema 22.2.3 nos dice que conocer los ideales de \(R_n\) es equivalente a conocer los códigos cíclicos en \({\mathbb Z}_2^n\text{.}\) Afortunadamente es fácil describir los ideales en \(R_n\text{.}\) El homomorfismo natural \(\phi : {\mathbb Z}_2[x] \rightarrow R_n\) definido por \(\phi[f(x)] = f(t)\) es un homomorfismo epiyectivo. El núcleo de \(\phi\) es el ideal generado por \(x^n - 1\text{.}\) Por el Teorema 16.3.15, todo ideal \(C\) en \(R_n\) es de la forma \(\phi(I)\text{,}\) donde \(I\) es un ideal en \({\mathbb Z}_2[x]\) que contiene al ideal \(\langle x^n - 1 \rangle\text{.}\) Por el Teorema 17.3.10, sabemos que todo ideal en \({\mathbb Z}_2[x]\) es un ideal principal, pues \({\mathbb Z}_2\) es un cuerpo. Por lo tanto, \(I = \langle g(x) \rangle\) para algún polinomio mónico en \({\mathbb Z}_2[x]\text{.}\) Como \(\langle x^n - 1 \rangle\) está contenido en \(I\text{,}\) se debe tener que \(g(x)\) divide a \(x^n - 1\text{.}\) Así, todo ideal \(C\) en \(R_n\) es de la forma
El polinomio único de grado mínimo que genera \(C\) se llama polinomio generador minimal de \(C\text{.}\)
Exemplo 22.2.4.
Si factorizamos \(x^7 - 1\) en sus componentes irreducibles, tenemos
Vemos que \(g(t) = (1 + t + t^3)\) genera un ideal \(C\) en \(R_7\text{.}\) Este es un código de bloque \((7, 4)\text{.}\) Como en el Ejemplo 22.2.2, es fácil calcular una matriz generadora examinando qué le hace \(g(t)\) a los polinomios 1, \(t\text{,}\) \(t^2\text{,}\) y \(t^3\text{.}\) Una matriz generadora para \(C\) es
En general, podemos determinar una matriz generadora para un código \((n, k)\) \(C\) por la forma en que se codifican los elementos \(t^k\text{.}\) Sea \(x^n - 1 = g(x) h(x)\) en \({\mathbb Z}_2[x]\text{.}\) Si \(g(x) = g_0 + g_1 x + \cdots + g_{n-k} x^{n-k}\) y \(h(x) = h_0 + h_1 x + \cdots + h_k x^k\text{,}\) entonces la matriz de \(n \times k\)
es una matriz generadora para el código \(C\) con generador polinomial \(g(t)\text{.}\) La matriz de verificación de paridad para \(C\) es la matriz de \((n-k) \times n\)
Dejaremos los detalles de la demostreción de la siguiente proposición como un ejercicio.
Proposição 22.2.5.
Sea \(C = \langle g(t) \rangle\) un código cíclico en \(R_n\) y supongamos que \(x^n - 1 = g(x) h(x)\text{.}\) Entonces \(G\) y \(H\) son matriz generadora y verificadora para \(C\text{,}\) respectivamente. Más aún, \(HG = 0\text{.}\)
Exemplo 22.2.6.
En el Ejemplo 22.2.4,
Por lo tanto, una matriz verificadora para este código es
Para determinanr las capacidades de detección y corrección de errores de un código cíclico, necesitamos saber algo sobre determinantes. Si \(\alpha_1, \ldots, \alpha_n\) son elementos en un cuerpo \(F\text{,}\) entonces la matriz de \(n \times n\)
se llama matriz de Vandermonde. El determinante de esta matriz se llama determinante de Vandermonde. Necesitaremos el siguiente lema en nuestro estudio de los códigos cíclicos.
Lema 22.2.7.
Sean \(\alpha_1, \ldots, \alpha_n\) elementos en un cuerpo \(F\) con \(n \geq 2\text{.}\) Entonces
En particular, si los \(\alpha_i\) son distintos, entonces el determinante es distinto de cero.
Demonstração.
Procederemos por inducción en \(n\text{.}\) Si \(n = 2\text{,}\) entonces el determinante es \(\alpha_2 - \alpha_1\text{.}\) Supongamos demostrado el resultado para \(n - 1\) y consideremos el polinomio \(p(x)\) definido por
Expandiendo este determinante por cofactores en la última columna, vemos que \(p(x)\) es un polinomio de grado a lo más \(n-1\text{.}\) Además, las raíces de \(p(x)\) son \(\alpha_1, \ldots, \alpha_{n-1}\text{,}\) pues la sustitución de cualquiera de esos elementos en la última columna producirá una columna idéntica a otra columna de la matriz. Recuerde que el determinante de una matriz es cero si esta tiene dos columnas idénticas. Por lo tanto,
donde
Por nuestra hipótesis de inducción,
Si evaluamos en \(x = \alpha_n\text{,}\) el resultados es una consecuencia inmediata.
El siguiente teorema nos entrega una estimación de las capacidades de detección y corrección de errores para un polinomio generador en particular.
Teorema 22.2.8.
Sea \(C = \langle g(t) \rangle\) un código cíclico en \(R_n\) y supongamos que \(\omega\) es una raíz \(n\)-ésima primitiva de la unidad sobre \({\mathbb Z}_2\text{.}\) Si \(s\) potencias consecutivas de \(\omega\) son raíces de \(g(x)\text{,}\) entonces la distacia mínima de \(C\) es al menos \(s + 1\text{.}\)
Demonstração.
Supongamos que
Sea \(f(x)\) algún polinomio en \(C\) con \(s\) o menos coeficientes distintos de cero. Podemos suponer que
es algún polinomio en \(C\text{.}\) Es suficiente con demostrar que todos los \(a_i\) tienen que ser cero. Como
y \(g(x)\) divide a \(f(x)\text{,}\)
Equivalentemente, tenemos el siguiente sistema de ecuaciones:
Por lo tanto, \((a_{i_0}, a_{i_1}, \ldots, a_{i_{s - 1}})\) es una solución del sistema de ecuaciones lineales homogéneo
Pero este sistema tiene solución única, pues el determinante de la matriz
no es cero por el Lema 22.2.7 y las propiedades básicas de los determinantes (Ejercicio). Por lo tanto, esta solución es \(a_{i_0} = a_{i_1} = \cdots = a_{i_{s - 1}} = 0\text{.}\)
Subseção 22.2.2 Códigos BCH
Entre los códigos más importantes, descubiertos independientemente por A. Hocquenghem en 1959 y por R. C. Bose y D. V. Ray-Chaudhuri en 1960, están los códigos BCH. Los sistemas de comunicación Europeo y Trasantlántico, ambos usan códigos BCH. Las palabras a codificar son de largo 231, y se usa un polinomio de grado 24 para generar el código. Como \(231 + 24 = 255 = 2^8-1\text{,}\) tenemos un código de bloque \((255, 231)\text{.}\) Este código BCH es capaz de detectar seis errores y tiene una razón de falla de 1 en 16 millones. Una ventaja de los códigos BCH es que existen algoritmos eficientes de corrección de errores para ellos.
La idea detrás de los códigos BCH es elegir un polinomio generador de grado minimal que tenga la mayor capacidad de detección y corrección de errores. Sea \(d = 2r + 1\) para algún \(r \geq 0\text{.}\) Supongamos que \(\omega\) es una raíz \(n\)-ésima primitiva de la unidad sobre \({\mathbb Z}_2\text{,}\) y sea \(m_i(x)\) el polinomio minimal sobre \({\mathbb Z}_2\) de \(\omega^i\text{.}\) Si
entonces el código cíclico \(\langle g(t) \rangle\) en \(R_n\) se denomina código BCH de largo \(n\) y distancia \(d\text{.}\) Por el Teorema 22.2.8, la distancia mínima de \(C\) es al menos \(d\text{.}\)
Teorema 22.2.9.
Sea \(C = \langle g(t) \rangle\) un código cíclico en \(R_n\text{.}\) Entonces las siguientes proposiciones son equivalentes.
El código \(C\) es un código BCH cuya distancia mínima es al menos \(d\text{.}\)
Un polinomio \(f(t)\) está en \(C\) si y solo si \(f( \omega^i) = 0\) para \(1 \leq i \lt d\text{.}\)
-
La matriz
\begin{equation*} H = \begin{pmatrix} 1 & \omega & \omega^2 & \cdots & \omega^{n-1}\\ 1 & \omega^2 & \omega^{4} & \cdots & \omega^{(n-1)(2)} \\ 1 & \omega^3 & \omega^{6} & \cdots & \omega^{(n-1)(3)} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & \omega^{2r} & \omega^{4r} & \cdots & \omega^{(n-1)(2r)} \end{pmatrix} \end{equation*}es una matriz verificadora para \(C\text{.}\)
Demonstração.
(1) \(\Rightarrow\) (2). Si \(f(t)\) está en \(C\text{,}\) entonces \(g(x) \mid f(x)\) en \({\mathbb Z}_2[x]\text{.}\) Luego, para \(i = 1, \ldots, 2r\text{,}\) \(f( \omega^i) = 0\) pues \(g( \omega^i ) = 0\text{.}\) Recíprocamente, supongamos que \(f( \omega^i) = 0\) for \(1 \leq i \leq d\text{.}\) Entonces \(f(x)\) es divisible por cada \(m_i(x)\text{,}\) pues \(m_i(x)\) es el polinomio minimal de \(\omega^i\text{.}\) Por lo tanto, \(g(x) \mid f(x)\) por la definición de \(g(x)\text{.}\) Así, \(f(x)\) es una palabra del código.
(2) \(\Rightarrow\) (3). Sea \(f(t) = a_0 + a_1 t + \cdots + a_{n - 1}v t^{n - 1}\) en \(R_n\text{.}\) La correspondiente \(n\)-tupla en \({\mathbb Z}_2^n\) es \({\mathbf x} = (a_0 a_1 \cdots a_{n - 1})^{\rm t}\text{.}\) Por (2),
precisamente cuando \(f(t)\) está en \(C\text{.}\) Luego, \(H\) es una matriz verificadora para \(C\text{.}\)
(3) \(\Rightarrow\) (1). Por (3), un polinomio \(f(t) = a_0 + a_1 t + \cdots + a_{n - 1} t^{n - 1}\) está en \(C\) exactamente cuando \(f(\omega^i) = 0\) for \(i = 1, \ldots, 2r\text{.}\) El menor tal polinomio es \(g(t) = \lcm[ m_1(t),\ldots, m_{2r}(t)]\text{.}\) Por lo tanto, \(C = \langle g(t) \rangle\text{.}\)
Exemplo 22.2.10.
Es fácil verificar que \(x^{15} - 1 \in {\mathbb Z}_2[x]\) se factoriza como
donde cada uno de estos factores es irreducible. Sea \(\omega\) una raíz de \(1 + x + x^4\text{.}\) El cuerpo de Galois \(\gf(2^4)\) es
Por el Ejemplo 22.1.8, \(\omega\) es una raíz 15 primitiva de la unidad. El polinomio minimal de \(\omega\) es \(m_1(x) = 1 + x + x^4\text{.}\) Es fácil ver que \(\omega^2\) y \(\omega^4\) también son raíces de \(m_1(x)\text{.}\) El polinomio minimal de \(\omega^3\) es \(m_2(x) = 1 + x + x^2 + x^3 + x^4\text{.}\) Por lo tanto,
tiene raíces \(\omega\text{,}\) \(\omega^2\text{,}\) \(\omega^3\text{,}\) \(\omega^4\text{.}\) Como tanto \(m_1(x)\) como \(m_2(x)\) dividen a \(x^{15} - 1\text{,}\) el código BCH es un código \((15, 7)\text{.}\) Si \(x^{15} -1 = g(x)h(x)\text{,}\) entonces \(h(x) = 1 + x^4 + x^6 + x^7\text{;}\) por lo tanto, una matriz verificadora para este código es
Sage.
Los Cuerpos Finitos son importantes en diversas disciplinas aplicadas, tales como criptografía y teoría de códigos (vea la introducción a estos tópicos en otros capítulos). Sage tiene una excelente implementación de los cuerpos finitos que permite una variedad de cálculos con éstos.