Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  decoders.gi   Sprache: unbekannt

 
#############################################################################
##
#A  decoders.gi             GUAVA library                       Reinald Baart
#A                                                        &Jasper Cramwinckel
#A                                                           &Erik Roijackers
##                                                              &David Joyner
##  This file contains functions for decoding codes
##
## Decodeword (unrestricted) modified 11-3-2004
## Decodeword (linear) created 10-2004
## Hamming, permutation, and BCH decoders moved into this file 10-2004
## GeneralizedReedSolomonDecoderGao added 11-2004
## GeneralizedReedSolomonDecoder added 11-2004
## bug fix in GRS decoder 11-29-2004
## added GeneralizedReedSolomonListDecoder and GRS<functions>, 12-2004
## added PermutationDecodeNC, CyclicDecoder 5-2005
## revisions to Decodeword, 11-2005 (fixed bug spotted by Cayanne McFarlane)
## 1-2006: added bit flip decoder
## 7-2007: Fixed several bugs in CyclicDecoder found by
##             Punarbasu Purkayastha <ppurka@umd.edu>
## 2009-3: Bugfix for Decodeword (J. Fields and wdj)
##


#############################################################################
##
#F  Decode( <C>, <v> )  . . . . . . . . .  decodes the vector(s) v from <C>
##
##  v can be a "codeword" or a list of "codeword"s
##

InstallMethod(Decode, "method for unrestricted code, codeword", true,
    [IsCode, IsCodeword], 0,
function(C, v)
    local c;
    if v in C then
        return Codeword(v, C);
    fi;
    c := Codeword(v, C);
    if HasSpecialDecoder(C) then
        return InformationWord(C, SpecialDecoder(C)(C, c) );
    elif IsCyclicCode(C) or IsLinearCode(C) then
        return Decode(C, c);
    else
        Error("no decoder present");
    fi;
end);

InstallOtherMethod(Decode,
    "method for unrestricted code, list of codewords",
    true, [IsCode, IsList], 0,
function(C, L)
    local i;
    return List(L, i->Decode(C, i));
end);

InstallMethod(Decode, "method for linear code, codeword", true,
    [IsLinearCode, IsCodeword], 0,
function(C, v)
    local ok, c, S, syn, index, corr, Gt, i, x, F;
    if v in C then
        return InformationWord(C,v);
    fi;
    c := Codeword(v, C);
    if HasSpecialDecoder(C) then
        return InformationWord(C, SpecialDecoder(C)(C, c) );
    fi;
    F := LeftActingDomain(C);
    S := SyndromeTable(C);
    syn := Syndrome(C, c);
    ok := false;
    for index in [1..Length(S)] do
        if IsBound(S[index]) and S[index][2] = syn then
           ok := true;
           break;
        fi;
    od;
    if not ok then  # this should never happen!
       Error("In Decodeword: index not found");
    fi;
#This is a hack.  The subtraction operation for codewords is causing an error
#and rather than trying to understand the method selection process, I'm brute-
#forcing things...

#    corr := VectorCodeword(c - S[index][1]);   # correct codeword
    corr := VectorCodeword(c) - VectorCodeword(S[index][1]);
    x := SolutionMat(GeneratorMat(C), corr);
    return Codeword(x,LeftActingDomain(C));     # correct "message"
end);



#############################################################################
##
#F  Decodeword( <C>, <v> )  . . . . . . .  decodes the vector(s) v from <C>
##
##  v can be a "codeword" or a list of "codeword"s
##

#nearest neighbor
InstallMethod(Decodeword, "method for unrestricted code, codeword", true,
    [IsCode, IsCodeword], 0,
function(C, v)
    local r, c, Cwords, NearbyWords, dist;
    if v in C then
        return v;
    fi;
    r := Codeword(v, C);
    if r in C then
        return r;
    fi;
    if HasSpecialDecoder(C) then
        return SpecialDecoder(C)(C, r);
    elif IsCyclicCode(C) or IsLinearCode(C) then
        return Decodeword(C, r);
    fi;
    dist:=Int((MinimumDistance(C)-1)/2);
    Cwords:=Elements(C);
    NearbyWords:=[];
    for c in Cwords do
        if WeightCodeword(r-c) <= dist then
            NearbyWords:=Concatenation(NearbyWords,[r]);
        fi;
    od;
    return NearbyWords;
end);


