TIPE2021/CompteRendu/CompteRendu.tex

379 lines
19 KiB
TeX
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

% !TeX encoding = UTF-8
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[margin=0.5in]{geometry}
\usepackage{csquotes}
\usepackage[french]{babel}
\usepackage{tabularx}
\usepackage{theorem}
\usepackage{amsmath}
\usepackage{amssymb}
\let\theoremstyle\relax
\usepackage{amsthm}
\usepackage{calrsfs}
\usepackage{setspace}
\usepackage{stmaryrd}
\usepackage{svg}
\usepackage{bashful}
\usepackage{pdfpages}
\bibliographystyle{plain}
\theorembodyfont{\upshape}
% Ajoute le joli séparateur entre les parties
\let\oldpart\part
\renewcommand\part{\hsep\oldpart}
% Un peu plus d'interligne, c'est plus lisible
\onehalfspacing
% Fait une jolie barre horizontale
\newcommand{\hsep}{\centerline{\rule{0.8\linewidth}{.05pt}}}
% Racourcis
\newcommand{\FD}{\mathbb{F}_2}
\newcommand\fsign[3]{\item \textbf{#1} : \textit{#2} \qquad Complexité en $\mathcal{O}(#3)$\\}
\newcommand\fsignz[2]{\item \textbf{#1} : \textit{#2}\\}
\newcommand\into{\textrightarrow\:}
\newtheoremstyle{break}
{\topsep}{\topsep}%
{}{}%
{\bfseries}{}%
{\newline}{}%
\theoremstyle{break}
\newtheorem{definition}{Définition}[section]
\newtheorem{theoreme}{Théorème}[section]
\theoremstyle{remark}
\newtheorem*{remarque}{Remarque}
%% Choose your 5/2
% 1: Dylan
% 2: Samy
% 3: Victor
\newcounter{cqd}
\setcounter{cqd}{2}
\newcommand\lequel[3]{
\ifnum\value{cqd}=1
#1
\else\ifnum\value{cqd}=2
#2
\else
#3
\fi\fi
}
%\usepackage[pdfauthor={\lequel{Dylan THEVENET}{Samy AVRILLON}{Victor BELLOT}}, pdftitle={Compte rendu du TIPE 2021}, pdftex]{hyperref}
\author{\lequel{Dylan THEVENET}{Samy AVRILLON}{Victor BELLOT}}
\title{Étude des codes correcteur d'erreurs}
\begin{document}
\lequel{
\includepdf[pages=-,linktodoc=false]{PageDeGarde-THEVENET.pdf}
}{
\includepdf[pages=-,linktodoc=false]{PageDeGarde-AVRILLON.pdf}
}{
\includepdf[pages=-,linktodoc=false]{PageDeGarde-BELLOT.pdf}
}
\maketitle
\hsep
\section*{Introduction}
\lequel{
Ce document est le compte rendu de mon TIPE fait pour l'année 2021.
Dans une société où de plus en plus d'échanges se font informatiquement, il est préférable d'avoir des algorithmes de transmission qui soient robustes aux erreurs, afin que l'information reçue soit la plus conforme possible à l'information envoyée.
Dans ce TIPE nous allons donc nous attacher à présenter quelques codes correcteurs d'erreurs, en particulier les codes cycliques, et nous développerons en particulier les outils mathématiques et les théorèmes qui nous assurent que ces codes sont efficaces.
}{
Puisque des erreurs de communication peuvent avoir des conséquences désastreuses, nous devons nous assurer que les nombreux échanges informatiques effectues chaque seconde se fassent sans dégradation de l'information. C'est pourquoi j'ai étudié pour mon TIPE les codes correcteurs d'erreurs, palliant en partie la défaillance naturelle des canaux de transmission (Exemple figure~\ref{gaussEx}). L'objectif premier est de créer un ensemble de modules OCaml permettant de manipuler et d'utiliser ces codes. Une première partie va donc s'intéresser aux différents concepts mathématiques derrière la théorie des codes correcteurs, ainsi qu'aux théorèmes qui permettront d'obtenir des algorithmes efficaces. La seconde partie va décrire les algorithmes et structures de données crées et décrire succinctement leur fonctionnement.
}{
Deutsches Ipsum Dolor sit Herr Doktor consectetur Nackenheim elit, danke do Guten Tag tempor Herr Doktor ut Hochzeit et Reise magna Gemeinsamkeit Ut Deutsche Mark ad Entschuldigung veniam, Danke nostrud Lukas Podolski ullamco Gesundheit nisi Die unendliche Geschichte aliquip Angela Merkel ea danke consequat. Grimms Märchen aute Entschuldigung dolor Schnaps reprehenderit Knappwurst voluptate Gesundheit esse Entschuldigung dolore Herr Doktor fugiat Kartoffelkopf pariatur. Joachim Löw sint Flughafen cupidatat Weltschmerz proident, Audi in Bezirksschornsteinfegermeister qui Stuttgart deserunt Die Ärzte anim Deutsche Mark est Aufschnitt
}
\ifnum\value{cqd}=1\else % Dylan n'a pas besoin de première partie
\part{Contexte mathématique}
\fi
\section{Codes}
\begin{definition}[Code, Codage]
On définit un code de paramètres $(n,k)$ comme une partie de $\FD^n$ associée à $\FD^k$. Un codage est une application de $\FD^k$ vers $\FD^n$ injective.
Un codage est dit systématique lorsque les $k$ premiers bits de l'image d'un élément sont égaux à cet élément.
\end{definition}
\begin{definition}[Distance de Hamming, Poids d'un mot]
La distance de Hamming entre deux mots $v$ et $w$ de $\FD^n$ est le nombre de coordonnées différentes des deux mots.
$$d(v,w) = \operatorname{card}(i\in \llbracket1,n\rrbracket,v_i \neq w_i)$$
Le poids d'un mot est son nombre de coordonnées non nulles, égal à sa distance au vecteur nul.
\end{definition}
\begin{definition}[Capacités d'un code]\label{thMinDist}
Étant donné un code $C$, on appelle capacité de détection $e_d$ et capacité de correction $e_c$ le plus grand nombre de bits erronés que l'on puisse détecter, respectivement corriger dans le code.
La distance minimale d'un code est la plus petite distance entre deux mots distincts du code.
$$d_C = \min_{x,y\in C\times C,x\neq y}\left(d(x,y)\right)$$
\end{definition}
\begin{theoreme}\label{thCapacité}
On peut alors exprimer $e_d$ et $e_c$ en fonction de $d_C$ :
$$ e_d = d_C - 1 \qquad e_c = \left\lfloor\frac{d_C - 1}{2}\right\rfloor$$
\end{theoreme}
\begin{definition}[Code Parfait]
Un code parfait est un code tel que pour tout mot $w$ de $\FD^n$, il existe un \underline{unique} mot de $C$ étant à une distance minimale de $w$. Autrement dit, il n'y a jamais d'ambigüité sur la façon de décoder un mot erroné.
\end{definition}
\begin{remarque}
Il n'existe que trois types de codes parfaits:
\begin{itemize}
\item Les codes de Hamming
\item Les codes de répétition pure
\item Le code de Golay binaire de longueur 23
\end{itemize}
\end{remarque}
\section{Codes linéaires}
On dit qu'un code est linéaire lorsqu'il a une structure naturelle de sous-espace vectoriel de $\FD^n$. Les codages linéaires associés sont des applications linéaires.
\begin{definition}[Matrice génératrice]
On appelle \textbf{matrice génératrice} d'un codage linéaire $\phi$ la matrice de $\mathcal{M}_{n,k}(\FD)$ associée à $\phi$.
\end{definition}
\begin{definition}[Matrice de contrôle]
On appelle \textbf{matrice de contrôle} n'importe quelle matrice de $\mathcal{M}_{n-k,n}(\FD)$ ayant $C$ pour noyau.
Tout code a au moins une matrice de contrôle.
\end{definition}
\begin{theoreme}[Calcul de distances]
La structure d'espace vectoriel ainsi que la définition~\ref{thMinDist} permettent de dire que la distance minimale d'un code linéaire est le plus petit poids non nul de ses vecteurs.
On peux aussi utiliser la borne de Singleton qui assure:
$$d_C \leqslant n+1-k$$
Enfin, on peut utiliser que la distance minimale d'un code linéaire est le nombre minimal de colonnes linéairement dépendantes de la matrice de contrôle $H$.
\end{theoreme}
Voici ici quelques concepts qui seront utiles au décodage.
\begin{definition}[Erreur et syndrome]
Si l'on souhaite envoyer un mot $X \in \FD^k$ qui est donc codé en $Y\in C$. Le mot réceptionné est $Z \in \FD^n$.
On appelle alors \textbf{mot erreur} le mot $E = Z - Y$.
On appelle \text{syndrome} le mot $S = H \cdot Z$.
On remarque que $E$ et $Z$ on le même syndrome. On peut plus généralement définir une relation d'équivalence «avoir le même syndrome». Les classes d'équivalence de cette relation sont appelées \textbf{classes latérales}.
\end{definition}
\section{Codes cycliques}
\begin{definition}[Code cyclique]
Un code linéaire est dit cyclique s'il est stable par décalage binaire cyclique. C'est à dire que si $w_1w_2w_3\ldots w_n$ est dans $C$ alors $w_2w_3w_4\ldots w_{n-1}w_nw_1$ appartient aussi à $C$.
On peut aussi définir le \textbf{code cyclique engendré} par un mot $w$, qui est le plus petit espace vectoriel stable par décalage cyclique qui contienne $w$.
\end{definition}
\begin{definition}
On définit le mot binaire associé au polynôme $P=\displaystyle\sum_{i=0}^{n-1}{a_i\cdotp X^i}$ comme étant le mot $a_0a_1\cdots a_{n-1}$. Le polynôme réciproquement associé à un mot binaire par ce procédé est appelé \textbf{représentation polynomiale} du mot.
\end{definition}
\begin{theoreme}[Théorème fondamental des codes cycliques]
Pour tout code cyclique $C$ de paramètres $(n,k)$, il existe un unique polynôme $g$ tel que le mot associé à $g$ engendre $C$ et que $g|X^n-1$. Ce polynôme est alors appelé \textbf{polynôme générateur du code cyclique $C$}.
On démontre que ce $g$ est alors de degré $n-k$ et que $(\sigma^i(w))_{i\in \llbracket 0,k-1\rrbracket}$ est une base de $C$ avec $\sigma$ l'opérateur de décalage binaire cyclique et $w$ le mot associé à $g$
\end{theoreme}
\begin{remarque}
Un codage naturel pour un code cyclique apparaît avec le polynôme générateur. Le codage appliqué à un mot $w$ est le mot associé au produit du polynôme générateur et du polynôme associé à $w$.
\end{remarque}
\ifnum\value{cqd}=1
\section{Codes BCH}
\begin{definition}[Racine primitive n-ième de l'unité]
On appelle \textbf{racine primitive n-ième de lunité} un nouveau nombre $\alpha$, tel que $\alpha^n = 1$ et $\forall k \in \llbracket1,n-1\rrbracket\,\alpha^k \neq 1$.
Ce nest pas un élément de $\FD$.
On peut donc factoriser $X^n+1 = \displaystyle\prod_{k=0}^{n-1}{\left(X-\alpha^k\right)}$, mais les termes ne sont malheureusement pas dans $\FD[X]$.
\end{definition}
\begin{definition}
On définit $\FD(\alpha)$ comme le plus petit corps contenant à la fois $\FD$ et le nouvel élément $\alpha$.
Alors, $\FD(\alpha) = \left\{P(\alpha) | P\in\FD[X]\right\}$
\end{definition}
\begin{definition}
$I = \left\{P \in \FD [X] | P(\alpha) = 0\right\}$ est un idéal de $\FD[X]$ engendré par un unique polynôme unitaire $M_\alpha$
\end{definition}
\begin{theoreme}
$\FD(\alpha)$ contient $2^q$ éléments, où $q = deg(M_\alpha)$
On peut de la même manière construire des corps de taille $p^m$, où $p$ est un nombre premier et $m$ est un entier naturel non nul.
\end{theoreme}
\begin{theoreme}
Soit $P$ un polynôme à coefficients dans $\FD (\alpha)$. On a léquivalence :
$$P\text{ est un polynôme à coefficients dans } \FD \iff P(X)^2 = P(X^2)$$
\end{theoreme}
\begin{theoreme}
Soit $P(X)= \displaystyle\prod_{i\in\Sigma} (X - \alpha^i)$
Alors $P(X) \in \FD [X]$ $\iff$ $\Sigma$ est stable par multiplication par 2 modulo n.
\end{theoreme}
Doù la définition suivante :
\begin{definition}[Classes cyclotomiques]
On appelle \textbf{classe cyclotomique engendrée par $j$} lensemble $\left\{j, 2j,\cdots, 2^{s-1}j\right\}$ (où les entiers sont réduits modulo n) avec $2^s j \equiv j\mod\,n$
Cest une partie de ${0,..., n - 1}$ stable par multiplication par 2 et minimale pour linclusion.
\end{definition}
Les classes cyclotomiques permettent donc de factoriser complètement $X^n + 1 dans \FD [X]$
\begin{theoreme}[Théorème BCH]
On note $C$ le code cyclique associé à la partie stable $\Sigma = \left\{i_1 ,\cdots, i_{n-k} \right\}$ (donc de polynôme générateur $\displaystyle\prod_{i\in\Sigma}{(X-\alpha^i)}$)
Sil existe des entiers $a$ et $s$ tels que $\Sigma$ contienne $a, a + 1, \cdots, a + s$ alors la distance minimale de $C$ est supérieure ou égale à $s+1$.
\end{theoreme}
\else
\part{Réalisation informatique}
\section{Des structures de données}
La première étape était de créer des structures de données adéquates, c'est à dire permettant d'effectuer les calculs nécessaire à l'utilisation des codes linéaires à moindre coût (temporel). Pour cela, on considère en temps constant les opérations suivantes: (\verb|lor,land,lxor,lsl,lsr,=,<,>| et les opérations internes aux structures de contrôle, comme \verb|if, for, match|...)
\subsection{Matrices et vecteurs}
Puisque nous avons affaire à des vecteurs de $\FD^n$ on peut les stocker sous forme d'entier «informatique». Nous sommes alors limités par la taille des mots du processeur, typiquement 32 bits ou 64 bits. Mais il est toujours possible de créer des entiers binaires virtuellement plus «grand». Un autre problème est qu'on ne peut pas récupérer la dimension d'un vecteur, et nous devons donc transmettre la donnée à coté.
Les matrices sont elles, des listes de vecteurs et sont donc naturellement stockées comme listes d'entiers binaires. On utilisera la structure de liste chainée native d'OCaml.
J'ai ensuite codé les fonctions suivantes: (Les complexités sont données pour des matrices de $\mathcal{M}_{n,k}(\FD)$, les opérations bit à bit se faisant à temps constant, ce qui est vrai pour les entiers natifs).
\begin{itemize}
\fsign{produit}{matrice \into vecteur \into vecteur}{k} Renvoie simplement le vecteur produit $Y = M \cdot X$
\fsign{identite}{int \into matrice}{n} Renvoie la matrice identité de $\mathcal{M}_n(\FD)$
\fsign{print\_matrice}{int \into matrice \into unit}{nk} Affiche la matrice dans le terminal. Il faut spécifier la dimension verticale (des vecteurs). Un exemple de valeur de sortie est donnée figure~\ref{print_matriceExemple}
\fsign{print\_vecteur}{int \into vecteur \into unit}{n} Affiche le vecteur dans le terminal, vu comme une matrice de $\mathcal{M}_{n,1}(\FD)$ (Exemple figure~\ref{print_matriceExemple})
\end{itemize}
\subsection{Polynômes}
De la même manière, les polynômes sont des vecteurs de l'espace vectoriel $\FD[X]$. On peut donc eux aussi les stocker comme entiers binaires, avec l'entier écrit en base 2: $a_0a_1a_2\cdots a_d$ correspondant au polynôme $P=\displaystyle\sum^d_{i=0}a_i\cdot X^i$. Là encore, nous nous limitons aux polynômes de degré 31 ou 63, à moins d'utiliser des objets virtuels plus avancés.
Les fonctions suivantes ont été créées (les complexités sont données pour les polynômes $P$ et $Q$ de degrés respectifs $p$ et $q$).
\begin{itemize}
\fsign{degre}{polynome \into int}{p} Renvoie le degré du polynôme
\fsign{polmul}{polynome \into polynome \into polynome}{\min(p,q)} Effectue le produit de deux polynômes dans l'algèbre $\FD[X]$
\fsign{poldiveuc}{polynome \into polynome \into polynome $\times$ polynome}{p^2} Effectue la division euclidienne de $P$ par $Q$.
\fsign{print\_polynome}{polynome \into unit}{p}(Exemple figure~\ref{print_matriceExemple})
\end{itemize}
\subsection{Codes}
Les différents codes (linéaires et cycliques) sont stockés comme des enregistrements.
Les codes linéaires sont la donnée de leurs matrices génératrice et une matrice de contrôle (redondante) ainsi que k et n (nécessaire car les «matrices» n'ont pas la donnée de leur hauteur). Bien que l'on puisse déduire une matrice de contrôle de la matrice génératrice, ce calcul peut se révéler coûteux.
Les codes cycliques sont simplement les données de k, de n et du polynôme générateur.
Les fonctions suivantes permettent de manipuler les structures:
\begin{itemize}
\fsign{systematiqueFromRedondance}{int \into int \into matrice \into code\_lineaire}{k} Renvoie le code linéaire systématique associé à la matrice de redondance de $\mathcal{M}_{n-k,k}$.
\end{itemize}
\section{Liste des fonctions}
J'ai ensuite écrit des fonctions permettant de manipuler les codes linéaires:
\begin{itemize}
\fsign{encoder}{code\_lineaire \into vecteur \into vecteur}{k}
Encode le vecteur de $\FD^k$ suivant le code linéaire spécifié, il s'agit alors d'un simple produit avec la matrice génératrice.
\fsign{appartenir}{code\_lineaire -> vecteur -> bool}{n}
Renvoie \textit{vrai} si et seulement si le vecteur appartient au code, c'est à dire, si et seulement si $HX=0$ avec $H$ la matrice de contrôle et $X$ le vecteur de $\FD^n$ en question.
\fsign{distance\_minimale}{code\_lineaire -> int}{n2^{d_C}}
Renvoie la distance minimale du code, utilisée pour calculer les capacités de détection et de correction du code (voir théorème~\ref{thCapacité}). Le calcul s'effectue en recherchant le plus petit mot (au sens du poids) qui soit dans le code.
\fsignz{decoder}{code\_lineaire \into vecteur \into Math.vecteur}
Décode le mot de $\FD^n$ donné. L'algorithme recherche le mot le plus proche du mot reçu qui soit dans le code et à une distance inférieure à la distance de correction. Si il est impossible de décoder, renvoie une exception du type \verb|IndecodableException|.
\fsign{genererClasses}{code\_lineaire \into classes\_latérales}{n\cdot2^k}Génère les classes latérales associées au code spécifié. Parcours les vecteurs par poids croissant (d'abord ceux de poids 1, puis 2, etc…) et référence leur syndrome dans \verb|classes.rpz : vecteur -> vecteur| qui à un syndrome associe le représentant de la classe latérale de poids le plus faible. Cette fonction est enregistrée comme un arbre binaire de recherche vis à vis de l'ordre lexicographique sur $\FD^n$, permettant un stockage et une recherche en $\mathcal{O}(n)$
\fsign{decoder2}{classes\_latérales \into vecteur \into vecteur}{n} Décode le mot $Z$ de $\FD^n$ donné. L'algorithme calcule le syndrome du mot, obtient le représentant de la classe latérale associée à ce vecteur $E$. Dans l'hypothèse où le mot reçu est effectivement décodable, alors, son «erreur» $E = Z-Y$, avec $Y$ le mot du code initialement envoyé, a la même classe latérale que $Z$. Donc $Y = Z+E$, on obtient un mot du code que l'on peut décoder.
\end{itemize}
\pagebreak
\part*{Annexes}
\begin{figure}[h]
\begin{center}
\includegraphics[width=.2\linewidth]{gaussV0-llow.png}
\includegraphics[width=.2\linewidth]{gaussVH-llow.png}
\hspace{.1\linewidth}
\includegraphics[width=.2\linewidth]{gaussV0-low.png}
\includegraphics[width=.2\linewidth]{gaussVH-low.png}
\small
Le codage utilisé est un codage d'Hamming (4,7).
Les images à gauche des paires correspondent à une transmission sans aucune correction.
\end{center}
\caption{Exemple d'application de codes correcteurs}
\label{gaussEx}
\end{figure}
\begin{figure}[h]
\begin{center}
\includesvg[scale=.3]{print_output_path.svg}
\caption{Exemple d'affichage de vecteur,matrice et polynômes}
\label{print_matriceExemple}
\end{center}
\end{figure}
\begin{figure}
\lstinputlisting[basicstyle=\scriptsize,language=Caml,frame=single]{../Math.mli}
\end{figure}
\begin{figure}
\lstinputlisting[basicstyle=\scriptsize,language=Caml,frame=single]{../Code.mli}
\end{figure}
\begin{figure}
\lstinputlisting[basicstyle=\scriptsize,linerange={48-59,105-128,133-134},language=Caml,frame=single]{../Math.ml}
\end{figure}
\begin{figure}
\lstinputlisting[basicstyle=\scriptsize,linerange={140-166},language=Caml,frame=single]{../Code.ml}
\end{figure}
\nocite{*}
\fi
\pagebreak
\bibliography{biblio}
\end{document}