//makes the fn+1 matrices from Lem 5, converts to matrices N of Cor 5
// makes the inverses, the automorphisms of S_n(q) then 
//makes t=fn+1 errors in a codeword and corrects the received word
 
//value for q and d
n:=d;
f<u>:= GaloisField(q);
w:=PrimitiveElement(f);
vv := VectorSpace(f, d);
gln:=GL(n,f);
E:=ext<f|d>;
z:=PrimitiveElement(E);

zd:=z^d;
L:=(q^d-1)/(q-1); "Length=",L;
v:=L;
fn:=Floor(L/d)-1;
"fn=",fn;
Z:=Integers();L:=Z!L;

SS:=SymmetricGroup(L);
Fq:=f;Fqs:={x:x in Fq|x ne 0};
HC:=HammingCode(GF(q),n);C:=Dual(HC);//MW(C);
G:=GeneratorMatrix(C); gpts:=[Transpose(G)[i]:i in [1..L]];
vn:=VectorSpace(Fq,L);
g:=SS;
 npts:=Seqset(gpts) diff Seqset(Basis(vv));
 fpts:=Basis(vv) cat Setseq(npts);
ns:=&cat[Eltseq(fpts[i]):i in [1..#fpts]];
G:=Transpose(Matrix(L,n,ns));
//standard form
C:=LinearCode(G);gpts:=fpts;
WD(C);

B0:={Eltseq(z^i,f):i in [0..d-1]};
B:={z^i:i in [0..d-1]};

Bas:=[B0];
for r:=1 to fn do
Br:={x*zd^r:x in B};
Bas:=Append(Bas,{Eltseq(x,f):x in Br});
end for;
//Bas;
EBas:=[{vv!x:x in Bas[i]}:i in [1..#Bas]];
NEBas:=[{Normalize(x):x in EBas[i]}:i in [1..#EBas]];
//NEBas;
ba1:=&join[NEBas[i]:i in [1..#NEBas]];#ba1,d*(fn+1),L;
for i:=1 to #NEBas do
m:=Dim(sub<vv|NEBas[i]>);
if m ne d then
"trouble at", i;
end if;
end for;

an:=[gln!(&cat[Eltseq(x):x in NEBas[i]]):i in [1..#NEBas]];
//this is the set of matrices N from Lem 6 or Cor 5
//Now make the inverses and convert thme into action on C
ian:=[an[i]^-1:i in [1..#an]];

pts:=gpts;
pian:=[];
cpian:=[];icpian:=[];
for l:=1 to #ian do
ma:=ian[l];
aa:=[];
cian:=[];
ician:=[];
for i:=1 to #pts do
x:=pts[i]*ma;
for j:=1 to #pts do
if pts[j] in sub<vv|x> then
//pts[j],x;
for y in Fq do
if pts[j] eq y*x then
cian:=Append(cian,y);
ician:=Append(ician,y^-1);
end if;
end for;

aa:=Append(aa,j);
end if;
end for;end for;
aap:=SS!aa;
pian:=Append(pian,aap);
cpian:=Append(cpian,cian);
icpian:=Append(icpian,ician);
end for;

mons:=[MonomialMatrix(cpian[i],pian[i]):i in [1..#ian]];
for i:=1 to #mons do
for j:=1 to n do
if not (G[j]*mons[i] in C) then
j,i;
end if;
end for;end for;

diags:=[DiagonalMatrix(icpian[i]):i in [1..#ian]];
pigs:=[diags[i]*mons[i]:i in [1..#ian]];

//now test the decoding for t=fn errors
t:=fn;
vd:=VectorSpace(Fq,L-n);
A:=&cat[[-G[i][j]:j in [n+1..L]]:i in [1..n]]; 
MA:=Matrix(n,L-n,A);
AT:=Transpose(MA);
SH:=&cat[Eltseq(AT[i]) cat Eltseq(Basis(vd)[i]):i in [1..L-n]];
H:=Matrix(L-n,L,SH);
HT:=Transpose(H);

e:=Random(C);
e1:=e;e1, "the sent codeword";
//fix t =number of errors

sl:={1..L};
ts:=[];
for i:=1 to t do
//ts:=Append(ts,Random(sl));
ts:=Append(ts,Random(sl diff Seqset(ts)));
end for;
#Seqset(ts) eq t, "that there are t places for errors";
for i:=1 to t do
e[ts[i]]:=Random(Fq)*e[ts[i]]+Random(Fq);
end for;

//e[4]:=e[4]+1;e[2]:=e[2]-1;e[8]:=e[8]-1;e[7]:=(q-1)*e[7];
e,"after t errors, received vector";
for i:=1 to #mons do
w:=Weight(e*mons[i]*HT);
i,w;
if w le t then
j:=i;break;
end if;
end for;
y:=e*mons[j];
sy:=vv![y[i]:i in [1..n]];
my:=sy*G;
r:=my*mons[j]^-1;
r,"corrected word",e1,"sent word";
r eq e1,"that the received word is corrected";