InstallOtherMethod(Decodeword,
    "method for unrestricted code, list of codewords",
    true, [IsCode, IsList], 0,
function(C, L)
    local i;
    return List(L, i->Decodeword(C, i));
end);

#syndrome decoding
InstallMethod(Decodeword, "method for linear code, codeword", true,
    [IsLinearCode, IsCodeword], 0,
function(C, v)
    local ok, c, c0, S, syn, index, corr, Gt, i, x, F;
    if v in C then
        return v;
    fi;
    c := Codeword(v, C);
    if HasSpecialDecoder(C) then
        c0:=SpecialDecoder(C)(C, c);
        if Size(c0) = Dimension(C) then
            return Codeword(c0*C);
        fi;
        if Size(c0) = Size(c) then
            return Codeword(c0);
        fi;
        return c0;
    fi;
    F := LeftActingDomain(C);
    S := SyndromeTable(C);
    syn := Syndrome(C, c);
    ok := false;
    for index in [1..Length(S)] do
        if IsBound(S[index]) and S[index][2] = syn then
           ok := true;
           break;
        fi;
    od;
    if not ok then  # this should never happen!
       Error("In Decodeword: index not found");
    fi;
    corr := VectorCodeword(c - S[index][1]);    # correct codeword
    return Codeword(corr,F);
end);


##################################################################
##
##  PermutationDecode( <C>, <v> ) -  decodes the vector v  to <C>
##
##   Uses Leon's AutomorphismGroup in the binary case,
##   PermutationAutomorphismGroup in the non-binary case,
##   performs permutation decoding when possible.
##   Returns original vector and prints "fail" when not possible.
##

InstallMethod(PermutationDecode, "attribute method for linear codes", true,
    [IsLinearCode,IsList], 0,
function(C,v)
 #C is a linear [n,k,d] code,
 #v is a vector with <=(d-1)/2 errors
local M,G,perm,F,P,t,p0,p,pc,i,k,pv,c,H,d,G0,H0;
 G:=GeneratorMat(C);
 H:=CheckMat(C);
 d:=MinimumDistance(C);
 k:=Dimension(C);
 G0 := List(G, ShallowCopy);
 perm:=PutStandardForm(G0);
 H0 := List(H, ShallowCopy);
 PutStandardForm(H0,false);
 F:=LeftActingDomain(C);
 if F=GF(2) then
   P:=AutomorphismGroup(C);
  else
   P:=PermutationAutomorphismGroup(C);
 fi;
 t:=Int((d-1)/2);
 p0:=0;
 if WeightCodeword(H0*v)=0 then return(v); fi;
 for p in P do
  pv:=Permuted(v,p);
  if WeightCodeword(Codeword(H0*pv))<=t then
    p0:=p;
    break;
  fi;
 od;
 if p0=0 then Print("fail \n"); return(v); fi;
 pc:=TransposedMat(G0)*List([1..k],i->pv[i]);
 c:=Permuted(pc,p0^(-1));
 return Codeword(Permuted(c,perm));
end);


##################################################################
##
##
##  PermutationDecodeNC( <C>, <v>, <P> ) -  decodes the
##                                vector v  to <C>
##
##   Performs permutation decoding when possible.
##   Returns original vector and prints "fail" when not possible.
##   NC version does Not Compute the aut gp so one must
##   input the permutation automorphism group
##   <P> subset SymmGp(n), n=wordlength(<C>)
##
####  wdj,2-7-2005

