This commit is contained in:
2026-05-18 10:47:39 +02:00
parent 8fd3f47a20
commit 17431d662f
3 changed files with 9983 additions and 8660 deletions

View File

@ -2578,8 +2578,9 @@
cetz.canvas(length: 1cm, {
import cetz.draw: *
let col_left = blue.darken(10%) // Bit 0 (Inversé)
let col_right = red.darken(10%) // Bit 1 (Inversé)
// Couleurs ajustées selon la logique mathématique
let col_bit1 = red.darken(10%) // Négatif -> Bit 1
let col_bit0 = blue.darken(10%) // Positif -> Bit 0
let col_ax = black
let col_mid = gray.darken(30%)
@ -2587,16 +2588,17 @@
let y0 = 0.0
let y_top = 1.8
// ── 1. Zones colorées (Dessinées en PREMIER, en HAUT) ──
// Zone gauche (négative) -> Bit 0
rect((-L, y0 + 0.02), (-0.05, y0 + 0.32), fill: col_left.lighten(92%), stroke: none)
content((-L / 2, y0 + 0.65), text(fill: col_left, weight: "bold", size: 0.9em)[Bit = 0])
// ── 1. Zones colorées (Corrigées) ──
// Zone droite (positive) -> Bit 1
rect((0.05, y0 + 0.02), (L, y0 + 0.32), fill: col_right.lighten(92%), stroke: none)
content((L / 2, y0 + 0.65), text(fill: col_right, weight: "bold", size: 0.9em)[Bit = 1])
// Zone gauche (négative) -> Bit 1
rect((-L, y0 + 0.02), (-0.05, y0 + 0.32), fill: col_bit1.lighten(92%), stroke: none)
content((-L / 2, y0 + 0.65), text(fill: col_bit1, weight: "bold", size: 0.9em)[Bit = 1])
// ── 2. Axe horizontal (Dessiné APRÈS pour passer AU-DESSUS) ──
// Zone droite (positive) -> Bit 0
rect((0.05, y0 + 0.02), (L, y0 + 0.32), fill: col_bit0.lighten(92%), stroke: none)
content((L / 2, y0 + 0.65), text(fill: col_bit0, weight: "bold", size: 0.9em)[Bit = 0])
// ── 2. Axe horizontal ──
line((-L, y0), (L, y0), stroke: 1.8pt + col_ax, mark: (end: "stealth", fill: col_ax, size: 0.22))
content((L + 0.5, y0), text(size: 0.85em)[$L(v_i)$], anchor: "west")
@ -2604,41 +2606,40 @@
line((0, -0.2), (0, 0.2), stroke: 1.5pt + col_mid)
content((0, -0.5), text(size: 0.8em, fill: col_mid)[0])
// ── 4. Points exemples (Sans les Volts) ──
// ── 4. Points exemples (Couleurs mises à jour) ──
// -6 (Bit 0 à gauche)
// -6 (Bit 1 à gauche désormais)
let px_left = -5.0
circle((px_left, y0), radius: 0.15, fill: col_left, stroke: none)
// La ligne pointillée part de l'axe vers le haut
line((px_left, y0), (px_left, y_top), stroke: (paint: col_left, thickness: 1pt, dash: "dashed"))
circle((px_left, y0), radius: 0.15, fill: col_bit1, stroke: none)
line((px_left, y0), (px_left, y_top), stroke: (paint: col_bit1, thickness: 1pt, dash: "dashed"))
content(
(px_left, y_top + 0.1),
box(fill: col_left.lighten(92%), stroke: 0.5pt + col_left, radius: 3pt, inset: 4pt)[
#text(fill: col_left, weight: "bold", size: 0.75em)[$-6$]
box(fill: col_bit1.lighten(92%), stroke: 0.5pt + col_bit1, radius: 3pt, inset: 4pt)[
#text(fill: col_bit1, weight: "bold", size: 0.75em)[$-6$]
],
anchor: "south",
)
// +0.3 (Proche de zéro, Bit 1)
// +0.3 (Proche de zéro, Bit 0)
let px_near = 0.6
circle((px_near, y0), radius: 0.15, fill: col_right.lighten(40%), stroke: none)
line((px_near, y0), (px_near, y_top - 0.7), stroke: (paint: col_right.lighten(20%), thickness: 1pt, dash: "dashed"))
circle((px_near, y0), radius: 0.15, fill: col_bit0.lighten(40%), stroke: none)
line((px_near, y0), (px_near, y_top - 0.7), stroke: (paint: col_bit0.lighten(20%), thickness: 1pt, dash: "dashed"))
content(
(px_near, y_top - 0.65),
box(fill: white, stroke: 0.5pt + col_right.lighten(30%), radius: 3pt, inset: 3pt)[
#text(fill: col_right.darken(20%), size: 0.7em)[$+0.3$]
box(fill: white, stroke: 0.5pt + col_bit0.lighten(30%), radius: 3pt, inset: 3pt)[
#text(fill: col_bit0.darken(20%), size: 0.7em)[$+0.3$]
],
anchor: "south-west",
)
// +10 (Bit 1 à droite)
// +10 (Bit 0 à droite)
let px_right = 5.8
circle((px_right, y0), radius: 0.15, fill: col_right, stroke: none)
line((px_right, y0), (px_right, y_top), stroke: (paint: col_right, thickness: 1pt, dash: "dashed"))
circle((px_right, y0), radius: 0.15, fill: col_bit0, stroke: none)
line((px_right, y0), (px_right, y_top), stroke: (paint: col_bit0, thickness: 1pt, dash: "dashed"))
content(
(px_right, y_top + 0.1),
box(fill: col_right.lighten(92%), stroke: 0.5pt + col_right, radius: 3pt, inset: 4pt)[
#text(fill: col_right, weight: "bold", size: 0.75em)[$+10$]
box(fill: col_bit0.lighten(92%), stroke: 0.5pt + col_bit0, radius: 3pt, inset: 4pt)[
#text(fill: col_bit0, weight: "bold", size: 0.75em)[$+10$]
],
anchor: "south",
)

18242
main.pdf

File diff suppressed because one or more lines are too long

296
main.typ
View File

@ -206,7 +206,7 @@
#[
#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$
- Sinon $s$ donne la signature de l'erreur $e$
]
// Possible décodage par syndrome
]
@ -240,6 +240,7 @@
- Message $display(u = #math.mat((text(fill: col-u)[1], text(fill: col-u)[1])))$
- Mot de code $c = u G$ :
#set text(size: 1.2em)
$
c = #math.mat((text(fill: col-u)[1], text(fill: col-u)[1]))
#math.mat(
@ -259,42 +260,55 @@
]
]
#myslide("Exemple d'une code linéaire")[
#[
#myslide("Exemple d'un code linéaire")[
#let colp = orange // Partie P (Parité)
#let colu = blue // Partie I (Identité)
#set math.mat(delim: "[")
#let colu = blue
#let colp = orange
#v(0.4cm)
#place(dx: 0cm, dy: 2.0cm)[
#set text(size: 1.1em)
Enfin
Structure systématique de $H$ :
#v(0.5em)
#align(center)[
#scale(120%)[
#dessiner_matrice($H =$, (
(texte: $P^top$, largeur: 2.0, fond: colp.lighten(90%)),
(texte: $I_3$, largeur: 3.0, fond: colu.lighten(90%)),
))
]
]
#v(0.8em)
Ainsi :
#align(center)[
#scale(115%)[
$
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,
H = mat(
text(fill: colp, "1"), text(fill: colp, "0"), text(fill: colu, "1"), text(fill: colu, "0"), text(fill: colu, "0");
text(fill: colp, "1"), text(fill: colp, "1"), text(fill: colu, "0"), text(fill: colu, "1"), text(fill: colu, "0");
text(fill: colp, "0"), text(fill: colp, "1"), text(fill: colu, "0"), text(fill: colu, "0"), text(fill: colu, "1")
)
$
]
]
#v(0.8em)
// Vérification du mot de code $c = mat(text(fill: colp, "1"), text(fill: colp, "1"), text(fill: colu, "1"), text(fill: colu, "0"), text(fill: colu, "1"))$ :
Vérification du mot de code $c = (#text(fill: colp)[1], #text(fill: colp)[1], #text(fill: colu)[1], #text(fill: colu)[0], #text(fill: colu)[1])$ :
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)
#v(0.4em)
#align(center)[
#scale(115%)[
$
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
)
text(fill: colp, "1"), text(fill: colp, "0"), text(fill: colu, "1"), text(fill: colu, "0"), text(fill: colu, "0");
text(fill: colp, "1"), text(fill: colp, "1"), text(fill: colu, "0"), text(fill: colu, "1"), text(fill: colu, "0");
text(fill: colp, "0"), text(fill: colp, "1"), text(fill: colu, "0"), text(fill: colu, "0"), text(fill: colu, "1")
) mat(
text(fill: colp, "1"), text(fill: colp, "1"), text(fill: colu, "1"), text(fill: colu, "0"), text(fill: colu, "1")
)^top
= mat(0; 0; 0)
$
]
@ -335,13 +349,13 @@
]
#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*.
#definition(titre: [Codes LDPC Réguliers])[
Code linéaire en bloc avec une matrice de contrôle $bold(H)$ *clairsemée*.
]
- *Poids de Colonne $w_c$*
- Poids de Colonne *$w_c$*
- *Poids de Ligne $w_r$*
- Poids de Ligne *$w_r$*
#v(0.5em)
@ -468,7 +482,7 @@
$
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 quad (f_0)$],
#text(fill: green.darken(20%))[$r_2 plus.o r_8 plus.o r_13 plus.o bold(r_24) plus.o r_26 plus.o r_30 &= 0 quad (f_7)$],
#text(fill: green.darken(20%))[$r_0 plus.o r_1 plus.o r_4 plus.o r_9 plus.o r_20 plus.o r_26 &= 0 quad (f_7)$],
#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 quad (f_14)$]
)
$
@ -477,7 +491,8 @@
#v(0.5cm)
- *$r_24$* : Surveillé simultanément par #text(fill: orange)[$f_0$], #text(fill: green.darken(20%))[$f_7$] et #text(fill: blue)[$f_14$].
- Si $forall j in {0, 7, 24}, space f_j = 1$, alors le bit est comme suspect.
- Si $forall j in {#text(fill: orange)[$0$], #text(fill: green.darken(20%))[$7$], #text(fill: blue)[$24$]}, space f_j = 1$, alors le bit est comme suspect.
]
@ -485,10 +500,10 @@
#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)$
Graphe bipartite $cal(G) = (#text(fill: blue)[$V$] union.sq #text(fill: orange)[$C$], A)$
:
#v(4pt)
$ (#text(fill: blue)[$v_j$], #text(fill: orange)[$c_i$]) in E space <==> space H_(i,j) = 1 $
$ (#text(fill: blue)[$v_j$], #text(fill: orange)[$c_i$]) in A space <==> space H_(i,j) = 1 $
]
#v(0.4em)
@ -498,7 +513,7 @@
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$]$],
[- $|A| = 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*
@ -821,12 +836,20 @@
]
#myslide("Méthode de génération de H")[
- Gallager
- Mackay-Neal
- Progressive Edge-growth
#align(center + horizon)[
#image("src/construction.jpg", width: 50%)
#place(center + horizon, dy: 7cm)[
#block(width: 100%)[
#text(size: 1.5em, weight: "bold", fill: black)[
Gallager \
Mackay-Neal \
Progressive Edge-growth
]
]
]
// #align(center + horizon)[
// #image("src/construction.jpg", width: 50%)
// ]
]
#myslide("Encodage LDPC : Calcul de G")[
@ -1292,23 +1315,38 @@
]
]
#myslide("QC-LDPC")[
#align(center + horizon)[
#image("src/construction.jpg", width: 80%)
]
]
// #myslide("QC-LDPC")[
// #align(center + horizon)[
// #image("src/construction.jpg", width: 80%)
// ]
// ]
//
// #myslide("Test réel")[
// Transmission hackrf, test de diff de debit avec paquets
// Test de transmission d'image avec différent ldpc non opti et opti (H diff etc)
// #align(center + horizon)[
// #image("src/construction.jpg", width: 80%)
// ]
// ]
//
// #myslide("FPGA")[
// #align(center + horizon)[
// #image("src/construction.jpg", width: 80%)
// ]
// ]
#myslide("Test réel")[
Transmission hackrf, test de diff de debit avec paquets
Test de transmission d'image avec différent ldpc non opti et opti (H diff etc)
#align(center + horizon)[
#image("src/construction.jpg", width: 80%)
]
]
#myslide("Conclusion")[
#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.5em, weight: "bold", fill: black)[
QC-LDPC \
#myslide("FPGA")[
#align(center + horizon)[
#image("src/construction.jpg", width: 80%)
FPGA \
Test réel
]
]
]
]
@ -1339,10 +1377,157 @@
]
#myslide("Maths derière Belief Propagation")[
#myslide("Richardson-Urbanke")[
]
#myslide("CN Update : Formalisme probabiliste")[
#set text(size: 16pt)
#v(-0.3em)
Soit $(V_u)_(u in cal(N)(c))$ une famille de variables aléatoires mutuellement indépendantes à valeurs dans $bb(F)_2$.
On cherche à déterminer la loi du message $R_(c arrow v)(b)$ envoyé par le nœud de contrôle $c$.
#v(0.5em)
#definition(titre: "Conditionnement de l'événement de parité", accent: orange)[
Le message $R_(c arrow v)(b)$ correspond à la probabilité conditionnelle :
#v(0.5em)
#align(center)[#scale(105%)[$
display(R_(c arrow v)(b) = P( limits(xor.big)_(u in cal(N)(c)) V_u = 0 | V_v = b ))
$]]
Par linéarité du XOR, cette condition est équivalente à :
#v(0.5em)
#align(center)[#scale(110%)[$ display(P( limits(xor.big)_(u in cal(N)(c) backslash {v}) V_u = b )) $]]
]
Par le théorème des probabilités totales appliqué au système complet d'événements associé aux configurations $x in bb(F)_2^(d_c - 1)$ des voisins :
#align(center)[#scale(120%)[
$
display(R_(c arrow v)(b) = limits(sum)_(x in bb(F)_2^(d_c - 1) \ limits(xor.big)_(u in cal(N)(c) backslash {v}) x_u = b) limits(product)_(u in cal(N)(c) backslash {v}) P(V_u = x_u))
$
]]
]
#myslide("CN Update (1) : Probabilités")[
#set text(size: 16pt)
#v(-0.3em)
En utilisant les messages entrants du graphe, on définit la probabilité locale $P_(u arrow c)(x_u) = P(V_u = x_u)$.
Le message sortant devient :
#v(1em)
#align(center)[#scale(130%)[
$
display(R_(c arrow v)(b) = limits(sum)_(x in bb(F)_2^(d_c - 1) \ limits(xor.big)_(u in cal(N)(c) backslash {v}) x_u = b) quad limits(product)_(u in cal(N)(c) backslash {v}) P_(u arrow c)(x_u))
$
]]
#v(1em)
Exacte mais complexité est exponentielle en $d_c$. On utilise alors une transformation pour simplifier le calcul (Lemme de Gallager).
]
#myslide("CN Update (2) : Lemme de Gallager")[
#set text(size: 16pt)
#block(
fill: orange.lighten(94%),
stroke: (left: 4pt + orange),
radius: 4pt,
inset: 20pt,
width: 100%,
)[
*Lemme de Gallager* -- Soient $(X_1, ..., X_n)$ des variables de Bernoulli indépendantes sur $bb(F)_2$.
#v(0.5em)
#align(center)[#scale(130%)[
$ display(P(limits(xor.big)_(i=1)^n X_i = 0) = 1/2 (1 + limits(product)_(i=1)^n E[(-1)^(X_i)])) $
]]
]
#v(0.8em)
// L'espérance correspond au biais de la loi, noté $delta_(u arrow c)$ :
On notes :
#align(center)[#scale(120%)[
$ display(E[(-1)^(V_u)] = delta_(u arrow c) = P(V_u = 0) - P(V_u = 1) = 1 - 2 P_(u arrow c)(1)) $
]]
#v(0.8em)
On en déduit les probabilités marginales conditionnelles pour le nœud $c$ :
#align(center)[#scale(120%)[
$
display(R_(c arrow v)(0) = 1/2 (1 + limits(product)_(u in cal(N)(c) backslash {v}) delta_(u arrow c)))
space , space space
display(R_(c arrow v)(1) = 1/2 (1 - limits(product)_(u in cal(N)(c) backslash {v}) delta_(u arrow c)))
$
]]
]
#myslide("CN Update (3) : Passage aux LLR")[
#set text(size: 16pt)
#definition(titre: "Log-Likelihood Ratio (LLR)", accent: blue.darken(10%))[
Le message LLR entrant $m_(u arrow c)$ au nœud de contrôle est défini par :
#v(0.5em)
#align(center)[#scale(130%)[
$ display(m_(u arrow c) = ln(frac(P(V_u = 0), P(V_u = 1)))) $
]]
]
#v(0.8em)
$delta_(u arrow c)$ s'exprime alors :
#align(center)[#scale(130%)[
$ display(delta_(u arrow c) = tanh(frac(m_(u arrow c), 2))) $
]]
#v(0.8em)
On en déduit le LLR du message sortant :
#align(center)[#scale(130%)[
$
display(m_(c arrow v) = ln(frac(R_(c arrow v)(0), R_(c arrow v)(1))) = 2 tanh^(-1) ( limits(product)_(u in cal(N)(c) backslash {v}) tanh(frac(m_(u arrow c), 2)) ))
$
]]
]
#myslide("CN Update (4) : Algorithmes")[
#set text(size: 16pt)
#block(
fill: orange.lighten(92%),
stroke: (left: 4pt + orange),
radius: 4pt,
inset: 15pt,
width: 100%,
)[
*Sum-Product* -- Mise à jour :
#v(0.5em)
#align(center)[#scale(130%)[
$
display(m_(c arrow v) = 2 tanh^(-1) ( limits(product)_(u in cal(N)(c) backslash {v}) tanh(frac(m_(u arrow c), 2)) ))
$
]]
]
#v(1em)
#block(
fill: blue.lighten(92%),
stroke: (left: 4pt + blue),
radius: 4pt,
inset: 15pt,
width: 100%,
)[
*Min-Sum* -- Approximation :
#v(0.5em)
#align(center)[#scale(130%)[
$
display(m_(c arrow v) approx ( limits(product)_(u in cal(N)(c) backslash {v}) op("sgn")(m_(u arrow c)) ) times limits(min)_(u in cal(N)(c) backslash {v}) |m_(u arrow c)|)
$
]]
]
]
#myslide("AWGN")[
]
@ -1350,3 +1535,4 @@
#myslide("PEG")[
]