implementation

This commit is contained in:
2026-05-12 21:22:55 +02:00
parent 22e61fcbd1
commit 86a437d12b
8 changed files with 12850 additions and 7508 deletions

View File

@ -1,6 +1,7 @@
#import "@preview/polylux:0.4.0": *
#import "@preview/cetz:0.5.0"
#import "@preview/cetz-plot:0.1.3": plot
#import "@preview/cetz:0.5.0": canvas
#set math.mat(delim: "[")
@ -26,10 +27,13 @@
// 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()
let fins = query(<fin>)
let tot = if fins.len() > 0 {
counter("logical-slide").at(fins.first().location()).first()
} else {
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))[
@ -37,7 +41,7 @@
#grid(
columns: (1.5fr, 2fr, 1fr, auto),
align: (left, center, center, right),
[#auteur #numero], [#titre], [#annee], [#(cur - 1) / #(tot - 1)],
[#auteur #numero], [#titre], [#annee], if cur <= tot [#(cur - 1) / #(tot - 1)] else [Annexe],
)
]
}
@ -801,8 +805,8 @@
let h_height = ny * cell_size
// Palette unifiée
let color_blue = blue
let color_orange = orange
let color_blue = orange
let color_orange = blue
let col_dot_base = gray.darken(30%)
// Définition des couleurs de fond (lighten)
@ -2825,15 +2829,15 @@
let msgs = (2.8, 0.7, 4.2, 1.8)
let sgns = (1, -1, 1, 1)
let vals = ("+2.8", "-0.7", "+4.2", "+1.8")
let col_ms = blue.darken(15%)
let col_min = red.darken(10%)
let col_vn_bg = blue.lighten(94%)
let col_vn_bg = blue.lighten(94%)
// --- 1. GRAPHE DE TANNER ---
group(name: "tanner", {
for i in (0, 1, 2, 3) {
let y_pos = 2.25 - i*1.5
let y_pos = 2.25 - i * 1.5
line((-6.5, y_pos), (-2.0, 0), stroke: 1.2pt + gray.lighten(30%))
}
@ -2841,15 +2845,19 @@
content((-2.0, 0), text(size: 1.2em, fill: orange, weight: "bold")[$c$])
for i in (0, 1, 2, 3) {
let y_pos = 2.25 - i*1.5
circle((-6.5, y_pos), radius: 0.4, name: "v"+str(i), fill: col_vn_bg, stroke: 1.5pt + blue)
content("v"+str(i), text(size: 0.75em, fill: blue.darken(20%), weight: "bold")[$v_#i$])
let y_pos = 2.25 - i * 1.5
circle((-6.5, y_pos), radius: 0.4, name: "v" + str(i), fill: col_vn_bg, stroke: 1.5pt + blue)
content("v" + str(i), text(size: 0.75em, fill: blue.darken(20%), weight: "bold")[$v_#i$])
let val = vals.at(i)
content(((-6.5, y_pos), 42%, (-2.0, 0)),
box(fill: col_vn_bg, stroke: 0.5pt + blue.lighten(60%), radius: 2pt, inset: 4pt)[
#text(size: 0.65em, fill: black.lighten(10%), weight: "bold")[#val]
])
content(((-6.5, y_pos), 42%, (-2.0, 0)), box(
fill: col_vn_bg,
stroke: 0.5pt + blue.lighten(60%),
radius: 2pt,
inset: 4pt,
)[
#text(size: 0.65em, fill: black.lighten(10%), weight: "bold")[#val]
])
}
})
@ -2858,7 +2866,7 @@
// --- 3. GRAPHIQUE DES BARRES ---
group(name: "bars", {
let base_x = 1.4
let base_x = 1.4
for (i, m) in msgs.enumerate() {
let x = base_x + i * 1.4
let is_min = (m == 0.7)
@ -2875,9 +2883,320 @@
// --- 4. FLÈCHE ROUGE ---
line((6.5, 0), (8.0, 0), mark: (end: "stealth", fill: col_min), stroke: 2pt + col_min)
// --- 5. RÉSULTAT FINAL (Décalé plus à droite à x = 11.5) ---
content((10.5, 0), box(stroke: 1.5pt + col_min, fill: col_min.lighten(96%), radius: 5pt, inset: 10pt)[
#text(size: 0.8em, weight: "bold")[$m_(c arrow v_"cible") = -0.7$]
])
})
#let waterfall_plot(pts_uncoded, pts_bf) = {
cetz.canvas({
import cetz.draw
plot.plot(
size: (23, 14.5),
x-label: pad(top: 5cm)[],
y-label: [BER],
x-min: 0,
x-max: 8,
y-min: -9,
y-max: 0.2,
x-tick-step: 1,
y-tick-step: 1,
x-grid: true,
y-grid: true,
y-format: y => $10^(#int(y))$,
x-format: x => pad(top: 1cm)[#x],
legend: (2, 6),
legend-style: (
padding: 0.3,
stroke: gray.lighten(50%),
fill: white,
),
{
plot.annotate({
// for decade in range(-9, 0) {
// for minor in (2, 3, 4, 5, 6, 7, 8, 9) {
// let y_pos = decade + (calc.log(minor) / calc.log(10))
// if y_pos >= -9 and y_pos <= 0 {
// draw.line(
// (0, y_pos),
// (8, y_pos),
// stroke: (paint: gray.lighten(70%), thickness: 0.3pt),
// )
// }
// }
// }
draw.content((4, -10), text(size: 1.2em)[$E_b/N_0$ (dB)])
})
plot.add(
pts_uncoded,
label: [Signal non codé],
style: (stroke: (paint: orange, thickness: 2pt, dash: "dashed")),
mark: "+",
mark-style: (stroke: orange, size: 0.5),
)
plot.add(
pts_bf,
label: [Bit-Flipping],
style: (stroke: (paint: blue, thickness: 2.5pt)),
mark: "square",
mark-style: (stroke: blue, fill: white, size: 0.25),
)
},
)
})
}
#let convergence_plot(iters, syndrms) = {
let n = iters.len()
let max_s = 160.0
let W = 20.0
let H = 15.0
let bw = W / n
cetz.canvas({
import cetz.draw
for tick in (0, 50, 100, 150) {
let y = (tick / max_s) * H
draw.line((0, y), (W, y), stroke: 0.5pt + gray.lighten(60%))
draw.content((-0.8, y), text(size: 13pt)[#tick])
}
for i in range(n) {
let s = syndrms.at(i)
let bh = (s / max_s) * H
let x0 = i * bw
let col = if s == 0 { green.darken(20%) } else { blue }
draw.rect(
(x0, 0),
(x0 + bw * 0.8, bh),
fill: col.lighten(70%),
stroke: 1.2pt + col,
)
if calc.rem(i, 2) == 0 or i == n - 1 {
draw.content((x0 + bw * 0.4, -0.4), text(size: 13pt)[#i])
}
}
draw.line((0, 0), (W + 0.8, 0), stroke: 2pt, mark: (end: "stealth"))
draw.line((0, 0), (0, H + 0.8), stroke: 2pt, mark: (end: "stealth"))
draw.content((W / 2, -1), text(size: 19pt, weight: "bold")[Itérations])
draw.content((-2.2, H / 2), angle: 90deg, text(size: 19pt, weight: "bold")[Syndromes])
})
}
#let waterfall_plot(pts_uncoded, pts_bf) = {
cetz.canvas({
import cetz.draw: *
plot.plot(
size: (22, 15),
x-label: none,
y-label: none,
x-min: 0,
x-max: 10,
y-min: -9,
y-max: 0.2,
x-tick-step: 1,
y-tick-step: 1,
x-grid: true,
y-grid: true,
style: (
axes: (
bottom: (tick: (label: (offset: 0.2))), // Chiffres plus proches de l'axe
left: (tick: (label: (offset: 0.2))),
),
),
y-format: y => $10^(#int(y))$,
x-format: x => [#x],
legend: (14.4, 12.9),
legend-style: (padding: 0.3, stroke: gray.lighten(50%), fill: white),
{
plot.annotate({
// for decade in range(-9, 0) {
// for minor in (2, 3, 4, 5, 6, 7, 8, 9) {
// let y_pos = decade + (calc.log(minor) / calc.log(10))
// if y_pos >= -9 and y_pos <= 0 {
// line((0, y_pos), (8, y_pos), stroke: (paint: gray.lighten(60%), thickness: 0.3pt))
// }
// }
// }
content((4, -9.9), text(size: 1.3em)[$E_b/N_0$ (dB)])
content((-1, -4.5), angle: 90deg, text(size: 1.3em)[BER])
})
plot.add(
pts_uncoded,
label: [Signal non codé],
style: (stroke: (paint: orange, thickness: 2pt, dash: "dashed")),
mark: "+",
mark-style: (stroke: orange, size: 0.5),
)
plot.add(
pts_bf,
label: [Bit-Flipping LDPC],
style: (stroke: (paint: blue, thickness: 2.5pt)),
mark: "square",
mark-style: (stroke: blue, fill: white, size: 0.25),
)
},
)
})
}
#let simulation_image_flow(img_orig, img_noisy, img_r05, img_r66, img_r75, img_w: 150pt, gap_top: 3.0, gap_bot: 4.0) = {
cetz.canvas({
import cetz.draw: *
let w_unit = img_w / 1cm
let y_top = 5.0
let y_bot = -6.0
let x_side = (w_unit + gap_top) / 2
let x_res = w_unit + gap_bot
// --- LIGNE 1 : ÉMISSION ET BRUIT (Texte collé en haut) ---
content(
(-x_side, y_top),
[
#set align(center)
#set par(leading: 0pt)
#set text(bottom-edge: "baseline") // Supprime l'espace sous les lettres
#text(weight: "bold", size: 1.3em)[Originale]
#v(-0.6cm)
#box(width: img_w, stroke: 2pt + black, radius: 4pt, inset: 0pt, img_orig)
],
name: "orig",
)
content(
(x_side, y_top),
[
#set align(center)
#set par(leading: 0pt)
#set text(bottom-edge: "baseline")
#text(weight: "bold", size: 1.3em, fill: red)[Reçue (Bruité)]
#v(-0.6cm)
#box(width: img_w, stroke: 2pt + red, radius: 4pt, inset: 0pt, img_noisy)
],
name: "noisy",
)
// --- FLÈCHE CANAL (Ajustée pour le nouveau centre de gravité) ---
let y_img_center = y_top - 1.4
line(
(-x_side + w_unit / 2, y_img_center),
(x_side - w_unit / 2, y_img_center),
stroke: 4pt + gray,
mark: (end: "stealth", fill: gray, size: 0.5),
)
content((0, y_img_center + 0.8), text(size: 1.1em, fill: gray.darken(40%), style: "italic")[AWGN (2.3 dB)])
// --- LIGNE 2 : COMPARAISON DES RENDEMENTS (Texte collé en bas) ---
let targets = (
(pos: (-x_res, y_bot), img: img_r05, rate: [$R = 1/2$], col: green.darken(20%), name: "r1"),
(pos: (0, y_bot), img: img_r66, rate: [$R = 2/3$], col: orange, name: "r2"),
(pos: (x_res, y_bot), img: img_r75, rate: [$R = 3/4$], col: red, name: "r3"),
)
for t in targets {
content(
t.pos,
[
#set align(center)
#set par(leading: 0pt)
#set text(top-edge: "baseline") // Supprime l'espace au-dessus des lettres
#box(width: img_w, stroke: 2.5pt + t.col, radius: 4pt, inset: 0pt, t.img)
#v(-0.6cm)
#text(weight: "bold", size: 1.5em, fill: t.col)[#t.rate]
],
name: t.name,
)
}
})
}
#let comparison_waterfall_plot(pts_unc, pts_bf, pts_sp, pts_ms) = {
cetz.canvas({
import cetz.draw: *
plot.plot(
size: (21, 15),
x-label: none,
y-label: none,
x-min: 0,
x-max: 11,
y-min: -8,
y-max: 0.2,
x-tick-step: 1,
y-tick-step: 1,
x-grid: true,
y-grid: true,
style: (
axes: (
bottom: (tick: (label: (offset: 0.2))),
left: (tick: (label: (offset: 0.2))),
),
),
y-format: y => $10^(#int(y))$,
x-format: x => [#x],
legend: (13.2, 11.4),
legend-style: (padding: 0.3, stroke: gray.lighten(50%), fill: white),
{
plot.annotate({
// Grille logarithmique étendue jusqu'à x=11
// for decade in range(-8, 0) {
// for minor in (2, 3, 4, 5, 6, 7, 8, 9) {
// let y_pos = decade + (calc.log(minor) / calc.log(10))
// if y_pos >= -8 and y_pos <= 0 {
// line((0, y_pos), (11, y_pos), stroke: (paint: gray.lighten(75%), thickness: 0.3pt))
// }
// }
// }
// Label X centré sur 11 unités (environ 5.5)
content((5.5, -8.7), text(size: 1.3em)[$E_b/N_0$ (dB)])
// Label Y
content((-1.2, -4.0), angle: 90deg, text(size: 1.3em)[BER])
})
plot.add(
pts_unc,
label: [Signal non codé],
style: (stroke: (paint: orange, thickness: 2pt, dash: "dashed")),
mark: "+",
mark-style: (stroke: orange, size: 1),
)
plot.add(
pts_bf,
label: [Bit-Flipping (Hard)],
style: (stroke: (paint: red, thickness: 2pt)),
mark: "x",
mark-style: (stroke: red, size: 1),
)
plot.add(
pts_ms,
label: [Min-Sum (Soft)],
style: (stroke: (paint: green.darken(20%), thickness: 2pt)),
mark: "triangle",
mark-style: (stroke: green.darken(20%), fill: white, size: 0.3),
)
plot.add(
pts_sp,
label: [Sum-Product (Soft)],
style: (stroke: (paint: blue, thickness: 2pt)),
mark: "square",
mark-style: (stroke: blue, fill: white, size: 1),
)
},
)
})
}