Vous êtes sur la page 1sur 16

CH.

2 CODES CORRECTEURS
• 2.1 Le canal bruité
• 2.2 La distance de Hamming
• 2.3 Les codes linéaires
• 2.4 Les codes de Reed-Muller
• 2.5 Les codes circulaires
• 2.6 Le câblage des codes circulaires
• 2.7 Les performances pratiques

Codage ch 2 1

2.1 Le canal bruité


On considère une source qui envoie un message constitué d'une suite de
0 et 1 (on peut aussi considérer un alphabet plus grand). Un message peut
alors être vu comme un mot x. Ce message va être codé y et transmis
à travers un canal bruité. Il s'agit d'un canal de communication qui
transmet des bits mais qui en modifie certains en cours de transmission.
Il peut soit les rendre illisibles (effacement), soit les échanger. On va
supposer que certains bits sont échangés.
A l'autre extrémité du canal, on reçoit donc un autre mot, y' = y + e, où
e est le vecteur d'erreurs. Il code les positions où les bits de y ont été
modifiés. Le décodeur doit, dans la mesure du possible, retrouver
le vecteur y pour en déduire le x transmis. Ce qui revient au même,
le décodeur doit trouver le vecteur d'erreurs en ne connaissant que le
mot y' reçu.

Codage ch 2 2
Source Codeur Décodeur Récepteur
x x
y Canal y'
bruité

Un code simple est le code à répétition de longueur 3 :


chaque octet de x est répété 3 fois.
Si x = 00101011, alors y = 00101011 00101011 00101011.

Supposons que le canal modifie tous les bits de la sixième à la treizième


position incluses. Donc, y' = 00101100 11010011 00101011. Le vecteur
d'erreurs est ici e = 00000111 11111000 00000000.

En effectuant bit par bit un décodage à la majorité, on reconstitue le


vecteur x. Tout vecteur d'erreurs comportant des 1 dans au plus 8
positions consécutives sera ainsi corrigé.
Un tel entrelacement permet ainsi la correction d'erreurs en rafale.

Codage ch 2 3

2.2 La distance de Hamming


Nous allons considérer uniquement des codes de longueur fixe n sur
l'alphabet {0, 1}.

Pour que l'altération d'un bit d'un mot du code permette de retrouver
le mot d'origine, il est nécessaire que ce mot altéré ne soit pas
dans le code. Le nombre de bits où deux mots diffèrent est appelé
distance de Hamming de ces deux mots. C'est une distance au
sens mathématique.

Puisque les mots sont binaires, si on note e = x + y, la distance de


Hamming d(x , y) = d(0, e) est le poids, ou nombre de 1 de e.

Lorsqu'on reçoit un mot y, on va supposer qu'il résulte d'un mot du code


par l'altération du minimum de bits. On cherche donc le mot x le plus
proche de y.
Codage ch 2 4
Si deux mots du code x et y diffèrent en 2e positions ou moins, une
modification de e bits de x et de e bits de y peuvent donner le même
mot. En revanche, si on est sûr que deux mots quelconques diffèrent
en 2e + 1 positions au moins, une modification de e bits d'un mot
permettra de retrouver le mot d'origine.

Théorème
Un code C est e-correcteur si et seulement si la distance minimum de
deux mots de C est supérieure ou égale à 2e +1.

On peut imaginer chaque mot du code entouré d'une sphère de rayon e.


Le code est e-correcteur si et seulement si ces sphères sont disjointes.

On a intérêt à avoir un code comportant le plus possible de mots pour une


longueur donnée n. Ce problème est un cas particulier du problème
consistant à trouver un empilement compact de sphères.
Codage ch 2 5

Malheureusement, le problème de l'empilement des sphères est NP...

La situation la plus favorable se présente lorsque tous les mots de 2n


sont dans une sphère. On dit qu'on a alors un code e-correcteur
parfait de longueur n.

Les codes à répétition tel que {000, 111} sont parfaits, mais pas très
intéressants. Nous verrons d'autres exemples de codes binaires parfaits.

Codage ch 2 6
2.3 Les codes linéaires
Pour des raisons pratiques (facilité de codage et de décodage), on
va s'intéresser à une classe particulière de codes correcteurs qui
sont les codes linéaires.

