Travaux Pratiques
du cours de
Théorie de l'Information
ALGORITHMES
ENUMERATEURS DE POIDS
- Poids d'un vecteur binaire.
Nous considérerons des espaces de Hamming binaires de dimension
<=64, ainsi nous utiliserons la définition typedef unsigned long long mot;
pour représenter les mots de l'espace de Hamming . Ecrire une
fonction uint poids( mot x ) qui
retourne le poids binaire du mot x.
- Construction de codes.
Un code est complétement défini par une matrice
génératrice, nous utiliserons le type :
typedef struct c {
uint dim;
uint nbc;
mot * code;
} code;
- Ecrire une fonction void
printcode( code c) qui imprime la matrice
génératrice du code c.
- Ecrire une fonction code
parite( uint n ) qui construit la matrice
génératrice du code des mots de poids pairs en longeur n.
Remarque c'est un code de dimension n-1 engendré par les mots x
poids 2 satisfaisant à l'équation x1 = 1.
- Ecrire une fonction code
randcode( uint k, uint n) qui construit un [n,k]-code aléatoire.
- Enumeration naive.
On rappelle que si G
désigne une matrice kxn d'un [n,k]-code C alors les mots de C
sont obtenus par les produits matriciels m.G en faisant varier m
dans l'espace binaire de Hamming de dimension k.
- Ecrire
une fonction mot encode(mot m, code G) pour calculer m.G
- L'énumérateur
de poids d'un [n,k]-code C est un tableau A de dimension n+1 tel que
A[i] soit égal au nombre de mots de poids i dans le code C.
Ecrire une fonction uint * enum(
code c ) qui calcule l'énumérateur de poids du
code c. Le coeur de cette fonction sera composé de la boucle :
for( m = 0; m < (1 << c.dim) - 1; m++ ) A[ poids( encode(m, c)
) ]++;
- Ecrire
une fonction void printp( uint *A) pour
imprimer le polyôme énumérateur des poids A.
- Vérifier le bon fonctionnement de votre code en
calculant l'énumérateur des poids des codes de
parité.
- Enumeration récursive.
Il s'agit de compléter d'écrire une fonction recursion(mot x, code c, uint nl, uint* a) compatible
avec la fonction ci-dessous. Si nl == c.dim alors met à jour a[
poids(x) ] sinon on énumère les combinaisons sans la
ligne nl par par recursion(x,
code c, nl + 1, a) puis on énumère avec les
autres avec recursion(x +
c.code[nl], c, nl + 1, * a)
uint* enumrec( code c )
{
uint * a;
a = (uint*) calloc( c.nbc,
sizeof(uint) );
recursion(0, code c,
0, a );
return a;
}
- Code de Gray.
Un code Gray pour l'espace de Hamming de dimension k est une
énumération des 2^k vecteurs v1, v2,
etc... telle que la distance de Hamming entre deux vecteurs
consécutifs soit égale à 1. Si on note numj
le numéro de la composante à changer pour passer de vj
à vj+1, on dispose d'un algorithme efficace pour
énumérer un [n,k]-code :
x = 0; j = 1;
tant que ( j < 2^k )
traitement( x );
x =
x + code[ numj ];
ftq
- Vous trouverez bien quelque part sur le web une preuve du
fait que si numj = le plus petit entier r tel que 0 = j0=
j1= ... = jr-1 < jr= 1, où j
= ( ... jr jr-1 ... j1j0)
désigne la décompostion de j en base 2 alors le numj
correspond bien à un code de Gray.
- Ecrire une fonction uint*
enumGray( code c )
- comparez les performances des trois méthodes
d'énumérations.
Philippe Langevin,
janvier 2006.