#import "composants.typ": * #set page( paper: "presentation-4-3", margin: 0cm, ) // Font #set text( font: "New Computer Modern", size: 20pt, fill: black, ) #set math.mat(delim: "[") // Page de garde #slide[ #place(center + horizon)[ #graphe_tanner_fond(1cm, 1.5) ] #v(1fr) #align(center + horizon)[ #pad(x: 2cm)[ #text(size: 3em, weight: "bold", fill: black)[#titre] #text(size: 1.2em, weight: "bold", fill: black)[#auteur] #h(0.5em) #text(size: 1.2em, fill: black)[n°#numero] #text(size: 0.95em, fill: black)[#annee] ] ] #v(1fr) ] #myslide("Plan")[ #grid( columns: (auto, 1fr), align: horizon, place(center + horizon, dx: 11.8cm, dy: 0.7cm)[#decor_matrice_etoilee()], design_plan(( [Introduction], [Codes linéaires], [LDPC], [Codage], [Décodage], [Analyse], )), ) ] #myslide("Introduction : Communication Numérique")[ #place(center + horizon, dy: 8cm)[ #canal_shannon_intro() ] ] #myslide("Introduction : Utilisation")[ #align(center + horizon)[ #grid( columns: (1.5fr, 1.5fr), gutter: 1.5cm, align: center + horizon, [ #box(width: 80%)[ #stack( dir: ttb, spacing: -0.5em, image("src/athena_fidus_no_text.jpg", width: 100%), align(left)[ #box( inset: (x: 5pt, y: 0pt), text(size: 0.45em, fill: white)[* https://gallery.ariane.group *], ) ], ) ] #v(0.5em) Athena-Fidus ], [ #box(width: 80%)[ #stack( dir: ttb, spacing: -0.5em, image("src/runcamfpv2.png", width: 100%), align(left)[ #box( inset: (x: 5pt, y: 0pt), text(size: 0.45em, fill: white)[* https://www.runcam.com/ *], ) ], ) ] #v(0.5em) Module OpenIPC ], ) ] ] #myslide("Problématique")[ #place(center + horizon, dy: 8.1cm)[#graphe_tanner_fond(0.9cm, 1.75)] #place(center + horizon, dy: 7.7cm)[ #block(width: 100%)[ #text(size: 1.2em, weight: "bold", fill: black)[ Comment utiliser les codes LDPC pour garantir la fiabilité d'une transmission en présence de bruit ? ] ] ] ] #myslide("Définition : Codes Linéaires en Bloc")[ #definition(titre: [Code $display((n,k) in NN^2)$])[ $cal(C)$ sous-espace vectoriel de dimension $k$ de $FF_2^n$ ] #[ #set text(size: 1.1em) - $k$ : longueur du message original - $n$ : longueur du mot de code - $m = n - k$ : nombre de bits de parités ] #definition(titre: "Encodage")[ $Phi : FF_2^k & -> FF_2^n in cal(L)(FF_2^k, FF_2^n)$ ] #v(-1.3em) #uncover(2)[ #align(center + horizon)[ #plongement_schema() ] ] ] #myslide("Définition : Matrice Génératrice")[ #definition(titre: "Matrice Génératrice")[ $G in cal(M)_(k,n)(FF_2)$ dont les lignes sont une base de $cal(C)$ ] #definition(titre: "Encodage")[ Pour un message $u in FF_2^k$ le mot de code $c in cal(C)$ est : $ c = Phi(u) = u dot.o G $ ] #definition(titre: "Forme systématique")[ // TODO : changer [I_k | P] en un graphique jolie avec I et P dans un carré coloré $ #dessiner_matrice($G =$, ((texte: $I_k$, largeur: 2.2, fond: gray.lighten(75%)), (texte: $P$, largeur: 2.2, fond: gray.lighten(75%)))) // G = mat( // I_k, P; // augment: #1, // delim: "[", // ) $ ] #[ #set text(size: 1.2em) // - Pour $u in FF_2^k, space display(u dot.o G = mat(u, u dot.o P; augment: #1, delim: "[",))$ - Pour $u in FF_2^k, space #dessiner_matrice($u dot.o G =$, ( (texte: $u$, largeur: 1.1, fond: gray.lighten(75%)), (texte: $u dot.o P$, largeur: 3.0, fond: gray.lighten(75%)), ))$ - $P in cal(M)_(k ,n-k)(FF_2)$ matrice de parité\ ] ] #myslide("Définition : Matrice de Contrôle")[ #definition(titre: "Matrice de Contrôle")[ // $H = mat( // P^top, I_(n-k); // augment: #1, // delim: "[", // ) $ #dessiner_matrice($H =$, ( (texte: $P^top$, largeur: 2.2, fond: gray.lighten(75%)), (texte: $I_(n-k)$, largeur: 2.2, fond: gray.lighten(75%)), )) $ ] #[ #set text(size: 1.2em) - $cal(C) = ker(H) = {v in FF_2^n | H dot.o v^top = 0}$ - $display(G dot.o H^top = 0)$ ] #definition(titre: "Syndrome")[ Pour un vecteur reçu $r = c + e, space s in FF_2^(n - k)$ $ s = H r^top = H c^top + H e^top = 0 + H e^top $ ] #[ #set text(size: 1.2em) - Si $s = 0, space r$ est un mot de code valide - Sinon s donne la signature de l'erreur $e$ ] // Possible décodage par syndrome ] #myslide("Exemple d'un code linéaire")[ #[ #set text(size: 1.1em) #let col-u = blue #let col-p = orange #underline(offset: 3pt)[Exemple d'un code $(5,2)$] - On choisit la matrice de parité $P$ : $ P = #math.mat( (text(fill: col-p)[1], text(fill: col-p)[1], text(fill: col-p)[0]), (text(fill: col-p)[0], text(fill: col-p)[1], text(fill: col-p)[1]), ) $ - Alors la matrice génératrice $G$ est : $ G = #math.mat( (text(fill: col-u)[1], text(fill: col-u)[0], text(fill: col-p)[1], text(fill: col-p)[1], text(fill: col-p)[0]), (text(fill: col-u)[0], text(fill: col-u)[1], text(fill: col-p)[0], text(fill: col-p)[1], text(fill: col-p)[1]), augment: 2, ) $ - Message $display(u = #math.mat((text(fill: col-u)[1], text(fill: col-u)[1])))$ - Mot de code $c = u G$ : $ c = #math.mat((text(fill: col-u)[1], text(fill: col-u)[1])) #math.mat( (text(fill: col-u)[1], text(fill: col-u)[0], text(fill: col-p)[1], text(fill: col-p)[1], text(fill: col-p)[0]), (text(fill: col-u)[0], text(fill: col-u)[1], text(fill: col-p)[0], text(fill: col-p)[1], text(fill: col-p)[1]), augment: 2, ) = #math.mat(( text(fill: col-u)[1], text(fill: col-u)[1], text(fill: col-p)[1], text(fill: col-p)[0], text(fill: col-p)[1], )) $ ] ] #myslide("Exemple d'une code linéaire")[ #[ #set math.mat(delim: "[") #let colu = blue #let colp = orange #place(dx: 0cm, dy: 2.0cm)[ #set text(size: 1.1em) Enfin $ H = #math.mat( (text(fill: colp)[1], text(fill: colp)[0], 1, 0, 0), (text(fill: colp)[1], text(fill: colp)[1], 0, 1, 0), (text(fill: colp)[0], text(fill: colp)[1], 0, 0, 1), augment: 2, ) $ #v(0.8em) Vérification du mot de code $display(c = mat(#text(fill: colu)[1], #text(fill: colu)[1], #text(fill: colp)[1], #text(fill: colp)[0], #text(fill: colp)[1]))$ #v(0.8em) $ H c^top = mat( 1, 0, 1, 0, 0; 1, 1, 0, 1, 0; 0, 1, 0, 0, 1 ) mat(#text(fill: colu)[1], #text(fill: colu)[1], #text(fill: colp)[1], #text(fill: colp)[0], #text(fill: colp)[1])^top = mat( 1 plus.o 0 plus.o 1 plus.o 0 plus.o 0; 1 plus.o 1 plus.o 0 plus.o 0 plus.o 0; 0 plus.o 1 plus.o 0 plus.o 0 plus.o 1 ) = mat(0; 0; 0) $ ] ] ] // A REMPLACER AVEC DE VRAI DONNE SUR DE VRAI CODE LDPC ET HAMMING PAR EXEMPLE #myslide("Approcher la Limite de Shannon")[ // Faire un graphique waterfall comme sur les papiers de recherche... #limite_shannon_graphique() ] // #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("Le Mur de la Complexité")[ #set text(size: 19pt) #definition(titre: [Décodage par Maximum de Vraisemblance (MDL)], accent: black)[ Chercher le mot de code $bold(c) in cal(C)$ le plus probable sachant $bold(r)$ reçu : $ hat(bold(c)) = arg min_(bold(c) in cal(C)) d_H (bold(r), bold(c)) $ ] - Équivalent à chercher l'erreur $bold(e)$ de poids minimal tel que $bold(H) bold(e)^top = bold(s)$. #v(0.5em) #definition(titre: "Le Problème du décodage par Syndrome")[ NP-Difficile et pour $H$ quelconque : $cal(O)(2^k)$ ] - Pour $k=100$ bits, $2^100 approx 10^30$ opérations nécessaires. ] #myslide("Définition des Codes LDPC")[ #definition(titre: [Formalisation des Codes LDPC Réguliers])[ Code linéaire en bloc avec une matrice de contrôle $bold(H)$ est *clairsemée*. ] - *Poids de Colonne $w_c$* - *Poids de Ligne $w_r$* #v(0.5em) #definition(titre: "Conditions de Faible Densité", accent: black)[ #set align(center) $w_c << n - k$ #h(2cm) $w_r << n$ ] #definition(titre: "Rendement")[ $ display(R = (n - op("rg")(H)) / n >= 1 - m / n) $ ] ] #myslide([Matrice de contrôle])[ #definition(titre: [Code LDPC $(6, 3)$])[ $m w_r = n w_c$ donc $H in cal(M)_(15, 30)(FF_2)$ et $display(R = 1 - m / n = 1/2)$ ] #v(2cm) #place(center + horizon, dx: 0cm, dy: 7.3cm)[ #scale(140%)[#hldpc()] ] ] #myslide("De la Matrice aux Équations de Parité")[ #set text(size: 17pt) #let v_space = 2.83cm #align(center)[ #scale(115%)[ #grid( columns: (auto, auto), gutter: -15pt, align: horizon, [#hldpc_dual(row1: 0, row2: none)], [ // #set math.mat(gap: 24.5pt) #move(dy: 13.8pt)[ $ underbrace( mat(r_0; r_1; #v(v_space);dots.v; r_29; delim: "["), #text()[Mot reçu] r space in space FF_2^30 ) $ ] ], ) ] ] #v(0.5cm) #set text(size: 1.1em) - Chaque ligne $j$ de $H$ définit une équation de parité $f_j$. - Pour $r$, on vérifie le syndrome : $H r^top = 0$. #v(0.2cm) #definition(titre: [Équations de Parité], accent: orange)[ #set text(size: 1em) #text(fill: orange)[$ f_0 : r_7 plus.o r_10 plus.o r_15 plus.o r_22 plus.o r_24 plus.o r_29 = 0 $] ] #v(0.3cm) #text(size: 1.1em)[- Si $f_j = 1$, un nombre impair de bits a été inversé par le canal.] ] #myslide("L'Entrelacement des Contraintes")[ #set text(size: 17pt) #align(center)[ #move(dx: -1.2cm)[ #scale(115%)[#hldpc_dual(row1: 0, row2: 14)] ] ] #v(1cm) #set text(size: 1.1em) - Chaque bit $r_i$ participe à $w_c = 3$ équations distinctes #v(1cm) // --- Étage 2 : Système et Décision --- #set align(center + horizon) #scale(115%)[ #block(fill: gray.lighten(95%), inset: 10pt, stroke: 0.5pt + gray, radius: 4pt)[ $ cases( #text(fill: orange)[$r_7 plus.o r_10 plus.o r_15 plus.o r_22 plus.o bold(r_24) plus.o r_29 &= 0$], #h(4.5cm) #text(size: 20pt)[$bold(dots.v)$], #text(fill: blue)[$r_1 plus.o r_3 plus.o r_12 plus.o bold(r_24) plus.o r_25 plus.o r_28 &= 0$] ) $ ] ] #v(1cm) #set align(left) #set text(size: 1.1em) - *$r_24$* : Surveillé par #text(fill: orange)[$f_0$] et #text(fill: blue)[$f_14$]. - Si #text(fill: orange)[$f_0 = 1$] et #text(fill: blue)[$f_14 = 1$], $r_24$ est suspect ] #myslide("Graphe de Tanner : Définition")[ #set text(size: 1em) #definition(titre: [Graphe de Tanner $cal(G)(bold(H))$])[ #set text(size: 0.9em) Graphe bipartite $cal(G) = (#text(fill: blue)[$V$] union.sq #text(fill: orange)[$C$], E)$ : #v(4pt) $ (#text(fill: blue)[$v_j$], #text(fill: orange)[$c_i$]) in E space <==> space H_(i,j) = 1 $ ] #v(0.4em) #set text(size: 1.1em) #grid( columns: (1.4fr, 1fr), gutter: 1em, [- $#text(fill: blue)[$V$] = {#text(fill: blue)[$v_0$], dots, #text(fill: blue)[$v_(n-1)$]}$ nœuds de *variable*], [- $|E| = n dot #text(fill: blue)[$w_c$] = m dot #text(fill: orange)[$w_r$]$], [ - $#text(fill: orange)[$C$] = {#text(fill: orange)[$c_0$], dots, #text(fill: orange)[$c_(m-1)$]}$ nœuds de *contrôle* ], [- $H tilde.equiv cal(G)$], [- $deg(#text(fill: blue)[$v_j$]) = #text(fill: blue)[$w_c$]$], [- $deg(#text(fill: orange)[$c_i$]) = #text(fill: orange)[$w_r$]$], ) #align(center)[ #scale(115%)[ #tanner_illustration() ] #text(size: 0.8em, style: "italic", fill: gray.darken(20%))[ Exemple $n=4, space m=2$ ] ] ] #myslide("Construction du Graphe : Les Nœuds")[ #v(1.2em) #align(center)[ #scale(100%)[ // #h_mini_tanner() #grid( columns: (1fr, 1fr), gutter: 1em, [#hldpc_dynamic(hl_cols: range(30), show_labels: false, h_show: true)], [#hldpc_dynamic(hl_rows: range(15), show_labels: false, h_show: false)], ) ] ] #v(3.5em) #align(center)[ #scale(180%)[ #tanner_canvas(colored: true) ] ] // #v(2.5em) // #[ // #set text(size: 1.05em) // - Chaque *colonne* $j$ de $bold(H)$ $arrow$ nœud de variable #text(fill: blue, weight: "bold")[$v_j in V$] \ #text(fill: blue)[$n = 30$] nœuds, représentés par des *cercles* ○ // - Chaque *ligne* $i$ de $bold(H)$ $arrow$ nœud de contrôle #text(fill: orange, weight: "bold")[$c_i in C$] \ #text(fill: orange)[$m = 15$] nœuds, représentés par des *carrés* □ // - Les arêtes seront déterminées par les $1$ de $bold(H)$ — étapes suivantes // ] ] #myslide("Construction du Graphe : Nœud de Contrôle")[ #v(1.2em) #align(center)[ #move(dx: 12.6pt, dy: -1.3pt)[ #scale(100%)[ #hldpc_dynamic(hl_rows: (0,), show_labels: true, h_show: true) ] ] ] #v(3.5em) #align(center)[ #move(dx: 2.7pt, dy: -13.8pt)[ #scale(180%)[ #tanner_canvas(hl_row: 0) ] ] ] // #v(0.4em) // #[ // #set text(size: 1.05em) // - Ligne #text(fill: orange, weight: "bold")[0] de $bold(H)$ : $bold(H)_(0,j) = 1$ pour $j in {7, 10, 15, 22, 24, 29}$ // - #text(fill: orange)[$c_0$] est relié à #text(fill: orange)[$v_7, v_10, v_15, v_22, v_24, v_29$] — chaque 1 crée une arête // - $deg(c_0) = 6 = w_r$ — $c_0$ porte l'équation : #text(fill: orange)[$f_0 : r_7 plus.o r_10 plus.o r_15 plus.o r_22 plus.o r_24 plus.o r_29 = 0$] // ] ] #myslide("Construction du Graphe : Nœud de Variable")[ #v(1.2em) #align(center)[ #scale(100%)[ #hldpc_dynamic(hl_cols: (10,), show_labels: true, h_show: true) ] ] #v(3.5em) #align(center)[ #move(dx: -0pt, dy: -39pt)[ #scale(180%)[ #tanner_canvas(hl_col: 10) ] ] ] // #v(0.15em) // #align(center)[ // #grid( // columns: (auto, auto), // column-gutter: 0.7cm, // align: horizon, // [#h_mini_tanner(hl_col: 10)], [#tanner_canvas(hl_col: 10)], // ) // ] // #[ // #set text(size: 1.05em) // - Colonne #text(fill: blue, weight: "bold")[10] de $bold(H)$ : $bold(H)_(i,10) = 1$ pour $i in {0, 5, 11}$ // - #text(fill: blue)[$v_10$] est relié aux nœuds de contrôle #text(fill: blue)[$c_0, c_5, c_11$] — participe à *3 équations* de parité // - $deg(v_10) = 3 = w_c$ — chaque bit est surveillé par $w_c$ contraintes indépendantes // ] ] #myslide("Graphe de Tanner Final")[ #move(dy: 4.5cm)[ #align(center + horizon)[ #tanner_canvas(scale: 0.91cm, show_all: true, colored: true, v_c_show: false) ] #align(center)[ #grid( columns: (1fr, 1fr), gutter: 0.45cm, block( fill: blue.lighten(88%), stroke: 0.5pt + blue.lighten(40%), radius: 6pt, inset: (x: 10pt, y: 8pt), width: 100%, )[ #place(dx: 47pt, dy: -0pt)[#scale(110%)[#icon_var]] #text(fill: blue, weight: "bold")[ Nœuds de variable] \ // $n = 30 quad deg = w_c = 3$ ], block( fill: orange.lighten(88%), stroke: 0.5pt + orange.lighten(40%), radius: 6pt, inset: (x: 10pt, y: 8pt), width: 100%, )[ #place(dx: 47pt, dy: -0pt)[#scale(110%)[#icon_chk]] #text( fill: orange, weight: "bold", )[ Nœuds de contrôle] \ // $m = 15 quad deg = w_r = 6$ ], ) ] ] ] #let mot_valide = ( 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, ) #myslide("La Contrainte de Somme Nulle")[ #set text(size: 18pt) #definition(titre: "Vision Graphe", accent: green)[ Si $s = 0$ alors que chaque nœud de contrôle est localement satisfait ] #v(1cm) #align(center)[ #scale(150%)[ #tanner_status( scale: 0.55cm, v_values: mot_valide, hl_v: (), ) ] ] #v(1.2cm) #set text(size: 20pt) #align(center + horizon)[ Chaque #icon_chk calcule le xor de ses voisins #icon_var : $space display(f_i = xor.big_(j in cal(N)(c_i)) v_j)$ ] #v(1em) #align(center)[ #move(dy: -10pt)[ #scale(150%)[ #zoom_contrainte(is_ok: true) ] ] ] // #v(1em) // #block(inset: 10pt, fill: rgb("#f0fdf4"), stroke: 1pt + rgb("#22c55e"), radius: 5pt)[ // Toutes les équations de parité sont vérifiées simultanément. // ] ] #myslide("?")[ #set text(size: 18pt) #definition(titre: "Détection d'Erreur", accent: red)[ Si un bit est inversé, toutes les contraintes associées sont à $1$ ] #v(1cm) #align(center)[ #let idx_erreur = 10 #let mot_erronne = mot_valide.enumerate().map(p => if p.first() == idx_erreur { 1 } else { p.last() }) #scale(150%)[ #tanner_status( scale: 0.55cm, v_values: mot_erronne, hl_v: (idx_erreur,), highlight_edges: true, ) ] ] #v(1.3cm) #align(center)[ $0 plus.o bold(1) plus.o 0 = bold(1) arrow$ *Erreur détectée* ] #v(1em) #align(center)[ #move(dy: 11.5pt)[ #scale(150%)[ #zoom_contrainte(is_ok: false) ] ] ] // #block(inset: 10pt, fill: rgb("#fef2f2"), stroke: 1pt + red, radius: 5pt)[ // *Principe du décodage :* // Le bit $v_{10}$ est relié à *plusieurs alarmes* (arêtes rouges au premier plan). Il est le suspect idéal pour une correction par "bit-flipping". // ] ] #myslide("La Topologie de H : Le Girth")[ #set text(size: 18pt) #definition(titre: "Définition : Le Girth (La Maille)", accent: blue)[ Longueur du plus court cycle dans le graphe de Tanner ] #v(0.5em) - Le girth est *pair* - La valeur minimale est $g = 4$. #v(1em) #align(center)[ #block(fill: rgb("#f8fafc"), stroke: 1pt + blue.lighten(50%), inset: 10pt, radius: 5pt)[ Girth élevé $=>$ Meilleure diffusion de l'information. ] ] #v(2.5em) #align(center)[ #scale(140%)[ #grid( columns: (1fr, 1fr), gutter: -7cm, [ #schema_girth_4(highlight: false) #v(0.5em) #text(size: 0.8em, style: "italic")[Graphe de Tanner] ], [ #schema_girth_4(highlight: true) #v(0.5em) #text(size: 0.8em, fill: red, weight: "bold")[4-Cycle] ], ) ] ] ] #myslide("Encodage LDPC : Calcul de G")[ #set text(size: 18pt) #definition(titre: "Encodage", accent: blue)[ Mot de code $bold(c)$ généré à partir d'un message $bold(u)$ : $bold(c) = bold(u) bold(G)$\ // $bold(H) bold(G)^top = bold(0)$ ] #v(2em) #align(center)[#scale(135%)[#paradoxe_densite_reel()]] #v(2em) #set text(size: 1em) - Forme Systématique : Par élimination de Gauss sur $bold(H)$, on obtient #v(1em) #align(center)[ #schema_systematique() ] #v(1em) #set text(size: 1em) - La matrice $bold(G)$ devient dense $=>$ encodage en $cal(O)(n^2)$ // #v(1em) // #block(fill: rgb("#fef2f2"), stroke: 1pt + red, inset: 10pt, radius: 5pt)[ // *Défi Matériel :* Pour $n=64\,800$ (DVB-S2), $n^2$ est prohibitif. Solution : les codes *quasi-cycliques* (5G). // ] ] #myslide("Décodage : Bit-Flipping")[ #set text(size: 16pt) #definition(titre: "Décision Stricte (Hard Decision)", accent: black)[ Algorithme *itératif* : les nœuds *échangent des bits* pour localiser les erreurs. ] #v(0.2em) #set text(size: 1em) #set text(size: 16pt) #definition(titre: "Message Passing", accent: blue)[ // L'information *circule le long des arêtes* du graphe de Tanner à chaque itération. - #icon_var envoie son bit courant à ses voisins #icon_chk - #icon_chk renvoie son *verdict de parité* ($0$ ou $1$) ] #v(0.6em) #set text(1em) - Si $v_j$ participe à *trop d'équations non satisfaites* $=>$ on l'inverse. #uncover(2)[ #grid( columns: (1fr, 1fr, 1fr), column-gutter: 10pt, // On aligne tout par le bas (bottom) pour que les CN soient sur la même ligne align: center + bottom, [ #bf_step1_sending() #v(-0.5em) #text(style: "italic", fill: gray.darken(40%), size: 0.8em)[VN $arrow$ CN] ], [ #bf_step2_verdict() #v(-0.5em) #text(style: "italic", fill: gray.darken(40%), size: 0.8em)[CN $arrow$ VN] ], [ #bf_step3_flip() #v(-0.5em) #text(style: "italic", fill: gray.darken(40%), size: 0.8em)[Correction] ], ) ] // #align(center + horizon)[ // #scale(100%)[#bp_hard_diagram()] // #v(0.4em) // #text( // size: 0.72em, // style: "italic", // fill: gray.darken(20%), // )[Échanges itératifs entre $V$ (cercles) et $C$ (carrés)] // ] ] #myslide("Bit-Flipping : Graphe de flot de contrôle")[ #set text(size: 17pt) // #grid( // columns: (1.25fr, 0.75fr), // gutter: 0.8cm, // align: top, // [ // #step_box(1, orange)[ // *CN Update — Évaluation* \ // #set text(size: 0.88em) // Chaque nœud de contrôle $c_i$ calcule sa parité : // $ // f_i = xor.big_(j in cal(N)(c_i)) v_j in {0, 1} // $ // Si $f_i = 1$ : *l'équation n'est pas satisfaite* $=>$ $c_i$ envoie le message "Erreur" à tous ses voisins. // ] // // #v(0.45em) // // #step_box(2, blue)[ // *VN Update — Vote* \ // #set text(size: 0.88em) // Chaque bit $v_j$ compte ses alarmes reçues $k_j$. // Si $k_j$ dépasse le seuil (ex. *majorité*) : // $ // v_j arrow.l 1 - v_j quad ("FLIP") // $ // ] // // #v(0.45em) // // #step_box(3, green.darken(10%))[ // *Vérification — Syndrome* \ // #set text(size: 0.88em) // On recalcule $bold(s) = bold(H) bold(r)^top$. // - Si $bold(s) = bold(0)$ : *Succès*, on s'arrête. // - Sinon : on recommence l'étape ① (jusqu'à `max_iter`). // ] // ], // [ // #align(center)[ // #v(0.3em) // #scale(96%)[#schema_boucle_bf()] // ] // ], // ) #align(center + horizon)[ #move(dx: 2.5cm, dy: -0.5cm)[#scale(95%)[#schema_boucle_bf()]] ] ] #myslide("Exemple implementation Bit-Flipping rust")[ ex + canal d'etude bruit AWGN avec ce qu'il se passe dans les radio / cable etc + tension ] #myslide("Bit-Flipping : Analyse")[ // TODO PARLER DU GIRTH 4 => MAUVAIS #set text(size: 17pt) #definition(titre: "Avantages", accent: green.darken(10%))[ #set text(size: 0.88em) - *Complexité* : simples XOR et compteurs — $cal(O)(n)$ par itération // - *Matériel* : idéal FPGA/ASIC, massivement parallélisable // - *Simplicité* : inventé par Gallager (1962) ] #definition(titre: "Limite", accent: red)[ #set text(size: 0.88em) - Ignore la *confiance* du récepteur physique dans le signal - Un bit reçu à $0.51$ V est traité comme $0$ // - $=>$ Sous-optimal par rapport à la limite de Shannon // #v(0.3em) // #align(center)[ // #box(fill: rgb("#fff7ed"), stroke: (left: 3pt + orange), inset: (x: 8pt, y: 5pt))[ // #text( // size: 0.82em, // )[$arrow$ Nécessite le *Soft-Decision* (Belief Propagation) pour exploiter les niveaux de gris du signal] // ] // ] ] ] #myslide("Décodage Soft : Le LLR")[ #set text(size: 17pt) #definition(titre: "Signal", accent: blue.darken(10%))[ On reçoit une valeur $y_i$ (ex: $+4.5$V ou $-0.2$V). Le LLR transforme cette mesure physique en une valeur statistique sans unité. ] #v(0.6em) #definition(titre: "Log-Likelihood Ratio (LLR)", accent: black)[ $ L(v_i) = ln(display(frac(P(v_i = 0 | y_i), P(v_i = 1 | y_i)))) $ ] #v(0.6em) #align(center)[ #scale(125%)[#schema_llr_droite()] ] #v(1em) // Blocs de légende centrés #align(center)[ #grid( columns: (220pt, 220pt), gutter: 1cm, block(fill: blue.lighten(92%), stroke: 1pt + blue, radius: 6pt, inset: 12pt)[ #align(center)[ #text(fill: blue.darken(20%), weight: "bold")[Signe] \ #text(size: 0.85em)[Définit la valeur du bit] ] ], block(fill: orange.lighten(90%), stroke: 1pt + orange, radius: 6pt, inset: 12pt)[ #align(center)[ #text(fill: orange.darken(20%), weight: "bold")[|Valeur|] \ #text(size: 0.85em)[Confiance dans la décision] ] ], ) ] ] #myslide("Sum-Product : Belief Propagation")[ #set text(size: 17pt) #v(-0.4em) #definition(titre: "Décodage Optimal")[ Échange itératif de croyances (LLR) entre les nœuds du graphe ] #definition(titre: "Information Extrinsèque")[ Exclure l'avis du destinataire pour éviter l'auto-influence ] #block( fill: orange.lighten(92%), stroke: (left: 4pt + orange), radius: 4pt, inset: 18pt, width: 100%, )[ #set text(size: 1.2em) *Mise à jour CN* \ #set text(size: 1.1em) $ tanh(m_(c arrow v) / 2) = product_(u != v) tanh(m_(u arrow c) / 2) $ ] #block( fill: blue.lighten(92%), stroke: (left: 4pt + blue), radius: 4pt, inset: 18pt, width: 100%, )[ #set text(size: 1.2em) *Mise à jour VN* \ #set text(size: 1.1em) $ m_(v arrow c) = L_"canal" + sum_(c' != c) m_(c' arrow v) $ ] ] #myslide("Sum-Product")[ #set text(size: 16pt) #place(left, dx: 1.5cm, dy: 0cm)[ #text(weight: "bold", size: 1.1em * 1.3)[Initialisation] ] #place(left, dx: 1.5cm, dy: 2cm)[ #scale(130%)[ #grid( columns: 1, gutter: 0.2cm, align: horizon, schema_detailed_init(), text(size: 0.9em)[$m_(v_j arrow c_i) = L_"canal"$], ) ] ] #place(right, dx: -4.5cm, dy: 0cm)[ #text(weight: "bold", fill: orange, size: 1.1em * 1.3)[Échange CN] ] #place(right, dx: -1cm, dy: 2.7cm)[ #scale(130%)[ #schema_detailed_cn() ] ] #place(left, dx: 1.5cm, dy: 9cm)[ #text(weight: "bold", fill: blue, size: 1.1em * 1.3)[Échange VN] ] #place(left, dx: 1.5cm, dy: 11cm)[ #scale(130%)[ #schema_detailed_vn() ] ] #place(right, dx: -3.5cm, dy: 9cm)[ #text(weight: "bold", fill: green, size: 1.1em * 1.3)[Décision Finale] ] #place(right, dx: -1cm, dy: 11cm)[ #scale(145%)[ #schema_detailed_decision() ] ] #place(center + horizon, dx: -0.9cm, dy: 8.2cm)[ #scale(115%)[ #cetz.canvas(length: 1cm, { import cetz.draw: * let col_iter = gray.darken(50%) arc( (0, 0), radius: 1.8, start: 150deg, delta: -300deg, stroke: (paint: col_iter, thickness: 2pt, cap: "round"), mark: (end: "stealth", fill: col_iter, size: 0.3), ) content((1.6, -1), [ #set text(fill: col_iter, weight: "bold", size: 0.8em) #set align(center) Itérations\ $i = 1, dots, I_(max)$ ]) }) ] ] ] #myslide("Implementation rust")[ ] #myslide("Min-Sum")[ #set text(size: 15pt) #grid( columns: (1fr, 1fr), gutter: 0.5cm, definition(titre: "Avantage Matériel", accent: black)[ - *Comparateurs* pour le minimum - *XOR* pour le produit des signes #v(0.21cm) ], definition(titre: "Mise à jour du CN", accent: orange)[ #set text(size: 19pt) $ m_(c arrow v_i) = product_(j != i) "sgn"(m_(v_j arrow c)) times min_(j != i) |m_(v_j arrow c)| $ ], ) #v(4.5em) #align(center)[#scale(130%)[#schema_min_sum_complet()]] #v(0.5em) #align(center)[ #text(size: 1.1em, fill: gray.darken(40%), style: "italic")[ Pour les VN : $m_(v arrow c) = L_"canal" + sum_(c' != c) m_(c' arrow v)$ ] ] ] #myslide("Test réel")[ 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")[ #align(center + horizon)[ Annexe ] #align(center + horizon)[ #image("src/construction.jpg", width: 80%) ] ] #myslide("Théorie deriere la définition des codes linaires")[ Poser les notations algebriques etc... ] #myslide("Decodage par maximum de vraisemblance")[ Expliquer, quelle distance ? etc ] #myslide("Code LDPC non régulier")[ ] #myslide("Maths deriere Belief Propagation")[ ]