From 36875fc40ad33f0e5cfdd3604783ef63a26a9b45 Mon Sep 17 00:00:00 2001 From: Mysaa Date: Wed, 2 Jun 2021 15:12:22 +0200 Subject: [PATCH] =?UTF-8?q?Nouvel=20algorithme=20de=20d=C3=A9codage=20avec?= =?UTF-8?q?=20enregistrement=20dans=20un=20dictionnaire=20des=20syndromes?= =?UTF-8?q?=20Fin=20de=20la=20r=C3=A9daction=20du=20dossier=20(manque=20en?= =?UTF-8?q?core=20des=20finitions)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Code.ml | 35 ++++- Code.mli | 14 +- CompteRendu/.gitignore | 1 + CompteRendu/CompteRendu.tex | 25 +-- CompteRendu/print_output.svg | 294 +++++++++++++++++++++-------------- Makefile | 10 +- Math.ml | 43 ++++- Math.mli | 8 + Test.ml | 22 ++- 9 files changed, 307 insertions(+), 145 deletions(-) diff --git a/Code.ml b/Code.ml index d56bc06..6f4992d 100644 --- a/Code.ml +++ b/Code.ml @@ -22,8 +22,8 @@ * on représente un vecteur dans F_2 par un entier dont la décomposition binaire correspond aux composantes du vecteur * on représente une matrice par un liste d'entier, il s'agit de la liste de ses colonnes (qui sont donc des vecteurs) -*) -(* + + #cd "/home/mysaa/Documents/Arbeiten/TIPE2021/";; #load "Math.cmo";; *) @@ -132,6 +132,37 @@ let decoder code z = ;; +(*** Décodage avec stockage des syndromes ***) + +(* syndr est une fonction qui à un vecteur associe son syndrome. +En effet, la notion de syndrome dépend de quelle matrice H nous avons choisi. +Créer cette fonction ici permet de ne plus dépendre de la matrice H de code_lineaire *) +type classesLaterales = {syndr : Math.vecteur -> Math.vecteur; + erreur : Math.vecteur -> Math.vecteur; + babr : Math.vecteur Math.binabr};; + + +let genererClasses code = + let syndr = function z -> Math.produit code.h z in + let compacteur babr v = if BFeuille<>babr && not (appartenir code v) + then (print_int v;putWho babr (syndr v)) v false + else BFeuille in + let rec iter babr0 lst = + let svts = suivants code.n lst in + let babr = List.fold_left compacteur babr0 svts in + if babr<>BFeuille + then iter babr svts + else babr0 (*On a dépassé la capacité de correction*) + in + let babr = iter (put BFeuille 0 0) [0] in + let erreur = function z -> get babr z + in {syndr=syndr;erreur=erreur;babr=babr} +;; + +let decoder2 classes z :vecteur= + let s = classes.syndr z in + let e = classes.erreur s in + z lxor e;; end;; (*************************************************************) diff --git a/Code.mli b/Code.mli index e068fe7..7d50bd9 100644 --- a/Code.mli +++ b/Code.mli @@ -6,12 +6,22 @@ type t = { g : Math.matrice; h : Math.matrice; } type code_lineaire = t +exception PasDansLeCodeException val encoder : code_lineaire -> Math.vecteur -> Math.vecteur -val systematiqueFromRedondance : int -> int -> matrice -> code_lineaire +val systematiqueFromRedondance : int -> int -> Math.matrice -> code_lineaire val distance_minimale : code_lineaire -> int -val decoder : code_lineaire -> int -> Math.vecteur +val decoder : code_lineaire -> Math.vecteur -> Math.vecteur val appartenir : code_lineaire -> Math.vecteur -> bool + +type classesLaterales = { + syndr : Math.vecteur -> Math.vecteur; + erreur : Math.vecteur -> Math.vecteur; + babr : Math.vecteur Math.binabr; +} +val genererClasses : t -> classesLaterales +val decoder2 : classesLaterales -> Math.vecteur -> Math.vecteur + end module CCyclique : diff --git a/CompteRendu/.gitignore b/CompteRendu/.gitignore index 05fe48d..dfdb29d 100644 --- a/CompteRendu/.gitignore +++ b/CompteRendu/.gitignore @@ -6,3 +6,4 @@ *.toc *.thm svg-inkscape/ +print_output_path.svg diff --git a/CompteRendu/CompteRendu.tex b/CompteRendu/CompteRendu.tex index d6fb497..bad00ab 100644 --- a/CompteRendu/CompteRendu.tex +++ b/CompteRendu/CompteRendu.tex @@ -123,6 +123,7 @@ $$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. @@ -149,11 +150,10 @@ 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{definition}[Polynôme générateur] - Un polynôme $P$ de $\FD\,[X]$ de degré $n-k$ est dit \textbf{générateur du code cyclique $C$ de paramètre $(k,n)$} lorsque $P | X^n + 1$ 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 est $w$ le mot associé à $P$ - \end{definition} \begin{theoreme}[Théorème fondamental des codes cycliques] - Tout code cyclique admet un et un seul polynôme générateur. + 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 est $w$ le mot associé à $y$ \end{theoreme} \begin{remarque} @@ -211,20 +211,25 @@ 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}{} + \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 -> Math.vecteur -> bool} + \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}{} - 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}{} + \fsign{distance\_minimale}{code\_lineaire -> int}{non} + 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é}). Le calcul s'effectue en recherchant le plus petit mot (au sens du poids) qui soit dans le code. + \fsign{decoder}{code\_lineaire \into vecteur \into Math.vecteur}{euhhhhhhhh} + Décode le mot de $\FD^n$ donné. L'algorithme recherche le mot le plus proche du mot recu qui soit dans le code et à une distance inferieure à la distance de correction. Si il est impossible de décoder, renvoie une exception du type \verb|IndecodableException|. + + \fsign{genererClasses}{code\_cyclique \into classes\_latérales}{well ...}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. + + \fsign{decoder2}{classes\_latérales \into vecteur \into vecteur}{n\cdot \ln(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} \part*{Annexes} \begin{figure}[h] \begin{center} \label{print_matriceExemple} - \includesvg[scale=.3]{print_output.svg} + \includesvg[scale=.3]{print_output_path.svg} \caption{Exemple d'affichage de vecteur,matrice et polynômes} \end{center} \end{figure} diff --git a/CompteRendu/print_output.svg b/CompteRendu/print_output.svg index cd59494..b5c0c47 100644 --- a/CompteRendu/print_output.svg +++ b/CompteRendu/print_output.svg @@ -25,9 +25,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="1.979899" - inkscape:cx="10.04794" - inkscape:cy="216.89603" + inkscape:zoom="0.35" + inkscape:cx="-109.9148" + inkscape:cy="-17.849234" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="false" @@ -48,7 +48,7 @@ image/svg+xml - + @@ -58,120 +58,178 @@ id="layer1" transform="translate(-0.53453934,-1.3999026)"> - - - - - - - - - - - - - - - - - - - - - - - - - - - + width="256.40485" + height="132.93906" + x="-1.7333201" + y="-5.4036703" /> + X^1 + X^2 + X^31 + X^21 + X^1 + X^4 + X^6 + X^9 + ┌011┐│101││111││100│└001┘ + ┌1┐│1││0││1││0││0││1││1│└0┘ + ┌100101110┐│101011000││011000000│└101011001┘ + + + + diff --git a/Makefile b/Makefile index 51bc595..4d4f9cc 100644 --- a/Makefile +++ b/Makefile @@ -7,14 +7,12 @@ ascii: $(shell find textes/ -type f -iname "*.txt" ! -iname "*.ascii.txt" | sed %.cmx: %.ml ocamlopt -c $< -Code.cmo: Code.ml Math.cmo +Code.cmo: Code.ml Code.mli Math.cmo ocamlc -c "Code.mli" ocamlc -c "Code.ml" -%.cmi: %.mli - ocamlc -c $< -%.cmo: %.ml - if [ -f $*".mli" ]; then ocamlc -c $*".mli" ; fi - ocamlc -c $< +Math.cmo: Math.ml Math.mli + ocamlc -c Math.mli + ocamlc -c Math.ml tipe: tipe.cmx ocamlopt -o tipe str.cmxa tipe.cmx diff --git a/Math.ml b/Math.ml index d74ce3f..2d20244 100644 --- a/Math.ml +++ b/Math.ml @@ -130,11 +130,44 @@ let poldiveuc (p:polynome) (q:polynome) : (polynome * polynome) = let poldiv (p:polynome) (q:polynome) : polynome = fst (poldiveuc p q);; let polrst (p:polynome) (q:polynome) : polynome = snd (poldiveuc p q);; - - - - - +(***************** Arbres de recherche de 'vecteurs' *****************) +type 'a binabr = BNoeud of 'a binabr * 'a binabr | BVal of 'a * 'a binabr | BFeuille;; + +let isEmpty babr = babr=BFeuille;;(* Ne renvoie que les biens fondés, c'est à dire sans Noeud vide*) + +exception NoSuchKeyException;; +let rec get ba (k:vecteur) = + match (ba,k) with + | (BNoeud(_,_) ,0) + | (BFeuille ,_) -> raise NoSuchKeyException + | (BVal(v,rr) ,0) -> v + | (BVal(v,rr) ,_) -> get rr k + | (BNoeud(t0,t1),_) -> + match k mod 2 with + | 0 -> get t0 (k lsr 1) + | 1 -> get t1 (k lsr 1) + | _ -> failwith "Félicitations, vous avez cassé les maths";; + + +let rec putWho ba (k:vecteur) v keepNew = + match (ba,k) with + | (BVal(old,rr) ,0) -> if keepNew then BVal(v,rr) else BVal(old,rr) + | (BFeuille ,0) + | (BNoeud(_,_) ,0) -> BVal(v,ba) + | (BVal(o,rr) ,_) -> BVal(o,putWho rr k v keepNew) + | (BFeuille ,_) -> putWho (BNoeud(BFeuille,BFeuille)) k v keepNew + (*match k mod 2 with + | 0 -> BNoeud(putWho BFeuille (k lsr 1) v keepNew, BFeuille) + | 1 -> BNoeud(BFeuille, putWho BFeuille (k lsr 1) v keepNew) + | _ -> failwith "Ich gratuliere Sie. Sie haben Mathe zerbrochen" + end*) + | (BNoeud(t0,t1),_) -> + match k mod 2 with + | 0 -> BNoeud(putWho t0 (k lsr 1) v keepNew, t1) + | 1 -> BNoeud(t0, putWho t1 (k lsr 1) v keepNew) + | _ -> failwith "99 7'4 c0mp1373m3n7 c4553 135 m47h5. 7u 73 23nd5 c0mp73 ?!";; + +let put ba k v = putWho ba k v true;; (* Par défaut, on garde le nouveau *) diff --git a/Math.mli b/Math.mli index 0ae1060..8ab2ac8 100644 --- a/Math.mli +++ b/Math.mli @@ -24,3 +24,11 @@ val polmul : polynome -> polynome -> polynome val poldiveuc : polynome -> polynome -> polynome * polynome val poldiv : polynome -> polynome -> polynome val polrst : polynome -> polynome -> polynome + + +type 'a binabr = BNoeud of 'a binabr * 'a binabr | BVal of 'a * 'a binabr | BFeuille + +exception NoSuchKeyException +val get : 'a binabr -> vecteur -> 'a +val putWho : 'a binabr -> vecteur -> 'a -> bool -> 'a binabr +val put : 'a binabr -> vecteur -> 'a -> 'a binabr diff --git a/Test.ml b/Test.ml index 45dc12a..7c5d2d3 100644 --- a/Test.ml +++ b/Test.ml @@ -6,6 +6,24 @@ Sys.command "make Math.cmo Code.cmo";; open Math;; open Code;; +let print_boolean b = match b with + | true -> print_string "true" + | false -> print_string "false";; + +let codeh = CLineaire.systematiqueFromRedondance 4 7 [7; 3; 5; 6];; +let vecteurs = matriceAuPif 9 (8-1);; +print_matrice 4 vecteurs;; +let classes = CLineaire.genererClasses codeh;; +let test v = try + CLineaire.encoder codeh (CLineaire.decoder codeh v) <> CLineaire.decoder2 classes v + with + Code.CLineaire.PasDansLeCodeException -> (print_int v;print_endline "*\n";false) in +List.find_opt test vecteurs;; +CLineaire.decoder codeh 119;; +CLineaire.encoder codeh 1;; +CLineaire.decoder2 classes 119;; +exit 0;; + (* Test du produit de matrice *) let matest = [0b01110; 0b00101; 0b10111];; print_matrice 5 matest;; @@ -16,7 +34,7 @@ let pol1 = 13 and pol2 = 67;; print_polynome pol1;; print_polynome pol2;; print_polynome (polmul pol1 pol2);; -let qt,rst=(poldiveuc pol2 pol1) in +let qt,rst=(poldiveuc pol2 pol1) in print_polynome qt; print_polynome rst;; @@ -78,7 +96,7 @@ print_matrice 4 cocylined.h;; CLineaire.distance_minimale cocylined;; -print_vecteur 7 (cyclencode cocycl 0b1010);; +print_vecteur 9 203;; (* Essayons de générer une table d'addition *)