  
  [1X2 A First Tutorial in [5XGUAVA[1X[0X
  
  An  error-correcting  code  is  essentially  just a subset of the set of all
  possible messages of a given length over some finite "alphabet."
  
  In  algebraic  coding  theory,  the  "alphabet" is usually some finite field
  (very  often GF(2)) and frequently the error-correcting code is chosen to be
  a  vector  subspace  of the space of all row vectors of some fixed length n.
  Such  codes  are  known  as [13XLinear Codes[0m, but, however a code is defined the
  point  is  to  have  a collection of "codewords" that are said to be "in the
  code"  and  any  other word (row vectors that are [13Xnot[0m "in the code") will be
  assumed to be a codeword that has been mangled by the addition of noise.
  
  When  a  message  is  received  that is not a codeword, we ask ourselves the
  question "Which codeword is closest to this message I've received?" In other
  words  we  make  the  presumption  that  the  received message is actually a
  codeword  that has been changed in a relatively small number of positions --
  and [13Xwe put them back the way they were supposed to be![0m
  
  That  process  is  called  "decoding."  Developing codes that have efficient
  decoding  algorithms  is  one  of  the  central problems of algebraic coding
  theory.
  
  
  [1X2.1 Working with codewords[0X
  
  So let's play around a bit.
  
  Start [5XGAP[0m in a terminal window, then issue the command
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> LoadPackage("guava");[0X
  [4X------------------------------------------------------------------[0X
  
  [5XGUAVA[0m  can construct codewords in a variety of ways. One of the most typical
  cases  is  for  a  codeword to consist of binary digits. In that case we say
  that "the code is over GF(2)" and codewords can be constructed as follows:
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> c1:=Codeword("101010101");[0X
    [4X[ 1 0 1 0 1 0 1 0 1 ][0X
    [4Xgap> v:=Z(2)*[1,1,1,1,1,1,1,1,1];[0X
    [4X[ Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0 ][0X
    [4Xgap> c2:=Codeword(v);[0X
    [4X[ 1 1 1 1 1 1 1 1 1 ][0X
    [4Xgap> c3:=c1+c2;[0X
    [4X[ 0 1 0 1 0 1 0 1 0 ][0X
    [4Xgap> Weight(c1);[0X
    [4X5[0X
    [4Xgap> Weight(c2);[0X
    [4X9[0X
    [4Xgap> Weight(c3);[0X
    [4X4[0X
  [4X------------------------------------------------------------------[0X
  
  The  previous  excerpt  from  a  [5XGAP[0m  session  shows  that  codewords can be
  constructed  from  quoted  strings  or  from  vectors whose entries lie in a
  finite  field.  We  also  see  that codewords can be added together and that
  there  is  a function called [11XWeight[0m which (if it isn't obvious) tells us how
  many entries in a codeword are non-zero.
  
  The  [13XHamming  distance[0m  is used extensively in coding theory. It tells us in
  how  many  positions  two codewords differ. In [5XGUAVA[0m the Hamming distance is
  implemented by a function called [11XDistanceCodeword[0m.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> DistanceCodeword(c1, c2);[0X
    [4X4[0X
  [4X------------------------------------------------------------------[0X
  
  Note  that  the  Hamming distance between [10Xc1[0m and [10Xc2[0m happens to give the same
  value  as the weight of their sum. This is no coincidence and has to do with
  the curious fact that in GF(2) adding and subtracting are the same thing.
  
  A  codeword can also be constructed using a polynomial. Indeed, the internal
  representation of a codeword requires either a polynomial or a vector. There
  are  [5XGUAVA[0m functions that allow one to switch back and forth between the two
  representations.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> x:=Indeterminate(GF(2));[0X
    [4Xx_1[0X
    [4Xgap> c4:=Codeword(x^7+x^2+x+1);[0X
    [4Xx^7 + x^2 + x + 1[0X
    [4Xgap> VectorCodeword(c4);[0X
    [4X<an immutable GF2 vector of length 8>[0X
    [4Xgap> Display(last);[0X
    [4X[ Z(2)^0, Z(2)^0, Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0 ][0X
    [4Xgap> c5:=Codeword([1,0,0,0,0,0,1]);[0X
    [4X[ 1 0 0 0 0 0 1 ][0X
    [4Xgap> PolyCodeword(c5);[0X
    [4Xx_1^6+Z(2)^0[0X
  [4X------------------------------------------------------------------[0X
  
  
  [1X2.2 Calculations with codes[0X
  
  A  code is fundamentally just a collection of codewords. Sometimes a code is
  merely  a  [13Xset[0m  of  codewords.  Other  times a code will be the vector space
  generated by some small set of codewords.
  
  First let's build a code that is merely a set:
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> l:=["111000", "011100", "001110", "000111", "100011", "110001", "000000",$[0X
    [4X[ "111000", "011100", "001110", "000111", "100011", "110001", "000000", [0X
    [4X  "111111" ][0X
    [4Xgap> m:=Codeword(l,6,GF(2));    [0X
    [4X[ [ 1 1 1 0 0 0 ], [ 0 1 1 1 0 0 ], [ 0 0 1 1 1 0 ], [ 0 0 0 1 1 1 ], [0X
    [4X  [ 1 0 0 0 1 1 ], [ 1 1 0 0 0 1 ], [ 0 0 0 0 0 0 ], [ 1 1 1 1 1 1 ] ][0X
    [4Xgap> C1:=ElementsCode(m, GF(2));[0X
    [4Xa (6,8,1..6)2..3 user defined unrestricted code over GF(2)[0X
    [4Xgap> IsLinearCode(C1);[0X
    [4Xfalse[0X
    [4Xgap> WeightDistribution(C1);[0X
    [4X[ 1, 0, 0, 6, 0, 0, 1 ][0X
  [4X------------------------------------------------------------------[0X
  
  In  this  example  we first wrote out a list of strings, then converted them
  into codewords over GF(2). The call to [11XElementsCode[0m constructs a code from a
  list  of elements. It is possible that the set of codewords we used actually
  is  a  vector  space, but the call to [11XIsLinearCode[0m says no. Finally the last
  function  tells  us  that there are 6 codewords of weight 3, and one each of
  weights 0 and 6 in this code.
  
  A very useful feature of [5XGUAVA[0m is the ability to construct random codes:
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> C:= RandomLinearCode(12,5,GF(2));[0X
    [4Xa  [12,5,?] randomly generated code over GF(2)[0X
  [4X------------------------------------------------------------------[0X
  
  An  error-correcting  code's  properties  are  fairly well captured by three
  numbers which traditionally are referred to using the letters n, k and d. We
  ask  for  a  random code by specifying n (the wordlength), and k (the code's
  dimension) as well as the field which serves as the alphabet for the code.
  
  One  of  the  most salient features of a code (a feature that determines how
  good  it will be at correcting errors) is its minimum weight, d. This is the
  smallest  weight  of  any  nonzero word in the code. If we wish to correct m
  errors we will need to have a minimum weight of at least 2m+1.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> MinimumWeight(C);[0X
    [4X3[0X
  [4X------------------------------------------------------------------[0X
  
  This particular code would be capable of correcting single bit errors.
  
  Finally,  one  might be interested in the entire distribution of the weights
  of  the  words  in a code. The weight distribution is a vector that tells us
  how  many  words there are in a code with each possible weight between 0 and
  n.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> WeightDistribution(C);[0X
    [4X[ 1, 0, 0, 2, 3, 6, 7, 6, 4, 2, 1, 0, 0 ][0X
  [4X------------------------------------------------------------------[0X
  
