This commit is contained in:
2026-05-27 17:37:40 +02:00
parent 17431d662f
commit 818acf844a
3 changed files with 13353 additions and 9102 deletions

View File

@ -441,7 +441,7 @@
)
}
#let limite_shannon_graphique() = {
#let limite_shannon_graphique_old() = {
let col-shannon = red.darken(10%)
let col-code-long = blue.darken(20%)
let col-code-short = gray.lighten(10%)
@ -610,6 +610,103 @@
]
}
#let limite_shannon_graphique() = {
let col-shannon = red.darken(10%)
let col-code-long = blue.darken(20%)
let col-code-short = gray.lighten(10%)
set text(size: 11pt)
move(dx: -5pt, dy: 0pt)[
#cetz.canvas({
import cetz.draw: *
plot.plot(
size: (23, 15),
x-label: pad(bottom: 30pt)[#move(dy: 80pt)[#text(size: 18pt)[$E_b/N_0$ (dB)]]],
y-label: move(dx: -20pt, dy: -10pt)[#text(size: 18pt)[Bit Error Rate (BER)]],
x-min: 0,
x-max: 10,
y-min: -8.5,
y-max: 0.2,
x-tick-step: 1,
y-tick-step: 2,
x-format: x => move(dy: 14pt)[#text(size: 16pt)[#x]],
y-format: y => move(dx: -5pt)[#text(size: 16pt)[$10^(#y)$]],
x-grid: true,
y-grid: true,
legend: "north-east",
legend-style: (
stroke: 0.5pt + gray,
fill: white,
padding: 0.2,
offset: (-161.4pt, -45.1pt),
),
{
// 1. Limite de Shannon
plot.add(
((1.5, -8.5), (1.5, 0.2)),
style: (stroke: (paint: col-shannon, thickness: 2.5pt, dash: "dashed")),
label: [Limite de Shannon],
)
// 2. Code court (n ≈ 100)
plot.add(
(
(0.0, 0.00),
(0.75, -0.06),
(1.5, -0.21),
(2.25, -0.38),
(3.0, -0.70),
(3.75, -1.08),
(4.5, -1.67),
(5.25, -2.33),
(6.0, -3.10),
(6.75, -3.92),
(7.5, -4.97),
(8.25, -6.08),
(9.0, -7.30),
(9.7, -8.50),
),
style: (stroke: (paint: col-code-short, thickness: 1.5pt, dash: "dashed")),
mark: "+",
mark-style: (stroke: (paint: col-code-short, thickness: 0.08), size: 0.6),
label: [$n approx 100$],
)
// 3. Code long (n = 64 800)
plot.add(
(
(0.0, 0.0),
(0.4, -0.01),
(0.8, -0.035),
(1.2, -0.10),
(1.4, -0.20),
(1.50, -0.40),
(1.60, -0.80),
(1.70, -1.50),
(1.80, -2.60),
(1.90, -4.20),
(2.00, -6.00),
(2.10, -7.50),
(2.20, -8.20),
(2.25, -8.50),
),
style: (stroke: (paint: col-code-long, thickness: 2.5pt)),
mark: "square",
mark-style: (stroke: (paint: col-code-long, thickness: 0.08), fill: white, size: 0.5),
label: [$n = 64\,800$],
)
},
)
})
]
}
#let decor_matrice_etoilee() = {
// Ajuste length (ex: 0.6mm ou 0.7mm) selon ta diapo
cetz.canvas(length: 0.7mm, {
@ -1227,7 +1324,55 @@
(28, 14),
)
#let tanner_illustration() = {
#let tricolor-j = context {
let w = measure($bold(j)$).width
let h = measure($bold(j)$).height
let d = measure($x$).height * 0.6
let total_h = h + d
// Marge gauche pour absorber le débordement italique du j
let margin = w * 0.25
let full_w = w + margin
let t = full_w / 3
// Biais vertical : la frontière se décale de `bias` entre haut et bas
let bias = w * 0.2
let n = 40
let stripe = total_h / n
box(baseline: d, width: w, height: total_h, clip: false, place(dx: -margin, dy: 0pt, stack(
dir: ttb,
..range(n).map(i => {
let frac = i / (n - 1)
// Frontières qui bougent uniquement verticalement
let f1 = full_w * 0.33 + bias * frac
let f2 = full_w * 0.66 + bias * frac
box(
width: full_w,
height: stripe,
clip: false,
place(dx: 0pt, dy: 0pt, box(width: f1, height: stripe, clip: true, move(dx: margin, dy: -stripe * i, text(
fill: orange,
weight: "bold",
)[$j$])))
+ place(dx: f1, dy: 0pt, box(width: f2 - f1, height: stripe, clip: true, move(
dx: margin - f1,
dy: -stripe * i,
text(fill: green.darken(20%), weight: "bold")[$j$],
)))
+ place(dx: f2, dy: 0pt, box(width: full_w - f2, height: stripe, clip: true, move(
dx: margin - f2,
dy: -stripe * i,
text(fill: blue, weight: "bold")[$j$],
))),
)
}),
)))
}
#let tanner_illustration_old() = {
cetz.canvas(length: 1.1cm, {
import cetz.draw: *
@ -1287,6 +1432,80 @@
})
}
#let tanner_illustration() = {
cetz.canvas(length: 1.1cm, {
import cetz.draw: *
let vy = 2.6
let cy = 0.0
let vxs = (0.0, 1.2, 2.4, 3.6)
let cxs = (0.9, 2.7)
let edges = ((0, 0), (1, 0), (2, 0), (1, 1), (2, 1), (3, 1))
let vr = 0.28
let cs = 0.30
let circle_border(cx, cy_n, r, dx, dy) = {
let len = calc.sqrt(dx * dx + dy * dy)
(cx + r * dx / len, cy_n + r * dy / len)
}
let square_border(cx, cy_n, s, dx, dy) = {
let ax = calc.abs(dx)
let ay = calc.abs(dy)
let t = if ax == 0.0 { s / ay } else if ay == 0.0 { s / ax } else { calc.min(s / ax, s / ay) }
(cx + t * dx, cy_n + t * dy)
}
// Dessin des arêtes
for (vi, ci) in edges {
let vx = vxs.at(vi)
let cx = cxs.at(ci)
let dx = cx - vx
let dy = cy - vy
let (px1, py1) = circle_border(vx, vy, vr, dx, dy)
let (px2, py2) = square_border(cx, cy, cs, -dx, -dy)
line((px1, py1), (px2, py2), stroke: 0.9pt + gray.darken(10%))
}
// Nœuds de contrôle (carrés, orange)
let cnames = ([$c_0$], [$c_1$])
for j in range(2) {
let cx = cxs.at(j)
let s = cs
rect(
(cx - s, cy - s),
(cx + s, cy + s),
fill: orange.lighten(75%),
stroke: 1.8pt + orange,
name: "c" + str(j),
)
content(
(cx, cy - s - 0.3),
anchor: "north",
text(size: 0.8em, fill: orange, weight: "bold")[#cnames.at(j)],
)
}
// Nœuds de variable (cercles, bleu)
let vnames = ([$v_0$], [$v_1$], [$v_2$], [$v_3$])
for i in range(4) {
let vx = vxs.at(i)
let r = vr
circle(
(vx, vy),
radius: r,
fill: blue.lighten(75%),
stroke: 1.8pt + blue,
name: "v" + str(i),
)
content(
(vx, vy + r + 0.25),
anchor: "south",
text(size: 0.8em, fill: blue, weight: "bold")[#vnames.at(i)],
)
}
})
}
// Mini matrice H avec surbrillance d'une ligne et/ou colonne
#let h_mini_tanner(hl_row: none, hl_col: none) = {
let pts = _h_pts
@ -2234,29 +2453,22 @@
})
}
//Comp 1
#let vvals = (1, 0, 1, 0)
#let edges = ((0, 0), (1, 0), (3, 0), (0, 1), (2, 1), (3, 1), (1, 2), (2, 2))
#let graph_layout(step: 1) = {
cetz.canvas(length: 0.85cm, {
import cetz.draw: *
let (vy, cy) = (4.5, 0.0) // vy = Top (Variable Nodes), cy = Bottom (Check Nodes)
let (vy, cy) = (4.5, 0.0)
let vxs = (0.0, 2.5, 5.0, 7.5)
let cxs = (1.25, 3.75, 6.25)
let r_v = 0.45
let s_c = 0.4
// --- 1. LES ARÊTES AVEC DIRECTIONALITÉ ---
// --- 1. LES ARÊTES ---
for (k, (vi, ci)) in edges.enumerate() {
let v_pos = (vxs.at(vi), vy)
let c_pos = (cxs.at(ci), cy)
if step == 1 {
// VN -> CN : On part du haut vers le bas
line(
v_pos,
c_pos,
@ -2266,7 +2478,6 @@
stroke: 2pt + blue,
)
} else if step == 2 {
// CN -> VN : On part du bas vers le haut
let is_err = (ci == 0 or ci == 2)
let col = if is_err { red } else { green.darken(20%) }
line(
@ -2278,11 +2489,9 @@
stroke: 2pt + col,
)
} else {
// Étape 3 : Passif
line(v_pos, c_pos, shorten-start: r_v, shorten-end: s_c, stroke: 1pt + gray.lighten(70%))
}
}
// --- 2. LES VARIABLE NODES (VN) ---
for i in range(4) {
let pos = (vxs.at(i), vy)
@ -2290,32 +2499,44 @@
let col = if is_flip { red } else { blue }
let bg = if is_flip { red.lighten(92%) } else { blue.lighten(90%) }
let val = if is_flip { "1" } else { str(vvals.at(i)) }
circle(pos, radius: r_v, fill: bg, stroke: (if is_flip { 2.5pt } else { 1.5pt }) + col)
content(pos, text(weight: "bold", fill: col, size: 1.1em)[#val])
content(pos, text(weight: "bold", fill: col, size: 1.1em, val))
content((pos.at(0), pos.at(1) + 0.8), text(size: 0.8em, fill: col.darken(0%))[$v_#i$])
if is_flip {
content((pos.at(0) + 0.1, pos.at(1) + 1.3), text(fill: red, weight: "bold", size: 0.7em)[FLIP !])
}
}
// --- 3. LES CHECK NODES (CN) ---
for j in range(3) {
let pos = (cxs.at(j), cy)
let val = if j == 1 { 0 } else { 1 }
let col = orange
let bg = orange.lighten(90%)
if step >= 2 {
let is_ok = (val == 0)
col = if is_ok { green.darken(20%) } else { red }
bg = col.lighten(92%)
let val_base = if j == 1 { 0 } else { 1 }
let val_num = if step == 3 and j != 1 { 0 } else { val_base }
let val_str = str(val_num)
let col = if step == 1 {
orange
} else if step == 2 {
if val_base == 0 { green.darken(20%) } else { red }
} else {
if val_num == 0 { green.darken(20%) } else { red }
}
rect((pos.at(0) - s_c, pos.at(1) - s_c), (pos.at(0) + s_c, pos.at(1) + s_c), fill: bg, stroke: 1.8pt + col)
content(pos, text(weight: "bold", fill: col, size: 1.1em)[#str(val)])
content((pos.at(0), pos.at(1) - 0.8), text(size: 0.8em, fill: col.darken(0%))[$c_#j$])
let bg = if step == 1 { orange.lighten(90%) } else { col.lighten(92%) }
let is_modified = step == 3 and j != 1
let x0 = pos.at(0) - s_c
let x1 = pos.at(0) + s_c
let y0 = pos.at(1) - s_c
let y1 = pos.at(1) + s_c
rect((x0, y0), (x1, y1), fill: bg, stroke: none)
if is_modified {
let ds = (paint: col, thickness: 1.3pt, dash: (array: (2pt, 3pt), phase: -0pt))
line((x0, y0), (x1, y0), stroke: ds)
line((x1, y0), (x1, y1), stroke: ds)
line((x1, y1), (x0, y1), stroke: ds)
line((x0, y1), (x0, y0), stroke: ds)
} else {
rect((x0, y0), (x1, y1), fill: none, stroke: (paint: col, thickness: 1.8pt))
}
content(pos, text(weight: "bold", fill: col, size: 1.1em, val_str))
content((pos.at(0), pos.at(1) - 0.8), text(size: 0.8em, fill: col)[$c_#j$])
}
})
}

21941
main.pdf

File diff suppressed because it is too large Load Diff

233
main.typ
View File

@ -114,28 +114,21 @@
]
#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()
#place(dy: 2.5cm)[
#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)$
]]
]
#myslide("Définition : Matrice Génératrice")[
@ -166,10 +159,10 @@
#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%)),
))$
// - 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é\
]
@ -192,9 +185,12 @@
]
#[
#set text(size: 1.2em)
- $cal(C) = ker(H) = {v in FF_2^n | H dot.o v^top = 0}$
// - $cal(C) = ker(H) = {v in FF_2^n | H dot.o v^top = 0}$
- $display(G dot.o H^top = 0)$
- $cal(C) = ker(H)$ -- $H c^top = 0$ $=>$ $c$ mot de code valide
// - $display(G dot.o H^top = 0)$
]
#definition(titre: "Syndrome")[
@ -205,8 +201,8 @@
]
#[
#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$
- $s = 0 => r space$ mot de code valide
- $s != 0$ donne la signature de l'erreur $e$
]
// Possible décodage par syndrome
]
@ -331,26 +327,30 @@
// ]
#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)) $
#place(dy: 2.5cm)[
#set text(size: 19pt)
#definition(titre: [Décodage par Maximum de Vraisemblance], 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.
]
- É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: [Codes LDPC Réguliers])[
Code linéaire en bloc avec une matrice de contrôle $bold(H)$ *clairsemée*.
#text(size: 22.97pt)[
Code linéaire en bloc avec une matrice de contrôle $bold(H)$ *clairsemée*.
]
]
- Poids de Colonne *$w_c$*
@ -365,13 +365,19 @@
]
#definition(titre: "Rendement")[
$ display(R = (n - op("rg")(H)) / n >= 1 - m / n) $
// $ display(R = (n - op("rg")(H)) / n >= 1 - m / n) $
$ display(R = 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)$
// ]
#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(8pt)
$H in cal(M)_(15, 30)(FF_2)$ et $display(R = 1/2)$
#v(5pt)
]
#v(2cm)
@ -410,11 +416,11 @@
#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$.
#set text(size: 1.2em)
// - Chaque ligne $j$ de $H$ définit une équation de parité $f_j$.
- $L_j$ 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)[
@ -465,7 +471,7 @@
// ]
#myslide("L'Entrelacement des Contraintes")[
#set text(size: 17pt)
#set text(size: 20pt)
#align(center)[
#move(dx: -1.2cm)[
@ -492,7 +498,7 @@
#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 {#text(fill: orange)[$0$], #text(fill: green.darken(20%))[$7$], #text(fill: blue)[$24$]}, space f_j = 1$, alors le bit est comme suspect.
- Si $forall #tricolor-j in {#text(fill: orange)[$0$], #text(fill: green.darken(20%))[$7$], #text(fill: blue)[$24$]}, space f_(#scale(80%)[#tricolor-j]) = 1$, alors le bit est comme suspect.
]
@ -794,7 +800,7 @@
]
#myslide("La Topologie de H : Le Girth")[
#set text(size: 18pt)
#set text(size: 20pt)
#definition(titre: "Définition : Le Girth (La Maille)", accent: blue)[
Longueur du plus court cycle dans le graphe de Tanner
@ -836,6 +842,7 @@
]
#myslide("Méthode de génération de H")[
#place(center + horizon, dy: 8.1cm)[#graphe_tanner_fond(0.9cm, 1.75)]
#place(center + horizon, dy: 7cm)[
#block(width: 100%)[
#text(size: 1.5em, weight: "bold", fill: black)[
@ -843,7 +850,7 @@
Mackay-Neal \
Progressive Edge-growth
Progressive Edge-Growth
]
]
]
@ -868,7 +875,8 @@
#v(2em)
#set text(size: 1em)
- Forme Systématique : Par élimination de Gauss sur $bold(H)$, on obtient
// - Forme Systématique : Par élimination de Gauss sur $bold(H)$, on obtient
- Forme Systématique
#v(1em)
#align(center)[
@ -1340,11 +1348,11 @@
#place(center + horizon, dy: 7.7cm)[
#block(width: 100%)[
#text(size: 1.5em, weight: "bold", fill: black)[
QC-LDPC \
FPGA \
Test réel
QC-LDPC \
Test réels
]
]
]
@ -1361,7 +1369,103 @@
]
]
#myslide("Théorie deriere la définition des codes linaires")[
#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)
#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("Théorie derrière la définition des codes linaires")[
Poser les notations algebriques etc...
]
@ -1532,7 +1636,16 @@
]
#myslide("PEG")[
#myslide("Gallager")[
]
#myslide("Mackay-Neal")[
]
#myslide("Progressive Edge-growth")[
]