Codes linéaires

Code Reed-Muller

Soient \(C_1\) et \(C_2\) deux codes, de matrices génératrices \(G_1,G_2\) et de vérificatrices \(V_1,V_2\).

Alors \([G_1,G_1;0,G_2]\) est génératrice de \(C_1\star C_2\), et \([V_1,0;-V_2,V_2]\) est vérificatrice.

On construit les vérificatrices du code de répétition \([n,1,n]\) et du code plein \([n,n,1]\)

v_plein(n) = matrix(0,n);
v_repet(n) = matconcat([matid(n-1),vectorv(n-1,i,1)]);

et la vérificatrice du code somme

v_rm(v1,v2) = matconcat(if(matsize(v1)[1],[v1,0;-v2,v2],[-v2,v2]));

Par exemple

v432 = v_rm(v_plein(2),v_repet(2))

Ce code est bien de distance 2.

On calcule une matrice vérificatrice du Reed-Muller \([16,5,8]\)

v844 = v_rm(v432, v_repet(4));
V = v_rm(v844, v_repet(8)) % 2

de même, une génératrice est

g_rm(g1,g2) = matconcat([g1,g1;0,g2]);
g_432 = g_rm(matid(2),vector(2,i,1));
g_844 = g_rm(g_432,vector(4,i,1));
G = g_rm(g_844,vector(8,i,1))

On vérifie la compatibilité.

V * G~ % 2

Décodage par syndrome

On calcule une table de syndromes en fonction d’une matrice vérificatrice. La fonction forsubset([n,r],  ) permet de parcourir les indices non nuls des éléments d’une boule de rayon r.

syndromes(V,t) = {
  my(s,x,n);
  n = matsize(V)[2];
  tab = Map();
  for(r=0,t,
    forsubset([n,r],s,
      x=vector(n);for(i=1,r,x[s[i]]=1);
      mapput(tab,V*x~,x);
      ));
  tab;
}

Le décodage par syndrome qui s’ensuit

decode_lin(V,s,y) = {
  if(mapisdefined(s,V*y~,&e),y-e,error("cannot decode"));
}

On décode avec le code de Reed-Muller \([16,5,8]\) ci-dessus. On part d’un mot de code c, on ajoute une erreur de transmission e, on reçoit le mot y = c+e.

c = [1,0,0,1,0] * G % 2;
e = [0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0];
y = (c + e) % 2

On calcule le syndrome

V = V * Mod(1,2);
tab = syndromes(V,3);

Il est non nul, et sa valeur permet de corriger l’erreur

decode_lin(V, tab, y) % 2
c