InstallMethod(PermutationDecodeNC, "attribute method for linear codes", true,
    [IsLinearCode,IsCodeword,IsGroup], 0,
function(C,v,P)
 #C is a linear [n,k,d] code,
 #v is a vector with <=(d-1)/2 errors
local M,G,G0, perm,F,t,p0,p,pc,i,k,pv,c,H,H0, d;
 G:=GeneratorMat(C);
 H:=CheckMat(C);
 d:=MinimumDistance(C);
 k:=Dimension(C);
 G0 := List(G, ShallowCopy);
 perm:=PutStandardForm(G0);
 H0 := List(H, ShallowCopy);
 PutStandardForm(H0,false);
 F:=LeftActingDomain(C);
 t:=Int((d-1)/2);
 p0:=0;
 if WeightCodeword(H0*v)=0 then return(v); fi;
 for p in P do
  pv:=Permuted(v,p);
  if WeightCodeword(Codeword(H0*pv))<=t then
    p0:=p;
#   Print(p0," = p0 \n",pv,"\n",H*pv,"\n");
    break;
  fi;
 od;
 if p0=0 then Print("fail \n"); return(v); fi;
 pc:=TransposedMat(G0)*List([1..k],i->pv[i]);
 c:=Permuted(pc,p0^(-1));
 return Codeword(Permuted(c,perm));
end);

#############################################################################
##
#F  CyclicDecoder( <C>, <w> )  . . . . . . . . . . . . decodes cyclic codes
##
InstallMethod(CyclicDecoder, "method for cyclic code, codeword", true,
    [IsCode, IsCodeword], 0,
function(C,w)
local d, g, wpol, s, ds, cpol, cc, c, i, m, e, x, n, ccc, r;
 if not(IsCyclicCode(C)) then
   Error("\n\n Code must be cyclic");
 fi;
 if Codeword(w) in C then return Codeword(w); fi; ## bug fix 7-6-2007
 n:=WordLength(C);
 d:=MinimumDistance(C);
 g:=GeneratorPol(C);
 x:=IndeterminateOfUnivariateRationalFunction(g);
 wpol:=PolyCodeword(w);
 for i in [0..(n-1)] do
   s:=x^i*wpol mod g;
   ds:=DegreeOfLaurentPolynomial(s);
   if ds<Int((d-1)/2) then
     m:=i;
     e:=x^(n-m)*s mod (x^n-1);
     cpol:=wpol-e;
     cc:=CoefficientsOfUnivariatePolynomial(cpol);
     r:=Length(cc);
     ccc:=Concatenation(cc,List([1..(n-r)],k-> Zero(LeftActingDomain(C)) ));
     c:=Codeword(ccc);
     #return InformationWord( C, c );
     return c;
   fi;
 od;
 return "fail";
end);

