ProblemSet 4 -- Finite field projective spaces **Solutions**

Posted on 2024-02-23 by George McNinch
  1. Find the irreducible factors of the polynomial T91 in F7[T].

    (You should include proofs that the factors you describe are irreducible).

    Note that the multiplicative group F7× has order 6 and hence contains an element of order 3; in fact, 2 has order 3 since 23=81(mod7).

    Now, F72× has order 491=48 which is not divisible by 9. And F73× has order 731(2)3190(mod9). So F73× has an element of order 9.

    Consider the polynomial T32. Any root α of this polynomial satisfies α3=2 and α9=1; this shows that the multiplicative order of α is 9.

    In particular, F7 contains no roots of f(T)=T32; since f(T) has degree 3, it is irreducible over F7.

    If α is a root of f(T), then α7 and α72=α4 are also roots (note that 72(2)2=4(mod9)). Thus f(T)=(Tα)(Tα7)(Tα4) and f(T)T91.

    Notice that F73 is a splitting field for f(T) over F7.

    Note that 22=4 is also an element of F7× of order 3. Arguing as before, any root of T34 is an element of multiplicative order 9.

    On the other hand, since gcd(2,9)=1, α2F73 is also an element of order 9.

    Moreover, the roots of its minimal polynomial g(T) have the form α2, α27=α5 (since 145(mod9)), and α272=α57=α3 (since 2728(mod9).

    Thus g(T)=(Tα2)(Tα5)(Tα8).

    Now, notice that (α2)3=(α3)2=22=4F7. Thus the minimal polynomial g(T) of α2 divides T34. It follows that g(T)=T34=(Tα2)(Tα5)(Tα8).

    Now, g(T)T91 and since gcd(f(T),g(T))=1 we see that f(T)g(T)T91. Thus T91=f(T)g(T)(T1)(T2)(T4).

  2. Let 0<k,mN, put n=mk, and consider the subspace CFqn defined by C={(v,v,,v)vFqk}Fqn. Find the minimal distance d of this code.

    For example, if n=6, k=3 and m=2 then C={(a1,a2,a3,a1,a2,a3)aiFq}Fq6.

    (Corrected)

    If v=(v,v,,v)C for vFqn, note that weight(v)=mweight(v).

    In particular, for a non-zero vector we see that weight(v)m.

    On the other hand, a standard basis vector v=eiFqn has weight 1, so if w=(ei,ei,,ei), then weight(w)=m.

    Thus min{weight(v)0vC}=m.

    For a linear code, the minimal distance is simply the minimal weight of a non-zero vector; thus the minimal distance of C is m.

  3. By an [n,k,d]q-system we mean a pair (V,P), where V is a finite dimensional vector space over Fq and P is an ordered finite family P=(P1,P2,,Pn) of points in V (in general, points of P need not be distinct – you should view P as a list of points which may contain repetitions) such that P spans V as a vector space. Evidently |P|dimV.

    The parameters [n,k,d] are defined by n=|P|,k=dimV,d=nmaxH|PH|. where the maximum defining d is taken over all linear hyperplanes HV and where points are counted with their multiplicity – i.e. |PH|=|{iPiH}|.

    Gjven a [n,k,d]q-system (V,P), let V denote the dual space to V and consider the linear mapping Φ:VFqn defined by Φ(ψ)=(ψ(P1),,ψ(Pn)).

    1. Show that Φ is injective.

      Φ is a linear mapping, so we just need to show that kerΦ={0}.

      Suppose that ψV and Φ(ψ)=0. This means that ψ(Pj)=0 for 1jn. Since ψ is linear, it follows that ψ vanishes at any linear combination of the vectors {Pj}.

      Since P spans V by assumption, it follows that ψ=0. This proves that Φ is injective.

    2. Write C=Φ(V) for the image of Φ, so that C is an [n,k]q-code. Show that the minimal distance of the code C is given by d.

      Write d for the minimal weight of C; we must argue that d=d=nmaxH|PH|.

      Let v=Φ(ψ)C be a non-zero vector. We have weight(v)=|{jψ(Pj)0}|.

      Write H=kerψ and note that |PH|=|{jψ(Pj)=0}|.

      Thus ()weight(v)=n|PH|.

      In maxH|PH| the hyperplanes H are precisely the kernels H=kerψ of functionals 0ψV. Thus () shows that minv=Φ(ψ)0weight(v)=nmaxH=kerψ,ψ0|PH|; it follows that d=d.

    3. Conversely, let CFqn be an [n,k,d]q-code, and put V=C. Let e1,,en(Fqn) be the dual basis to the standard basis. The restriction of ei to the subspace C determines an element Pi of C=V. Write P=(P1,P2,,Pn) for the resulting list of vectors in V..

      Prove that the minimum distance d of the code C satisfies d=nmaxH|PH|.

      We have V=(C)=C; the mapping Φ:V=CFqn is just the given inclusion. Indeed, let x=(x1,x2,,xn)CFqn. The mapping Φ:VFqn is given by Φ(x)=(e1(x),,en(x))=(x1,,xn).

      Now the equality d=nmaxH|PH| follows from the result of part (b).

  4. Let C be the linear code over F5 generated by the matrix G=(100112010121001211).

    1. Find a check matrix H for C.

      k = GF(5)
      V = VectorSpace(k,6)
      
      C =V.subspace([ V([1,0,0,1,1,2]),
                      V([0,1,0,1,2,1]),
                      V([0,0,1,2,1,1])])
      
      # generator matrix, in standard form
      G = MatrixSpace(k,3,6).matrix(C.basis())
      G
      => 
      [1 0 0 1 1 2]
      [0 1 0 1 2 1]
      [0 0 1 2 1 1]
      
      A = MatrixSpace(k,3,3).matrix([b[3:6] for b in G])
      
      # construct the check matrix, as a block matrix
      H = block_matrix([[-A.transpose(),
                         MatrixSpace(k,3,3).one()]],
                     subdivide=False)        
      
      H
      =>
      [4 4 3 1 0 0]
      [4 3 4 0 1 0]
      [3 4 4 0 0 1]
      
      ## verification:
      H * G.T
      =>
      [0 0 0]
      [0 0 0]
      [0 0 0]
    2. Find the minimum distance of C.

      The minimal distance of C is 4.

      We check the weight of a vector using the following function:

      def weight(v):
          r = [x for x in v if x != 0]
          return len(r)

      Now, we can just find the minimal weight of the non-zero vectors of V, as follows:

      min([ weight(v) for v in C if v != 0])
      =>
      4

      Alternatively, you can investigate the columns of the check matrix H.

      W = VectorSpace(k,3)  # column space
      
      # return the ith column of the 3xm matrix M
      def col(M,i):
          return W([ b[i] for b in M ])
      
      # check whether the columns of the 3xm matrix M 
      # specified by the list ll of indices are lin indep
      def cols_lin_indep(M,ll):
          vecs =  [ col(M,i) for i in ll ]
      
         # the method `linear_dependence` returns a list 
         # of *linear relations*
      
         # so we return True if `W.linear_dependence(vecs)` is 
         # the empty list
      
          return W.linear_dependence(vecs) == []
      
      # check whether all collections of r columns of the 
      # 3xm matrix M are linearly independent
      def check(M,r):
          # get the number of columns of M.
          l = len(list(M.T))
      
         # get all lists of r-element subses of the numbers 0,...,l-1
          al = map(list,Subsets(range(l),r))
      
         # return True iff `cols_lin_indep(M,ll)` is true for every 
         # r-element subset ll of range(l)
          return all([ cols_lin_indep(M,ll) for ll in al])
      
      check(H,3)
      =>
      True
      
      check(H,4)
      =>
      False

      This shows that every collection of 3 columns of H is linearly independent, while there is some collection of 4 columns of H that is linearly dependent; thus d=4.

    3. Decode the received vectors (0,2,3,4,3,2) and (0,1,2,0,4,0) using syndrome decoding.

      The minimal distance of the code C is 4, so we should expect to correct (41)/2=3/2=1 error.

      We first make the lookup table

      lookup = { tuple(H*v):v for v in V if weight(v) <= 1 }
      lookup
      =>
      {(0, 0, 0): (0, 0, 0, 0, 0, 0),
       (4, 4, 3): (1, 0, 0, 0, 0, 0),
       (3, 3, 1): (2, 0, 0, 0, 0, 0),
       (2, 2, 4): (3, 0, 0, 0, 0, 0),
       (1, 1, 2): (4, 0, 0, 0, 0, 0),
       (4, 3, 4): (0, 1, 0, 0, 0, 0),
       (3, 1, 3): (0, 2, 0, 0, 0, 0),
       (2, 4, 2): (0, 3, 0, 0, 0, 0),
       (1, 2, 1): (0, 4, 0, 0, 0, 0),
       (3, 4, 4): (0, 0, 1, 0, 0, 0),
       (1, 3, 3): (0, 0, 2, 0, 0, 0),
       (4, 2, 2): (0, 0, 3, 0, 0, 0),
       (2, 1, 1): (0, 0, 4, 0, 0, 0),
       (1, 0, 0): (0, 0, 0, 1, 0, 0),
       (2, 0, 0): (0, 0, 0, 2, 0, 0),
       (3, 0, 0): (0, 0, 0, 3, 0, 0),
       (4, 0, 0): (0, 0, 0, 4, 0, 0),
       (0, 1, 0): (0, 0, 0, 0, 1, 0),
       (0, 2, 0): (0, 0, 0, 0, 2, 0),
       (0, 3, 0): (0, 0, 0, 0, 3, 0),
       (0, 4, 0): (0, 0, 0, 0, 4, 0),
       (0, 0, 1): (0, 0, 0, 0, 0, 1),
       (0, 0, 2): (0, 0, 0, 0, 0, 2),
       (0, 0, 3): (0, 0, 0, 0, 0, 3),
       (0, 0, 4): (0, 0, 0, 0, 0, 4)} 

      Now we can decode using the lookup table

      def decode(v):
        return v-lookup[tuple(H*v)]
      
      [ (decode(v), decode(v) in C) for v in [ V([0,2,3,4,3,2]),
                                               V([0,1,2,0,4,0])]]
      =>
      [((1, 2, 3, 4, 3, 2), True), ((0, 1, 2, 0, 4, 3), True)]