ldpc notes
This commit is contained in:
8462
Notes/notes.pdf
8462
Notes/notes.pdf
File diff suppressed because it is too large
Load Diff
256
Notes/notes.typ
256
Notes/notes.typ
@ -252,8 +252,264 @@ Pas de retransmissions.
|
|||||||
|
|
||||||
#pad(left: 1cm)[
|
#pad(left: 1cm)[
|
||||||
|
|
||||||
|
_Block codes_ définis par une matrice _parity-check_ *$H$* très *creuse* (beaucoup de 0).\
|
||||||
|
$=>$ Décodage en $cal(O)(n)$
|
||||||
|
|
||||||
|
== Défintions et Propriétés
|
||||||
|
|
||||||
|
*Création* : On construit d'abord la matrice creuse *$H$*, puis on en déduit la matrice génératrice *$G$* (contrairement aux codes classiques).\
|
||||||
|
|
||||||
|
*Décodage* : Décodage itératif basé sur une représentation graphique de *$H$* (Graphe de Tanner) (au lieu du décodage ML habituel).
|
||||||
|
|
||||||
|
*Régularité* : Un code LDPC est dit $(w_c, w_r)$-régulier si :
|
||||||
|
- Chaque bit de code appartient à $w_c$ équations de parité.
|
||||||
|
- Chaque équation de parité contient $w_r$ bits de code.
|
||||||
|
|
||||||
|
*Irréguliers*
|
||||||
|
Le nombre de $1$ varie selon les lignes et les colonnes de *$H$*.\
|
||||||
|
On définit la *distribution des degrés* $(v, h)$ :
|
||||||
|
- *$v_i$* : la fraction des colonnes (bits) ayant un poids de $i$.
|
||||||
|
- *$h_i$* : la fraction des lignes (équations de parité) ayant un poids de $i$.
|
||||||
|
|
||||||
|
#pad(left: 1cm)[
|
||||||
|
*Propriété : nombre total de $1$ dans $H$ :* \
|
||||||
|
Pour une matrice de $m$ lignes et $n$ colonnes :
|
||||||
|
- Code régulier : $m dot w_r = n dot w_c$
|
||||||
|
- Code irrégulier : $m sum_i (h_i dot i) = n sum_i (v_i dot i)$
|
||||||
|
]
|
||||||
|
|
||||||
|
== LDPC constructions
|
||||||
|
|
||||||
|
*Principe * : On part d'une matrice remplie de zéros et on y place un petit nombre de $1$ pour respecter la distribution de degrés.
|
||||||
|
|
||||||
|
=== Gallager
|
||||||
|
|
||||||
|
Il faut imaginer que la matrice *$H$* (de *$m$* lignes) est découpée horizontalement en *$w_c$* "bandes" de même taille (chacune a donc *$m / w_c$* lignes).
|
||||||
|
|
||||||
|
- *Création de la 1ère bande* : On place *$w_r$* $1$ consécutifs sur chaque ligne. À chaque fois qu'on descend d'une ligne, on décale ces $1$ vers la droite.
|
||||||
|
|
||||||
|
- *Création des autres bandes* : On prend simplement la 1ère bande et on mélange aléatoirement l'ordre de ses colonnes.
|
||||||
|
|
||||||
|
- *Résultat* : Comme on a superposé *$w_c$* bandes, et que dans chaque bande il y a exactement un $1$ par colonne, on est certain que chaque colonne de *$H$* aura exactement un poids de *$w_c$*.
|
||||||
|
|
||||||
|
- Exemple :
|
||||||
|
|
||||||
|
|
||||||
|
#pad(left: 1cm)[
|
||||||
|
Code régulier avec $n = 12$ colonnes, $w_c = 3$ et $w_r = 4$.\
|
||||||
|
|
||||||
|
*$H$* aura $m = (12 dot 3) / 4 = 9$ lignes.\
|
||||||
|
|
||||||
|
On divise ces 9 lignes en $w_c = 3$ blocs horizontaux de 3 lignes.
|
||||||
|
|
||||||
|
*Bloc 1* (Escalier) :
|
||||||
|
$
|
||||||
|
B_1 = mat(
|
||||||
|
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0;
|
||||||
|
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0;
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1;
|
||||||
|
)
|
||||||
|
$
|
||||||
|
|
||||||
|
*Bloc 2* (Permutation aléatoire des colonnes du Bloc 1) :
|
||||||
|
$
|
||||||
|
B_2 = mat(
|
||||||
|
1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0;
|
||||||
|
0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1;
|
||||||
|
0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0
|
||||||
|
)
|
||||||
|
$
|
||||||
|
|
||||||
|
*Bloc 3* (Permutation aléatoire des colonnes du Bloc 1) :
|
||||||
|
$
|
||||||
|
B_3 = mat(
|
||||||
|
1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0;
|
||||||
|
0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1;
|
||||||
|
0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0
|
||||||
|
)
|
||||||
|
$
|
||||||
|
|
||||||
|
Et donc
|
||||||
|
|
||||||
|
$
|
||||||
|
H = mat(B_1; B_2; B_3; row-gap: #0.75em)
|
||||||
|
$
|
||||||
|
|
||||||
|
Finalement dans n'importe quel bloc en regardant une colonne il n'y à qu'un $1$.
|
||||||
|
]
|
||||||
|
|
||||||
|
=== MacKay et Neal
|
||||||
|
|
||||||
|
- La matrice *$H$* est remplie une colonne à la fois, de gauche à droite.
|
||||||
|
- Les $1$ sont placés aléatoirement dans les lignes qui ne sont pas encore pleines.
|
||||||
|
- Si à un moment, il y a plus de lignes incomplètes que de colonnes restantes à ajouter, la distribution des lignes ne sera pas exacte. On peut alors revenir de quelques colonnes en arrière ou recommencer le processus jusqu'à obtenir le bon résultat.
|
||||||
|
|
||||||
|
- Exemple :
|
||||||
|
|
||||||
|
#pad(left: 1cm)[
|
||||||
|
Code régulier $(3,4)$ de longueur $12$.\
|
||||||
|
Quand on ajoute la $11$ème colonne, les lignes non remplies étaient les lignes $2, 4, 5, 6$ et $9$.\
|
||||||
|
L'algorithme a choisi d'y placer un $1$ sur les lignes $2, 4$ et $6$.
|
||||||
|
|
||||||
|
$
|
||||||
|
H = mat(
|
||||||
|
1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0;
|
||||||
|
1, 0, 0, 1, 1, 0, 0, 0, 0, 0, bold(1), 0;
|
||||||
|
0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1;
|
||||||
|
0, 0, 1, 0, 0, 0, 1, 1, 0, 0, bold(1), 1;
|
||||||
|
0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0;
|
||||||
|
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, bold(1), 1;
|
||||||
|
0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0;
|
||||||
|
0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0;
|
||||||
|
0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1
|
||||||
|
)
|
||||||
|
$
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
=== Codes Repeat-Accumulate (RA)
|
||||||
|
|
||||||
|
- Les *$m$* dernières colonnes de la matrice *$H$* ont toutes un poids de $2$ et forment un motif "en escalier".
|
||||||
|
- Encodage rapide.
|
||||||
|
|
||||||
|
- Exemple :
|
||||||
|
|
||||||
|
#pad(left: 1cm)[
|
||||||
|
Code RA de longueur $12$ avec un ratio de $1/4$.
|
||||||
|
|
||||||
|
$
|
||||||
|
H = mat(
|
||||||
|
1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0;
|
||||||
|
1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0;
|
||||||
|
0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0;
|
||||||
|
0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0;
|
||||||
|
0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0;
|
||||||
|
0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0;
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0;
|
||||||
|
0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0;
|
||||||
|
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1
|
||||||
|
)
|
||||||
|
$
|
||||||
|
|
||||||
|
Les trois premières colonnes de *$H$* correspondent aux bits du message initial.\
|
||||||
|
Les bits de parité (à partir de la 4ème colonne) se calculent ensuite en cascade :\
|
||||||
|
$c_4 = c_1$\
|
||||||
|
$c_5 = c_4 plus.o c_1$\
|
||||||
|
$c_6 = c_5 plus.o c_2$\
|
||||||
|
...\
|
||||||
|
Chaque bit de parité peut être calculé un par un en utilisant seulement les bits du message et le bit de parité juste avant lui.
|
||||||
|
]
|
||||||
|
|
||||||
|
== Graphe de Tanner
|
||||||
|
|
||||||
|
Deux ensembles de sommets :
|
||||||
|
- $G = (X union.sq Y, A)$ biparti.
|
||||||
|
- $X = {text("bits du codeword")}$ et $|X| = n$
|
||||||
|
- $Y = {text("équations de parité")}$ (_check-nodes_) et $|Y| = m$
|
||||||
|
- Soit $x in X, y in Y$, alors il existe $(x, y) in A$ si le bit est inclu dans l'équation de parité corerspondante.
|
||||||
|
- $|A| =$ nombre de $1$ dans la matrice de parité.
|
||||||
|
|
||||||
|
*Exemple :*
|
||||||
|
Pour la matrice _parity-check_ suivante (régulière $w_c=2$, $w_r=3$)
|
||||||
|
$
|
||||||
|
H = mat(
|
||||||
|
1, 1, 0, 1, 0, 0;
|
||||||
|
0, 1, 1, 0, 1, 0;
|
||||||
|
1, 0, 0, 0, 1, 1;
|
||||||
|
0, 0, 1, 1, 0, 1
|
||||||
|
)
|
||||||
|
$
|
||||||
|
|
||||||
|
Le graphe de Tanner correspondant
|
||||||
|
|
||||||
|
#align(center)[
|
||||||
|
#cetz.canvas(length: 1.2cm, {
|
||||||
|
import cetz.draw: *
|
||||||
|
|
||||||
|
content((0, 6.5), [*Noeuds de bits* \ (Variables $s_i$)], anchor: "south")
|
||||||
|
content(
|
||||||
|
(4, 6.5),
|
||||||
|
[*Noeuds de parité* \ (Contraintes $f_j$)],
|
||||||
|
anchor: "south",
|
||||||
|
)
|
||||||
|
|
||||||
|
for i in range(1, 7) {
|
||||||
|
circle((0, 6.5 - i), radius: 0.3, name: "b" + str(i), fill: white)
|
||||||
|
content("b" + str(i), [$s_#i$])
|
||||||
|
}
|
||||||
|
|
||||||
|
for j in range(1, 5) {
|
||||||
|
let y = 6.5 - j * 1.2
|
||||||
|
rect(
|
||||||
|
(4 - 0.3, y - 0.3),
|
||||||
|
(4 + 0.3, y + 0.3),
|
||||||
|
name: "f" + str(j),
|
||||||
|
fill: rgb("e0e0e0"),
|
||||||
|
)
|
||||||
|
content("f" + str(j), [$f_#j$])
|
||||||
|
}
|
||||||
|
|
||||||
|
line("b1", "f1", stroke: (paint: gray, thickness: 2pt))
|
||||||
|
line("b2", "f1", stroke: (paint: gray, thickness: 2pt))
|
||||||
|
line("b4", "f1")
|
||||||
|
|
||||||
|
line("b2", "f2", stroke: (paint: gray, thickness: 2pt))
|
||||||
|
line("b3", "f2")
|
||||||
|
line("b5", "f2", stroke: (paint: gray, thickness: 2pt))
|
||||||
|
|
||||||
|
line("b1", "f3", stroke: (paint: gray, thickness: 2pt))
|
||||||
|
line("b5", "f3", stroke: (paint: gray, thickness: 2pt))
|
||||||
|
line("b6", "f3")
|
||||||
|
|
||||||
|
line("b3", "f4")
|
||||||
|
line("b4", "f4")
|
||||||
|
line("b6", "f4")
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
- *_Girth_* : La taille du plus petit cycle présent dans tout le graphe. (biparti $=>$ cycle de taille pair donc plus petit cycle de taille $4$).
|
||||||
|
|
||||||
|
- *Exemple :*
|
||||||
|
Dans notre $H$ le plus petit cycle est de taille 6 en gris.
|
||||||
|
$c = s_1 -> f_1 -> s_2 -> f_2 -> s_5 -> f_3 -> s_1$.
|
||||||
|
|
||||||
|
On veut éviter les cycles courts, il existe un algorithme de Mackay Neal qui permet de d'éviter les $4$-cycles. algorithme @johnson p14. D'autre methode vont être vu (algébriques) pour des court codes.
|
||||||
|
|
||||||
|
|
||||||
|
== Encodage
|
||||||
|
|
||||||
|
Matrice _parity-check_
|
||||||
|
$ H = [A, I_(n-k)] $ avec $A in M_((n-k) times k)(ZZ\/2ZZ)$ on trouve alors $G$ par réducation de Gausse-Jordan sur $H$.
|
||||||
|
|
||||||
|
$
|
||||||
|
G = [I_k, A^T]
|
||||||
|
$
|
||||||
|
|
||||||
|
1. Mettre $H$ sous forme échelonée puis sous forme ligne-cheloné réduite puis sous forme standard (avec des permutation de colonnes) puis construire $G$ voir @johnson p15. Cette méthode ne rend pas la matrice creuse donc complexité nul.
|
||||||
|
2. Transformer $H$ en matrice triangulaire inférieur aproximative. Voir @johnson p17.
|
||||||
|
|
||||||
|
|
||||||
|
== Décodage
|
||||||
|
|
||||||
|
Voir les exemple du papier @johnson p21.
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#pagebreak()
|
||||||
|
|
||||||
|
= QC-LDPC
|
||||||
|
|
||||||
|
= Code Rust
|
||||||
|
#pad(left: 1cm)[
|
||||||
|
- Voir la strucutre du projet en amont
|
||||||
|
- Implémentation des codes ldpc (avec un peu toutes les méthodes possible pour faire des test etc)
|
||||||
|
- Implémentation avec $H$ aléatoire (donc G assez dense et $O(n^2)$)
|
||||||
|
- Implémenter le "repeat-accumulate" (RA)
|
||||||
|
- Et faire un export pour visualiser les matrice et le graphe dans un fichier typst par exemple ou autre
|
||||||
|
- Implementation en rust https://github.com/daniestevez/ldpc-toolbox (lire le code pour voir)
|
||||||
|
- Voir SIMD (`std::simd`) pour le calcul de LLR sur plusieur bits en même temps.
|
||||||
|
- Voir le multi-threadage possible (après l'implementation)
|
||||||
|
]
|
||||||
|
|
||||||
#pagebreak()
|
#pagebreak()
|
||||||
#bibliography("sources.yml", style: "ieee")
|
#bibliography("sources.yml", style: "ieee")
|
||||||
|
|||||||
Reference in New Issue
Block a user