Il a en fait été démontré par van Lint que le théorème de Shannon


restait vrai même si on imposait aux codes d'être linéaires.

On considère ici les mots du code comme des vecteurs dans l'espace
vectoriel de dimension n sur le corps à deux éléments F2. Un code
linéaire est un sous-espace vectoriel de F2n. Comme tout sous-espace
vectoriel, un code linéaire a donc une dimension k. Le nombre de
mots d'un tel code est donc 2k.

Si x et y sont deux mots d'un code linéaire, il en est de même de x + y.

Codage ch 2 7

Si donc la distance minimum entre deux mots du code est 2e + 1, en


ajoutant ces deux mots, on trouve un autre mot non nul du code,
de poids 2e + 1. D'où la proposition suivante.

Proposition
Un code linéaire C est e-correcteur si et seulement si le poids minimum
d'un mot non nul de C est 2e + 1.

Les trois paramètres longueur n, dimension k et poids minimum d'un


mot non nul d permettent d'en évaluer les performances. On dit qu'on
a affaire à un code [n, k, d].

Par exemple, le code {000, 111} est [3, 1, 3].

Codage ch 2 8
Si on considère une base e1, e2, ... , ek d'un code C, tout mot de ce code
est déterminé par les k coordonnées de ce mot sur cette base, qui est
une suite de k bits..

Le code étant linéaire, il suffit pour trouver l'image d'une suite de k bits,
de connaître les coordonnées dans F2n des k vecteurs de base. Le vecteur
x1e1 + x2e2 + ... + xkek aura donc ses coordonnées données par le produit
de matrices [ x ] G = [ y ], où G est la matrice k x n dont les lignes sont
constituées des coordonnées des k vecteurs e1, e2, ... , ek.

La matrice G est appelée matrice génératrice du code.

Les vecteurs e1, e2, ... , ek sont linéairement indépendants, donc la matrice
G est de rang maximum k. On peut donc, quitte à effectuer un
changement de base (pivot), supposer qu'elle est de la forme suivante.

Codage ch 2 9

G = [ Ik A ], où Ik est la matrice identité de taille k et A est une matrice


k x (n – k).

Par exemple, considérons le code engendré par

1000111
0100011
G=
0010101
0001110
Ce code est de longueur 7 et de dimension 4. C'est le code de
Hamming [7, 4].
L'image du vecteur [ 1 0 1 1] est donc [ 1 0 1 1 1 0 0 ]

On constate que le vecteur à coder se retrouve sur les k premières


positions du code. Les n – k bits suivants du code sont appelés
bits de contrôle.
Codage ch 2 10
Comment effectuer le décodage et quelles sont les capacités de
correction d'un code linéaire ?

Dans l'exemple précédent, on pourrait vérifier que le poids minimum d'un


mot du code est 3. Le code est alors un code [7, 4, 3] et donc permet
la correction d'une erreur.

Il n'est pas nécessaire d'écrire tous les mots du code pour faire cette
vérification. On peut utiliser des propriétés générales d'algèbre
linéaire.

Les éléments d'un sous-espace vectoriel de dimension k sont définis


par un ensemble de n – k équations linéaires. Il est facile de trouver
ces équations, étant donnée la forme de particulière de G.

Codage ch 2 11

Théorème
Un vecteur y appartient au sous-espace engendré par la matrice
G = [ Ik A ] si et seulement s'il satisfait [ y ] H = 0, où
A
H= , dans laquelle In – k est la matrice identité de taille n – k.
In – k

Pour le démontrer, on remarque que le produit G H = 0 (produit


par blocs des matrices). Donc si [ y ] = [ x ] G, on a [ y ] H = 0.

Réciproquement, puisque la matrice H est de rang n – k, l'ensemble des


solutions du système [ y ] H = 0 est un sous-espace de dimension k. On
sait que les éléments du sous-espace engendré par G satisfont ce
système et sont de dimension k. C'est donc exactement l'ensemble des
solutions.

Cette matrice H est appelée matrice de contrôle de parité.


