Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/GAP/pkg/guava/lib/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 1.1.2025 mit Größe 74 kB image not shown  

SSL codeman.gi   Sprache: unbekannt

 
Spracherkennung für: .gi vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

############################################################################
##
#A  codeman.gi              GUAVA library                       Reinald Baart
#A                                                        &Jasper Cramwinckel
#A                                                           &Erik Roijackers
##
##  This file contains functions for manipulating codes
##
## ConstantWeightSubcode revised 10-23-2004
##
## added 12-207 (CJ): ConstructionXCode, ConstructionXXCode, BZCode functions
##

#############################################################################
##
#F  DualCode( <C> ) . . . . . . . . . . . . . . . . . . . .  dual code of <C>
##

InstallMethod(DualCode, "generic method for codes", true, [IsCode], 0,
function(C)
 local Cnew;
 if IsCyclicCode(C) or IsLinearCode(C) then
  return DualCode(C);
 else
  Cnew := CheckMatCode(BaseMat(VectorCodeword(AsSSortedList(C))),
       "dual code", LeftActingDomain(C));
  Cnew!.history := History(C);
  return(Cnew);
 fi;
end);

InstallMethod(DualCode, "method for linear codes", true, [IsLinearCode], 0,
function(C)
 local C1, Pr, n, newwd, wd, oldrow, newrow, i, j, q;
 if IsCyclicCode(C) then
  return DualCode(C);
 elif HasGeneratorMat(C) then
  C1 := CheckMatCode(GeneratorMat(C), "dual code", LeftActingDomain(C));
 elif HasCheckMat(C) then
  C1 := GeneratorMatCode(CheckMat(C), "dual code", LeftActingDomain(C));
 else
  Error("No GeneratorMat or CheckMat for C");
 fi;
 if HasWeightDistribution(C) then
  n := WordLength(C);
  wd := WeightDistribution(C);
  q := Size(LeftActingDomain(C)) - 1;
  newwd := [Sum(wd)];
  oldrow := List([1..n+1],i->1);
  newrow := [];
  for i in [2..n+1] do
            newrow[1] := Binomial(n, i-1) * q^(i-1);
            for j in [2..n+1] do
                newrow[j] := newrow[j-1] - q * oldrow[j] - oldrow[j-1];
            od;
            newwd[i] := newrow * wd;
            oldrow := ShallowCopy(newrow);
        od;
        SetWeightDistribution(C1, newwd / ((q+1) ^ Dimension(C)) );
        Pr := PositionProperty(WeightDistribution(C1){[2..n+1]}, i-> i <> 0);
        if Pr = false then
            Pr := n;
        fi;
        C1!.lowerBoundMinimumDistance := Pr;
        C1!.upperBoundMinimumDistance := Pr;
    fi;
    C1!.history := History(C);
    return C1;
end);

InstallMethod(DualCode, "method for self dual codes", true,[IsSelfDualCode], 0,
function(C)
 return ShallowCopy(C);
end);

InstallMethod(DualCode, "method for cyclic codes", true, [IsCyclicCode], 0,
function(C)
 local C1, r, n, Pr, wd, q, newwd, oldrow, newrow, i, j;
    if HasGeneratorPol(C) then
  r := ReciprocalPolynomial(GeneratorPol(C),Redundancy(C));
  r := r/LeadingCoefficient(r);
  C1 := CheckPolCode(r, WordLength(C), "dual code", LeftActingDomain(C));
 elif HasCheckPol(C) then
  r := ReciprocalPolynomial(CheckPol(C),Dimension(C));
  r := r/LeadingCoefficient(r);
  C1 := GeneratorPolCode(r, WordLength(C), "dual code",
        LeftActingDomain(C));
 else
  Error("No GeneratorPol or CheckPol for C");
 fi;
 if HasWeightDistribution(C) then
  n := WordLength(C);
  wd := WeightDistribution(C);
  q := Size(LeftActingDomain(C)) - 1;
  newwd := [Sum(wd)];
  oldrow := List([1..n+1], i->1);
  newrow := [];
  for i in [2..n+1] do
   newrow[1] := Binomial(n, i-1) * q^(i-1);
   for j in [2..n+1] do
    newrow[j] := newrow[j-1] - q * oldrow[j] - oldrow[j-1];
   od;
            newwd[i] := newrow * wd;
   oldrow := ShallowCopy(newrow);
  od;
  SetWeightDistribution(C1, newwd / ((q+1) ^ Dimension(C)));
     Pr := PositionProperty(WeightDistribution(C1){[2..n+1]}, i-> i <> 0);
     if Pr = false then
          Pr := n;
     fi;
     C1!.lowerBoundMinimumDistance := Pr;
     C1!.upperBoundMinimumDistance := Pr;
 fi;
 C1!.history := History(C);
 return C1;
end);


#############################################################################
##
#F  AugmentedCode( <C> [, <L>] )  . . .  add words to generator matrix of <C>
##

InstallMethod(AugmentedCode, "unrestricted code and codeword list/object",
 true, [IsCode, IsObject], 0,
function (C, L)
 if IsLinearCode(C) then
  return AugmentedCode(C, L);
 else
  Error("argument must be a linear code");
 fi;
end);

InstallOtherMethod(AugmentedCode, "unrestricted code", true, [IsCode], 0,
function(C)
 return AugmentedCode(C, NullMat(1, WordLength(C), LeftActingDomain(C))
        + One(LeftActingDomain(C)));
end);

InstallMethod(AugmentedCode, "linear code and codeword object/list",
 true, [IsCode, IsObject], 0,
function (C, L)
    local Cnew;
 L := VectorCodeword(Codeword(L, C) );
 if not IsList(L[1]) then
  L := [L];
 else
  L := Set(L);
 fi;
    Cnew := GeneratorMatCode(BaseMat(Concatenation(GeneratorMat(C),L)),
                 Concatenation("code, augmented with ", String(Length(L)),
                         " word(s)"), LeftActingDomain(C));
    if Length(GeneratorMat(Cnew)) > Dimension(C) then
        Cnew!.upperBoundMinimumDistance := Minimum(
                 UpperBoundMinimumDistance(C),
                 Minimum(List(L, l-> Weight(Codeword(l)))));
        Cnew!.history := History(C);
        return Cnew;
    else
        return ShallowCopy(C);
    fi;
end);


#############################################################################
##
#F  EvenWeightSubcode( <C> )  . . .  code of all even-weight codewords of <C>
##

InstallMethod(EvenWeightSubcode, "method for unrestricted codes", true,
 [IsCode], 0,
function(Cold)
 local C, n, Els, E, d, i, s, q, wd;

 if IsCyclicCode(Cold) or IsLinearCode(Cold) then
  return EvenWeightSubcode(Cold);
 fi;

    q := Size(LeftActingDomain(Cold));
    n := WordLength(Cold);
    Els := AsSSortedList(Cold);
    E := [];
 s := 0;
    for i in [1..Size(Cold)] do
        if IsEvenInt(Weight(Els[i])) then
            Append(E, [Els[i]]);
            s := s + 1;
        fi;
    od;
    if s <> Size(Cold) then
        C := ElementsCode( E, "even weight subcode", GF(q) );
        d := [LowerBoundMinimumDistance(Cold),
              UpperBoundMinimumDistance(Cold)];
        for i in [1..2] do
            if q=2 and IsOddInt(d[i] mod 2) then
                d[i] := Minimum(d[i]+1,n);
            fi;
        od;
        C!.lowerBoundMinimumDistance := d[1];
        C!.upperBoundMinimumDistance := d[2];
        if HasWeightDistribution(Cold) then
            wd := ShallowCopy(WeightDistribution(Cold));
            for i in [1..QuoInt(n+1,2)] do
                wd[2*i] := 0;
            od;
         SetWeightDistribution(C, wd);
  fi;
        C!.history := History(Cold);
        return C;
    else
        return ShallowCopy(Cold);
    fi;
end);

InstallMethod(EvenWeightSubcode, "method for linear codes", true,
 [IsLinearCode], 0,
function(Cold)
    local C, P, edited, n, G, Els, E, i, s,q, Gold, wd, lbmd;
    if IsCyclicCode(Cold) then
  return EvenWeightSubcode(Cold);
 fi;
 q := Size(LeftActingDomain(Cold));
    n := WordLength(Cold);
    edited := false;
    if q = 2 then
        # Why is the next line needed?
        P := NullVector(n, GF(2));
        G := [];
        Gold := GeneratorMat(Cold);
        for i in [1..Dimension(Cold)] do
            if Weight(Codeword(Gold[i])) mod 2 <> 0 then
                if not edited then
                    P := Gold[i];
                    edited := true;
                else
                    Append(G, [Gold[i]+P]);
                fi;
            else
                Append(G, [Gold[i]]);
            fi;
        od;
        if edited then
            C := GeneratorMatCode(BaseMat(G),"even weight subcode",GF(q));
        fi;
    else
        Els := AsSSortedList(Cold);
        E := []; s := 0;
        for i in [1..Size(Cold)] do
            if IsEvenInt(Weight(Els[i])) then
                Append(E, [Els[i]]);
                s := s + 1;
            fi;
        od;
        edited := (s <> Size(Cold));
        if edited then
            C := ElementsCode(E, "even weight subcode", GF(q) );
        fi;
    fi;

    if edited then
        lbmd := Minimum(n, LowerBoundMinimumDistance(Cold));
        if q = 2 and IsOddInt(lbmd) then
            lbmd := lbmd + 1;
        fi;
        C!.lowerBoundMinimumDistance := lbmd;
  if HasWeightDistribution(Cold) then
            wd := ShallowCopy(WeightDistribution(Cold));
            for i in [1..QuoInt(n+1,2)] do
                wd[2*i] := 0;
            od;
   SetWeightDistribution(C, wd);
  fi;
  C!.history := History(Cold);
        return C;
    else
        return ShallowCopy(Cold);
    fi;
end);

