#import "@preview/polylux:0.4.0": * #import "@preview/cetz:0.5.0" #set page( paper: "presentation-4-3", margin: 0cm, ) // Font #set text( font: "New Computer Modern", size: 20pt, fill: black, ) // Infos #let auteur = "Anthony PERRONI" #let numero = "49871" #let titre = "Codes LDPC" #let annee = "2025 - 2026" // Template #let myslide(partie, contenu) = slide[ // Header #block(width: 100%, fill: black, inset: (top: 0.6cm, bottom: 0.6cm, left: 1.5cm, right: 1.5cm))[ #set text(fill: white, size: 28pt, weight: "bold") #partie ] // Contenu #pad(x: 1.5cm, top: 0.2cm)[ #set text(size: 20pt) #contenu ] // Footer #v(1fr) #context { let cur = counter(page).get().first() let tot = counter(page).final().first() if cur > 1 { block(width: 100%, fill: black, inset: (top: 0.2cm, bottom: 0.2cm, left: 1.5cm, right: 1.5cm))[ #set text(fill: white, size: 12pt, weight: "bold") #grid( columns: (1.5fr, 2fr, 1fr, auto), align: (left, center, center, right), [#auteur n°#numero], [#titre], [#annee], [#(cur - 1) / #(tot - 1)], ) ] } } ] // Plan // Plan #let design_plan(items) = { let r = 6pt let epaisseur = 2pt let hauteur_ligne = 2.5em let espace_vertical = 20pt pad(left: 1cm, top: 1cm)[ #block[ #place(dx: r, dy: hauteur_ligne / 2)[ #line( length: (items.len() - 1) * (hauteur_ligne + espace_vertical), angle: 90deg, stroke: epaisseur + black, ) ] #grid( columns: (2 * r, auto), column-gutter: 20pt, row-gutter: espace_vertical, // On applique la variable ici ..items .map(item => ( box(height: hauteur_ligne, align(center + horizon)[ #circle(radius: r, fill: white, stroke: epaisseur + black) ]), box(height: hauteur_ligne, align(left + horizon)[ #text(weight: "bold", size: 1.1em)[#item] ]), )) .flatten() ) ] ] } // Page de garde #slide[ #v(1fr) #align(center)[ #pad(x: 1.5cm)[ #text(size: 3em, weight: "bold")[#titre] #v(0cm) #text(size: 1.4em)[*#auteur n°#numero*] \ #v(1cm) #text(size: 1.1em)[#annee] ] ] #v(1fr) ] #myslide("Plan")[ #design_plan(( [Introduction], [Codes linéaires], [LDPC], [Codage], [Décodage], [Analyse], )) ] #myslide("Introduction : transmission numérique")[ // Schema Shannon #align(center + horizon)[ #cetz.canvas({ import cetz.draw: * // Styles let s = (stroke: 2pt + black) let s_fleche = (stroke: 2pt + black) let pointe_pleine = (end: "stealth", fill: black) let espacement = 5.5 // Blocs content((0, 0), [Source], name: "src", frame: "rect", ..s, padding: .3) content((espacement, 0), [Emetteur], name: "em", frame: "rect", ..s, padding: .3) content((espacement * 2, 0), [Canal], name: "chan", frame: "rect", ..s, padding: .3) content((espacement * 3, 0), [Récepteur], name: "rec", frame: "rect", ..s, padding: .3) content((espacement * 4, 0), [Destinataire], name: "dest", frame: "rect", ..s, padding: .3) // Bruit content((rel: (0, 1.8), to: "chan"), [Bruit], name: "bruit", frame: "rect", ..s, padding: .3) // Codage / Décodage content((rel: (0, 1), to: "em"), [*Codage*]) content((rel: (0, 1), to: "rec"), [*Décodage*]) // Flèches (On utilise s_fleche et pointe_pleine) line("src.east", "em.west", mark: pointe_pleine, ..s_fleche) line("em.east", "chan.west", mark: pointe_pleine, ..s_fleche) line("chan.east", "rec.west", mark: pointe_pleine, ..s_fleche) line("rec.east", "dest.west", mark: pointe_pleine, ..s_fleche) line("bruit.south", "chan.north", mark: pointe_pleine, ..s_fleche) // Annotation let note-style = (size: 0.75em, style: "italic") content((espacement * 0.5, -0.5), text(..note-style)[Message]) content((espacement * 1.5, -0.5), text(..note-style)[Signal]) content((espacement * 2.5, -0.5), text(..note-style)[Signal]) content((espacement * 3.5, -0.5), text(..note-style)[Message]) }) ] #v(5cm) image de mon drone FPV, 5G ] #myslide("Problématique")[ #align(center)[ Comment utiliser les codes LDPC pour garantir la fiabilité d'une transmission en présence de bruit ? ] ] #myslide("Définition : Codes Linéaires")[ $cal(C)$ de paramètres $(n, k) in NN^2$, ($n > k$) // $Phi : & FF_2^k --> FF_2^n \ // & x arrow.long.bar Phi(x) = c$ // $Phi : #box(baseline: 1.6em)[$ cases( // delim: "|", // bb(F)_2^k & arrow bb(F)_2^n, // x & arrow.long.bar Phi(x) // ) $]$ // $Phi$ linéaire et injective Espace des messages : $FF_2^k$\ Espace des mots transmis :$FF_2^n$ Redondance de $n - k$ bits Rendement $display(R = k / n)$ #align(center)[ #cetz.canvas(length: 1.5cm, { import cetz.draw: * // Styles let style-pointille = (stroke: (paint: black, thickness: 1.2pt, dash: "dashed")) let style-point = (fill: black, stroke: none) let rayon-point = 0.08 let pointe-fleche = (end: "stealth", fill: black) let m = ( p00: (-4, 0), p01: (-2, 0), p11: (-2, -2), p10: (-4, -2), ) // Arêtes pointillés line(m.p00, m.p01, m.p11, m.p10, close: true, ..style-pointille) // Points sur les sommets circle(m.p00, radius: rayon-point, ..style-point) circle(m.p01, radius: rayon-point, ..style-point) circle(m.p11, radius: rayon-point, ..style-point) circle(m.p10, radius: rayon-point, ..style-point) // Étiquettes content(m.p00, [00], anchor: "south-east", padding: .2) content(m.p01, [01], anchor: "south-west", padding: .2) content(m.p11, [11], anchor: "north-west", padding: .2) content(m.p10, [10], anchor: "north-east", padding: .2) content((-3, -3), [$FF_2^2$]) line((-1.2, -1), (1.2, -1), mark: pointe-fleche, stroke: 1.5pt + black) content((0, -0.6), [*Plongement*]) // Sommets face arrière let cb = (p000: (2.5, 0), p001: (4.5, 0), p011: (4.5, -2), p010: (2.5, -2)) // Sommets face avant (décalés) let cf = (p100: (3.5, 1), p101: (5.5, 1), p111: (5.5, -1), p110: (3.5, -1)) // Arêtes pointillés du cube line(cb.p000, cb.p001, cb.p011, cb.p010, close: true, ..style-pointille) // Face arrière line(cf.p100, cf.p101, cf.p111, cf.p110, close: true, ..style-pointille) // Face avant line(cb.p000, cf.p100, ..style-pointille) // Liaisons line(cb.p001, cf.p101, ..style-pointille) line(cb.p011, cf.p111, ..style-pointille) line(cb.p010, cf.p110, ..style-pointille) // Points sur les sommets du cube circle(cb.p000, radius: rayon-point, ..style-point) circle(cb.p001, radius: rayon-point, ..style-point) circle(cb.p011, radius: rayon-point, ..style-point) circle(cb.p010, radius: rayon-point, ..style-point) circle(cf.p100, radius: rayon-point, ..style-point) circle(cf.p101, radius: rayon-point, ..style-point) circle(cf.p111, radius: rayon-point, ..style-point) circle(cf.p110, radius: rayon-point, ..style-point) // Étiquettes du cube content(cb.p000, [000], anchor: "south-east", padding: .2) content(cb.p001, [001], anchor: "south-west", padding: .2) content(cb.p011, [011], anchor: "north-west", padding: .2) content(cb.p010, [010], anchor: "north-east", padding: .2) content(cf.p100, [100], anchor: "south-east", padding: .2) content(cf.p101, [101], anchor: "south-west", padding: .2) content(cf.p111, [111], anchor: "north-west", padding: .2) content(cf.p110, [110], anchor: "north-east", padding: .2) content((4, -3), [$FF_2^3$]) }) ] ] // #myslide("Définition : Codes Linéaires")[ // // Matrice génératrice : $op("Mat")_cal(B)(Phi) = G in cal(M)_(k, n)(FF_2)$, $op("rg")(G) = k$ // // // $cal(C) = op("Im")(Phi) = {x G | x in FF_2^k}$ // // Forme bilinéaire symétrique : // $forall x, y in FF_2^n, space (x|y)_(FF_2^n) = display(sum_(i=0)^n x_i y_i)$ // // Encodage : // $Phi : #box(baseline: 1.6em)[$ cases( // delim: "|", // FF_2^k & -> FF_2^n, // x & arrow.long.bar Phi(x) // ) $]$ // // $Phi in cal(L)(FF_2^k, FF_2^n)$, $op("rg")(Phi) = k$, $Phi$ injective // // $cal(C) = op("Im")(Phi)$ // // $G = op("Mat")_cal(B)(Phi) in cal(M)_(k,n)(FF_2)$ // Pour $x in FF_2^k, Phi(x) = x G$ // // $Phi$ admet un unique adjoint $Phi^*$, // $ // forall x in FF_2^k, forall y in FF_2^n, (Phi(x) | y)_(FF_2^n) = (x, Phi(y)^*)_(FF_2^k) // $ // de plus $cal(C)^bot = op("Im")(Phi)^bot = ker(Phi^*)$ et $dim(cal(C)^bot) = n - k$ // // Equation du code dual : $y in cal(C^bot) <==> Phi(y)^* = 0 <==> y G^T = 0$ // // De plus $display((cal(C)^bot)^bot) = cal(C)$ (car non dégénérée) // // // ] // // #myslide("Définition : Codes Linéaires")[ // // $(h_1, ..., h_(n-k))$ base de $cal(C)^bot$ // Définisson $H in cal(M)_(n-k, n)(FF_2)$ avec les $h_i$ comme lignes // $H$ : matrice de contrôle de parité // // $forall c in FF_2^n, c in cal(C) <==> c H^T = 0$ // // $S : #box(baseline: 1.6em)[$ cases( // delim: "|", // FF_2^n & -> FF_2^(n-k), // y & arrow.long.bar y H^T // ) $]$ // et $ker(S) = cal(C)$ ... // // ] #myslide("Définition : Codes Linéaires")[ faire un truc plus theoriques... ] #myslide("Définition : Codes Linéaires")[ - Matrice génératrice $G in cal(M)_(k,n)(FF_2)$ - Encodage : $m in FF_2^k, c = m dot.o G$ - Forme systématique : $G = [I_k | P]$ avec $P$ matrice de parité - Matrice de contrôle de parité $H = [- P^top | I_(n-k)]$ $c in FF_2^n$ est un mot de code valide $<==>$ $c^top dot.o H = 0$ De plus $G dot.o H^T = 0$ ] #myslide("Définition : Codes Linéaires")[ Reception de $r = c + e$ avec $c in cal(C), e in FF_2^n$ $r^top dot.o H = s$ le syndrome $(c + e)^top H = c^top H + e^top H = e^top H$ ] #myslide("Redondance et limite théorique")[ Graphique waterfall avec n = 100 et n = 64800 avec limite de Shannon, $display(R = k /n) < 1$, $m = n - k$ Bande passante... Il existe $C$ pour un canal tel que pour $R < C$ on peut atteindre une probabilité d'erreur nulle. $=>$ gros bloc (moyenne du bruit aléatoire) ] #myslide("Décodage par Maximum de Vraisemblance")[ Trouver le message envoyer le + probable sachant le message recu : NP-COMPLET (Max) Decodage par syndrome d'une code lin'aire général est NP-Complet Complexité $O(2^k)$ ] #myslide("LDPC")[ Matrice $H$ clairsemée(low density) donc complexité mointre, pas de produit de matrice mais algorithme itératif efficace quasi linéaire Graphique d'un H très grand clairesemée avec plein de 0, généré en rust par exemple où les 1 sont des points noir et le reste du blanc Défniition avec (w_r,w_c) ] #myslide("Graphe de Tanner")[ Il existe un isomorphisme entre H et le Graphe de Tanner Graphe de tanner (cetz) Contrainte de somme nulle ] #myslide("Encodage")[ ] #myslide("Décodage")[ Canal d'étude (AWGN) analogique, tension etc, ce qui se passe en radio dans les cables etc ] #myslide("Hard decoding")[ Nul (0 ou 1) transition perte d'information ] #myslide("Implementation")[ ] #myslide("Soft decoding")[ belief propagation, log ou virgule fixe, explication resultat meilleur ] #myslide("Implementation")[ ] #myslide("Test")[ Irl hackrf, test de diff de debit avec des paquets ] #myslide("Image")[ Test de transmission d'image avec différent ldpc non opti et opti (le H) ] #myslide("Annexe")[ Annexe ] #myslide("Théorie deriere la définition des codes linaires")[ Poser les notations algebriques ] #myslide("Unicité de l'adjoint")[ Unicité de l'adjoint pour une forme bilinéaire symétrique non dégénérée. ]