#############################################################################
##
#F  BCHDecoder( <C>, <r> )  . . . . . . . . . . . . . . . . decodes BCH codes
##
InstallMethod(BCHDecoder, "method for code, codeword", true,
    [IsCode, IsCodeword], 0,
function (C, r)
    local F, q, n, m, ExtF, x, a, t, ri_1, ri, rnew, si_1, si, snew,
          ti_1, ti, qi, sigma, i, cc, cl, mp, ErrorLocator, zero,
          Syndromes, null, pol, ExtSize, ErrorEvaluator, Fp;
    F := LeftActingDomain(C);
    q := Size(F);
    n := WordLength(C);
    m := OrderMod(q,n);
    t := QuoInt(DesignedDistance(C) - 1, 2);
    ExtF := GF(q^m);
    x := Indeterminate(ExtF);
    a := PrimitiveUnityRoot(q,n);
    zero := Zero(ExtF);
    r := PolyCodeword(Codeword(r, n, F));
    if Value(GeneratorPol(C), a) <> zero then
        return Decode(C, r);  ##LR - inf loop !!!
    fi;
    # Calculate syndrome: this simple line is faster than using minimal pols.
    Syndromes :=  List([1..2*QuoInt(DesignedDistance(C) - 1,2)],
                       i->Value(r, a^i));
    if Maximum(Syndromes) = Zero(F) then # no errors
        return Codeword(r mod (x^n-1), C);
    fi;
    # Use Euclidean algorithm:
    ri_1 := x^(2*t);
    ri := LaurentPolynomialByCoefficients(
            ElementsFamily(FamilyObj(ExtF)),
            Syndromes, 0);
    rnew := ShallowCopy(ri);
    si_1 := x^0; si := 0*x; snew := 0*x;
    ti_1 := 0*x; ti := x^0; sigma := x^0;
    while Degree(rnew) >= t do
        rnew := (ri_1 mod ri);
        qi := (ri_1 - rnew) / ri;
        snew := si_1 - qi*si;
        sigma := ti_1 - qi*ti;
        ri_1 := ri; ri := rnew;
        si_1 := si; si := snew;
        ti_1 := ti; ti := sigma;
    od;
    # Chien search for the zeros of error locator polynomial:
    ErrorLocator := [];
    null := a^0;
    ExtSize := q^m-1;
    for i in [0..ExtSize-1] do
        if Value(sigma, null) = zero then
            AddSet(ErrorLocator, (ExtSize-i) mod n);
        fi;
        null := null * a;
    od;
    # And decode:
    if Length(ErrorLocator) = 0 then
        Error("not decodable");
    fi;
    x := Indeterminate(F);
    if q = 2 then # error locator is not necessary
        pol := Sum(List([1..Length(ErrorLocator)], i->x^ErrorLocator[i]));
        return Codeword((r - pol) mod (x^n-1), C);
    else
        pol := Derivative(sigma);
        Fp := One(F)*(x^n-1);
        #Print(ErrorLocator, "\n");
        ErrorEvaluator := List(ErrorLocator,i->
                              Value(rnew,a^-i)/Value(pol, a^-i));
        pol := Sum(List([1..Length(ErrorLocator)], i->
                       -ErrorEvaluator[i]*x^ErrorLocator[i]));
        return  Codeword((r - pol) mod (x^n-1) , C);
    fi;
end);

#############################################################################
##
#F  HammingDecoder( <C>, <r> )  . . . . . . . . . . . . decodes Hamming codes
##
##  Generator matrix must have all unit columns
##
InstallMethod(HammingDecoder, "method for code, codeword", true,
    [IsCode, IsCodeword], 0,
function(C, r)
    local H, S,p, F, fac, e,z,x,ind, i,Sf;
    S := VectorCodeword(Syndrome(C,r));
    r := ShallowCopy(VectorCodeword(r));
    F := LeftActingDomain(C);
    p := PositionProperty(S, s->s<>Zero(F));
    if p <> fail then
        z := Z(Characteristic(S[p]))^0;
        if z = S[p] then
            fac := One(F);
        else
            fac := S[p]/z;
        fi;
        Sf := S/fac;
        H := CheckMat(C);
        ind := [1..WordLength(C)];
        for i in [1..Redundancy(C)] do
            ind := Filtered(ind, j-> H[i][j] = Sf[i]);
        od;
        e := ind[1];
        r[e] := r[e]-fac;     # correct error
    fi;
    #x := SolutionMat(GeneratorMat(C), r);
    #return Codeword(x);
    return Codeword(r, C);
end);

