On considère le corps fini muni d’une racine primitive de l’unité.
>>> Fq := GF(16,'a')
On pose pour l’instant les paramètres
>>> n:= 15; t := 3
Construire un polynôme générateur \(g(x)\) d’un code MDS \(t\)-correcteur.
>>> g = prod(x-a^i for i in range(1,2*t+1))
Écrire une fonction syndrome(y)
qui calcule le syndrome du mot reçu
\(y(x)\).
def syndrome(y):
return sum( y(x=a^l)*x^(l-1) for l in range(1,2*t+1) )
Écrire une fonction pade(B,n,k)
qui, pour un polynôme \(B\) de degré
inférieur à \(n\) retourne un couple R,V
tel que
\(VB\equiv R\bmod x^{n+1}\) avec \(\deg(V)\leq n-k\), \(\deg(R)\leq k\).
def pade(B,n,k):
assert(B.degree()<=n)
x, = B.variables()
A = x^(n+1)
""" extended euclidean algorithm """
u1, u = 1, 0
v1, v = 0, 1
r1, r = A, B
while r.degree() > k:
q, rr = r1.quo_rem(r)
l = rr.leading_coefficient()
r1, r = r, rr/l
u1, u = u, (u1 - q*u)/l
v1, v = v, (v1 - q*v)/l
return r, v
Écrire une fonction corrige(y)
qui corrige le mot reçu \(y\in E\).
def corrige(y):
S = syndrome(y)
if S == 0: return y
R,E = pade(S,2*t-1,t)
T = [ i for i in range(1,n) if E(x=a^(-i))==0 ]
Ep = E.derivative()
e = sum( - R(x=a^(-i))/Ep(x=a^(-i)) * x^i for i in T )
return y+e
Écrire une classe RS(q,d)
qui construise un code de
Reed-Solomon de distance \(d\) sur \(\F_q\), et implante les méthodes
code(m)
et decode(y)
.
class RS:
def __init__(self,q,t):
Fq.<a> = GF(q)
self.a = Fq.multiplicative_generator()
Fx.<x> = Fq['x']
self.x = x
d = 2*t+1
self.g = prod( x-a^i for i in range(1,d) )
self.n = q-1
self.t = t
self.k = q-d
def code(self,m):
assert( len(m) <= self.k)
x = self.x
M = sum( m[i]*x^i for i in range(len(m)) )
return M*self.g
def syndrome(self,y):
a, x, t = self.a, self.x, self.t
return sum( y(x=a^l)*x^(l-1) for l in range(1,2*t+1) )
def corrige(self,y):
S = self.syndrome(y)
if S == 0: return y
t = self.t
R,E = pade(S,2*t-1,t)
a, x, t = self.a, self.x, self.t
return sum( y(x=a^l)*x^(l-1) for l in range(1,2*t+1) )
T = [ i for i in range(1,n) if E(x=a^(-i))==0 ]
Ep = E.derivative()
e = sum( - R(x=a^(-i))/Ep(x=a^(-i)) * x^i for i in T )
return y-e
primitif(n,p)
qui renvoie un polynôme de degré \(n\)
primitif sur \(\F_p\).Écrire une fonction SR(P,u,n)
qui retourne la liste des \(n\) premiers
termes de la suite récurrente \((u)\) dont on fournit un annulateur \(P\) et la
liste des \(d\) premiers termes, où \(d=\deg(P)\).
def SR(P,u,n):
d = P.degree()
assert(d == len(u))
for i in range(d,n):
u.append( - sum( P[i]*u[n-d+i] for i in range(d) ) )
return u
Écrire une fonction SRp(l,n,q=2)
qui renvoie les \(n\) premiers termes
d’une suite récurrente périodique de période exactement \(l\) sur \(\F_q\).
>>> P = cyclotomic_polynomial(35)
>>> SR(P,[ (-1)^i for i in range(24) ], 50)
Utiliser la fonction pade
pour calculer un annulateur des suites
ci-dessus.