girth
This commit is contained in:
224
composants.typ
224
composants.typ
@ -1517,3 +1517,227 @@
|
|||||||
rect((-0.35em, -0.35em), (0.35em, 0.35em), fill: orange.lighten(88%), stroke: 1.5pt + orange)
|
rect((-0.35em, -0.35em), (0.35em, 0.35em), fill: orange.lighten(88%), stroke: 1.5pt + orange)
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// Calcule la parité d'un Check Node i en fonction des Variable Nodes connectés
|
||||||
|
#let calcule_parite(v_values, index_chk) = {
|
||||||
|
let neighbors = _h_pts.filter(p => p.at(1) == index_chk).map(p => p.at(0))
|
||||||
|
let somme = 0
|
||||||
|
for n in neighbors {
|
||||||
|
somme = somme + v_values.at(n)
|
||||||
|
}
|
||||||
|
calc.rem(somme, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let tanner_status(
|
||||||
|
scale: 0.43cm,
|
||||||
|
v_values: none,
|
||||||
|
hl_v: (),
|
||||||
|
highlight_edges: false,
|
||||||
|
) = {
|
||||||
|
let pts = _h_pts
|
||||||
|
cetz.canvas(length: scale, {
|
||||||
|
import cetz.draw: *
|
||||||
|
let n_var = 30
|
||||||
|
let n_chk = 15
|
||||||
|
let vy = 5.5
|
||||||
|
let cy = 0.0
|
||||||
|
let gap_v = 1.0
|
||||||
|
let gap_c = 1.8
|
||||||
|
let width_v = (n_var - 1) * gap_v
|
||||||
|
let width_c = (n_chk - 1) * gap_c
|
||||||
|
let offset_c = (width_v - width_c) / 2
|
||||||
|
|
||||||
|
let col_ok = green
|
||||||
|
let col_err = red
|
||||||
|
|
||||||
|
for (vj, ci) in pts {
|
||||||
|
let vx = vj * gap_v
|
||||||
|
let ccx = offset_c + (ci * gap_c)
|
||||||
|
let p_ci = calcule_parite(v_values, ci)
|
||||||
|
let is_err_edge = highlight_edges and hl_v.contains(vj) and p_ci == 1
|
||||||
|
|
||||||
|
if not is_err_edge {
|
||||||
|
line((vx, vy), (ccx, cy), stroke: 0.4pt + gray.lighten(60%))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (vj, ci) in pts {
|
||||||
|
let vx = vj * gap_v
|
||||||
|
let ccx = offset_c + (ci * gap_c)
|
||||||
|
let p_ci = calcule_parite(v_values, ci)
|
||||||
|
let is_err_edge = highlight_edges and hl_v.contains(vj) and p_ci == 1
|
||||||
|
|
||||||
|
if is_err_edge {
|
||||||
|
line((vx, vy), (ccx, cy), stroke: 1.5pt + col_err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for j in range(n_chk) {
|
||||||
|
let ccx = offset_c + (j * gap_c)
|
||||||
|
let sz = 0.40
|
||||||
|
let p = calcule_parite(v_values, j)
|
||||||
|
let is_ok = (p == 0)
|
||||||
|
|
||||||
|
rect(
|
||||||
|
(ccx - sz, cy - sz),
|
||||||
|
(ccx + sz, cy + sz),
|
||||||
|
fill: if is_ok { col_ok.lighten(92%) } else { col_err.lighten(92%) },
|
||||||
|
stroke: if is_ok { 1.2pt + col_ok } else { 1.5pt + col_err },
|
||||||
|
)
|
||||||
|
content((ccx, cy), text(size: 0.65em, weight: "bold", fill: if is_ok { col_ok } else { col_err })[#p])
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in range(n_var) {
|
||||||
|
let vx = i * gap_v
|
||||||
|
let r = 0.33
|
||||||
|
let val = v_values.at(i)
|
||||||
|
let is_err = hl_v.contains(i)
|
||||||
|
|
||||||
|
circle(
|
||||||
|
(vx, vy),
|
||||||
|
radius: r,
|
||||||
|
fill: if is_err { col_err.lighten(92%) } else { blue.lighten(92%) },
|
||||||
|
stroke: if is_err { 1.5pt + col_err } else { 1.2pt + blue },
|
||||||
|
)
|
||||||
|
content((vx, vy), text(size: 0.55em, weight: "bold", fill: if is_err { col_err } else { blue })[#val])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Composant de zoom d'une seule contrainte (CN) et ses VN voisins
|
||||||
|
#let zoom_contrainte(is_ok: true) = {
|
||||||
|
cetz.canvas(length: 1cm, {
|
||||||
|
import cetz.draw: *
|
||||||
|
let col = if is_ok { green } else { red }
|
||||||
|
|
||||||
|
rect((-2.2, -1.2), (2.2, 2.0), stroke: none, fill: none)
|
||||||
|
|
||||||
|
let blue_fill = blue.lighten(90%)
|
||||||
|
let blue_stroke = 1.2pt + blue
|
||||||
|
let red_fill = red.lighten(90%)
|
||||||
|
let red_stroke = 2pt + red
|
||||||
|
let gray_stroke = 0.8pt + gray
|
||||||
|
|
||||||
|
for i in (0, 1, 2) {
|
||||||
|
let x = i * 1.5 - 1.5
|
||||||
|
let is_failed_vn = not is_ok and i == 1
|
||||||
|
line((x, 1.5), (0, 0), stroke: if is_failed_vn { red_stroke } else { gray_stroke })
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in (0, 1, 2) {
|
||||||
|
let x = i * 1.5 - 1.5
|
||||||
|
let is_failed_vn = not is_ok and i == 1
|
||||||
|
circle(
|
||||||
|
(x, 1.5),
|
||||||
|
radius: 0.3,
|
||||||
|
stroke: if is_failed_vn { red_stroke } else { blue_stroke },
|
||||||
|
fill: if is_failed_vn { red_fill } else { blue_fill },
|
||||||
|
)
|
||||||
|
|
||||||
|
let val = if is_failed_vn { "1" } else { "0" }
|
||||||
|
content((x, 1.5), text(size: 12pt, fill: if is_failed_vn { col } else { blue }, weight: "bold")[#val])
|
||||||
|
}
|
||||||
|
|
||||||
|
rect(
|
||||||
|
(-0.3, -0.3),
|
||||||
|
(0.3, 0.3),
|
||||||
|
stroke: if not is_ok { red_stroke } else { 2pt + col },
|
||||||
|
fill: if not is_ok { red_fill } else { col.lighten(90%) },
|
||||||
|
)
|
||||||
|
content((0, 0), text(fill: col, weight: "bold", size: 15pt)[#(if is_ok { "0" } else { "1" })])
|
||||||
|
|
||||||
|
let eq_size = 14pt
|
||||||
|
if is_ok {
|
||||||
|
content(
|
||||||
|
(0, -0.7),
|
||||||
|
text(fill: col, size: eq_size)[$0 plus.o 0 plus.o 0 = bold(0)$],
|
||||||
|
anchor: "north",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
content(
|
||||||
|
(0, -0.71),
|
||||||
|
text(fill: col, size: eq_size)[$0 plus.o 1 plus.o 0 = bold(1)$],
|
||||||
|
anchor: "north",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Schémas pour la Topologie et la Construction ---
|
||||||
|
// Visualisation du Girth et d'un cycle de longueur 4
|
||||||
|
#let schema_girth_4(highlight: false) = {
|
||||||
|
cetz.canvas(length: 0.8cm, {
|
||||||
|
import cetz.draw: *
|
||||||
|
let s_dash = (paint: red, thickness: 2pt, dash: "dashed")
|
||||||
|
|
||||||
|
// Positionnement
|
||||||
|
let v0 = (-1.5, 2)
|
||||||
|
let v1 = (1.5, 2)
|
||||||
|
let c0 = (-1.5, 0)
|
||||||
|
let c1 = (1.5, 0)
|
||||||
|
|
||||||
|
// Arêtes
|
||||||
|
line(v0, c0, v1, c1, v0, stroke: if highlight { s_dash } else { 1pt + gray })
|
||||||
|
// line(v0, c1, stroke: 1pt + gray.lighten(60%))
|
||||||
|
|
||||||
|
// Noeuds
|
||||||
|
circle(v0, radius: 0.3, fill: blue.lighten(90%), stroke: 1.2pt + blue)
|
||||||
|
circle(v1, radius: 0.3, fill: blue.lighten(90%), stroke: 1.2pt + blue)
|
||||||
|
rect(
|
||||||
|
(c0.at(0) - 0.3, c0.at(1) - 0.3),
|
||||||
|
(c0.at(0) + 0.3, c0.at(1) + 0.3),
|
||||||
|
fill: orange.lighten(90%),
|
||||||
|
stroke: 1.2pt + orange,
|
||||||
|
)
|
||||||
|
rect(
|
||||||
|
(c1.at(0) - 0.3, c1.at(1) - 0.3),
|
||||||
|
(c1.at(0) + 0.3, c1.at(1) + 0.3),
|
||||||
|
fill: orange.lighten(90%),
|
||||||
|
stroke: 1.2pt + orange,
|
||||||
|
)
|
||||||
|
|
||||||
|
// if highlight {
|
||||||
|
// content(
|
||||||
|
// (0, 1),
|
||||||
|
// text(fill: red, weight: "bold", size: 0.8em)[Cycle $L=4$],
|
||||||
|
// frame: "rect",
|
||||||
|
// stroke: none,
|
||||||
|
// fill: rgb("ffffffcc"),
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#let echo_chamber() = {
|
||||||
|
cetz.canvas(length: 1cm, {
|
||||||
|
import cetz.draw: *
|
||||||
|
let v0 = (0, 2)
|
||||||
|
let c0 = (0, 0)
|
||||||
|
|
||||||
|
line(v0, c0, mark: (end: "stealth", fill: red), stroke: 2pt + red)
|
||||||
|
arc((0, 0), start: -45deg, stop: 225deg, radius: 0.5, mark: (end: "stealth", fill: red), stroke: 1.5pt + red)
|
||||||
|
|
||||||
|
circle(v0, radius: 0.3, fill: blue.lighten(90%), stroke: 1.5pt + blue)
|
||||||
|
rect((-0.3, -0.3), (0.3, 0.3), fill: orange.lighten(90%), stroke: 1.5pt + orange)
|
||||||
|
|
||||||
|
content((1, 1), text(fill: red, size: 0.8em, style: "italic")[Auto-renforcement \ d'une erreur], anchor: "west")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#let peg_concept() = {
|
||||||
|
cetz.canvas(length: 0.6cm, {
|
||||||
|
import cetz.draw: *
|
||||||
|
circle((0, 4), radius: 0.4, fill: blue.lighten(80%), stroke: 1.5pt + blue)
|
||||||
|
let targets = ((-3, 0), (0, 0), (3, 0))
|
||||||
|
for t in targets {
|
||||||
|
line((0, 4), t, stroke: 1.5pt + green)
|
||||||
|
rect(
|
||||||
|
(t.at(0) - 0.3, t.at(1) - 0.3),
|
||||||
|
(t.at(0) + 0.3, t.at(1) + 0.3),
|
||||||
|
fill: orange.lighten(90%),
|
||||||
|
stroke: 1.2pt + orange,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
content((0, -1.2), text(size: 0.8em, fill: green, weight: "bold")[Distance maximale], anchor: "north")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
203
main.typ
203
main.typ
@ -150,6 +150,7 @@
|
|||||||
]
|
]
|
||||||
|
|
||||||
#definition(titre: "Forme systématique")[
|
#definition(titre: "Forme systématique")[
|
||||||
|
// TODO : changer [I_k | P] en un graphique jolie avec I et P dans un carré coloré
|
||||||
$
|
$
|
||||||
G = mat(
|
G = mat(
|
||||||
I_k, P;
|
I_k, P;
|
||||||
@ -496,7 +497,7 @@
|
|||||||
|
|
||||||
#align(center)[
|
#align(center)[
|
||||||
#scale(180%)[
|
#scale(180%)[
|
||||||
#tanner_canvas(colored: false)
|
#tanner_canvas(colored: true)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -617,8 +618,163 @@
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
#myslide("Graphe de Tanner")[
|
#let mot_valide = (
|
||||||
AJOUTER UNE SLIDE SUR LA CONTRAINE DE SOMME NUL POUR UNE MOT DE CODE 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")[
|
#myslide("Encodage")[
|
||||||
@ -721,3 +877,44 @@
|
|||||||
// ],
|
// ],
|
||||||
// )
|
// )
|
||||||
// ]
|
// ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#myslide("tt")[
|
||||||
|
f
|
||||||
|
]
|
||||||
|
|
||||||
|
// --- SLIDE 2 : DANGER ET SOLUTIONS (À placer plus tard) ---
|
||||||
|
//
|
||||||
|
// #myslide("Cycles courts : Danger et Solutions")[
|
||||||
|
// #set text(size: 18pt)
|
||||||
|
//
|
||||||
|
// #grid(
|
||||||
|
// columns: (1fr, 1fr),
|
||||||
|
// gutter: 1.5cm,
|
||||||
|
// [
|
||||||
|
// #text(weight: "bold", fill: red, size: 1.1em)[1. Le Danger : L'Effet d'Écho]
|
||||||
|
// #v(1em)
|
||||||
|
//
|
||||||
|
// #align(center)[#echo_chamber()]
|
||||||
|
//
|
||||||
|
// #v(1em)
|
||||||
|
// *Conséquences sur le décodage :*
|
||||||
|
// - Une information erronée se renforce elle-même en tournant dans le cycle.
|
||||||
|
// - Empêche la convergence de l'algorithme.
|
||||||
|
// - Crée un *Error Floor* (plancher d'erreur) impossible à dépasser.
|
||||||
|
// ],
|
||||||
|
// [
|
||||||
|
// #text(weight: "bold", fill: green, size: 1.1em)[2. La Solution : Algorithme PEG]
|
||||||
|
// #v(1em)
|
||||||
|
//
|
||||||
|
// #align(center)[#peg_concept()]
|
||||||
|
//
|
||||||
|
// #v(1em)
|
||||||
|
// *Progressive Edge-Growth :*
|
||||||
|
// - Algorithme de construction de $bold(H)$ "bord à bord".
|
||||||
|
// - On connecte chaque nouveau nœud au point le plus *distant* du graphe existant.
|
||||||
|
// - *Résultat :* On "casse" les cycles courts et on maximise le Girth.
|
||||||
|
// ],
|
||||||
|
// )
|
||||||
|
// ]
|
||||||
|
|||||||
Reference in New Issue
Block a user