#############################################################################
##
#F  GeneralizedReedSolomonDecoderGao( <C>, <v> )   . . decodes
##                                           generalized Reed-Solomon codes
##                                           using S. Gao's method
##
InstallMethod(GeneralizedReedSolomonDecoderGao,"method for code, codeword", true,
    [IsCode, IsCodeword], 0,
function(C,vec)
 local vars,a,b,n,i,g0,g1,geea,u,q,v,r,g,f,F,R,x,k,GcdExtEuclideanUntilBound;
 if C!.name<>" generalized Reed-Solomon code" then
   Error("\N This method only applies to GRS codes.\n");
 fi;

GcdExtEuclideanUntilBound:=function(F,f,g,d,R)
## S Gao's version
## R is a poly ring
local vars,u,v,r,q,i,num,x;
 vars:=IndeterminatesOfPolynomialRing(R);
 x:=vars[1]; # define local x
 u:=List([1..3],i->Zero(F)); ## Need u[3] as a temporary variable
 v:=List([1..3],i->Zero(F));
 r:=List([1..3],i->Zero(F));
 q:=Zero(F);
 u[1]:=One(F); u[2]:=Zero(F); v[1]:=Zero(F); v[2]:=One(F);
 r[2]:=f; r[1]:=g;           ### applied with r2=f=g1, r1=g=g0
 while DegreeIndeterminate(r[2],x)> d-1 do    ### assume Degree(0) < 0.
  q   := EuclideanQuotient(R,r[1],r[2]);
  r[3]:=EuclideanRemainder(R,r[1],r[2]);
  u[3]:=u[1] - q*u[2];
  v[3]:=v[1] - q*v[2];
  r[1]:=r[2]; r[2] :=r[3];
  u[1]:=u[2]; u[2] :=u[3];
  v[1]:=v[2]; v[2] :=v[3];
 od;
 return([r[2],u[2],v[2]]);
end;

 a:=C!.points;
 R:=C!.ring;
 k:=C!.degree;
 F:=CoefficientsRing(R);
 b:=VectorCodeword(vec);
 vars:=IndeterminatesOfPolynomialRing(R);
 x:=vars[1]; # define local x
 n:=Length(a);
 if Size(Set(a)) < n then
   Error("`Points in 1st vector must be distinct.`\n\n");
 fi;
 g0:=One(F)*Product([1..n],i->x-a[i]);
 g1:=InterpolatedPolynomial(F,a,b);
 geea:=GcdExtEuclideanUntilBound(F,g1,g0,(n+k)/2,R);
 u:=geea[2]; v:=geea[3]; g:=geea[1];
 if v=Zero(F) then return("fail"); fi;
 if v=One(F) then
     q:=g;
     r:=Zero(F);
   else
     q:=EuclideanQuotient(R,g,v);
     r:=EuclideanRemainder(R,g,v);
 fi;
 if ((r=Zero(F) or LeadingCoefficient(r)=Zero(F)) and (Degree(q) < k)) then
     f:=q;
   else
     f:="fail";  ## this does not occur if num errors < (mindist - 1)/2
 fi;
 if f="fail" then return(f); else
    return Codeword(List(a,i->Value(f,i)),C);
 fi;
end);

##########################################################
#
# Input: Pts=[x1,..,xn], l = highest power,
#       L=[h_1,...,h_ell] is list of powers
#       r=[r1,...,rn] is received vector
# Output: Computes matrix described in Algor. 12.1.1 in [JH]
#
GRSLocatorMat:=function(r,Pts,L)
  local a,j,b,ell,DiagonalPower,add_col_mat,add_row_mat,block_matrix;

 add_col_mat:=function(M,N) ## "AddColumnsToMatrix"
  #N is a matrix with same rowdim as M
  #the fcn adjoins N to the end of M
  local i,j,S,col,NT;
  col:=MutableTransposedMat(M);  #preserves M
  NT:=MutableTransposedMat(N);   #preserves N
  for j in [1..DimensionsMat(N)[2]] do
      Add(col,NT[j]);
  od;
  return MutableTransposedMat(col);
 end;

 add_row_mat:=function(M,N) ## "AddRowsToMatrix"
  #N is a matrix with same coldim as M
  #the fcn adjoins N to the bottom of M
  local i,j,S,row;
  row:=ShallowCopy(M);#to preserve M;
  for j in [1..DimensionsMat(N)[1]] do
    Add(row,N[j]);
  od;
  return row;
 end;

 block_matrix:=function(L) ## slightly simpler syntax IMHO than "BlockMatrix"
  # L is an array of matrices of the form
  # [[M1,...,Ma],[N1,...,Na],...,[P1,...,Pa]]
  # returns the associated block matrix
  local A,B,i,j,m,n;
  n:=Length(L[1]);
  m:=Length(L);
  A:=[];
  if n=1 then
     if m=1 then return L[1][1]; fi;
     A:=L[1][1];
     for i in [2..m] do
         A:=add_row_mat(A,L[i][1]);
     od;
     return A;
  fi;
  for j in [1..m] do
    A[j]:=L[j][1];
  od;
  for j in [1..m] do
   for i in [2..n] do
    A[j]:=add_col_mat(A[j],L[j][i]);
   od;
  od;
  B:=A[1];
  for j in [2..m] do
   B:= add_row_mat(B,A[j]);
  od;
  return B;
 end;

 DiagonalPower:=function(r,j)
  local R,n,i;
  n:=Length(r);
  R:=DiagonalMat(List([1..n],i->r[i]^j));
  return R;
 end;

  ell:=Length(L);
  a:=List([1..ell],j->DiagonalPower(r,(j-1))*VandermondeMat(Pts,L[j]));
  b:=List([1..ell],j->[1,j,a[j]]);
  return (block_matrix([a]));
