Saltar al contenido
El bit perdido
Newsletter

Lección 7 de 11

Códigos cíclicos: palabras que son polinomios

Un código cíclico se describe con un solo polinomio, el generador. Aprenderás a construirlo y verás que un código de Hamming es uno de ellos.

Borrador: pendiente de que lo revise el autor. Esta página no aparece en Google.

Al terminar sabrás:

  • Reconocer si un código lineal es cíclico
  • Pasar una palabra a polinomio y ver el desplazamiento como multiplicar por x
  • Obtener el polinomio generador y la dimensión del código
  • Listar los códigos cíclicos binarios de longitud 7

Si sabes multiplicar matrices, resolver un sistema de ecuaciones lineales y operar con polinomios (sumar, multiplicar, dividir), puedes seguirlo. Lo demás (aritmética módulo 2, subespacios, cuerpos finitos) se explica sobre la marcha.

En la lección anterior decodificamos con una tabla de síndromes. Cuando nn crece, guardar GG o una tabla grande es incómodo. ¿Hay códigos que se describan con muy poca información y se codifiquen con circuitos sencillos?

Sí: los códigos cíclicos. Son la base de los CRC que protegen las tramas de red y los archivos ZIP, y (lo verás en la lección 9) de los códigos Reed-Solomon de los QR. Hace falta una idea nueva: tratar las palabras como polinomios.

La idea

Toma 11010001101000 y desplázala una posición a la derecha, de forma que el último símbolo vuelva al principio: 01101000110100. Otro desplazamiento da 00110100011010. Tras 7 desplazamientos vuelves a la original: es girar una rueda con 7 casillas.

Un código es cíclico si es lineal y, cada vez que una palabra está en el código, sus desplazamientos también lo están. Parece una condición caprichosa, pero el código queda determinado por una sola palabra. El truco: escribir cada palabra como los coeficientes de un polinomio. Entonces desplazar es multiplicar por xx, y el álgebra de polinomios hace el trabajo.

Aviso de numeración. Solo en las lecciones de códigos cíclicos, las posiciones de una palabra se numeran desde 0: c=(c0,c1,…,cn−1)c = (c_0, c_1, \dots, c_{n-1}). Así el coeficiente de xix^i es cic_i y no hay que restar unos.

Palabras como polinomios

A cada palabra c=(c0,c1,…,cn−1)c = (c_0, c_1, \dots, c_{n-1}) de Fqn\mathbb{F}_q^n le asociamos el polinomio

c(x)=c0+c1x+⋯+cn−1xn−1.c(x) = c_0 + c_1 x + \dots + c_{n-1}x^{n-1}.

Por ejemplo, 11010001101000 se corresponde con 1+x+x31 + x + x^3. El polinomio de una palabra de longitud nn tiene grado menor que nn.

Ahora multiplica por xx:

x c(x)=c0x+c1x2+⋯+cn−2xn−1+cn−1xn.x\,c(x) = c_0 x + c_1 x^2 + \dots + c_{n-2}x^{n-1} + c_{n-1}x^{n}.

Casi es el desplazamiento, pero el último coeficiente ha quedado en xnx^n, fuera de rango. Para devolverlo al principio declaramos que xn=1x^n = 1, es decir, trabajamos con los restos de dividir entre xn−1x^n - 1 (el recuadro lo explica). Ese conjunto se escribe Fq[x]/(xn−1)\mathbb{F}_q[x]/(x^n-1). En él,

x c(x)≡cn−1+c0x+c1x2+⋯+cn−2xn−1,x\,c(x) \equiv c_{n-1} + c_0 x + c_1 x^2 + \dots + c_{n-2}x^{n-1},

que es exactamente la palabra desplazada. Multiplicar por xx es desplazar.

Repaso Polinomios módulo xⁿ − 1: un reloj de polinomios

