Sauter au contenu
Logo image

Section 8.2 Codes linéaires

Pour mieux connaître un code particulier et développer des techniques plus efficaces d’encodage, de décodage et de détection d’erreurs, nous devons ajouter une structure supplémentaire à nos codes. Une façon d’y parvenir est d’exiger que le code soit également un groupe. Un code de groupe est un code qui est également un sous-groupe de \({\mathbb Z}_2^n\text{.}\)
Pour vérifier qu’un code est un code de groupe, il suffit de vérifier une seule chose. Si nous additionnons deux éléments quelconques du code, le résultat doit être un \(n\)-uplet qui est à nouveau dans le code. Il n’est pas nécessaire de vérifier que l’inverse du \(n\)-uplet est dans le code, puisque chaque mot de code est son propre inverse, et il n’est pas non plus nécessaire de vérifier que \({\mathbf 0}\) est un mot de code. Par exemple,
\begin{equation*} (11000101) + (11000101) = (00000000)\text{.} \end{equation*}

Exemple 8.2.1.

Supposons que nous avons un code qui consiste en les 7-uplets suivants :
\begin{align*} &(0000000) & & (0001111) & & (0010101) & & (0011010)\\ &(0100110) & & (0101001) & & (0110011) & & (0111100)\\ &(1000011) & & (1001100) & & (1010110) & & (1011001)\\ &(1100101) & & (1101010) & & (1110000) & & (1111111)\text{.} \end{align*}
C’est une tâche directe bien que fastidieuse de vérifier que ce code est également un sous-groupe de \({\mathbb Z}_2^7\) et, par conséquent, un code de groupe. Ce code est un code de détection et de correction d’erreur simple, mais c’est un processus long et fastidieux de calculer toutes les distances entre les paires de mots de code pour déterminer que \(d_{\min} = 3\text{.}\) Il est beaucoup plus facile de voir que le poids minimum de tous les mots de code non nuls est \(3\text{.}\) Comme nous le verrons bientôt, ce n’est pas une coïncidence. Cependant, la relation entre les poids et les distances dans un code particulier dépend fortement du fait que le code est un groupe.

Démonstration.

Supposons que \({\mathbf x}\) et \({\mathbf y}\) sont des \(n\)-uplets binaires. Alors la distance entre \({\mathbf x}\) et \({\mathbf y}\) est exactement le nombre de positions dans lesquelles \({\mathbf x}\) et \({\mathbf y}\) diffèrent. Mais \({\mathbf x}\) et \({\mathbf y}\) diffèrent dans une coordonnée particulière exactement quand la somme dans cette coordonnée est \(1\text{,}\) puisque
\begin{align*} 1 + 1 & = 0\\ 0 + 0 & = 0\\ 1 + 0 & = 1\\ 0 + 1 & = 1\text{.} \end{align*}
Par conséquent, le poids de la somme doit être la distance entre les deux mots de code.

Démonstration.

Observons que
\begin{align*} d_{\min} & = \min \{ d({\mathbf x},{\mathbf y}) : {\mathbf x}\neq{\mathbf y} \}\\ &= \min \{ d({\mathbf x},{\mathbf y}) : {\mathbf x}+{\mathbf y} \neq {\mathbf 0} \}\\ &= \min\{ w({\mathbf x} + {\mathbf y}) : {\mathbf x}+{\mathbf y}\neq {\mathbf 0} \}\\ & = \min\{ w({\mathbf z}) : {\mathbf z} \neq {\mathbf 0} \}\text{.} \end{align*}

Sous-section 8.2.1 Codes linéaires

À partir de Exemple 8.2.1, il est maintenant facile de vérifier que le poids minimal non nul est \(3\) ; par conséquent, le code détecte et corrige bien toutes les erreurs simples. Nous avons maintenant réduit le problème de trouver de « bons » codes à celui de générer des codes de groupe. Un moyen facile de générer des codes de groupe est d’utiliser un peu de théorie matricielle.
Définissons le produit scalaire de deux \(n\)-uplets binaires par
\begin{equation*} {\mathbf x} \cdot {\mathbf y} = x_1 y_1 + \cdots + x_n y_n\text{,} \end{equation*}
\({\mathbf x} = (x_1, x_2, \ldots, x_n)^\transpose\) et \({\mathbf y} = (y_1, y_2, \ldots, y_n)^\transpose\) sont des vecteurs colonnes.
 1 
Puisque nous travaillerons avec des matrices, nous écrirons les \(n\)-uplets binaires comme vecteurs colonnes pour le reste de ce chapitre.
Par exemple, si \({\mathbf x} = (011001)^\transpose\) et \({\mathbf y} = (110101)^\transpose\text{,}\) alors \({\mathbf x} \cdot {\mathbf y} = 0\text{.}\) Nous pouvons également considérer un produit scalaire comme le produit d’une matrice ligne par une matrice colonne ; c’est-à-dire,
\begin{align*} {\mathbf x} \cdot {\mathbf y} & = {\mathbf x}^\transpose {\mathbf y}\\ & = \begin{pmatrix} x_1 & x_2 & \cdots & x_n \end{pmatrix} \begin{pmatrix} y_1 \\ y_2 \\ \vdots \\ y_n \end{pmatrix}\\ & = x_{1}y_{1} + x_{2}y_{2} + \cdots + x_{n}y_{n}\text{.} \end{align*}

Exemple 8.2.4.

Supposons que les mots à encoder consistent en tous les \(3\)-uplets binaires et que notre schéma d’encodage est la parité paire. Pour encoder un \(3\)-uplet arbitraire, nous ajoutons un quatrième bit pour obtenir un nombre pair de \(1\)s. Remarquez qu’un \(n\)-uplet arbitraire \({\mathbf x} = (x_1, x_2, \ldots, x_n)^\transpose\) a un nombre pair de \(1\)s exactement quand \(x_1 + x_2 + \cdots + x_n = 0\) ; par conséquent, un \(4\)-uplet \({\mathbf x} = (x_1, x_2, x_3, x_4)^\transpose\) a un nombre pair de \(1\)s si \(x_1+ x_2+ x_3+ x_4 = 0\text{,}\) ou
\begin{equation*} {\mathbf x} \cdot {\mathbf 1} = {\mathbf x}^\transpose {\mathbf 1} = \begin{pmatrix} x_1 & x_2 & x_3 & x_4 \end{pmatrix} \begin{pmatrix} 1 \\ 1 \\ 1 \\ 1 \end{pmatrix} = 0\text{.} \end{equation*}
Cet exemple nous laisse espérer qu’il y a un lien entre les matrices et la théorie des codes.
Soit \({\mathbb M}_{m \times n}({\mathbb Z}_2)\) l’ensemble de toutes les matrices \(m \times n\) à entrées dans \({\mathbb Z}_2\text{.}\) Nous effectuons les opérations matricielles comme d’habitude sauf que toutes nos opérations d’addition et de multiplication se produisent dans \({\mathbb Z}_2\text{.}\) Définissons le noyau d’une matrice \(H \in {\mathbb M}_{m \times n}({\mathbb Z}_2)\) comme l’ensemble de tous les \(n\)-uplets binaires \({\mathbf x}\) tels que \(H{\mathbf x} = {\mathbf 0}\text{.}\) Nous notons le noyau d’une matrice \(H\) par \(\Null(H)\text{.}\)

Exemple 8.2.5.

Supposons que
\begin{equation*} H = \begin{pmatrix} 0 & 1 & 0 & 1 & 0 \\ 1 & 1 & 1 & 1 & 0 \\ 0 & 0 & 1 & 1 & 1 \end{pmatrix}\text{.} \end{equation*}
Pour qu’un \(5\)-uplet \({\mathbf x} = (x_1, x_2, x_3, x_4, x_5)^\transpose\) soit dans le noyau de \(H\text{,}\) il faut que \(H{\mathbf x} = {\mathbf 0}\text{.}\) Autrement dit, le système d’équations suivant doit être satisfait :
\begin{align*} x_2 + x_4 & = 0\\ x_1 + x_2 + x_3 + x_4 & = 0\\ x_3 + x_4 + x_5 & = 0\text{.} \end{align*}
L’ensemble des \(5\)-uplets binaires satisfaisant ces équations est
\begin{equation*} (00000) \qquad (11110) \qquad (10101) \qquad (01011)\text{.} \end{equation*}
Il est facile de vérifier que ce code est un code de groupe.

Démonstration.

Puisque chaque élément de \({\mathbb Z}_2^n\) est son propre inverse, la seule chose qu’il est vraiment nécessaire de vérifier ici est la clôture. Soient \({\mathbf x}, {\mathbf y} \in \Null(H)\) pour une matrice \(H\) dans \({\mathbb M}_{m \times n}({\mathbb Z}_2)\text{.}\) Alors \(H{\mathbf x} = {\mathbf 0}\) et \(H{\mathbf y} = {\mathbf 0}\text{.}\) Donc
\begin{equation*} H({\mathbf x}+{\mathbf y}) = H{\mathbf x} + H{\mathbf y} = {\mathbf 0} + {\mathbf 0} = {\mathbf 0}\text{.} \end{equation*}
Par conséquent, \({\mathbf x} + {\mathbf y}\) est dans le noyau de \(H\) et doit donc être un mot de code.
Un code est un code linéaire s’il est déterminé par le noyau d’une matrice \(H \in {\mathbb M}_{m \times n}({\mathbb Z}_2)\text{.}\)

Exemple 8.2.7.

Soit \(C\) le code donné par la matrice
\begin{equation*} H = \begin{pmatrix} 0 & 0 & 0 & 1 & 1 & 1 \\ 0 & 1 & 1 & 0 & 1 & 1 \\ 1 & 0 & 1 & 0 & 0 & 1 \end{pmatrix}\text{.} \end{equation*}
Supposons que le \(6\)-uplet \({\mathbf x} = (010011)^\transpose\) est reçu. C’est une simple multiplication matricielle de déterminer si \({\mathbf x}\) est ou non un mot de code. Puisque
\begin{equation*} H{\mathbf x} = \begin{pmatrix} 0 \\ 1 \\ 1 \end{pmatrix}\text{,} \end{equation*}
le mot reçu n’est pas un mot de code. Nous devons soit tenter de corriger le mot, soit demander qu’il soit retransmis.