Codage ch 2 12
Si on reçoit le vecteur y' = y + e, on peut calculer le produit de
matrices [ y' ] H. C'est un vecteur-ligne de taille n – k, qu'on
appelle le syndrome de y' .

Puisque [ y ] H = 0, le syndrome ne dépend pas de y, mais du vecteur


d'erreurs e. Pour corriger les erreurs, il faut pouvoir, avec la seule
connaissance du syndrome, identifier le vecteur d'erreurs. Pour
pouvoir corriger une erreur, il suffit que les n + 1 syndromes
correspondant aux n + 1 vecteurs d'erreurs de poids 0 ou 1 soient
différents.
De même, pour corriger deux erreurs, il suffit que les syndromes
correspondant aux n(n – 1)/2 + n + 1 vecteurs de poids
0, 1 ou 2 soient différents.
Et ainsi de suite.

Codage ch 2 13

Le syndrome du vecteur nul vaut toujours 0.


Les syndromes des n vecteurs de poids 1 sont les n lignes de H.

On a donc pour les codes 1-correcteurs le résultat agréable suivant.

Proposition
Un code est 1-correcteur si et seulement si les lignes de sa matrice de
contrôle de parité sont différentes deux à deux.

Si on reprend le code de Hamming [7, 4], on trouve comme matrice


de contrôle de parité :

Codage ch 2 14
111 Les lignes de cette matrice étant deux à deux
011 distinctes, le code est 1-correcteur.
101 Supposons que, comme dans l'exemple, le
H= 110 vecteur à coder soit x = [ 1 0 1 1]. Son image
100 par multiplication par G est y = [ 1 0 1 1 1 0 0 ].
010 Si le vecteur reçu est y' = [ 1 0 0 1 1 0 0 ], donc avec
001 une erreur sur le 3e bit, celle-ci va être
détectée parce que le syndrome de y' vaut [ 1 0 1 ]. C'est la troisième
ligne de H, donc le syndrome de e = [ 0 0 1 0 0 0 0 ]. On a donc
pu corriger l'erreur sur ce 3e bit, reconstituer y = [ 1 0 1 1 1 0 0 ] et,
en gardant les 4 premières positions, retrouver x.

On peut remarquer que les 7 lignes de H sont tous les vecteurs possibles
de longueur 3. Tout vecteur de longueur 7 est donc soit un mot du code
de Hamming [7,4], soit n'en diffère que par un bit.

Codage ch 2 15

Le code de Hamming est donc un code binaire parfait.

On peut de la même manière construire un code de Hamming pour


toutes les valeurs de k. La matrice de contrôle de parité est constituée
de tous les 2k – 1 vecteurs non nuls de longueur k. On a donc
toujours un code 1-correcteur parfait. La matrice H est de taille
(2k – 1) x k. La matrice G est donc de taille k x (2k – k – 1).
Les codes de Hamming [2k – 1, 2k – k – 1] constituent donc une famille
infinie de codes 1-correcteurs parfaits

On a en fait le résultat plus fort suivant.


Théorème
Les seuls codes binaires parfaits sont :
- les codes à répétition [2k + 1, 1, k] ;
- les codes de Hamming [2k – 1, 2k – k – 1, 3] ;
- un code exceptionnel, le code de Golay [23, 12, 7].

Codage ch 2 16
2.4 Les codes de Reed-Muller
Il s'agit d'un algorithme permettant de fabriquer facilement des codes,
en particulier des codes linéaires, ayant des caractéristiques intéressantes
en termes de rapport dimension/longueur et de pouvoir de correction.
Ils ont été introduits par Reed et Muller vers 1954. L'un d'entre eux a été
utilisé par la NASA pour les missions spatiales de 1969 à 1976.

Soient C1 un code [n, k1, d1] et C2 un code [n, k2, d2] deux codes
linéaires de même longueur. On fabrique un nouveau code C3 = C1 * C2
de longueur 2n et de dimension k1+ k2 de la façon suivante :
les mots de C3 sont les mots w = (u, u + v) où u et v sont tous les mots
de C1 et de C2 respectivement. La longueur de C3 vaut bien 2n et sa
dimension k1+ k2.

Pour ce qui est du poids minimum d'un tel mot w, si v ≠ 0, son poids est
au moins celui de v. Sinon, son poids est deux fois celui de u.
Codage ch 2 17

En d'autres termes, C3 = C1 * C2 est un code [2n, k1+ k2, min(2d1, d2)].

Exemples :
Partons de {00, 01, 10, 11}, code [2, 2, 1] et de {00, 11}, code [2, 1, 2].
On fabrique un code [4, 3, 2] constitué de
{0000, 0011, 0101, 0110, 1010, 1001, 1111, 1100}.
Combinant celui-ci avec {0000, 1111} qui est un code [4,1,4], on
fabrique Ĥ, code [8, 4, 4]. Combinant de dernier avec un code [8, 1, 8],
on fabrique un code [16, 5, 8]. Celui-ci, à son tour combiné avec un
code à répétition [16, 1, 16] fournit un code [32, 6, 16] qui a été le code
utilisé par la NASA, code où 6 bits sont codés sur 4 octets avec une
capacité de corriger 7 erreurs (et d'en détecter 8, mais sans pouvoir
les corriger). On peut aussi mentionner les codes [32, 16, 8], proche des
caractéristiques du code de Golay, et un [128, 64,16].
Tous ces codes sont appelés codes de Reed-Muller.

Codage ch 2 18
En tant que codes linéaires, la cosntruction de la matrice génératrice
est très simple. Ik1 A1 Ik1 A1
Si G1 = [ Ik1 A1 ] et G2 = [ Ik2 A2 ], alors G3 =
0 Ik2 A2
Cette matrice n'est pas sous forme canonique, mais une permutation de
colonnes et quelques opérations de pivot peuvent la rendre canonique.
La matrice du code [8, 4, 4] appelé Ĥ est, après ces opérations de
normalisation, 10001110
01001101
Ĝ=
00101011
00010111
où on reconnaît la matrice engendrant le code de Hamming [7, 4, 3]
complété par un 8e bit de contrôle de parité (code de Hamming étendu).
Les autres codes de Hamming apparaissent aussi comme codes de
de Reed-Muller.

Codage ch 2 19

2.5 Les codes circulaires


Les codes linéaires gardent comme inconvénient de devoir faire des
produits de matrices pour effectuer le codage et le décodage et une
recherche dans une table pour effectuer la ou les corrections.

Pour pallier ces inconvénients, on s'intéresse ici à un type particulier


de codes linéaires appelés codes polynomiaux ou codes circulaires.

On considère un polynôme irréductible g(x), de degré k, sur le corps


F2. Ce polynôme est appelé polynôme générateur du code.

L'étude des anneaux de polynômes sur un corps fini et l'étude des


corps finis sont à la base des résultats sur les codes circulaires.

Codage ch 2 20
Parmi ces résultats, nous énoncerons le théorème suivant.

Théorème
Pour tout entier k positif, il existe au moins un polynôme irréductible
de degré k sur n'importe quel corps fini.

Par exemple, les polynômes x2 + x + 1, x3 + x + 1, x4 + x + 1 sont


irréductibles sur F2.

Calculons la suite des puissances de x modulo g.


Il y a un nombre fini de restes modulo g. Donc il existe deux exposants
u < v tels que xu = xv mod g. Donc xv – u = 1. La suite des puissances de
x est donc périodique. Le plus petit entier positif n tel que xn = 1 mod g
est appelé l'ordre de x mod g. On voit donc que g(x) divise xn – 1.

Nous supposerons que le corps est F2, donc + et – sont la même opération.

Codage ch 2 21

Par exemple, avec g = x3 + x + 1, on trouve, modulo g :


x0 = 1 ; x1 = x ; x2 = x2 ; x3 = x + 1 ; x4 = x2 + x ; x5 = x2 + x + 1 ; x6 = x2 + 1.
L'ordre de x vaut 7 et g divise x7 + 1.

On dispose donc d'un polynôme irréductible g de degré k et de l'ordre n


de x modulo g.

L'ensemble des polynômes de degré inférieur à n forme un espace


vectoriel de dimension n.
L'ensemble de ces polynômes qui sont des multiples de g forme un
sous-espace vectoriel. Pour savoir si un polynôme p est multiple de
g, on le divise par g et on regarde le reste de la division. L'application
qui à p associe son reste modulo g est une application linéaire. Les
polynômes 1, x, ... , xk – 1 sont invariants par cette application linéaire.
Le rang de cette application linéaire est donc k, la dimension de son
noyau ( = le sous-espace des multiples de g) est donc n – k.
Codage ch 2 22
On peut donc s'intéresser au code linéaire constitué des polynômes
de degré inférieur à n et multiples de g. Il s'agit d'un code [n, n – k].

Il est facile de trouver les multiples de g. Soit p un polynôme de degré


inférieur à n. On le divise par g, ce qui donne le quotient q et le
reste r : p = g q + r. Le polynôme p – r = gq est donc multiple de g
et de degré inférieur à n.

Pour coder un message de longueur n – k, on considère celui-ci comme


les coefficients d'un polynôme p contenant uniquement les puissances
xk à xn – 1. Le reste r de la division de p par g donne les k bits de
contrôle comme coefficients de r.
Le mot du code correspondant est donc s = p + r.

Codage ch 2 23

Les puissances xk , xk + 1 , ... , xn – 1 sont les messages de poids 1. Si on


sait comment ils sont codés, on retrouve le codage de n'importe quel
message par combinaison linéaire.

Par exemple, avec g = x3 + x + 1, on trouve, en fonction des calculs déjà


faits, x3 + x + 1, x4 + x2 + x, x5 + x2 + x + 1, x6 + x2 + 1 comme codages
respectifs de x3, x4, x5, x6. En écrivant suivant les puissances croissantes
et sous forme matricielle, si p = a1 x3 + a2 x4 + a3 x5 + a4 x6, le polynôme
codant le message est s = b0 + b1 x + b2 x2 + b3 x3 + b4 x4 + b5 x5 + b6 x6,
le passage de a à b se faisant de la manière suivante :
1101000
0110100
[b]=[a]
1110010
1010001

Codage ch 2 24
On reconnaît à permutation près la matrice génératrice du code de
Hamming [7,4].

Pour le décodage d'un code circulaire, si le polynôme reçu est s' = s + e,


on divise s' par g. On obtient comme reste le syndrome de s' qui est
aussi celui de e.

Le code est donc k-correcteur si les restes des polynômes de poids 0,


1, ... , k sont tous différents.

Dans notre exemple, les restes des puissances de x, donc des polynômes
de poids 1, sont tous différents, donc le code est 1-correcteur. De plus,
tous les syndromes possibles sont effectivement obtenus, donc le code
est parfait.

Codage ch 2 25

Le code [7, 4] engendré par x3 + x + 1 est un code 1-correcteur parfait.

Un polynôme irréductible g de degré k tel que x ait comme ordre 2k – 1


est appelé polynôme primitif. On montre que pour tout k il existe au
au moins un polynôme primitif de degré k. Ce polynôme engendre donc
un code 1-correcteur parfait, le code de Hamming [2k – 1, 2k – k – 1, 3].

Le code parfait exceptionnel de Golay, mentionné plus haut, est engendré


par le polynôme g = x11 + x9 + x7 + x6 + x5 + x + 1, dont on peut vérifier
qu'il est irréductible. L'ordre de x est 23. Le code engendré est donc un
code [23, 12]. On peut vérifier que tous les polynômes de degré au plus
22 et de poids inférieur ou égal à 3, ont tous des restes distincts modulo g.
Il y a 1 polynôme de poids 0, 23 de poids 1, 253 de poids 2 et 1771 de
poids 3, soit au total 2048. Comme il y a 2048 polynômes polynômes
de degré au plus 11, tous les syndromes possibles sont obtenus et
le code est parfait.
Codage ch 2 26
2.6 Le câblage des codes circulaires
Les codes circulaires peuvent être facilement implémentés en dur
au moyen de registres à décalage.

On va traiter l'exemple du code de Hamming [7, 4] engendré par


g = x3 + x + 1.

Pour réaliser la division d'un polynôme par g, on utilise le registre


à décalage suivant :
0 0 0
Les coefficients du polynôme à diviser entrent par la gauche, par ordre
décroissant des puissances. Les coefficients du quotient sortent
par la droite par ordre décroissant. Le registre contient au début 0 0 0
et à la fin les coefficients du reste, dans l'ordre 1, x, x2 de gauche à droite.
Les flèches réentrantes indiquent qu'il faut modifier le contenu du
registre si le bit sortant vaut 1 (ou exclusif).
Codage ch 2 27

La démonstration se fait en constatant que ce circuit réalise exactement


le schéma de la division euclidienne posée de la manière habituelle.

Par exemple, divisons p = x7 + x5 + x2 + x + 1 par x3 + x + 1.


Les coefficients de p sont par ordre croissant 1 1 1 0 1 1 0 1.
Les étapes sont (en gras, registre modifié par le bit en sortie) :
11100101 000
1110010 100
111001 010
11100 101
1110 100 1 début du quotient
111 010 01
11 101 001
1 000 1001
100 01001 quotient complet.

On trouve bien x7 + x5 + x2 + x + 1 = (x3 + x + 1)(x4 + x) + 1.


Codage ch 2 28
Ce dispositif peut être utilisé pour le codage : on rentre le message à
coder, complété par des 0 ; ce qui reste dans le registre à la fin est le
contrôle, qu'on transmet donc après le message.

Pour le décodage, on fait passer le mot reçu dans le registre. Ce qui reste
à la fin est le syndrome. On peut utiliser une table pour retrouver le
polynôme d'erreurs correspondant. Il existe aussi d'autres moyens.

Le registre est simple à câbler et permet un codage et un décodage à la


volée.

C'est pourquoi des codes correcteurs circulaires sont utilisés dans des
dispositifs tels que téléphones portables, CD et DVD (codes de Reed-
Solomon entrelacés), etc.

Codage ch 2 29

2.7 Les performances pratiques


La situation réelle d'un canal de transmission est la suivante :
Canal physique bruité

Source Codeur Décodeur Récepteur


x y x

Mais l'utilisateur voit en fait ça :

Source Récepteur
x

Un canal binaire symétrique est caractérisé par sa capacité C et la


probabilité p qu'un bit arrive avec la mauvaise valeur. Les bits sont
supposés indépendants et équiprobables.

Dans la situation réelle, un paquet de k bits est codé sur n bits. Ces n bits
transitent par un canal de caractéristiques C et p.
Codage ch 2 30
La probabilité qu'un paquet de n bits transmis soit correctement décodé
si on utilise un code 1-correcteur est donc
(1 – p)n [aucune erreur] + np (1 – p)n – 1 [une seule erreur]

Cette probabilité est donc celle qu'un message de k bits soit correctement
décodé.

Pour l'utilisateur, tout se passe comme si son message de k bits arrivait


sans erreur sur un canal binaire symétrique avec capacité Ck/n et
probabilité d'erreur par bit p'. Sur un tel canal, la probabilité qu'un
message de k bits arrive sans erreur est (1 – p')k. Donc,
p' = 1 – ((1 – p)n + np (1 – p)n – 1)1/k, soit, en prenant un développement
limité,
p' = 1 – (1 – n p + (n – 1) (n – 2)p2/2 – ... + np (1 – (n – 1) p + ...)) 1/k
= 1 – (1 – n (n – 1)p2/2 + ...) )1/k
= n (n – 1)p2/2k + ...
Codage ch 2 31

Avec un code de Hamming [7, 4], on trouve, pour le canal apparent,


C' = 4C/7 et p' ∼ 5,25p2. Si p = 10–3 (un bit sur 1000 erroné en moyenne),
le canal apparent a une capacité supérieure à la moitié et une probabilité
d'erreur par bit de p' ∼ 5,25.10–6 (5 bits sur un million).

Avec le code de Golay [23, 12] qui est 3-correcteur, un calcul analogue
donne C' = 12C/23 et p' ∼ 738p4. Avec les mêmes valeurs numériques
de départ, on trouve p' ∼ 7,38.10–10 (moins d'un bit sur un milliard).

La démonstration du théorème de Shannon est une formalisation


soigneuse de ce genre de calculs de probabilités.

D'autres techniques de fabrication de codes correcteurs existent : extensions


de corps, courbes elliptiques, géométries finies, etc.

Codage ch 2 32