## Math 5410 Cyclic Codes II

### IV. Dimension, Generator and Parity-Check Matrices

We would now like to consider how the ideas we have previously discussed for linear codes are interpreted in this polynomial version of cyclic codes.

Theorem 6: If the generator polynomial g(x) of C has degree n-k then C is an (n,k)-cyclic code. If g(x) = a0 + a1x + a2x2 + ... + an-k xn-k then a generator matrix for C is the k x n matrix,

Proof: The vectors g(x), xg(x), x2g(x), ..., xk-1g(x) are linearly independent. If not, there would exist coefficients {bi} so that

b0g(x) + b1xg(x) + b2 x2 g(x) + ... + bk-1 xk-1 g(x) = 0,
(b0 + b1x + b2x2 + ... + bk-1 xk-1) g(x) = 0.

But this product has degree k - 1 + n - k = n - 1 < n, so it can not be = 0 mod (xn - 1) unless all the bi = 0.

Let c(x) be in C, then c(x) = b(x) g(x) and we may assume that b(x) has degree <= k - 1 (otherwise the product will have degree > n - 1 and we would reduce modulo (xn - 1) to get a b'(x) which satisfies this degree constraint). Thus, c(x) can be written as a linear combination of the xi g(x).

The set of {xi g(x) }, 0 <= i <= k - 1 is thus a basis for C and so this cyclic code has dimension k.

Now that we have a polynomial approach to describe a cyclic code C, we consider the related polynomial representation of the dual code Cperp of C. We shall see that Cperp is a cyclic code if C is cyclic.

Consider h(x) = (xn - 1)/g(x) where g(x) is the generator of C. If the deg g(x) = n - k, then deg h(x) = k and it is also monic, so h(x) generates a cyclic code C' of dimension n - k. Now consider c1(x) = a1(x)g(x) in C and c2(x) = a2(x)h(x) in C'. Then

c1(x) c2(x) = a1(x)g(x)a2(x)h(x) = a1(x)a2(x)f(x) = 0 (mod f(x)),

where f(x) = xn - 1. Therefore, using polynomial multiplication mod f(x), any codeword from C multiplies with any codeword from C' to give the polynomial 0. Does this imply that C' is the dual code of C? Unfortunately no, since the isomorphism that we set up does not preserve inner products. However, we now show that the codes C' and C are closely related - they are equivalent codes.

Consider two vectors

a = (a0 a1 ... an-1) in C
and
b = (b0 b1 ... bn-1) in C',

and the corresponding polynomial product

for some ci in F. The constant term in this product is

c0 = a0 b0 + a1bn-1 + a2 bn-2 + ... + an-1 b1,

since xn = 1 (mod f(x)). Now c0 can be written as the inner product

c0 = a b'

where b' is the vector obtained from b by cyclically shifting b one position to the left and then reversing the order of the components (i.e., (b0 bn-1 bn-2 ... b1)). Observe that multiplying the polynomial [sum from {i=0} to {n-1} ci xi] by xn-t results in ct being the constant term, and hence the constant term in the product a(x)(xn-t b(x)). Therefore,

ct = a b'

where b' is now the vector associated with xn-t b(x). In terms of b(x), b' is the vector obtained by cyclically shifting b t+1 positions to the left and then reversing the order of the components.

Example: Consider n = 3, and the vectors a = (a0 a1 a2) and b = (b0 b1 b2). Then modulo x3 - 1,

a(x)b(x) = (a0 + a1x + a2 x2)(b0 + b1x + b2 x2)
= (a0 b0 + a1b2 + a2 b1) + (a0 b1 + a1 b0 + a2 b2)x + (a0 b2 + a1 b1 + a2 b0)x2.

The coefficient of x2 is a(b2 b1 b0). This b vector is obtained from b by shifting 3 ( = 2 + 1) positions to the left (putting b back into its original order) and then reversing the order of the components from last to first. The b-vector in the x coefficient is obtained from b by shifting 2 ( = 1 + 1) to the left, obtaining (b2 b0 b1) and then reversing the components.

Now since a(x)b(x) = 0 mod (xn - 1), the coefficient of each power of x must be 0. From the discussion above, this implies that ac = 0 (i.e., a and c are orthogonal) whenever c is any cyclic shift of the vector obtained from b by reversing the components of b. Since h(x) generates C', {h(x), xh(x), ..., xn-k-1h(x) } is a basis for C' and G' = [h(x), xh(x), ..., xn-k-1h(x)]t is a generator matrix for C'. Now G' generates the code C' which has the same dimension n - k as C . Furthermore, taking b(x) in the above arguments to be h(x) itself, we see that the reverse of every vector in C' is orthogonal to every vector in C. It follows that if we reorder the columns of G' last to first, we obtain a matrix H which generates C , and hence is the parity-check matrix for C.

Example: Suppose we wish to construct a generator matrix and a parity-check matrix for a (7,4)- binary cyclic code. Since g(x) = 1 + x + x3 divides f(x) = x7 - 1, g(x) generates a (7,4) - cyclic code C. h(x) = f(x)/g(x) = 1 + x + x2 + x4 generates a (7,3)-cyclic code C'. A generator matrix for C is

A generator matrix for C' is

Writing the columns of G' last to first, a generator matrix for Cperp is

A simple check verifies that GHt = 0.

Since C' and Cperp can be obtained from each other by simply reversing the components in all vectors, C' and Cperp are equivalent codes. Recalling a definition that we have seen before,

Definition : Let h(x) = a0 + a1 x + ... + ak xk be a polynomial of degree k (ak not 0). Define the reciprocal polynomial hR (x) of h(x) by

Note that hR(x) = xk h(1/x), where k = deg h(x). With this we may summarize the preceding discussion with the following result.

Theorem 7 : Let g(x) be a monic divisor of f(x) = xn - 1 of degree n-k, and hence the generator for a cyclic (n,k)-code C. Let h(x) = f(x)/g(x). Then hR(x), the reciprocal polynomial of h(x), generates Cperp .

### V. Syndromes and Error Trapping

Let us first consider an alternate form for the generator matrix of a cyclic code of the form [R, Ik] when C is an (n,k)-cyclic code. Let g(x) be the generator polynomial for the code. Divide xn-k+i by g(x) for 0 <= i <= k-1. This gives

xn-k+i = qi(x)g(x) + ri(x)

where deg ri(x) < deg g(x) = n-k or ri(x) = 0. Then

xn-k+i - ri(x) = qi(x)g(x) in C

is a set of k linearly independent code words and the matrix whose rows are these codewords is a generator matrix of the required form.

Example: Consider the binary (7,4)-cyclic code generated by g(x) = 1 + x + x3. By the division algorithm we compute,

x3 = (1)(x3 + x + 1) + (1+ x)
x4 = (x)(x3 + x + 1) + (x + x2)
x5 = (x2 + 1)(x3 + x + 1) + (1 + x + x2)
x6 = (x3 + x + 1)(x3 + x + 1) + (1 + x2).

A generator matrix for this code is

```                    1 1 0 1 0 0 0                                         1 1 0
0 1 1 0 1 0 0                                         0 1 1
G =    1 1 1 0 0 1 0    =  [R I4]            where R  =      1 1 1
1 0 1 0 0 0 1                                         1 0 1   .
```
Notice that the rows of R are just the remainder polynomials.

The corresponding parity-check matrix for this generator is H = [In-k -Rt]. A reason for making this selection is that it affords a convenient polynomial interpretation for the syndrome of a vector.

Theorem 8 : Let r(x) and s(x) be the respective polynomial representations of a vector r and its syndrome s = Hrt. Then s(x) is the remainder polynomial when r(x) is divided by g(x).

Proof: Suppose r(x) = a0 + a1 x + ... + an-1 xn-1. Noting that column i, 0 <= i <= n-k-1, of H corresponds to the polynomial xi and column j, n-k <= j <= n-1, corresponds to rj-n+k(x), so that

where h(x) = an-k q0(x) + ... + an-1 qk-1(x). Thus r(x) = h(x)g(x) + s(x). Since deg ri(x) <= n-k-1, it follows that deg s(x) <= n-k-1. By the uniqueness of the quotient and remainder in the division algorithm for polynomials, we conclude that s(x) is the remainder when r(x) is divided by g(x).

Therefore the syndrome of a vector can be determined by polynomial division. Furthermore, the syndrome of a vector and its cyclic shift are closely related. Suppose

r(x) = q(x)g(x) + s(x),

where deg s(x) is at most n-k-1. By the above theorem s(x) is the syndrome of r(x). Now

xr(x) = xq(x)g(x) + xs(x).

If xs(x) has degree at most n-k-1, then again by the above theorem it is the syndrome of xr(x). Otherwise, the syndrome of xr(x) is the remainder when xs(x) is divided by g(x). In this case, let

Let the (monic) generator polynomial be,

Then

where deg (xs'(x) - sn-k-1 g'(x)) <= n - k - 1. Now by the uniqueness of the remainder in the division algorithm and the previous theorem, we see that the syndrome of xs(x) is xs(x) - sn-k-1 g(x). We summarize this as,

Theorem 9 : Let C be a cyclic (n,k)-code over F with generator polynomial g(x), and let r(x) be a polynomial with syndrome s(x) = s0 + s1 x + ... + sm xm. Then the syndrome of xr(x) is

1. xs(x) if deg s(x) < n-k-1, and
2. xs(x) - sn-k-1 g(x), if deg s(x) = n-k-1.
Example: Consider the previous example with g(x) = 1 + x + x3. From the generator matrix written there, we may form the parity check matrix,
```                                              1 0 0 1 0 1 1
H = [I3  -Rt]  =        0 1 0 1 1 1 0    .
0 0 1 0 1 1 1
```
Consider r = (1011011). The syndrome of r is Hrt = (001)t = s. Now,

r(x) = 1 + x2 + x3 + x5 + x6.

If we divide r(x) by g(x), we get

r(x) = (x3 + x2 + x + 1)g(x) + x2.

The remainder is, as expected, s.

Now let us compute the syndrome of a cyclic shift of r. Let w = (1101101) which corresponds to the polynomial xr(x). Hwt = (110)t. We can compute this syndrome using polynomial operations as follows. Since deg s(x) = 2 = n-k-1, the syndrome of xr(x) is

xs(x) - 1g(x) = x3 - (x3 + x + 1) = 1 + x.

The preceding observations lead us to an interesting method of decoding certain error patterns in cyclic codes. The technique is sometimes referred to as error trapping.

Suppose C is an (n,k)-code with minimum distance d = 2t + 1, and parity-check matrix H = [In-k A]. Let c be a codeword and e an error pattern of weight at most t. If r = c + e is received, then the syndrome of r is

s = H rt = H (c + e)t = H et.

Let e* = (st, 0), where 0 is the k-tuple of all 0's. Then H e*t = s, and e* and e have the same syndrome, so are in the same coset of C. Now suppose wt(s) <= t. Then wt(e*)<= t and it follows that e = e* since a coset can contain at most one vector of weight less than or equal to t. Hence, the error is known to be e = (st,0) in this case.

Now suppose C is cyclic with generating polynomial g(x). Let e be an error pattern of weight at most t with a cyclic run of at least k 0's. Then there is some i, 0 <= i <= n-1, such that a cyclic shift of e through i positions is a vector whose non-zero components all lie within the first n-k components. For this i, wt(si(x)) <= t, where si(x) is the syndrome of xi e(x) mod (xn - 1). If we compute si(x) as the remainder of xi r(x) divided by g(x), then when wt(si(x)) <= t, for this i by the above argument xi e(x) = (si,0). Thus e(x) = xn-i(si,0). This gives rise to the following algorithm (stated for the binary case, but easily modifiable for the q-ary case):

1. Compute the syndrome s0(x) of r(x) from the division algorithm.
2. Set i = 0.
3. If wt(si(x)) <= t, then set e(x) = xn-i(si,0), and decode to r(x) - e(x).
4. Set i = i + 1.
5. If i = n then stop; the error pattern is not trappable.
6. If deg si-1(x) < n-k-1, then set si(x) = xsi-1(x); otherwise si(x) = xsi-1(x) - g(x).
7. Go to (3).
Example: g(x) = 1 + x2 + x3 generates a binary (7,4)-cyclic code having minimum distance 3 (and so is 1-error correcting). Consider the codeword 1 + x + x5 = (1 + x + x2) g(x), if upon transmission r(x) = 1 + x + x5 + x6 is received we would decode as follows. Divide r(x) by g(x) to find the syndrome,

r(x) = (x3 + 1)g(x) + (x + x2),

so s(x) = x + x2. Since the weight of s(x) is > 1 (= t), we compute the syndrome s1(x) of xr(x). As the degree of s(x) = 2 = n - k - 1, we mutiply s(x) by x and subtract g(x) to get s1(x) = 1. As this has weight 1, we obtain the error pattern

e(x) = x7-1(s1,0) = x6(1000000) = x6.

Since for n = 7 all error patterns of weight 1 have a cyclic run of six 0's and 6 > k = 4, this technique will correct all single errors.

Example: g(x) = 1 + x4 + x6 + x7 + x8 generates a binary (15,7)-cyclic code. If the minimum distance of this code is 5, then t = 2. Any (at most) weight 2 error pattern must contain a run of at least 7 0's and so can be trapped. If a received 15-tuple is

r = (1100 1110 1100 010)

we calculate,

r(x) = (x + x2 + x4 + x5)g(x) + (1 + x2 + x5 + x7).

We then compute the syndrome si(x) of xi r(x) until wt(si(x)) <= 2.

```
i              si(x)

0             10100101
1             11011001
2             11100111
3             11111000
4             01111100
5             00111110
6             00011111
7             10000100
```
Thus the error pattern is

e = x15-7(s7,0) = x8(100001000000000) = (0000 0000 1000 010),

and we decode r(x) to r - e = (1100 1110 0100 000).