diff --git a/Code.ml b/Code.ml index b468f78..d56bc06 100644 --- a/Code.ml +++ b/Code.ml @@ -131,8 +131,6 @@ let decoder code z = | (_, e) -> antecedent code ((lxor) z e) ;; -let cyclencode code (x:vecteur) :vecteur = polmul code.pol x;; - end;; @@ -150,6 +148,8 @@ type code_cyclique = t;; let get k n pol = {k=k;n=n;pol=pol};; +let cyclencode code (x:vecteur) :vecteur = polmul code.pol x;; + end;; (*************************************************************) @@ -191,4 +191,4 @@ let lineaireVersCyclique code = -(* Voilà *) \ No newline at end of file +(* Voilà *) diff --git a/Code.mli b/Code.mli index 4f845ee..e068fe7 100644 --- a/Code.mli +++ b/Code.mli @@ -8,7 +8,7 @@ type t = { type code_lineaire = t val encoder : code_lineaire -> Math.vecteur -> Math.vecteur -val systematiqueFromRedondance : int -> int -> int list -> code_lineaire +val systematiqueFromRedondance : int -> int -> matrice -> code_lineaire val distance_minimale : code_lineaire -> int val decoder : code_lineaire -> int -> Math.vecteur val appartenir : code_lineaire -> Math.vecteur -> bool diff --git a/CompteRendu/.gitignore b/CompteRendu/.gitignore index cd039b8..05fe48d 100644 --- a/CompteRendu/.gitignore +++ b/CompteRendu/.gitignore @@ -5,3 +5,4 @@ *.synctex.gz *.toc *.thm +svg-inkscape/ diff --git a/CompteRendu/CompteRendu.tex b/CompteRendu/CompteRendu.tex index 9471d68..d6fb497 100644 --- a/CompteRendu/CompteRendu.tex +++ b/CompteRendu/CompteRendu.tex @@ -13,6 +13,7 @@ \usepackage{calrsfs} \usepackage{setspace} \usepackage{stmaryrd} +\usepackage{svg} \usepackage{bashful} @@ -31,6 +32,8 @@ % Racourcis \newcommand{\FD}{\mathbb{F}_2\hspace{-.2em}} +\newcommand\fsign[3]{\item \textbf{#1} : \textit{#2} \qquad Complexité en $\mathcal{O}(#3)$\\} +\newcommand\into{\textrightarrow\:} \newtheoremstyle{break} {\topsep}{\topsep}% @@ -80,7 +83,7 @@ $$d_C = \min_{x,y\in C\times C}\left(d(x,y)\right)$$ \end{definition} - \begin{theoreme} + \begin{theoreme}\label{thCapacité} On peut alors exprimer $e_d$ et $e_c$ en fonction de $d_C$ : $$ e_c = d_C - 1 \qquad e_d = \left\lfloor\frac{d_C - 1}{2}\right\rfloor$$ @@ -131,7 +134,7 @@ 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} + 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'équivale nce de cette relation sont appelées \textbf{classes latérales}. \end{definition} \section{Codes cycliques} @@ -159,7 +162,71 @@ \part{Algorithmes} \section{Des structures de données} - \section{Liste des fonctions} + 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 cycliques à moindre coût (temporel). + + \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. + + + Nous avons 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} + + + Nous avons ensuite écrit des fonctions permettant de manipuler les codes linéaires: + \begin{itemize} + \fsign{encoder}{code\_lineaire \into Math.vecteur \into Math.vecteur}{} + 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 -> Math.vecteur -> bool} + 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}{} + Renvoie la distance minimale du code, utilisée pour calculer les capacités de détéction et de correction du code (voir \ref{thCapacité}) + \fsign{decoder}{code\_lineaire \into int \into Math.vecteur}{} + \end{itemize} + + \part*{Annexes} + \begin{figure}[h] + \begin{center} + \label{print_matriceExemple} + \includesvg[scale=.3]{print_output.svg} + \caption{Exemple d'affichage de vecteur,matrice et polynômes} + \end{center} + \end{figure} \end{document} diff --git a/CompteRendu/print_output.svg b/CompteRendu/print_output.svg new file mode 100644 index 0000000..cd59494 --- /dev/null +++ b/CompteRendu/print_output.svg @@ -0,0 +1,177 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Makefile b/Makefile index 6108f82..51bc595 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,9 @@ ascii: $(shell find textes/ -type f -iname "*.txt" ! -iname "*.ascii.txt" | sed %.cmx: %.ml ocamlopt -c $< -Code.cmo: Math.cmo - +Code.cmo: Code.ml Math.cmo + ocamlc -c "Code.mli" + ocamlc -c "Code.ml" %.cmi: %.mli ocamlc -c $< %.cmo: %.ml diff --git a/Math.mli b/Math.mli index 48f67f9..0ae1060 100644 --- a/Math.mli +++ b/Math.mli @@ -1,20 +1,26 @@ type vecteur = int type matrice = int list type polynome = int + +val deux_puissance : int -> int +val changer_bit : int -> int -> int +val decagauche : int -> int -> int + val nthOfBinarint : int -> int -> string val print_matrice : int -> matrice -> unit val print_vecteur : int -> vecteur -> unit val print_polynome : polynome -> unit + val produit : matrice -> vecteur -> vecteur -val deux_puissance : int -> int +val identite : int -> matrice val orderize : 'a -> 'a -> 'a * 'a -val identite : int -> int list -val changer_bit : int -> int -> int -val decagauche : int -> int -> int + + val respecter : int -> int list -> bool val matriceAuPif : int -> int -> matrice -val polmul : polynome -> polynome -> polynome + val degre : polynome -> int +val polmul : polynome -> polynome -> polynome val poldiveuc : polynome -> polynome -> polynome * polynome val poldiv : polynome -> polynome -> polynome val polrst : polynome -> polynome -> polynome