end;

##############################################################
#
#
# Input: Pts=[x1,..,xn],
#       L=[h_1,...,h_ell] is list of powers
#       r=[r1,...,rn] is received vector
#
# Compute kernel of matrix in alg 12.1.1 in [JH].
# Choose a basis vector in kernel.
# Output: the lists of coefficients of the polynomial Q(x,y) in alg 12.1.1.
#
GRSErrorLocatorCoeffs:=function(r,Pts,L)
  local a,j,b,vec,e,QC,i,lengths,ker,ell;
  ell:=Length(L);
  e:=GRSLocatorMat(r,Pts,L);
  ker:=TriangulizedNullspaceMat(TransposedMat(e));
  if ker=[] then Print("Decoding fails.\n"); return []; fi;
  vec:=ker[Length(ker)];
  QC:=[];
  lengths:=List([1..ell],i->Sum(List([1..i],j->1+L[j])));
  QC[1]:=List([1..lengths[1]],j->vec[j]);
  for i in [2..ell] do
  QC[i]:=List([(lengths[i-1]+1)..lengths[i]],j->vec[j]);
  od;
  return QC;
end;


#######################################################
#
# Input: List L of coefficients ell, R = F[x]
#        Pts=[x1,..,xn],
# Output: list of polynomials Qi as in Algor. 12.1.1 in [JH]
#
GRSErrorLocatorPolynomials:=function(r,Pts,L,R)
  local q,p,i,ell;
  ell:=Length(L)+1; ##  ?? Length(L) instead ??
  q:=GRSErrorLocatorCoeffs(r,Pts,L);
  if q=[] then Print("Decoding fails.\n"); return []; fi;
  p:=[];
  for i in [1..Length(q)] do
     p:=Concatenation(p,[CoefficientToPolynomial(q[i],R)]);
  od;
  return p;
end;

##########################################################
#
# Input: List L of coefficients ell, R = F[x]
#       Pts=[x1,..,xn],
# Output: interpolating polynomial Q as in Algor. 12.1.1 in [JH]
#
GRSInterpolatingPolynomial:=function(r,Pts,L,R)
  local poly,i,Ry,F,y,Q,ell;
  ell:=Length(L)+1; ##  ?? Length(L) instead ??  ##### not used ???
Q:=GRSErrorLocatorPolynomials(r,Pts,L,R);
  if Q=[] then Print("Decoding fails.\n"); return 0; fi;
  F:=CoefficientsRing(R);
  y:=IndeterminatesOfPolynomialRing(R)[2];
# Ry:=PolynomialRing(F,[y]);
# poly:=CoefficientToPolynomial(Q,Ry);
  poly:=Sum(List([1..Length(Q)],i->Q[i]*y^(i-1)));
  return poly;
end;

