This commit is contained in:
2026-05-08 13:00:00 +02:00
parent 9a8000c851
commit 504527269a
3 changed files with 6281 additions and 4817 deletions

View File

@ -1517,3 +1517,227 @@
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")
})
}