En la lección 2 viste la aritmética del reloj: en Z7\mathbb{Z}_7, 7=07 = 0 y los números dan la vuelta, como las horas. Con polinomios hacemos lo mismo: para n=7n = 7 declaramos x7=1x^7 = 1. Cada x7x^7 se cambia por 11; x8x^8 es xx y x9x^9 es x2x^2. Todo polinomio se reduce a uno de grado menor que 7, es decir, a una palabra de 7 símbolos.

Al multiplicar por xx, el coeficiente de x6x^6 pasa a x7=1x^7 = 1 y da la vuelta al principio: es la rueda de 7 casillas. Y xn−1x^n - 1 vale 00 en este reloj.

Repaso División de polinomios y restos módulo 2

Dividir polinomios es como dividir números, quitando el término de mayor grado. Con coeficientes en F2\mathbb{F}_2, restar es lo mismo que sumar, porque 1+1=01 + 1 = 0.

Divide x5+x3+1x^5 + x^3 + 1 entre g(x)=x3+x+1g(x) = x^3 + x + 1:

  1. El primer término del cociente es x2x^2, porque x2⋅x3=x5x^2 \cdot x^3 = x^5.
  2. Calcula x2⋅g(x)=x5+x3+x2x^2 \cdot g(x) = x^5 + x^3 + x^2 y réstalo (súmalo, en módulo 2): (x5+x3+1)+(x5+x3+x2)=x2+1(x^5 + x^3 + 1) + (x^5 + x^3 + x^2) = x^2 + 1.
  3. El resto x2+1x^2 + 1 tiene grado 2, menor que el de gg (grado 3): ya hemos terminado.

Cociente x2x^2 y resto x2+1x^2 + 1. Se escribe x5+x3+1≡x2+1(modg(x))x^5 + x^3 + 1 \equiv x^2 + 1 \pmod{g(x)}. Si el resto es 0, se dice que gg divide al polinomio.

El polinomio generador

Un código cíclico es cerrado por multiplicar por xx, y por tanto por multiplicar por cualquier polinomio a(x)a(x) (multiplicar por x2x^2 es desplazar dos veces; sumar palabras es linealidad). Entre todos los polinomios no nulos del código, escoge el de menor grado y hazlo mónico (coeficiente principal igual a 1). Es el polinomio generador g(x)g(x) del código. Tiene tres propiedades:

  • Todas las palabras son múltiplos de g(x)g(x), y todo múltiplo de gg de grado menor que nn está en el código (es una combinación de desplazamientos de gg). Es decir, C={ m(x)g(x):deg⁡m<n−deg⁡g }C = \{\,m(x)g(x) : \deg m < n - \deg g\,\}.
  • g(x)g(x) divide a xn−1x^n - 1. Si divides, xn−1=q(x)g(x)+s(x)x^n - 1 = q(x)g(x) + s(x). En nuestro reloj xn−1x^n - 1 vale 0, así que el resto cumple s≡−q gs \equiv -q\,g en el reloj: es un múltiplo de gg, es decir, una palabra del código. Pero tiene grado menor que gg, que es la palabra no nula de menor grado: luego s=0s = 0.
  • La dimensión es k=n−deg⁡gk = n - \deg g. Hay un polinomio m(x)m(x) de grado menor que kk por cada palabra, así que ∣C∣=qk|C| = q^k.

Y al revés: cada divisor mónico gg de xn−1x^n-1 genera un código cíclico de dimensión n−deg⁡gn - \deg g. Por eso, para encontrar todos los códigos cíclicos de longitud nn basta factorizar xn−1x^n - 1 y combinar los factores.

Los códigos cíclicos binarios de longitud 7

Sobre F2\mathbb{F}_2, el polinomio x7−1=x7+1x^7 - 1 = x^7 + 1 se factoriza en irreducibles (no se puede romper más) como

x7−1=(x+1)(x3+x+1)(x3+x2+1).x^7 - 1 = (x+1)(x^3+x+1)(x^3+x^2+1).

(Compruébalo: (x3+x+1)(x3+x2+1)=x6+x5+⋯+x+1(x^3+x+1)(x^3+x^2+1) = x^6+x^5+\dots+x+1, y al multiplicar por x+1x+1 queda x7+1x^7+1.) Tiene 3 factores irreducibles distintos, luego hay 23=82^3 = 8 divisores mónicos y 8 códigos cíclicos binarios de longitud 7:

generador g(x)g(x)kkddqué es
1171todo F27\mathbb{F}_2^7
x+1x+162palabras de peso par
x3+x+1x^3+x+143Hamming
x3+x2+1x^3+x^2+143Hamming (otro)
(x+1)(x3+x+1)=x4+x3+x2+1(x+1)(x^3+x+1) = x^4+x^3+x^2+134dual de un Hamming
(x+1)(x3+x2+1)=x4+x2+x+1(x+1)(x^3+x^2+1) = x^4+x^2+x+134dual del otro
(x3+x+1)(x3+x2+1)=x6+⋯+x+1(x^3+x+1)(x^3+x^2+1) = x^6+\dots+x+117repetición
x7+1x^7+10no haysolo la palabra 00

Los extremos son triviales. El de g=x+1g = x + 1 es el código de paridad (palabras de peso par) de longitud 7, la versión larga del de la primera lección. El de g=x6+x5+⋯+1g=x^6+x^5+\dots+1 repite el mismo bit 7 veces. Lo interesante está en medio: para buscar buenos códigos ya no exploras subespacios a ciegas, factorizas un polinomio.

Un código de Hamming cíclico

Toma g(x)=1+x+x3g(x) = 1 + x + x^3. Como deg⁡g=3\deg g = 3, la dimensión es k=4k = 4. Sus palabras son los m(x)g(x)m(x)g(x) con deg⁡m<4\deg m < 4: hay 1 de peso 0, 7 de peso 3, 7 de peso 4 y 1 de peso 7. Es la distribución de pesos del Hamming [7,4,3][7,4,3] del hilo, y no por casualidad: este código es equivalente al del hilo, es decir, se obtiene de él reordenando las posiciones. Ojo: el código del hilo, con la GG de las lecciones 3 a 6, no es cíclico; lo es su versión reordenada. Tiene d=3d = 3 y corrige 1 error.

Este gg ya lo conoces: x3+x+1x^3+x+1 es el polinomio con el que construimos F8\mathbb{F}_8 en la lección 2, y α\alpha es una raíz suya (α3=α+1\alpha^3 = \alpha + 1). Raíces y códigos volverán a juntarse con Reed-Solomon.

Las siete palabras de peso 3 son los siete desplazamientos de g=1101000g = 1101000:

1101000, 0110100, 0011010, 0001101, 1000110, 0100011, 1010001.1101000,\ 0110100,\ 0011010,\ 0001101,\ 1000110,\ 0100011,\ 1010001.

Las cuatro primeras son las filas de la matriz generatriz cíclica (g,xg,x2g,x3gg, xg, x^2g, x^3g). Las de peso 4 se obtienen sumando 11111111111111 a estas (cambia ceros por unos), y faltan 00000000000000 y 11111111111111.

Ejemplo resuelto

Pregunta: ¿es r=(1,1,0,1,0,0,1)r = (1,1,0,1,0,0,1) una palabra del código cíclico de generador g(x)=1+x+x3g(x) = 1 + x + x^3?

  1. Pasa a polinomio, con índices desde 0: r(x)=1+x+x3+x6r(x) = 1 + x + x^3 + x^6.
  2. Está en el código si y solo si g(x)g(x) divide a r(x)r(x). Divide: el término principal es x6=x3⋅x3x^6 = x^3 \cdot x^3, así que resta x3g(x)=x3+x4+x6x^3 g(x) = x^3 + x^4 + x^6. Queda x4+x+1x^4 + x + 1.
  3. Ahora el término principal es x4=x⋅x3x^4 = x \cdot x^3. Resta x g(x)=x+x2+x4x\,g(x) = x + x^2 + x^4. Queda x2+1x^2 + 1, de grado menor que 3.

El resto no es 0: rr no es palabra del código.

Y una que sí: c=(1,0,0,1,0,1,1)c = (1,0,0,1,0,1,1), es decir, c(x)=1+x3+x5+x6c(x) = 1 + x^3 + x^5 + x^6. Resta x3gx^3g: queda 1+x4+x51 + x^4 + x^5. Resta x2g=x2+x3+x5x^2g = x^2+x^3+x^5: queda 1+x2+x3+x41 + x^2 + x^3 + x^4. Resta x gx\,g: queda 1+x+x31 + x + x^3. Resta gg: queda 00. El resto es 0, así que cc sí está en el código (es (1+x+x2+x3) g(1+x+x^2+x^3)\,g).

Ejercicios

Ejercicio 1

Halla todos los códigos cíclicos binarios de longitud 3. Para cada uno, da el generador, kk y las palabras. Pista: x=1x = 1 es raíz de x3+1x^3 + 1, luego x+1x + 1 lo divide.

Ver la solución

Al dividir x3+1x^3+1 entre x+1x+1 sale x2+x+1x^2+x+1, que no tiene raíces en F2\mathbb{F}_2 (vale 1 en 0 y en 1). Así, x3+1=(x+1)(x2+x+1)x^3 + 1 = (x+1)(x^2+x+1). Hay 2 factores irreducibles distintos, luego 22=42^2 = 4 divisores y 4 códigos:

  • g=1g = 1: k=3k = 3, es todo F23\mathbb{F}_2^3.
  • g=x+1g = x+1: k=2k = 2, palabras 000,011,101,110000, 011, 101, 110 (las de peso par).
  • g=x2+x+1g = x^2+x+1: k=1k = 1, palabras 000000 y 111111 (el código de repetición).
  • g=x3+1g = x^3+1: k=0k = 0, solo la palabra 000000.

Ejercicio 2

Considera el código cíclico de longitud 7 con g(x)=1+x2+x3+x4g(x) = 1 + x^2 + x^3 + x^4. Calcula su dimensión, escribe sus palabras y halla su distancia mínima.

Ver la solución

Como deg⁡g=4\deg g = 4, la dimensión es k=7−4=3k = 7 - 4 = 3 y hay 23=82^3 = 8 palabras. Como g=1011100g = 1011100, sus desplazamientos son

1011100, 0101110, 0010111, 1001011, 1100101, 1110010, 0111001,1011100,\ 0101110,\ 0010111,\ 1001011,\ 1100101,\ 1110010,\ 0111001,

siete palabras distintas; con 00000000000000 completan las 8. Todas las no nulas tienen peso 4, así que d=4d = 4 y el código es un [7,3,4][7,3,4]. Es el que aparece en la tabla como «dual de un Hamming».

Comprobación: g=(x+1)(x3+x+1)g = (x+1)(x^3+x+1), y en efecto (x+1)(x3+x+1)=x4+x3+x2+1(x+1)(x^3+x+1) = x^4 + x^3 + x^2 + 1.

En resumen

  • Un código es cíclico si es lineal y cerrado por desplazamientos cíclicos. Con polinomios, desplazar es multiplicar por xx módulo xn−1x^n - 1.
  • Todo código cíclico tiene un polinomio generador g(x)g(x), divisor de xn−1x^n - 1, y sus palabras son los múltiplos de gg. La dimensión es k=n−deg⁡gk = n - \deg g.
  • Los códigos cíclicos de longitud nn se obtienen factorizando xn−1x^n - 1. Sobre F2\mathbb{F}_2 y n=7n = 7 hay 8, entre ellos dos [7,4,3][7,4,3].
  • Un código de Hamming [7,4,3][7,4,3] (equivalente al del hilo: el mismo con las posiciones reordenadas) es cíclico, con g(x)=1+x+x3g(x) = 1 + x + x^3.
  • Una palabra está en el código si y solo si el resto de dividirla entre gg es 0.

Siguiente lección: Codificar un código cíclico, y de ahí los CRC

Para profundizar