#############################################################################
##
#F  GeneralizedReedSolomonDecoder( <C>, <v> )   . . decodes
##                                           generalized Reed-Solomon codes
##                                           using the interpolation algorithm
##
InstallMethod(GeneralizedReedSolomonDecoder,"method for code, codeword", true,
    [IsCode, IsCodeword], 0,
function(C,vec)
local v,R,k,P,z,F,f,s,t,L,n,Qpolys,vars,x,c,y;

 v:=VectorCodeword(vec);
 R:=C!.ring;
 P:=C!.points;
 k:=C!.degree;
 F:=CoefficientsRing(R);
 vars:=IndeterminatesOfPolynomialRing(R);
 x:=vars[1];
#y:=vars[2];
 n:=Length(v);
 t:=Int((n-k)/2);
 L:=[n-1-t,n-t-k];
 Qpolys:=GRSErrorLocatorPolynomials(v,P,L,R);
 f:=-Qpolys[2]/Qpolys[1];
 c:=List(P,s->Value(f,[x],[s]));
 return Codeword(c,n,F);
end);


#############################################################################
##
#F  GeneralizedReedSolomonListDecoder( <C>, <v> , <ell> )   . . ell-list decodes
##                                           generalized Reed-Solomon codes
##                                           using M. Sudan's algorithm
##
##
## Input: v is a received vector (a GUAVA codeword)
##        C is a GRS code
##        ell>0 is the length of the decoded list (should be at least
##                  2 to beat GeneralizedReedSolomonDecoder
##                  or Decoder with the special method of interpolation decoding)
##
InstallMethod(GeneralizedReedSolomonListDecoder,"method for code, codeword, integer",
    true, [IsCode, IsCodeword, IsInt], 0,
function(C,v,ell)
local f,h,g,x,R,R2,L,F,t,i,c,Pts,k,n,tau,Q,divisorsf,div,
      CodewordList,p,vars,y,degy, divisorsdeg1;
 R:=C!.ring;
 F:=CoefficientsRing(R);
 vars:=IndeterminatesOfPolynomialRing(R);
 x:=vars[1];
 Pts:=C!.points;
 n:=Length(Pts);
 k:=C!.degree;
 tau:=Int((n-k)/2);
 L:=List([0..ell],i->n-tau-1-i*(k-1));
 y:=X(F,vars);;
 R2:=PolynomialRing(F,[x,y]);
 vars:=IndeterminatesOfPolynomialRing(R2);
 Q:=GRSInterpolatingPolynomial(v,Pts,L,R2);
 divisorsf:=DivisorsMultivariatePolynomial(Q,R2);
 divisorsdeg1:=[];
 CodewordList:=[];
 for div in divisorsf do
  degy:=DegreeIndeterminate(div,y);
  if degy=1 then ######### div=h*y+g
    g:=Value(div,vars,[x,Zero(F)]);
    h:=Derivative(div,y);
   if DegreeIndeterminate(h,x)=0 then
      f:= -h^(-1)*g*y^0;
      divisorsdeg1:=Concatenation(divisorsdeg1,[f]);
    if g=Zero(F)*x then
       c:=List(Pts,p->Zero(F));
     else
       c:=List(Pts,p->Value(f,[x,y],[p,Zero(F)]));
    fi;
    CodewordList:=Concatenation(CodewordList,[Codeword(c,C)]);
   fi;
  fi;
 od;
 return CodewordList;
end);

#############################################################################
##
#F  NearestNeighborGRSDecodewords( <C>, <v> , <dist> )   . . . finds all
##                                           generalized Reed-Solomon codewords
##                                           within distance <dist> from v
##                                           *and* the associated polynomial,
##                                           using "brute force"
##
## Input: v is a received vector (a GUAVA codeword)
##        C is a GRS code
##        dist>0 is the distance from v to search
## Output: a list of pairs [c,f(x)], where wt(c-v)<dist
##         and c = (f(x1),...,f(xn))
##
## ****** very slow*****
##
InstallMethod(NearestNeighborGRSDecodewords,"method for code, codeword, integer",
    true, [IsCode, IsCodeword, IsInt], 0,
function(C,r,dist)
# "brute force" decoder
local k,F,Pts,v,p,x,f,NearbyWords,c,a;
 k:=C!.degree;
 Pts:=C!.points;
 F:=LeftActingDomain(C);
 NearbyWords:=[];
 for v in F^k do
   a := Codeword(v);
   f:=PolyCodeword(a);
   x:=IndeterminateOfLaurentPolynomial(f);
   c:=Codeword(List(Pts,p->Value(f,[x],[p])));
   if WeightCodeword(r-c) <= dist then
   NearbyWords:=Concatenation(NearbyWords,[[c,f]]);
 fi;
od;
return NearbyWords;
end);

#############################################################################
##
#F  NearestNeighborDecodewords( <C>, <v> , <dist> )   . . . finds all
##                                           codewords in a linear code C
##                                           within distance <dist> from v
##                                           using "brute force"
##
## Input: v is a received vector (a GUAVA codeword)
##        C is a linear code
##        dist>0 is the distance from v to search
## Output: a list of c in C, where wt(c-v)<dist
##
## ****** very slow*****
##
InstallMethod(NearestNeighborDecodewords,"method for code, codeword, integer",
    true, [IsCode, IsCodeword, IsInt], 0,
function(C,r,dist)
# "brute force" decoder
local k,F,Pts,v,p,x,f,NearbyWords,c,a;
 F:=LeftActingDomain(C);
 NearbyWords:=[];
 for v in C do
   c := Codeword(v);
   if WeightCodeword(r-c) <= dist then
   NearbyWords:=Concatenation(NearbyWords,[c]);
 fi;
od;
return NearbyWords;
end);


#############################################################################
##
#F  BitFlipDecoder( <C>, <v>  )   . . . decodes *binary* LDPC codes using bit-flipping
##                                                           or Gallager hard-decision
##               ** often fails to work if C is not LDPC **
##
## Input: v is a received vector (a GUAVA codeword)
##        C is a binary LDPC code
## Output: a c in C, where wt(c-v)<mindis(C)
##
## ****** fast *****
##
checksetJ:=function(H,w)
 local i,I,n,k;
 I:=[];
 n:=Length(H[1]);
 for i in [1..n] do
    if H[w][i]<>0*Z(2) then
        I:=Concatenation(I,[i]);
    fi;
 od;
 return I;
end;

checksetI:=function(H,u)
 return checksetJ(TransposedMat(H),u);
end;

BFcounter:=function(I,s)
 local S,i;
 S:=Codeword(List(I, i -> List(s)[i]));
 return WeightCodeword(S);
end;

bit_flip:=function(H,v)
 local i,j,s,q,n,k,rho,gamma,I_j,tH;
 tH:=TransposedMat(H);
 q:=ShallowCopy(v);
 s:=H*q;
 n:=Length(H[1]);
 k:=n-Length(H);
 rho:=Length(Support(Codeword(H[1])));
 #gamma:= Length(Support(Codeword(TransposedMat(H)[1])));
 for j in [1..n] do
   gamma:= Length(Support(Codeword(tH[j])));
   I_j:=checksetI(H,j);
       if BFcounter(I_j,s)>gamma/2 then
           q[j]:=q[j]+Z(2);
           break;
       fi;
 od;
 return Codeword(q);
end;

InstallMethod(BitFlipDecoder,"method for code, codeword, integer",
    true, [IsCode, IsCodeword], 0,
function(C,v)
 local H,r,qnew,q;
 H:=CheckMat(C);
 r:=ShallowCopy(v);
 if Length(Support(Codeword(H*v)))=0 then
        return v;
 fi;
 q:=bit_flip(H,r);
 if Length(Support(Codeword(H*q)))=0 then
        return Codeword(q);
 fi;
 while Length(Support(Codeword(H*q)))<Length(Support(Codeword(H*r))) do
 #while q<>r do
   qnew:=q;
   r:=q;
   q:=bit_flip(H,qnew);
   Print("  ",Length(Support(Codeword(H*q))),"  ",Length(Support(Codeword(H*r))),"\n");
 od;
 return Codeword(r);
end);


[ Dauer der Verarbeitung: 0.4 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge