Le plus petit corps de nombres, celui des entiers modulo ,
ne contient que 0 et . On le note
.
Sur l'ensemble des -uplets de 0 ou de , les
opérations de
agissent composante par composante.
Par exemple pour :
Cet ensemble, noté
,
est un espace vectoriel sur
,
tout comme
est un espace
vectoriel sur
.
Deux éléments de
qui diffèrent en une seule coordonnée sont dits
voisins. Si on met une arête entre deux -uplets voisins, on
obtient un graphe, que l'on appelle l'hypercube de dimension
. Pourquoi hypercube ? La figure 4 devrait vous
convaincre.
Figure 4:
Cube en dimension . Chaque arête joint deux triplets
qui diffèrent par une seule coordonnée.
|
L'espace vectoriel
est-il une
fantaisie de mathématicien ? Pas du tout !
Les ordinateurs ne connaissent que les 0 et les
(les bits), rangés en mémoire
par -uplets, avec (les octets ou bytes), , ,
, ...
Ils peuvent représenter n'importe quel ensemble fini,
pourvu que l'on ait choisi au préalable une application injective
de cet ensemble dans
pour un certain . Cette
application s'appelle un code. Le plus connu est le code ASCII
standard qui associe caractères (chiffres, lettres, $, %,
, ...) aux éléments de
.
Les transmissions entre ordinateurs, que ce soit par câble, par
ondes radio ou infra-rouges, sont des échanges de signaux composés
de paquets de 0 et de , qui ont été codés par l'émetteur
et seront décodés par le récepteur. Mais si dans un paquet une
erreur est commise (un 0 est changé en ou le contraire), alors
le paquet entier, et peut-être tout le message, seront perdus. A
moins que l'on utilise un code correcteur d'erreurs.
Un code est «correcteur d'erreurs» si parmi les voisins dans
l'hypercube d'un
élément codé, on ne trouve jamais ni un autre élément
codé, ni l'un de ses voisins. De cette façon, si
un -uplet est reçu, soit il a été transmis sans erreur et
il figure dans le code, soit une erreur a été commise, et elle
sera corrigée en remplaçant le -uplet reçu par celui de
ses voisins qui figure dans le code. Cela ne fonctionne plus si deux
erreurs ou plus ont été commises, mais on peut généraliser :
il existe des codes capables de corriger plusieurs erreurs.
Contentons nous pour l'instant de comprendre le problème en
dimension (cf. figure 5). Supposons que
code un objet, alors aucun de ses voisins ne peut être
codant ; mais si un de ces voisins est reçu, il faut pouvoir le
relier à sans ambiguïté.
Donc les voisins des voisins de
0 ne peuvent pas non plus coder. Il reste vecteurs codants
possibles, , , , et
. Si l'un de ceux-là est codant, aucun des autres ne
peut l'être. Donc on ne peut utiliser que éléments, par exemple
et . Si une coordonnée est changée, on
pourra retrouver où est l'erreur et la corriger. Observons au
passage que l'ensemble
est un sous-espace
vectoriel de dimension de
: c'est une «droite»
vectorielle.
Figure 5:
Hypercube en dimension . Chaque arête joint deux quadruplets
qui diffèrent par une seule coordonnée.
|
Nous allons présenter un exemple de code correcteur d'erreur, le
code de Hamming. Notre objectif sera surtout de relier ses
propriétés aux applications linéaires sur
l'espace vectoriel
.
Nous considérons le problème de coder les éléments de
par ceux de
, donc de
définir une application injective
de
dans
.
Evidemment, doit être plus grand que
. Pour les codes de Hamming, on prend , et , où
est un certain entier. Nous prendrons l'exemple , donc nous
coderons les éléments de
par autant
d'éléments choisis dans
( éléments).
Dans la pratique, on
utilise les codes de Hamming pour des valeurs de beaucoup plus
élevées, et la «place perdue» n'est pas aussi importante qu'il y
paraît. Comme nous l'avons vu précédemment, si on
veut pouvoir corriger une erreur, deux mots du code ne peuvent ni
être voisins, ni avoir un voisin en commun. Ils doivent donc
différer en au moins coordonnées.
Nous devons donc trouver une application de
dans
, telle que les images de deux vecteurs quelconques
diffèrent en coordonnées au moins.
Dans toute la suite, les espaces vectoriels considérés sont munis
de leur base canonique.
Considérons l'application linéaire , de
dans
, définie par
la matrice suivante.
Notons
les vecteurs colonnes de . Pour
vérifier que est injective, c'est-à-dire que son noyau est
réduit au seul vecteur nul, il suffit de montrer que son image est
de dimension , ou encore que les vecteurs
forment une famille libre. On voit immédatement que c'est le cas en
examinant leurs dernières coordonnées.
Les 4 vecteurs
codent les 4 vecteurs de la base
canonique de
. Pour obtenir le code (l'image par )
d'un autre vecteur
de
, il suffit de le multiplier par la matrice
(toutes les opérations se font dans
, c'est-à-dire
modulo ). Voici par exemple le calcul de , avec
.
Observons que les dernières lignes de la matrice sont celles
de la matrice identité en dimension . Donc l'image par d'un
vecteur de bits quelconque se termine par ces mêmes
bits. Les trois bits de tête sont des «bits de correction». Nous
laissons au lecteur le soin de calculer les images par
des vecteurs de
et de vérifier que ces images
diffèrent deux à deux en au moins bits.
Pour comprendre comment fonctionne la
correction d'erreur, il faut considérer l'application linéaire
, de
dans
,
dont la matrice est la suivante.
Remarquez que les colonnes de sont les écritures en base des
entiers de à .
Proposition 10
Le noyau de l'application de matrice et l'image de
l'application de matrice sont le même sous-espace vectoriel
de dimension de
.
Démonstration : Il est facile de vérifier que l'image par des 4 vecteurs
est le vecteur nul. Ceci entraîne que
. Il suffit alors de montrer que les
dimensions de
et
sont toutes deux égales
à . Nous l'avons déjà fait pour
. Pour
, observons que les trois premiers vecteurs
colonnes de sont les vecteurs de la base canonique en
dimension . Donc
a pour dimension , et donc
a pour dimension , d'après le théorème du rang.
Par la proposition précédente, l'image par d'un vecteur
quelconque est dans le noyau de . Donc si un code a été
correctement transmis, son image par doit être nulle.
Reprenons le vecteur
et
supposons maintenant qu'une erreur a été commise sur son
codage : au lieu de transmettre le vecteur
, on a transmis
, c'est-à-dire que le cinquième bit a été
changé : c'est qui a été transmis, avec
. Puisque est le vecteur nul,
l'image par de est , à savoir la cinquième
colonne de .
Etant donné un vecteur de bits reçu, on commence par
prendre son image par (en le multipliant par la matrice ).
Si cette image est nulle, alors il n'y a
pas eu d'erreur de transmission, et il suffit de lire
les derniers bits du vecteur transmis. Si l'image est égale
à l'un des vecteurs colonnes de , disons le -ième,
alors le -ième bit du vecteur reçu est faux :
on le corrige et on lit ensuite les derniers bits du vecteur
corrigé.
© UJF Grenoble, 2011
Mentions légales