##LR See co'd roots stuff, nd reinstate sometime.
InstallMethod(EvenWeightSubcode, "method for cyclic codes", true,
 [IsCyclicCode], 0,
function(Cold)
    local C, P, edited, n, Els, E, i, q, lbmd, wd;
    q := Size(LeftActingDomain(Cold));
    n := WordLength(Cold);
    edited := false;
    if (q =2) then
        P := Indeterminate(GF(2))-One(GF(2));
        if Gcd(P, GeneratorPol(Cold)) <> P then
            C := GeneratorPolCode( GeneratorPol(Cold)*P, n,
                         "even weight subcode", LeftActingDomain(Cold));
            #if IsBound(C.roots) then
            #    AddSet(C.roots, Z(2)^0);
            #fi;
            edited := true;
        fi;
    else
        Els := AsSSortedList(Cold);
        E := [];
        for i in [1..Size(Cold)] do
            if IsEvenInt(Weight(Els[i])) then
                Append(E, [Els[i]]);
            else
                edited := true;
            fi;
        od;
        if edited then
            C := ElementsCode(E, "even weight subcode", LeftActingDomain(Cold));
        fi;
    fi;

    if edited then
        lbmd := Minimum(n, LowerBoundMinimumDistance(Cold));
        if q = 2 and IsOddInt(lbmd) then
            lbmd := lbmd + 1;
        fi;
        C!.lowerBoundMinimumDistance := lbmd;
  if HasWeightDistribution(Cold) then
            wd := ShallowCopy(WeightDistribution(Cold));
            for i in [1..QuoInt(n+1,2)] do
                wd[2*i] := 0;
            od;
         SetWeightDistribution(C, wd);
  fi;
        C!.history := History(Cold);
        return C;
    else
        return ShallowCopy(Cold);
    fi;
end);


#############################################################################
##
#F  ConstantWeightSubcode( <C> [, <w>] )  .  all words of <C> with weight <w>
##

InstallMethod(ConstantWeightSubcode, "method for unrestricted code, weight",
 true, [IsCode, IsInt], 0,
function(C, wt)
  local D, Els,path;
  if IsLinearCode(C) then
 return ConstantWeightSubcode(C, wt);
  fi;
  Els := Filtered(AsSSortedList(C), c -> Weight(c) = wt);
  if Els <> [] then
    D := ElementsCode(Els, Concatenation( "code with codewords of weight ", String(wt)), LeftActingDomain(C) );
    D!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C);
    D!.history := History(C);
    return D;
   else
    Error("no words of weight", wt);
  fi;
end);

InstallOtherMethod(ConstantWeightSubcode, "method for unrestricted code",
 true, [IsCode], 0,
function(C)
  local wt;
  if IsLinearCode(C) then
 return ConstantWeightSubcode(C, MinimumDistance(C));
  fi;
  wt := PositionProperty(WeightDistribution(C){[2..WordLength(C)+1]}, i-> i > 0);
  if wt = false then
 wt := WordLength(C);
  fi;
 return ConstantWeightSubcode(C, wt);
end);

InstallMethod(ConstantWeightSubcode, "method for linear code, weight", true,
 [IsLinearCode, IsInt], 0,
function(C, wt)
   local S, c, a, CWS, path, F, incode, infile, cwsc, Els, i, D;
   a:=wt;
   if wt = 0 then
      return NullCode(WordLength(C), LeftActingDomain(C));
   fi;
   if Dimension(C) = 0 then
      Error("no constant weight subcode of a null code is defined");
   fi;

   path := DirectoriesPackagePrograms( "guava" );

   if ForAny( ["desauto", "leonconv", "wtdist"],
                 f -> Filename( path, f ) = fail ) then
      Print("the C code programs are not compiled, so using GAP code...\n");
      F:=LeftActingDomain(C);
      S:=[];
      for c in Elements(C) do
         if WeightCodeword(c)=a then
            S:=Concatenation([c],S);
         fi;
      od;
      CWS:=ElementsCode(S,"constant weight subcode",F);
      CWS!.lowerBoundMinimumDistance:=a;
      CWS!.upperBoundMinimumDistance:=a;
      return CWS;
   else
      #Print("the C code programs are compiled, so using Leon's binary....\n");
      incode := TmpName();
      PrintTo( incode, "\n" );
      infile := TmpName();
      cwsc := TmpName();
      PrintTo( infile, "\n" );
      GuavaToLeon(C, incode);
      Process(DirectoryCurrent(),
         Filename(DirectoriesPackagePrograms("guava"), "wtdist"),
  InputTextNone(),
  OutputTextNone(),
  ["-q",  Concatenation(incode,"::code"), wt,
   Concatenation(cwsc,"::code")]
      );
      if IsReadableFile( cwsc ) then
         Process(DirectoryCurrent(),
              Filename(DirectoriesPackagePrograms("guava"), "leonconv"),
              InputTextNone(),
              OutputTextNone(),
              ["-c", cwsc, infile]
         );
      else
         Error("\n Sorry, no codes words of weight ",wt,"\n");
      fi;
      Read(infile);
      RemoveFiles(incode,cwsc,infile);
      Els := [];
      for i in AsSSortedList(LeftActingDomain(C)){[2..Size(LeftActingDomain(C))]} do
         Append(Els, i * GUAVA_TEMP_VAR);
      od;
      if Els <> [] then
         D := ElementsCode(Els, Concatenation( "code with codewords of weight ",
                 String(wt)), LeftActingDomain(C)
         );
         D!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C);
         D!.history := History(C);
         return D;
      else
         Error("no words of weight ",wt);
         Print("\n no words of weight ",wt);
      fi;
   fi; ## end if-then-else
end);

InstallOtherMethod(ConstantWeightSubcode, "method for linear code", true,
 [IsLinearCode], 0,
function(C)
 return ConstantWeightSubcode(C, MinimumDistance(C));
end);


#############################################################################
##
#F  ExtendedCode( <C> [, <i>] ) . . . . . code with added parity check symbol
##

InstallMethod(ExtendedCode, "method to extend unrestricted code i times", true,
 [IsCode, IsInt], 0,
function(Cold, nrcolumns)
 local n, q, zeros, elements, word, vec, lbmd, ubmd, i, indist, wd, C;
 if nrcolumns < 1 then
  return ShallowCopy(Cold);
 elif IsLinearCode(Cold) then
  return ExtendedCode(Cold,nrcolumns);
 fi;

    n := WordLength(Cold)+1;
    q := Size(LeftActingDomain(Cold));
    zeros:= List( [ 2 .. nrcolumns ], i-> Zero(LeftActingDomain(Cold)) );
    elements := [];
    for word in AsSSortedList(Cold) do
        vec := VectorCodeword(word);
        Add(elements, Codeword(Concatenation(vec, [-Sum(vec)], zeros)));

    od;
    C := ElementsCode( elements, "extended code", q );
    lbmd := LowerBoundMinimumDistance(Cold);
    ubmd := UpperBoundMinimumDistance(Cold);
    if q = 2 then
        if lbmd mod 2 = 1 then
            lbmd := lbmd + 1;
        fi;
        if ubmd mod 2 = 1 then
            ubmd := ubmd + 1;
        fi;
        C!.lowerBoundMinimumDistance := lbmd;
  C!.upperBoundMinimumDistance := ubmd;
  if HasInnerDistribution(Cold) then
            indist := NullVector(n+1);
            indist[1] := InnerDistribution(Cold)[1];
            for i in [1 .. QuoInt( WordLength(Cold), 2 ) ] do
                indist[i*2+1]:= InnerDistribution(Cold)[i*2+1]+
                                    InnerDistribution(Cold)[i*2];
            od;
            if IsOddInt(WordLength(Cold)) then
                indist[WordLength(Cold) + 2] :=
                  InnerDistribution(Cold)[WordLength(Cold) + 1];
            fi;
         SetInnerDistribution(C, indist);
  fi;
        if HasWeightDistribution(Cold) then
            wd := NullVector( n + 1);
            wd[1] := WeightDistribution(Cold)[1];
            for i in [1 .. QuoInt( WordLength(Cold), 2 ) ] do
                wd[i*2+1]:= WeightDistribution(Cold)[i*2+1]+
                                WeightDistribution(Cold)[i*2];
            od;
            if IsOddInt(WordLength(Cold)) then
                wd[WordLength(Cold) + 2] :=
                  WeightDistribution(Cold)[WordLength(Cold) + 1];
            fi;
         SetWeightDistribution(C, wd);
  fi;
        if IsBound(Cold!.boundsCoveringRadius)
           and Length( Cold!.boundsCoveringRadius ) = 1 then
            C!.boundsCoveringRadius :=
              [ Cold!.boundsCoveringRadius[ 1 ] + nrcolumns ];
        fi;
    else
        C!.upperBoundMinimumDistance := UpperBoundMinimumDistance(Cold) + 1;
    fi;
    C!.history := History(Cold);
    return C;
end);

InstallOtherMethod(ExtendedCode, "method for unrestricted code",
 true, [IsCode], 0,
function(C)
 return ExtendedCode(C, 1);
end);

InstallMethod(ExtendedCode, "method to extend linear code i times", true,
 [IsLinearCode, IsInt], 0,
function(Cold, nrcolumns)
    local C, G, word, zeros, i, n, q, lbmd, ubmd, wd;
 if nrcolumns < 1 then
  return ShallowCopy(C);
 fi;

    n := WordLength(Cold) + nrcolumns;
    zeros := List( [2 .. nrcolumns], i-> Zero(LeftActingDomain(Cold)) );
    q := Size(LeftActingDomain(Cold));
    G := List(GeneratorMat(Cold), i-> ShallowCopy(i));
    for word in G do
        Add(word, -Sum(word));
        Append(word, zeros);
    od;
    C := GeneratorMatCode(G, "extended code", q);
    lbmd := LowerBoundMinimumDistance(Cold);
    ubmd := UpperBoundMinimumDistance(Cold);
    if q = 2 then
        if IsOddInt( lbmd ) then
            lbmd := lbmd + 1;
        fi;
        if IsOddInt( ubmd ) then
            ubmd := ubmd + 1;
        fi;
        C!.lowerBoundMinimumDistance := lbmd;
  C!.upperBoundMinimumDistance := ubmd;
  if HasWeightDistribution(Cold) then
            wd := NullVector(n + 1);
            wd[1] := 1;
            for i in [ 1 .. QuoInt( WordLength(Cold), 2 ) ] do
                wd[i*2+1]:=WeightDistribution(Cold)[i*2+1]+
                                 WeightDistribution(Cold)[i*2];
            od;
            if IsOddInt(WordLength(Cold)) then
                wd[WordLength(Cold) + 2] :=
                  WeightDistribution(Cold)[WordLength(Cold) + 1];
            fi;
         SetWeightDistribution(C, wd);
  fi;
        if IsBound(Cold!.boundsCoveringRadius)
           and Length( Cold!.boundsCoveringRadius ) = 1 then
            C!.boundsCoveringRadius :=
              [ Cold!.boundsCoveringRadius[ 1 ] + nrcolumns ];
        fi;
    else
        C!.upperBoundMinimumDistance := UpperBoundMinimumDistance(Cold) + 1;
    fi;
    C!.history := History(Cold);
    return C;
end);


#############################################################################
##
#F  ShortenedCode( <C> [, <L>] )  . . . . . . . . . . . . . .  shortened code
##
##

InstallMethod(ShortenedCode, "Method for unrestricted code, position list",
 true, [IsCode, IsList], 0,
function(C, L)
    local Cnew, i, e, zero, q, baseels, element, max, number,
          temp, els, n;
 if IsLinearCode(C) then
  return ShortenedCode(C,L);
 fi;
 L := Reversed(Set(L));
    zero := Zero(LeftActingDomain(C));
    baseels := AsSSortedList(LeftActingDomain(C));
    q := Size(LeftActingDomain(C));
    els := VectorCodeword(AsSSortedList(C));
    for i in L do
        temp := List(els, x -> x[i]);
        max := 0;
        for e in baseels do
            number := Length(Filtered(temp, x -> x=e));
            if number > max then
                max := number;
                element := e;
            fi;
        od;
        temp := [];
        n := Length(els[1]);
        for e in els do
            if e[i] = element then
                Add(temp,Concatenation(e{[1..i-1]},e{[i+1..n]}));
            fi;
            els := temp;
        od;
    od;
    Cnew := ElementsCode(temp, "shortened code", LeftActingDomain(C));
    Cnew!.history := History(C);
    Cnew!.lowerBoundMinimumDistance := Minimum(LowerBoundMinimumDistance(C),
                                              WordLength(Cnew));
    return Cnew;
end);

InstallOtherMethod(ShortenedCode, "method for unrestricted code, int position",
 true, [IsCode, IsInt], 0,
function(C, i)
 return ShortenedCode(C, [i]);
end);

InstallOtherMethod(ShortenedCode, "method for unrestricted code", true,
 [IsCode], 0,
function(C)
 return ShortenedCode(C, [1]);
end);

InstallMethod(ShortenedCode, "method for linear code and position list",
 true, [IsLinearCode, IsList], 0,
function(C, L)
 local Cnew, G, i, e, zero, q, baseels, temp, n;
 L := Reversed(Set(L));
    zero := Zero(LeftActingDomain(C));
    baseels := AsSSortedList(LeftActingDomain(C));
    q := Size(LeftActingDomain(C));
    G := ShallowCopy(GeneratorMat(C));
    for i in L do
        e := 0;
        repeat
            e := e + 1;
        until (e > Length(G)) or (G[e][i] <> zero);
        if G <> [] then
            n := Length(G[1]);
        else
            n := WordLength(C);
        fi;
        if e <= Length(G) then
            temp := G[e];
            G := Concatenation(G{[1..e-1]},G{[e+1..Length(G)]});
            G := List(G, x-> x - temp * (x[i] / temp[i]));
        fi;
        G := List(G, x->Concatenation(x{[1..i-1]},x{[i+1..n]}));
        if G = [] then
            return NullCode(WordLength(C)-Length(L), LeftActingDomain(C));
        fi;
    od;
    Cnew := GeneratorMatCode(BaseMat(G), "shortened code", LeftActingDomain(C));
    Cnew!.history := History(C);
    Cnew!.lowerBoundMinimumDistance := Minimum(LowerBoundMinimumDistance(C),
                                              WordLength(Cnew));
 if IsCyclicCode(C) then
  Cnew!.upperBoundMinimumDistance := Minimum(WordLength(Cnew),
           UpperBoundMinimumDistance(C));

 fi;
 return Cnew;
end);


#############################################################################
##
#F  PuncturedCode( <C> [, <list>] ) . . . . . . . . . . . . .  punctured code
##
##  PuncturedCode(C [, remlist]) punctures a code by leaving out the
##  coordinates given in list remlist. If remlist is omitted, then
##  the last coordinate will be removed.
##

InstallMethod(PuncturedCode,
 "method for unrestricted codes, position list provided",
 true, [IsCode, IsList], 0,
function(Cold, remlist)
 local keeplist, n, C;
 if IsLinearCode(Cold) then
  return PuncturedCode(Cold, remlist);
 fi;
 n := WordLength(Cold);
 remlist := Set(remlist);
 keeplist := [1..n];
 SubtractSet(keeplist, remlist);
    C := ElementsCode(
                 VectorCodeword(Codeword(
      AsSSortedList(Cold))){[1 .. Size(Cold)]}{keeplist},
                 "punctured code", LeftActingDomain(Cold));
    C!.history := History(Cold);
    C!.lowerBoundMinimumDistance := Maximum(LowerBoundMinimumDistance(Cold) -
                                           Length(remlist), 1);
    C!.upperBoundMinimumDistance := Minimum( Maximum( 1,
                                           UpperBoundMinimumDistance(Cold) ),
                                           n-Length(remlist));
    return C;
end);

InstallOtherMethod(PuncturedCode,
 "method for unrestricted codes, int position provided",
 true, [IsCode, IsInt], 0,
function(C, n)
 return PuncturedCode(C, [n]);
end);

InstallOtherMethod(PuncturedCode, "method for unrestricted codes", true,
 [IsCode], 0,
function(C)
 return PuncturedCode(C, [WordLength(C)]);
end);

InstallMethod(PuncturedCode, "method for linear codes, position list provided",
 true, [IsLinearCode, IsList], 0,
function(Cold, remlist)
 local C, keeplist, n;
 n := WordLength(Cold);
 remlist := Set(remlist);
 keeplist := [1..n];
 SubtractSet(keeplist, remlist);
    C := GeneratorMatCode(
                 GeneratorMat(Cold){[1..Dimension(Cold)]}{keeplist},
                 "punctured code", LeftActingDomain(Cold) );
    C!.history := History(Cold);
    C!.lowerBoundMinimumDistance := Maximum(LowerBoundMinimumDistance(Cold) -
                                           Length(remlist), 1);

# Cyclic codes always have at least one codeword with minimal weight in the
# i-th column (for every i), so if you remove a column, that word has a
# weight of one less -> the minimumdistance is reduced by one
 if IsCyclicCode(Cold) then
  C!.upperBoundMinimumDistance := Minimum( Maximum( 1,
            UpperBoundMinimumDistance(Cold)-1),
            n - Length(remlist) );
 else
  C!.upperBoundMinimumDistance := Minimum( Maximum( 1,
                                           UpperBoundMinimumDistance(Cold) ),
                                           n - Length(remlist));
    fi;
 return C;
end);


#############################################################################
##
#F  ExpurgatedCode( <C>, <L> )  . . . . .  removes codewords in <L> from code
##
##  The usual way of expurgating a code is removing all words of odd weight.
##

InstallMethod(ExpurgatedCode, "method for unrestricted codes, codeword list",
 true, [IsCode, IsList], 0,
function(C, L)
 if IsLinearCode(C) then
  return ExpurgatedCode(C, L);
 else
  Error("can't expurgate a non-linear code; ",
     "consider using RemovedElementsCode");
 fi;
end);

InstallOtherMethod(ExpurgatedCode, "method for unrestricted code, codeword",
 true, [IsCode, IsCodeword], 0,
function(C, w)
 return ExpurgatedCode(C, [w]);
end);

InstallOtherMethod(ExpurgatedCode, "method for unrestricted code", true,
 [IsCode], 0,
function(C)
 if IsLinearCode(C) then
  return ExpurgatedCode(C);
 else
  Error("can't expurgate a non-linear code; ");
 fi;
end);

InstallMethod(ExpurgatedCode, "method for linear code, codeword list",
 true, [IsLinearCode, IsList], 0,
function(Cold, L)
    local C, num, H, F;
 L := VectorCodeword( L );
 L := Set(L);
    F := LeftActingDomain(Cold);
    L := Filtered(L, l-> Codeword(l) in Cold);
    H := List(L, function(l)
        local V,p;
        V := NullVector(WordLength(Cold), F);
        p := PositionProperty(l, i-> not (i = Zero(F)));
        if not (p = false) then
            V[p] := One(F);
        fi;
        return V;
    end);
 H := BaseMat(Concatenation(CheckMat(Cold), H));
    num := Length(H) - Redundancy(Cold);
    if num > 0 then
        C := CheckMatCode( H, Concatenation("code, expurgated with ",
                     String(num), " word(s)"), F);
        C!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(Cold);
        C!.history := History(Cold);
        return C;
    else
        return ShallowCopy(Cold);
    fi;
end);

InstallOtherMethod(ExpurgatedCode, "method for linear code", true,
 [IsLinearCode], 0,
function(C)
 local C2;
 C2 := EvenWeightSubcode(C);
 ##LR - prob if C2 not lin.  Try on DualCode(RepetitionCode(5, GF(3)))
 if Dimension(C2) = Dimension(C) then
  ## No words of odd weight, so expurgate by removing first row of
  ## generator matrix.
  return ExpurgatedCode(C, Codeword(GeneratorMat(C)[1]));
 else
  return C2;
 fi;
end);


#############################################################################
##
#F  AddedElementsCode( <C>, <L> ) . . . . . . . . . .  adds words in list <L>
##

InstallMethod(AddedElementsCode, "method for unrestricted code, codeword list",
 true, [IsCode, IsList], 0,
function(C, L)
    local Cnew, e, w, E, CalcWD, wd, num;
    L := VectorCodeword( L );
 L := Set(L);
    E := ShallowCopy(VectorCodeword(AsSSortedList(C)));
    if HasWeightDistribution(C) then
        wd := ShallowCopy(WeightDistribution(C));
        CalcWD := true;
    else
        CalcWD := false;
    fi;
    num := 0;
    for e in L do
        if not (e in C) then
            Add(E, e);
            num := num + 1;
            if CalcWD then
                w := Weight(Codeword(e)) + 1;
                wd[w] := wd[w] + 1;
            fi;
        fi;
    od;
    if num > 0 then
        Cnew := ElementsCode(E, Concatenation( "code with ", String(num),
                " word(s) added"), LeftActingDomain(C));
        if CalcWD then
            SetWeightDistribution(Cnew, wd);
        fi;
        Cnew!.history := History(C);
        return Cnew;
    else
        return ShallowCopy(C);
    fi;
end);

InstallOtherMethod(AddedElementsCode, "method for unrestricted code, codeword",
 true, [IsCode, IsCodeword], 0,
function(C, w)
 return AddedElementsCode(C, [w]);
end);


#############################################################################
##
#F  RemovedElementsCode( <C>, <L> ) . . . . . . . . removes words in list <L>
##

InstallMethod(RemovedElementsCode,
 "method for unrestricted code, codeword list",
 true, [IsCode, IsList], 0,
function(C, L)
    local E, E2, e, num, s, CalcWD, wd, w, Cnew;
    L := VectorCodeword( L );
    E := Set(VectorCodeword(AsSSortedList(C)));
    E2 := [];
    if HasWeightDistribution(C) then
        wd := ShallowCopy(WeightDistribution(C));
        CalcWD := true;
    else
        CalcWD := false;
    fi;
    for e in E do
        if not (e in L) then
            Add(E2, e);
        elif CalcWD then
            w := Weight(Codeword(e)) + 1;
            wd[w] := wd[w] - 1;
        fi;
    od;
    num := Size(E) - Size(E2);
    if num > 0 then
        Cnew := ElementsCode(E2, Concatenation( "code with ", String(num),
                " word(s) removed"), LeftActingDomain(C) );
        if CalcWD then
            SetWeightDistribution(Cnew, wd);
        fi;
        Cnew!.history := History(C);
        Cnew!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C);
        return Cnew;
    else
        return ShallowCopy(C);
    fi;
end);

InstallOtherMethod(RemovedElementsCode,
 "method for unrestricted code, codeword",
 true, [IsCode, IsCodeword], 0,
function(C, w)
 return RemovedElementsCode(C, [w]);
end);


#############################################################################
##
#F  LengthenedCode( <C> [, <i>] ) . . . . . . . . . . . . . .  lengthens code
##

InstallMethod(LengthenedCode, "method for unrestricted code, number of columns",
 true, [IsCode, IsInt], 0,
function(C, nrcolumns)
    local Cnew;
    Cnew := ExtendedCode(AugmentedCode(C), nrcolumns);
    Cnew!.history := History(C);
    Cnew!.name := Concatenation("code, lengthened with ",String(nrcolumns),
            " column(s)");
    return Cnew;
end);

InstallOtherMethod(LengthenedCode, "unrestricted code", true, [IsCode], 0,
function(C)
 return LengthenedCode(C, 1);
end);


#############################################################################
##
#F  ResidueCode( <C> [, <w>] )  . .  takes residue of <C> with respect to <w>
##
##  If w is omitted, a word from C of minimal weight is used
##

InstallMethod(ResidueCode, "method for unrestricted code, codeword", true,
 [IsCode, IsCodeword], 0,
function(C, w)
 if not IsLinearCode(C) then
  Error("argument must be a linear code");
 else
  return ResidueCode(C, w);
 fi;
end);

InstallOtherMethod(ResidueCode, "method for unrestricted code", true,
 [IsCode], 0,
function(C)
 if not IsLinearCode(C) then
  Error("argument must be a linear code");
 else
  return ResidueCode(C);
 fi;
end);

InstallOtherMethod(ResidueCode, "method for linear code", true,
 [IsLinearCode], 0,
function(C)
    local w, i, d;
 d := MinimumDistance(C);
 i := 2;
 while Weight(CodewordNr(C, i)) > d do
  i := i + 1;
 od;
 w := CodewordNr(C, i);
    return ResidueCode(C, w);
end);

InstallMethod(ResidueCode, "method for linear code, codeword", true,
 [IsLinearCode, IsCodeword], 0,
function(C, w)
    local Cnew, q, d;
    if Weight(w) = 0 then
  Error("word of weight 0 is not allowed");
 elif Weight(w) = WordLength(C) then
  Error("all-one word is not allowed");
 fi;
 Cnew := PuncturedCode(ExpurgatedCode(C, w), Support(w));
    q := Size(LeftActingDomain(C));
    d := MinimumDistance(C) - Weight(w) * ( (q-1) / q );
    if not IsInt(d) then
        d := Int(d) + 1;
    fi;
    Cnew!.lowerBoundMinimumDistance := d;
    Cnew!.history := History(C);
    Cnew!.name := "residue code";
    return Cnew;
end);


#############################################################################
##
#F  ConstructionBCode( <C> )  . . . . . . . . . . .  code from construction B
##
##  Construction B (See M&S, Ch. 18, P. 9) assumes that the check matrix has
##  a first row of weight d' (the dual distance of C). The new code has a
##  check matrix equal to this matrix, but with columns removed where the
##  first row is 1.
##

InstallMethod(ConstructionBCode, "method for unrestricted codes", true,
 [IsCode], 0,
function(C)
 if LeftActingDomain(C) <> GF(2) then
  Error("only valid for binary codes");
 elif IsLinearCode(C) then
  return ConstructionBCode(C);
 else
  Error("only valid for linear codes");
 fi;
end);

InstallMethod(ConstructionBCode, "method for linear codes", true,
 [IsLinearCode], 0,
function(C)
    local i, H, dd, M, mww, Cnew, DC, keeplist;
 if LeftActingDomain(C) <> GF(2) then
  Error("only valid for binary codes");
 fi;
 DC := DualCode(C);
    H := ShallowCopy(GeneratorMat(DC));        # is check matrix of C
    M := Size(DC);
    dd := MinimumDistance(DC);          # dual distance of C
    i := 2;
    repeat
        mww := CodewordNr(DC, i);
        i := i + 1;
    until Weight(mww) = dd;
    i := i - 2;
    keeplist := Set([1..WordLength(C)]);
    SubtractSet(keeplist, Support(mww));
    mww := VectorCodeword(mww);
    # make sure no row dependencies arise;
    H[Redundancy(C)-LogInt(i, Size(LeftActingDomain(C)))] := mww;
    H := List(H, h -> h{keeplist});
    Cnew := CheckMatCode(H, Concatenation("Construction B (",String(dd),
            " coordinates)"), LeftActingDomain(C));
    Cnew!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C);
    Cnew!.history := History(DC);
    return Cnew;
end);

#############################################################################
##
#F  ConstructionB2Code( <C> )  . . . . . . . . . .  code from construction B2
##
##  Construction B2 is mixtures of shortening and puncturing. Given an
##  [n,k,d] code which has dual code of minimum distance s, we obtain
##  an [n-s, k-s+2j+1, d-2j] code for each j with 2j+1 < s.
##
##  For more details, see A. Brouwer (1998), "Bounds on the size of linear
##  codes,", in Handbook of Coding Theory, V. S. Pless and W. C. Huffmann
##  ed., pp. 311
##
##  added by CJ, April 2006  -  FIXME this function is NOT complete
##

InstallMethod(ConstructionB2Code, "method for unrestricted codes", true,
 [IsCode], 0,
function(C)
 Error("ConstructionB2 is not implemented yet ....... sorry\n");
end);

#############################################################################
##
#F  SubCode( <C>, [<s>] ) . .  . . . . . . . . . . . . . . . . subcode of C
##
##  Given C, an [n,k,d] code, return a subcode of C with dimension k-s.
##  If s is not given, it is assumed to be 1.
##
##  added by CJ, April 2006  -  FIXME this function is NOT complete
##

InstallMethod(SubCode, "method for linear codes, int provided", true,
 [IsCode, IsInt], 0,
function(C, s)
 local G, Gs, Cs;
 if (IsLinearCode(C) = false) then
  Error("SubCode only works for linear code\n");
 fi;
 if (Dimension(C)-s = 0) then
  return NullCode(CodeLength(C), LeftActingDomain(C));
 elif (Dimension(C) <= s) then
  Error("Dimension of the code must be greater than s\n");
 else
  G  := ShallowCopy(GeneratorMat(C));
  Gs := List([1..Length(G)-s], x->G[x]);
      Cs := GeneratorMatCode(BaseMat(Gs), "subcode", LeftActingDomain(C));
     Cs!.lowerBoundMinimumDistance := Maximum(LowerBoundMinimumDistance(C), 1);
     Cs!.upperBoundMinimumDistance := Minimum(Maximum(1, UpperBoundMinimumDistance(C)), CodeLength(C));
     Cs!.history := History(C);
     return Cs;
 fi;
end);

InstallOtherMethod(SubCode, "method for linear codes", true,
 [IsCode], 0,
function(C)
 return SubCode(C, 1);
end);

#############################################################################
##
#F  PermutedCode( <C>, <P> )  . . . . . . . permutes coordinates of codewords
##

InstallMethod(PermutedCode, "method for unrestricted codes", true,
 [IsCode, IsPerm], 0,
function(Cold, P)
 local C, field, fields;
 if IsCyclicCode(Cold) or IsLinearCode(Cold) then
  return PermutedCode(Cold, P);
 fi;

    C := ElementsCode(
    PermutedCols(VectorCodeword(Codeword(AsSSortedList(Cold))), P),
                "permuted code", LeftActingDomain(Cold));
    # Copy the fields that stay the same:
    fields := [WeightDistribution, InnerDistribution, IsPerfectCode,
    IsSelfDualCode, MinimumDistance, CoveringRadius];
 for field in fields do
  if Tester(field)(Cold) then
   Setter(field)(C, field(Cold));
  fi;
 od;
 fields := ["lowerBoundMinimumDistance", "upperBoundMinimumDistance",
    "boundsCoveringRadius"];
 for field in fields do
  if IsBound(Cold!.(field)) then
   C!.(field) := Cold!.(field);
  fi;
 od;
 C!.history := History(Cold);
    return C;
end);

InstallMethod(PermutedCode, "method for linear codes", true,
 [IsLinearCode, IsPerm], 0,
function(Cold, P)
 local C, field, fields;
 if IsCyclicCode(Cold) then
  return PermutedCode(Cold, P);
 fi;
    C := GeneratorMatCode(
                 PermutedCols(GeneratorMat(Cold), P),
                 "permuted code", LeftActingDomain(Cold));
    # Copy the fields that stay the same:
    fields := [WeightDistribution, IsPerfectCode, IsSelfDualCode,
    MinimumWeightOfGenerators, MinimumDistance, CoveringRadius];
 for field in fields do
        if Tester(field)(Cold) then
   Setter(field)(C, field(Cold));
  fi;
 od;
 fields := ["lowerBoundMinimumDistance", "upperBoundMinimumDistance",
    "boundsCoveringRadius"];
 for field in fields do
        if IsBound(Cold!.(field)) then
   C!.(field) := Cold!.(field);
  fi;
 od;
 C!.history := History(Cold);
    return C;
end);

InstallMethod(PermutedCode, "method for cyclic codes", true,
 [IsCyclicCode, IsPerm], 0,
function(Cold, P)
    local C, field, fields;
    C := GeneratorMatCode(
                 PermutedCols(GeneratorMat(Cold), P),
                 "permuted code", LeftActingDomain(Cold) );
    # Copy the fields that stay the same:
 fields := [WeightDistribution, IsPerfectCode, IsSelfDualCode,
                MinimumWeightOfGenerators, MinimumDistance, CoveringRadius,
    UpperBoundOptimalMinimumDistance];
 for field in fields do
  if Tester(field)(Cold) then
         Setter(field)(C, field(Cold));
     fi;
 od;
 fields := ["lowerBoundMinimumDistance", "upperBoundMinimumDistance",
             "boundsCoveringRadius"];
 for field in fields do
     if IsBound(Cold!.(field)) then
         C!.(field) := Cold!.(field);
     fi;
 od;

    C!.history := History(Cold);
    return C;
end);


#############################################################################
##
#F  StandardFormCode( <C> ) . . . . . . . . . . . . standard form of code <C>
##

##LR - all of these methods used to use a ShallowCopy, but that doesn't
##    allow for unbinding/unsetting of attributes.  So now a whole new
##    code is created.  However, should figure out what can be saved and
##    use that.

InstallMethod(StandardFormCode, "method for unrestricted code", true,
 [IsCode], 0,
function(C)
 local Cnew;
 if IsLinearCode(C) then
  return StandardFormCode(C);
 fi;
 Cnew := ElementsCode(AsSSortedList(C), "standard form",
       LeftActingDomain(C));
 Cnew!.history := History(C);
 return Cnew;
end);

InstallMethod(StandardFormCode, "method for linear codes", true,
 [IsLinearCode], 0,
function(C)
 local G, P, Cnew;
 G := ShallowCopy(GeneratorMat(C));
 P := PutStandardForm(G, true, LeftActingDomain(C));
 if P = () then
  Cnew := ShallowCopy(C);
  # this messes up code names
  #Cnew!.name := "standard form";
 else
  Cnew := GeneratorMatCode(G,
   Concatenation("standard form, permuted with ",
                  String(P)),
          LeftActingDomain(C));
 fi;
 Cnew!.history := History(C);
 return Cnew;
end);


#############################################################################
##
#F  ConversionFieldCode( <C> )  . . . . . converts code from GF(q^m) to GF(q)
##

InstallMethod(ConversionFieldCode, "method for unrestricted code", true,
 [IsCode], 0,
function (C)
 local F, x, q, m, i, ConvertElms, Cnew;
 if IsLinearCode(C) then
  return ConversionFieldCode(C);
 fi;

    ConvertElms := function (M)
        local res,n,k,vec,coord, ConvTable, Nul, g, zero;
        res := [];
        n := Length(M[1]);
        k := Length(M);
        g := MinimalPolynomial(GF(q), Z(q^m));
        zero := Zero(F);
        Nul := List([1..m], i -> zero);
        ConvTable := [];
        x := Indeterminate(GF(q));
        for i in [1..Size(F) - 1] do
            ConvTable[i] := VectorCodeword(Codeword(x^(i-1) mod g, m));
        od;
        for vec in [1..k] do
            res[vec] := [];
            for coord in [1..n] do
                if M[vec][coord] <> zero then
                    Append(res[vec],
       ConvTable[LogFFE(M[vec][coord], Z(q^m)) + 1]);
                else
                    Append(res[vec], Nul);
                fi;
            od;
        od;
        return res;
    end;

    F := LeftActingDomain(C);
    q := Characteristic(F);
    m := Dimension(F);
    Cnew := ElementsCode(
                    ConvertElms(VectorCodeword(AsSSortedList(C))),
                    Concatenation("code, converted to basefield GF(",
                            String(q),")"),
                    F );
    Cnew!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C);
    Cnew!.upperBoundMinimumDistance := Minimum(WordLength(C),
                                              m*UpperBoundMinimumDistance(C));
    Cnew!.history := History(C);
    return Cnew;
end);

InstallOtherMethod(ConversionFieldCode, "method for linear code", true,
 [IsLinearCode], 0,
function(C)
    local F, Cnew;
    F := LeftActingDomain(C);
    Cnew := GeneratorMatCode(
                    HorizontalConversionFieldMat( GeneratorMat(C), F),
                    Concatenation("code, converted to basefield GF(",
                            String(Characteristic(F)), ")"),
                    GF(Characteristic(F)));
    Cnew!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C);
    Cnew!.upperBoundMinimumDistance := Minimum(WordLength(C),
                                 Dimension(F) * UpperBoundMinimumDistance(C));
    Cnew!.history := History(C);
    return Cnew;
end);


#############################################################################
##
#F  CosetCode( <C>, <f> ) . . . . . . . . . . . . . . . . . . .  coset of <C>
##

InstallMethod(CosetCode, "method for unrestricted codes", true,
 [IsCode, IsCodeword], 0,
function(C, f)
 local i, els, Cnew;
 if IsLinearCode(C) then
  return CosetCode(C, f);
 fi;
    f := Codeword(f, LeftActingDomain(C));
    els := [];
    for i in [1..Size(C)] do
        Add(els, AsSSortedList(C)[i] + f);
    od;
    Cnew := ElementsCode(els, "coset code", LeftActingDomain(C) );
    Cnew!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C);
    Cnew!.upperBoundMinimumDistance := UpperBoundMinimumDistance(C);
    Cnew!.history := History(C);
    return Cnew;
end);

InstallMethod(CosetCode, "method for linear codes", true,
 [IsLinearCode, IsCodeword], 0,
function(C, f)
    local Cnew, i, els, Cels;
    f := Codeword(f, LeftActingDomain(C));
    if f in C then
        return ShallowCopy(C);
    fi;
    els := [];
    Cels := AsSSortedList(C);
    for i in [1..Size(C)] do
        Add(els, Cels[i] + f);
    od;
    Cnew := ElementsCode(els, "coset code", LeftActingDomain(C) );
 if HasWeightDistribution(C) then
        SetInnerDistribution(Cnew, ShallowCopy(WeightDistribution(C)));
    fi;
    Cnew!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C);
    Cnew!.upperBoundMinimumDistance := UpperBoundMinimumDistance(C);
    Cnew!.history := History(C);
    return Cnew;
end);


#############################################################################
##
#F  DirectSumCode( <C1>, <C2> ) . . . . . . . . . . . . . . . . .  direct sum
##
##  DirectSumCode(C1, C2) creates a (n1 + n2 , M1 M2 , min{d1 , d2} ) code
##  by adding each codeword of the second code to all the codewords of the
##  first code.
##

InstallMethod(DirectSumCode, "method for unrestricted codes", true,
 [IsCode, IsCode], 0,
function(C1, C2)
 local i, j, C, els, n, sumcr, wd, id;
 if IsLinearCode(C1) and IsLinearCode(C2) then
        return DirectSumCode(C1, C2);
 fi;
 if LeftActingDomain(C1) <> LeftActingDomain(C2) then
        Error("Codes are not in the same basefield");
 fi;

    els := [];
    for i in VectorCodeword(AsSSortedList(C1)) do
        Append(els,List(VectorCodeword(AsSSortedList(C2)),
                x-> Concatenation(i, x ) ) );
    od;
    C := ElementsCode( els, "direct sum code", LeftActingDomain(C1) );
    n := WordLength(C1) + WordLength(C2);
    if Size(C) <= 1 then
        C!.lowerBoundMinimumDistance := n;
        C!.upperBoundMinimumDistance := n;
    else
        C!.lowerBoundMinimumDistance := Minimum(LowerBoundMinimumDistance(C1),
                                               LowerBoundMinimumDistance(C2));
        C!.upperBoundMinimumDistance := Minimum(UpperBoundMinimumDistance(C1),
                                               UpperBoundMinimumDistance(C2));
    fi;
    if HasWeightDistribution(C1) and HasWeightDistribution(C2) then
        wd := NullVector(WordLength(C)+1);
        for i in [1..WordLength(C1)+1] do
            for j in [1..WordLength(C2)+1] do
                wd[i+j-1] := wd[i+j-1]+
                             WeightDistribution(C1)[i] *
                             WeightDistribution(C2)[j];
            od;
        od;
     SetWeightDistribution(C, wd);
 fi;
    if HasInnerDistribution(C1) and HasInnerDistribution(C2) then
        id := NullVector(WordLength(C) + 1);
        for i in [1..WordLength(C1) + 1 ] do
            for j in [1..WordLength(C2) + 1 ] do
                id[i+j-1] := id[i+j-1]+
                             InnerDistribution(C1)[i] *
                             InnerDistribution(C2)[j];

            od;
        od;
  SetInnerDistribution(C, id);
 fi;
    if IsBound(C1!.boundsCoveringRadius)
       and IsBound(C2!.boundsCoveringRadius) then
        sumcr := List( C1!.boundsCoveringRadius,
          x -> x + C2!.boundsCoveringRadius);
        sumcr := Set( Flat( sumcr ) );
        IsRange( sumcr );
        C!.boundsCoveringRadius := sumcr;
    fi;
    C!.history := MergeHistories(History(C1), History(C2));
    return C;
end);

InstallMethod(DirectSumCode, "method for linear codes", true,
 [IsLinearCode, IsLinearCode], 0,
function(C1, C2)
 local i, j, C, zeros1, zeros2, G, n, sumcr, wd;
 if LeftActingDomain(C1) <> LeftActingDomain(C2) then
        Error("Codes are not in the same basefield");
 fi;

 zeros1 := NullVector(WordLength(C1), LeftActingDomain(C1));
    zeros2 := NullVector(WordLength(C2), LeftActingDomain(C1));
    G := List(GeneratorMat(C1),x -> Concatenation(x,zeros2));
    Append(G,List(GeneratorMat(C2),x -> Concatenation(zeros1,x)));
    C := GeneratorMatCode( G, "direct sum code", LeftActingDomain(C1) );
    n := WordLength(C1) + WordLength(C2);
    if Size(C) <= 1 then
        C!.lowerBoundMinimumDistance := n;
        C!.upperBoundMinimumDistance := n;
    else
        C!.lowerBoundMinimumDistance := Minimum(LowerBoundMinimumDistance(C1),
                                               LowerBoundMinimumDistance(C2));
        C!.upperBoundMinimumDistance := Minimum(UpperBoundMinimumDistance(C1),
                                               UpperBoundMinimumDistance(C2));
    fi;
    if HasWeightDistribution(C1) and HasWeightDistribution(C2) then
        wd := NullVector(WordLength(C)+1);
        for i in [1..WordLength(C1)+1] do
            for j in [1..WordLength(C2)+1] do
                wd[i+j-1] := wd[i+j-1]+
                             WeightDistribution(C1)[i] *
                             WeightDistribution(C2)[j];
            od;
        od;
     SetWeightDistribution(C, wd);
 fi;
    if IsBound(C1!.boundsCoveringRadius)
       and IsBound(C2!.boundsCoveringRadius) then
        sumcr := List( C1!.boundsCoveringRadius,
          x -> x + C2!.boundsCoveringRadius);
        sumcr := Set( Flat( sumcr ) );
        IsRange( sumcr );
        C!.boundsCoveringRadius := sumcr;
    fi;
    if HasIsNormalCode(C1) and HasIsNormalCode(C2) and
       IsNormalCode( C1 ) and IsNormalCode( C2 ) then
        SetIsNormalCode(C, true);
    fi;
    if HasIsSelfOrthogonalCode(C1) and HasIsSelfOrthogonalCode(C2)
       and IsSelfOrthogonalCode(C1) and IsSelfOrthogonalCode(C2) then
        SetIsSelfOrthogonalCode(C, true);
    fi;
    C!.history := MergeHistories(History(C1), History(C2));
    return C;
end);


#############################################################################
##
#F  ConcatenationCode( <C1>, <C2> ) . . . . .  concatenation of <C1> and <C2>
##

InstallMethod(ConcatenationCode, "method for unrestricted codes", true,
 [IsCode, IsCode], 0,
function(C1, C2)
 local E,e,C;
 if IsLinearCode(C1) and IsLinearCode(C2) then
  return ConcatenationCode(C1, C2);
 elif Size(C1) <> Size(C2) then
  Error("both codes must have equal size");
 elif LeftActingDomain(C1) <> LeftActingDomain(C2) then
  Error("both codes must be over the same field");
 fi;

 E := [];
 for e in [1..Size(C1)] do
  Add(E,Concatenation(VectorCodeword(AsSSortedList(C1)[e]),
    VectorCodeword(AsSSortedList(C2)[e])));
 od;
 C := ElementsCode( E, "concatenation code", LeftActingDomain(C1) );
 C!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C1) +
           LowerBoundMinimumDistance(C2);
 C!.upperBoundMinimumDistance := UpperBoundMinimumDistance(C1) +
           UpperBoundMinimumDistance(C2);
 # CoveringRadius?
 C!.history := MergeHistories(History(C1), History(C2));
 return C;
end);


InstallMethod(ConcatenationCode, "method for linear codes", true,
 [IsLinearCode, IsLinearCode], 0,
function(C1, C2)
 local e, C, G, G1, G2;
 if Size(C1) <> Size(C2) then
        Error("both codes must have equal size");
 elif LeftActingDomain(C1) <> LeftActingDomain(C2) then
  Error("both codes must be over the same field");
 fi;

 G := [];
 G1 := GeneratorMat(C1);
 G2 := GeneratorMat(C2);
 for e in [1..Dimension(C1)] do
  Add(G, Concatenation(G1[e], G2[e]));
 od;
 C := GeneratorMatCode(G, "concatenation code", LeftActingDomain(C1));
 C!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C1) +
           LowerBoundMinimumDistance(C2);
 C!.upperBoundMinimumDistance := UpperBoundMinimumDistance(C1) +
           UpperBoundMinimumDistance(C2);
 # CoveringRadius?
 C!.history := MergeHistories(History(C1), History(C2));
 return C;
end);


#############################################################################
##
#F  DirectProductCode( <C1>, <C2> ) . . . . . . . . . . . . .  direct product
##
##  DirectProductCode constructs a new code from the direct product of two
##  codes by taking the Kronecker product of the two generator matrices
##

InstallMethod(DirectProductCode, "method for unrestricted codes", true,
 [IsCode, IsCode], 0,
function(C1, C2)
 if IsLinearCode(C1) and IsLinearCode(C2) then
  return DirectProductCode(C1,C2);
 else
  Error("both codes must be linear");
 fi;
end);

InstallMethod(DirectProductCode, "method for linear codes", true,
 [IsLinearCode, IsLinearCode], 0,
function(C1, C2)
 local C;
 if LeftActingDomain(C1) <> LeftActingDomain(C2) then
  Error("both codes must have the same basefield");
 fi;
 C := GeneratorMatCode(
     KroneckerProduct(GeneratorMat(C1), GeneratorMat(C2)),
     "direct product code",
     LeftActingDomain(C1));
 if Dimension(C) = 0 then
  C!.lowerBoundMinimumDistance := WordLength(C);
  C!.upperBoundMinimumDistance := WordLength(C);
 else
  C!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C1) *
            LowerBoundMinimumDistance(C2);
  C!.upperBoundMinimumDistance := UpperBoundMinimumDistance(C1) *
            UpperBoundMinimumDistance(C2);
 fi;
 C!.history := MergeHistories(History(C1), History(C2));
 if IsBound( C1!.boundsCoveringRadius ) and
    IsBound( C2!.boundsCoveringRadius ) then
  C!.boundsCoveringRadius := [
  Maximum( WordLength( C1 ) * C2!.boundsCoveringRadius[ 1 ],
       WordLength( C2 ) * C1!.boundsCoveringRadius[ 1 ] )
    .. GeneralUpperBoundCoveringRadius( C ) ];
 fi;
 return C;
end);


#############################################################################
##
#F  UUVCode( <C1>, <C2> ) . . . . . . . . . . . . . . .  u | u+v construction
##
##  Uuvcode(C1, C2) # creates a ( 2n , M1 M2 , d = min{2 d1 , d2} ) code
##  with codewords  (u | u + v) for all u in C1 and v in C2
##

InstallMethod(UUVCode, "method for linear codes", true,
 [IsLinearCode, IsLinearCode], 0,
function(C1, C2)
 local C, F, diff, zeros, zeros2, G, n;
 if LeftActingDomain(C1)<>LeftActingDomain(C2) then
        Error("Codes are not in the same basefield");
 fi;
 F := LeftActingDomain(C1);
 n := WordLength(C1)+Maximum(WordLength(C1),WordLength(C2));
 diff := WordLength(C1)-WordLength(C2);
 zeros := NullVector(WordLength(C1), F);
 zeros2 := NullVector(AbsInt(diff), F);
 if diff < 0 then
  G := List(GeneratorMat(C1),u -> Concatenation(u,u,zeros2));
  Append(G,List(GeneratorMat(C2),v -> Concatenation(zeros,v)));
 else
  G:=List(GeneratorMat(C1),u -> Concatenation(u,u));
  Append(G,List(GeneratorMat(C2),v->Concatenation(zeros,v,zeros2)));
 fi;
 C := GeneratorMatCode( G, "U|U+V construction code", F );
 if Dimension(C1) = 0 then
  if Dimension(C2) = 0 then
   C!.lowerBoundMinimumDistance := n;
   C!.upperBoundMinimumDistance := n;
  else
   C!.lowerBoundMinimumDistance := LowerBoundMinimumDistance(C2);
   C!.upperBoundMinimumDistance := UpperBoundMinimumDistance(C2);
  fi;
 elif Dimension(C2) = 0 then
  C!.lowerBoundMinimumDistance := 2*LowerBoundMinimumDistance(C1);
  C!.upperBoundMinimumDistance := 2*UpperBoundMinimumDistance(C1);
 else
  C!.lowerBoundMinimumDistance := Minimum(
   2*LowerBoundMinimumDistance(C1),LowerBoundMinimumDistance(C2));
  C!.upperBoundMinimumDistance := Minimum(
   2*UpperBoundMinimumDistance(C1),UpperBoundMinimumDistance(C2));
 fi;

 C!.history := MergeHistories(History(C1), History(C2));
 return C;
end);

InstallMethod(UUVCode, "method for unrestricted codes", true,
 [IsCode, IsCode], 0,
function(C1, C2)
 local C, F, i, M1, diff, zeros, extended, Els1, Els2, els, n;
    if LeftActingDomain(C1)<>LeftActingDomain(C2) then
  Error("Codes are not in the same basefield");
 elif IsLinearCode(C1) and IsLinearCode(C2) then
  return UUVCode(C1, C2);
 fi;
 F := LeftActingDomain(C1);
 n := WordLength(C1)+Maximum(WordLength(C1),WordLength(C2));
 diff := WordLength(C1)-WordLength(C2);
 M1 := Size(C1);
 zeros := NullVector(AbsInt(diff), F);
 els := [];
 Els1 := AsSSortedList(C1);
 Els2 := AsSSortedList(C2);
 if diff>0 then
  extended := List(Els2,x->Concatenation(VectorCodeword(x),zeros));
  for i in [1..M1] do
   Append(els, List(extended,x-> Concatenation(VectorCodeword(Els1[i]),
     VectorCodeword(Els1[i]) + x ) ) );
  od;
 elif diff<0 then
  for i in [1..M1] do
   extended := Concatenation(VectorCodeword(Els1[i]),zeros);
   Append(els,List(Els2,x-> Concatenation(VectorCodeword(Els1[i]),
     extended + VectorCodeword(x) ) ) );
  od;
 else
  for i in [1..M1] do
   Append(els,List(Els2,x-> Concatenation(VectorCodeword(Els1[i]),
     VectorCodeword(Els1[i]) + VectorCodeword(x) ) ) );
  od;
 fi;
 C := ElementsCode(els, "U|U+V construction code", F);
 C!.lowerBoundMinimumDistance := Minimum(2*LowerBoundMinimumDistance(C1),
             LowerBoundMinimumDistance(C2));
 C!.upperBoundMinimumDistance := Minimum(2*UpperBoundMinimumDistance(C1),
             UpperBoundMinimumDistance(C2));

 C!.history := MergeHistories(History(C1), History(C2));
 return C;
end);


#############################################################################
##
#F  UnionCode( <C1>, <C2> ) . . . . . . . . . . . . .  union of <C1> and <C2>
##

InstallMethod(UnionCode, "method for two linear codes", true,
 [IsLinearCode, IsLinearCode], 0,
function(C1, C2)
 local C, Els, e;
 if LeftActingDomain(C1) <> LeftActingDomain(C2) then
  Error("codes are not in the same basefield");
 elif WordLength(C1) <> WordLength(C2) then
  Error("wordlength must be the same");
 fi;
 C := AugmentedCode(C1, GeneratorMat(C2));
 C!.upperBoundMinimumDistance := Minimum(UpperBoundMinimumDistance(C1),
             UpperBoundMinimumDistance(C2));
 C!.history := MergeHistories(History(C1), History(C2));
 C!.name := "union code";
 return C;
end);

# should there be a special function for cyclic codes? Or in other words:
# If C1 and C2 are cyclic, does that mean that UnionCode(C1, C2) is cyclic?

InstallMethod(UnionCode, "method for one or both unrestricted codes", true,
 [IsCode, IsCode], 0,
function(C1, C2)
 if IsLinearCode(C1) and IsLinearCode(C2) then
  return UnionCode(C1,C2);
 else
  Error("use AddedElementsCode for non-linear codes");
 fi;
end);


#############################################################################
##
#F  IntersectionCode( <C1>, <C2> )  . . . . . . intersection of <C1> and <C2>
##

InstallMethod(IntersectionCode, "method for unrestricted codes", true,
 [IsCode, IsCode], 0,
function(C1, C2)
 local C, Els, e;
 if (IsCyclicCode(C1) and IsCyclicCode(C2)) or
    (IsLinearCode(C1) and IsLinearCode(C2)) then
  return IntersectionCode(C1, C2);
 fi;
 if LeftActingDomain(C1) <> LeftActingDomain(C2) then
  Error("codes are not in the same basefield");
 elif WordLength(C1) <> WordLength(C2) then
  Error("wordlength must be the same");
 fi;
 Els := [];
 for e in AsSSortedList(C1) do
  if e in C2 then Add(Els, e); fi;
 od;
 if Els = [] then
  return false; # or an Error?
 else
  C := ElementsCode(Els, "intersection code", LeftActingDomain(C1));
 fi;
 C!.lowerBoundMinimumDistance := Maximum(LowerBoundMinimumDistance(C1),
             LowerBoundMinimumDistance(C2));
 C!.history := MergeHistories(History(C1), History(C2));
 return C;
end);

InstallMethod(IntersectionCode, "method for linear codes", true,
 [IsLinearCode, IsLinearCode], 0,
function(C1, C2)
 local C;
 if IsCyclicCode(C1) and IsCyclicCode(C2) then
  return IntersectionCode(C1, C2);
 fi;
 if LeftActingDomain(C1) <> LeftActingDomain(C2) then
  Error("codes are not in the same basefield");
 elif WordLength(C1) <> WordLength(C2) then
  Error("wordlength must be the same");
 fi;
 C := DualCode(AugmentedCode(DualCode(C1), CheckMat(C2)));
 C!.lowerBoundMinimumDistance := Maximum(LowerBoundMinimumDistance(C1),
             LowerBoundMinimumDistance(C2));
 C!.history := MergeHistories(History(C1), History(C2));
 C!.name := "intersection code";
 return C;
end);

InstallMethod(IntersectionCode, "method for cyclic codes", true,
 [IsCyclicCode, IsCyclicCode], 0,
function(C1, C2)
 local C;
 if LeftActingDomain(C1) <> LeftActingDomain(C2) then
        Error("codes are not in the same basefield");
 elif WordLength(C1) <> WordLength(C2) then
  Error("wordlength must be the same");
 fi;
 C := GeneratorPolCode(
     Lcm(GeneratorPol(C1), GeneratorPol(C2)), WordLength(C1),
     "intersection code", LeftActingDomain(C1) );
 if HasRootsOfCode(C1) and HasRootsOfCode(C2) then
  SetRootsOfCode(C, UnionSet(RootsOfCode(C1), RootsOfCode(C2)));
 fi;
 C!.lowerBoundMinimumDistance := Maximum(LowerBoundMinimumDistance(C1),
             LowerBoundMinimumDistance(C2));
 C!.history := MergeHistories(History(C1), History(C2));
 return C;
end);

#############################################################################
##
#F    ConstructionXCode( <C>, <A> )  ... code from Construction X
##
##
InstallMethod(ConstructionXCode, "linear code constructed using Construction X",
 true, [IsList, IsList], 0,
function( C, A )
 #
 # Construction X (see N. Sloane, S. Reddy and C. Chen, ``New binary codes,''
 #                     IEEE Trans. Inform. Theory, vol. IT-18, pp. 503-510,
 #                     Jul. 1972
 #                )
 #
 # Consider a list of linear codes of the same length N, C := [ C_1, C_2, ... , C_j ],
 # where the parameter of ith code, C_i, is [N, K_i, D_i] and C_1 > C_2 > ... > C_j.
 # Consider a list of (Size(C)-1) auxiliary linear codes A := [ A_1, A_2, ..., A_{j-1} ]
 # where the parameter of ith code A_i is [n_i, k_i=(K_1-K_{i+1}), d_i], a [n, k, d]
 # can be constructed where n = N + (n_1 + n_2 + ... + n_{j-1}), k = K_1, and
 # d = min{ D_j, D_{j-1} + d_{j-1}, D_{j-2} + d_{j-2} + d_{j-1}, ..., D_1 + (d_1 +
 # ... + d_{j-1}) }.
 #
 local i, j, k, p, r,
       K, S, GC, GA, GX, CX, ZeroVec;

 # Make sure list C contains all linear codes
 if (PositionNot( List([1..Size(C)], i->IsLinearCode(C[i])), true ) < Size(C)) then
  Error("The list C contains non linear code(s)\n"); return (0);
 fi;

 # Make sure list A contains all linear codes
 if (PositionNot( List([1..Size(A)], i->IsLinearCode(A[i])), true ) < Size(A)) then
  Error("The list A contains non linear code(s)\n"); return (0);
 fi;

 # Make sure all codes in C and A have the same LeftActingDomain
 K:=Filtered([2..Size(C)], i->LeftActingDomain(C[i]) <> LeftActingDomain(C[1]));;
 if Size(K) > 0 then
  Error("Codes in C are not of the same left-acting-domain\n");
 fi;
 S:=Filtered([2..Size(A)], i->LeftActingDomain(A[i]) <> LeftActingDomain(A[1]));;
 if Size(S) > 0 then
  Error("Codes in A are not of the same left-acting-domain\n");
 fi;
 if LeftActingDomain(C[1]) <> LeftActingDomain(A[1]) then
  Error("Codes in C and A are of different left-acting-domain\n");
 fi;

 # Ensure that Dimension(C[1]) < Dimension(C[2]) < ... < Dimension(C[j]), i.e. we need to sort them
 K:=List([1..Size(C)], i->Dimension(C[i]));;
 S:=List([1..Size(C)], i->Dimension(C[i]));;
 Sort(S);;
 C:=List([1..Size(K)], i->C[Position(K, S[i])]);;

 # Need to make sure that C[1] < C[2] < ... < C[j], i.e. subset
 if (PositionNot(List([0..Size(C)-2], i->IsSubset(C[Size(C)-i], C[Size(C)-i-1])), true) < Size(C)-1) then
  Error("Inappropriate chain of codes\n");
 fi;

 # Now, ensure that codes in A are sorted such that their dimensions are in ascending order
 K:=List([1..Size(A)], i->Dimension(A[i]));;
 S:=List([1..Size(A)], i->Dimension(A[i]));;
 Sort(S);;
 A:=List([1..Size(K)], i->A[Position(K, S[i])]);;

 # Number codes in A should be 1 less than that in C
 if (Size(A) <> Size(C)-1) then
  Error("Inappropriate list of codes given\n");
 fi;

 # Need to make sure that the dimension of each of the auxiliary codes (codes in A)
 # is equal to the difference in dimension between the appropriate pair of codes in C.
 for i in [1..Size(A)] do;
  if (Dimension(A[i]) <> (Dimension(C[Size(C)])-Dimension(C[Size(C)-i]))) then
   Error("Inappropriate auxiliary codes\n");
  fi;
 od;

 # Generator matrices of the chain codes
 GC:=List([1..Size(C)], i->ShallowCopy(GeneratorMat(C[i])));;
 GA:=List([1..Size(A)], i->ShallowCopy(GeneratorMat(A[i])));;

 # Generator matrix of the largest code in chain format
 GX:=GC[Size(C)];;
 i:=1;;
 p:=1;;
 while (i < Size(C)) do
  for j in [p..Dimension(C[i])] do;
   GX[p] := GC[i][j];
   p := p + 1;
  od;
  i := i + 1;
 od;

 GX:=ShallowCopy(GX);;
 # Add the G matrix of the tail codes
 k:=Dimension(C[Size(C)]);;
 for i in [1..Size(A)] do
  r:=1;;
  ZeroVec:=List([1..CodeLength(A[i])], i->Zero( LeftActingDomain(C[1]) ));;
  while (r <= k-Dimension(A[i])) do
   GX[r]:=ShallowCopy(GX[r]);;
   Append(GX[r], ZeroVec);;
   r := r + 1;;
  od;
  j:=1;;
  while (r <= k) do
   GX[r]:=ShallowCopy(GX[r]);;
   Append(GX[r], GA[i][j]);;
   j := j + 1;;
   r := r + 1;;
  od;
 od;
 CX:=GeneratorMatCode(GX, "Construction X code", LeftActingDomain(C[1]));

 K:=[C[1]!.lowerBoundMinimumDistance];;
 S:=[C[1]!.upperBoundMinimumDistance];;
 i:=1;;
 while (i <= Size(A)) do;
  r:=0;;
  p:=0;;
  for j in [1..i] do;
   r := r + A[Size(A)-j+1]!.lowerBoundMinimumDistance;
   p := p + A[Size(A)-j+1]!.upperBoundMinimumDistance;
  od;
  Append(K, [r + C[i+1]!.lowerBoundMinimumDistance]);
  Append(S, [p + C[i+1]!.upperBoundMinimumDistance]);
  i := i + 1;
 od;
 CX!.lowerBoundMinimumDistance := Minimum(K);;
 CX!.upperBoundMinimumDistance := Minimum(S);;

 # This can be displayed using Display(C) or History(C). This shows the
 # component codes that are used to construct the concatenated code
 CX!.history := [ Concatenation(String("Base codes: "), String(C)),
      Concatenation(String("Auxiliary codes: "), String(A)) ];

 return CX;
end);

#########################################################################################
##
#F    ConstructionXXCode( <C1>, <C2>, <C3>, <A1>, <A2> )  ... code from Construction XX
##
##
InstallMethod(ConstructionXXCode, "linear code constructed using Construction XX",
 true, [IsCode, IsCode, IsCode, IsCode, IsCode], 0,
function( C1, C2, C3, A1, A2 )
 #
 # Construction XX (see W.O. Alltop, ``A method for extending binary linear codes,''
 #                      IEEE Trans. Inform. Theory, vol. 30, pp. 871-872, 1984
 #                 )
 #
 # Consider a set of linear codes of the same length n, C1 [n, k_1, d_1], C2 [n, k_2, d_2]
 # and C3 [n, k_3, d_3] such that C1 contains C2, C1 contains C3 and C4 [n,k_4,d_4] is the
 # intersection code of C2 and C3. Given two auxiliary codes A1 [n_1, k_1-k-2, e_1] and
 # A2 [n_2, k_1-k_3, e_2], there exists a [n + n_1 + n_2, k_1, d] CXX code where
 # d = min{d_4, d_3 + e_1, d_2 + e_2, d_1 + e_1 + e_2}.
 #
 # The codewords of CXX can be partitioned into 3 sections ( v | a | b ) where v has length
 # n, a has length n_1 and b has length n_2. A codeword from Construction XX takes the form:
 #    ( v | 0...0 | 0...0 ) if v is a codeword of C4,
 #    ( v |  a_1  | 0...0 ) if v is a codeword of C3\C4,
 #    ( v | 0...0 |  a_2  ) if v is a codeword of C2\C4,
 #    ( v |  a_1  |  a_2  ) otherwise.
 #
 local i, q, p, a1, a2,
  K, L, U, G1, G2, G3, G4, C4, GA1, GA2, GXX, CXX, ZeroVec1, ZeroVec2;

 # Make sure all codes are linear
 if ( (IsLinearCode(C1) = false) or (IsLinearCode(C2) = false) or
  (IsLinearCode(C3) = false) or (IsLinearCode(A1) = false) or
      (IsLinearCode(A2) = false) ) then
  Error("Not all codes are linear\n");
 fi;

 # Make sure all codes have the same LeftActingDomain
 q:=LeftActingDomain(C1);;
 if ((LeftActingDomain(C2) <> q) or (LeftActingDomain(C3) <> q) or
--> --------------------

--> maximum size reached

--> --------------------

[ Verzeichnis aufwärts0.117unsichere Verbindung  ]