This commit is contained in:
2026-05-05 21:20:38 +02:00
parent 09e4bfabdb
commit 3ff2fc630f
14 changed files with 17847 additions and 2601 deletions

502
composants.typ Normal file
View File

@ -0,0 +1,502 @@
#import "@preview/polylux:0.4.0": *
#import "@preview/cetz:0.5.0"
#import "@preview/cetz-plot:0.1.3": plot
#set math.mat(delim: "[")
// 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()
let cur = counter("logical-slide").get().first()
let tot = counter("logical-slide").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 #numero], [#titre], [#annee], [#(cur - 1) / #(tot - 1)],
)
]
}
}
]
// 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,
..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()
)
]
]
}
// Graphe de Tanner en filigrane
#let graphe_tanner_fond(taille, spread) = {
cetz.canvas(length: taille, {
import cetz.draw: *
let n_var = 18
let n_chk = 9
let var_y = 11
let chk_y = -8
// Calcul automatique pour que le graphe soit centré sur X=0
let dist_v = (n_var - 1) * spread
let v_start = -dist_v / 2
let vpos = range(n_var).map(i => (v_start + i * spread, var_y))
let spread_c = dist_v / (n_chk - 1)
let c_start = -dist_v / 2
let cpos = range(n_chk).map(i => (c_start + i * spread_c, chk_y))
let edges = (
(0, 0),
(0, 4),
(0, 8),
(1, 1),
(1, 5),
(1, 0),
(2, 2),
(2, 6),
(2, 1),
(3, 3),
(3, 7),
(3, 2),
(4, 4),
(4, 8),
(4, 3),
(5, 5),
(5, 0),
(5, 4),
(6, 6),
(6, 1),
(6, 5),
(7, 7),
(7, 2),
(7, 6),
(8, 8),
(8, 3),
(8, 7),
(9, 0),
(9, 3),
(9, 6),
(10, 1),
(10, 4),
(10, 7),
(11, 2),
(11, 5),
(11, 8),
(12, 0),
(12, 5),
(12, 7),
(13, 1),
(13, 3),
(13, 8),
(14, 2),
(14, 4),
(14, 6),
(15, 0),
(15, 4),
(15, 7),
(16, 1),
(16, 5),
(16, 8),
(17, 2),
(17, 3),
(17, 6),
)
for e in edges {
let vp = vpos.at(e.at(0))
let cp = cpos.at(e.at(1))
line((vp.at(0), vp.at(1)), (cp.at(0), cp.at(1)), stroke: 0.45pt + rgb("#e0e0e0"))
}
for p in vpos {
circle((p.at(0), p.at(1)), radius: 0.25, fill: white, stroke: 0.8pt + rgb("#cccccc"))
}
for p in cpos {
let (x, y) = p
rect((x - 0.25, y - 0.25), (x + 0.25, y + 0.25), fill: white, stroke: 0.8pt + rgb("#cccccc"))
}
})
}
// Schema Shannon
#let canal_shannon_intro() = {
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])
})
}
#let plongement_schema() = {
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, -2.6), [$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((rel: (-0.85, 0.1), to: 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((rel: (0.85, -0.1), to: cf.p110), [110], anchor: "north-east", padding: .2)
content((4, -2.6), [$FF_2^3$])
})
}
#let definition(
titre: "Définition",
accent: black,
titre_taille: 1.13em,
corps_taille: 1.2em,
contenu,
) = {
block(
width: 100%,
fill: rgb("#f8f9fa"),
stroke: 0.5pt + gray.lighten(60%),
radius: 8pt,
clip: true,
grid(
columns: (5pt, 1fr),
rows: auto,
fill: (col, row) => if col == 0 { accent },
[],
block(
width: 100%,
inset: (x: 16pt, y: 15pt),
{
{
set text(fill: accent, weight: 800, size: titre_taille, tracking: 0.5pt)
show math.equation: set text(weight: 700, size: 1.05em)
titre
}
v(18pt, weak: true)
{
set text(size: corps_taille)
set par(leading: 0.7em, justify: false)
contenu
}
},
),
),
)
}
#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),
// 1. On grossit les labels d'axes (15pt)
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,
// Axis
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,
// Légende positionnée en bas.
legend: "north-east",
legend-style: (
stroke: 0.5pt + gray,
fill: white,
padding: 0.2,
offset: (-161.4pt, -45.1pt),
),
{
// 1. Limite de Shannon (Asymptote)
plot.add(
((1.5, -8.5), (1.5, 0.2)),
style: (stroke: (paint: col-shannon, thickness: 2pt, dash: "dashed")),
label: [Limite de Shannon],
)
// 2. Petit bloc linéaire (n ≈ 100) - Ultra-densifié (smooth)
plot.add(
(
(0.0, 0.00),
(0.2, -0.01),
(0.4, -0.03),
(0.6, -0.05),
(0.8, -0.07),
(1.0, -0.10),
(1.2, -0.13),
(1.4, -0.17),
(1.6, -0.21),
(1.8, -0.25),
(2.0, -0.30),
(2.2, -0.36),
(2.4, -0.43),
(2.6, -0.51),
(2.8, -0.60),
(3.0, -0.70),
(3.2, -0.80),
(3.4, -0.91),
(3.6, -1.03),
(3.8, -1.16),
(4.0, -1.30),
(4.2, -1.44),
(4.4, -1.59),
(4.6, -1.75),
(4.8, -1.92),
(5.0, -2.10),
(5.2, -2.28),
(5.4, -2.47),
(5.6, -2.67),
(5.8, -2.88),
(6.0, -3.10),
(6.2, -3.32),
(6.4, -3.55),
(6.6, -3.79),
(6.8, -4.04),
(7.0, -4.30),
(7.2, -4.56),
(7.4, -4.83),
(7.6, -5.11),
(7.8, -5.40),
(8.0, -5.70),
(8.2, -6.00),
(8.4, -6.31),
(8.6, -6.63),
(8.8, -6.96),
(9.0, -7.30),
(9.2, -7.62),
(9.4, -7.95),
(9.6, -8.29),
(9.8, -8.64),
(10.0, -9.00),
),
style: (stroke: (paint: col-code-short, thickness: 1.5pt)),
label: [Code court ($n approx 100$)],
)
// 3. Grand bloc linéaire (n = 64 800) - Ultra-densifié (smooth & waterfall net)
plot.add(
(
(0.0, 0.0),
(0.2, -0.005),
(0.4, -0.01),
(0.6, -0.02),
(0.8, -0.035),
(1.0, -0.05),
(1.1, -0.07),
(1.2, -0.10),
(1.3, -0.14),
(1.4, -0.20),
(1.45, -0.28),
(1.50, -0.40),
(1.52, -0.45),
(1.54, -0.52),
(1.56, -0.60),
(1.58, -0.69),
(1.60, -0.80),
(1.62, -0.92),
(1.64, -1.05),
(1.66, -1.19),
(1.68, -1.34),
(1.70, -1.50),
(1.72, -1.69),
(1.74, -1.89),
(1.76, -2.11),
(1.78, -2.35),
(1.80, -2.60),
(1.82, -2.88),
(1.84, -3.18),
(1.86, -3.50),
(1.88, -3.84),
(1.90, -4.20),
(1.92, -4.52),
(1.94, -4.86),
(1.96, -5.22),
(1.98, -5.60),
(2.00, -6.00),
(2.02, -6.32),
(2.04, -6.64),
(2.06, -6.94),
(2.08, -7.23),
(2.10, -7.50),
(2.12, -7.66),
(2.14, -7.81),
(2.16, -7.95),
(2.18, -8.08),
(2.20, -8.20),
(2.22, -8.32),
(2.24, -8.44),
(2.25, -8.50),
),
style: (stroke: (paint: col-code-long, thickness: 3.5pt)),
label: [Code long ($n = 64\,800$)],
)
},
)
})
]
}

10186
main.pdf Normal file

File diff suppressed because one or more lines are too long

363
main.typ Normal file
View File

@ -0,0 +1,363 @@
#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)[#numero]
#text(size: 0.95em, fill: black)[#annee]
]
]
#v(1fr)
]
#myslide("Plan")[
#design_plan((
[Introduction],
[Codes linéaires],
[LDPC],
[Codage],
[Décodage],
[Analyse],
))
]
#myslide("Introduction : Transmission Numérique")[
#align(center + horizon)[
#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")[
$
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: "[",))$
- $P in cal(M)_(k ,(n-k))(FF_2)$ matrice de parité\
]
]
#myslide("Défniition: Matrice de Contrôle")[
#definition(titre: "Matrice de Contrôle")[
$
H = mat(
P^top, I_(n-k);
augment: #1,
delim: "[",
)
$
]
#[
#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
#v(0.5em)
#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")[
#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("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 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")[
#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...
]

17
pres.md
View File

@ -36,6 +36,23 @@ Linéarité => decodage par syndrome
Ajouter de la redondance coûte cher en débit, c'est ce que l'on appelle l'overhead. Pour garder un débit élevé tout en corrigeant beaucoup d'erreurs, la solution est d'utiliser des codes de très grande taille. En augmentant la longueur du bloc N, nous permettons au décodeur de traiter l'information de manière statistique et de nous approcher très près de la capacité limite du canal. Ajouter de la redondance coûte cher en débit, c'est ce que l'on appelle l'overhead. Pour garder un débit élevé tout en corrigeant beaucoup d'erreurs, la solution est d'utiliser des codes de très grande taille. En augmentant la longueur du bloc N, nous permettons au décodeur de traiter l'information de manière statistique et de nous approcher très près de la capacité limite du canal.
## 2 ## 2
La correction d'erreur n'est pas gratuite : elle se paie en débit. Pour ne pas gaspiller de bande passante tout en restant fiable, la théorie de Shannon nous montre qu'il faut utiliser des codes de très grande taille. Un bloc long permet de mieux diluer l'impact du bruit. C'est pour cette raison que les standards modernes (5G, Wi-Fi) utilisent des codes LDPC massifs : ils offrent le meilleur ratio 'correction / sacrifice de débit' possible à ce jour. La correction d'erreur n'est pas gratuite : elle se paie en débit. Pour ne pas gaspiller de bande passante tout en restant fiable, la théorie de Shannon nous montre qu'il faut utiliser des codes de très grande taille. Un bloc long permet de mieux diluer l'impact du bruit. C'est pour cette raison que les standards modernes (5G, Wi-Fi) utilisent des codes LDPC massifs : ils offrent le meilleur ratio 'correction / sacrifice de débit' possible à ce jour.
## 3
Pourquoi des codes “longs” ?
• Moyennage du bruit : Plus le
bloc est grand, plus le bruit
aléatoire du canal se rapproche de
sa moyenne statistique (Loi des
Grands Nombres).
• Phénomène de Waterfall : Pour
les grands 𝑛, on observe une chute
brutale de la probabilité derreur à
un seuil précis.
• Convergence : Shannon a prouvé
que la capacité 𝐶 nest atteinte
que lorsque 𝑛⟶∞.
• Standard DVB-S2 : Utilise 𝑛=
64, 800 pour être à moins de 1 dB
de la limite théorique.
# MDL # MDL
## 1 ## 1

File diff suppressed because one or more lines are too long

View File

@ -1,414 +0,0 @@
#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 #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.
]

BIN
src/athena_fidus.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

BIN
src/athena_fidus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 MiB

BIN
src/construction.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
src/construction.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
src/runcamfpv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
src/runcamfpv2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB