Path: blob/master/src/sage/coding/code_constructions.py
8815 views
r"""1Linear code constructions23This file contains constructions of error-correcting codes which are4pure Python/Sage and not obtained from wrapping GUAVA functions.5The GUAVA wrappers are in guava.py.67All codes available here can be accessed through the ``codes`` object::89sage: codes.HammingCode(3,GF(2))10Linear code of length 7, dimension 4 over Finite Field of size 21112Let `F` be a finite field with `q` elements.13Here's a constructive definition of a cyclic code of length14`n`.1516#. Pick a monic polynomial `g(x)\in F[x]` dividing17`x^n-1`. This is called the generating polynomial of the18code.1920#. For each polynomial `p(x)\in F[x]`, compute21`p(x)g(x)\ ({\rm mod}\ x^n-1)`. Denote the answer by22`c_0+c_1x+...+c_{n-1}x^{n-1}`.2324#. `{\bf c} =(c_0,c_1,...,c_{n-1})` is a codeword in25`C`. Every codeword in `C` arises in this way26(from some `p(x)`).2728The polynomial notation for the code is to call29`c_0+c_1x+...+c_{n-1}x^{n-1}` the codeword (instead of30`(c_0,c_1,...,c_{n-1})`). The polynomial31`h(x)=(x^n-1)/g(x)` is called the check polynomial of32`C`.3334Let `n` be a positive integer relatively prime to35`q` and let `\alpha` be a primitive36`n`-th root of unity. Each generator polynomial `g`37of a cyclic code `C` of length `n` has a38factorization of the form394041.. math::4243g(x) = (x - \alpha^{k_1})...(x - \alpha^{k_r}),444546where `\{k_1,...,k_r\} \subset \{0,...,n-1\}`. The47numbers `\alpha^{k_i}`, `1 \leq i \leq r`, are48called the zeros of the code `C`. Many families of cyclic49codes (such as BCH codes and the quadratic residue codes) are50defined using properties of the zeros of `C`.5152- BCHCode - A 'Bose-Chaudhuri-Hockenghem code' (or BCH code for short)53is the largest possible cyclic code of length n over field F=GF(q),54whose generator polynomial has zeros (which contain the set)55`Z = \{a^i\ |\ i \in C_b\cup ... C_{b+delta-2}\}`, where56`a` is a primitive `n^{th}` root of unity in the57splitting field `GF(q^m)`, `b` is an integer58`0\leq b\leq n-delta+1` and `m` is the multiplicative59order of `q` modulo `n`. The default here is `b=0`60(unlike Guava, which has default `b=1`). Here `C_k` are61the cyclotomic codes (see ``cyclotomic_cosets``).6263- BinaryGolayCode, ExtendedBinaryGolayCode, TernaryGolayCode,64ExtendedTernaryGolayCode the well-known"extremal" Golay codes,65http://en.wikipedia.org/wiki/Golay_code6667- cyclic codes - CyclicCodeFromGeneratingPolynomial (= CyclicCode),68CyclicCodeFromCheckPolynomial,69http://en.wikipedia.org/wiki/Cyclic_code7071- DuadicCodeEvenPair, DuadicCodeOddPair: Constructs the "even72(resp. odd) pair" of duadic codes associated to the "splitting" S1,73S2 of n. This is a special type of cyclic code whose generator is74determined by S1, S2. See chapter 6 in [HP]_.7576- HammingCode - the well-known Hamming code,77http://en.wikipedia.org/wiki/Hamming_code7879- LinearCodeFromCheckMatrix - for specifying the code using the80check matrix instead of the generator matrix.8182- QuadraticResidueCodeEvenPair, QuadraticResidueCodeOddPair: Quadratic83residue codes of a given odd prime length and base ring either don't84exist at all or occur as 4-tuples - a pair of85"odd-like" codes and a pair of "even-like" codes. If n 2 is prime86then (Theorem 6.6.2 in [HP]_) a QR code exists over GF(q) iff q is a87quadratic residue mod n. Here they are constructed as"even-like"88duadic codes associated the splitting (Q,N) mod n, where Q is the89set of non-zero quadratic residues and N is the non-residues.90QuadraticResidueCode (a special case) and91ExtendedQuadraticResidueCode are included as well.9293- RandomLinearCode - Repeatedly applies Sage's random_element applied94to the ambient MatrixSpace of the generator matrix until a full rank95matrix is found.9697- ReedSolomonCode - Given a finite field `F` of order `q`,98let `n` and `k` be chosen such that99`1 \leq k \leq n \leq q`.100Pick `n` distinct elements of `F`, denoted101`\{ x_1, x_2, ... , x_n \}`. Then, the codewords are obtained102by evaluating every polynomial in `F[x]` of degree less than103`k` at each `x_i`.104105- ToricCode - Let `P` denote a list of lattice points in106`\ZZ^d` and let `T` denote a listing of all107points in `(F^x )^d`. Put `n=|T|` and let `k`108denote the dimension of the vector space of functions109`V = \mathrm{Span} \{x^e \ |\ e \in P\}`.110The associated toric code `C` is111the evaluation code which is the image of the evaluation map112`eval_T : V \rightarrow F^n`, where `x^e` is the113multi-index notation.114115- WalshCode - a binary linear `[2^m,m,2^{m-1}]` code116related to Hadamard matrices.117http://en.wikipedia.org/wiki/Walsh_code118119REFERENCES:120121.. [HP] W. C. Huffman, V. Pless, Fundamentals of Error-Correcting122Codes, Cambridge Univ. Press, 2003.123124AUTHOR:125126- David Joyner (2007-05): initial version127128- " (2008-02): added cyclic codes, Hamming codes129130- " (2008-03): added BCH code, LinearCodeFromCheckmatrix, ReedSolomonCode, WalshCode,131DuadicCodeEvenPair, DuadicCodeOddPair, QR codes (even and odd)132133- " (2008-09) fix for bug in BCHCode reported by F. Voloch134135- " (2008-10) small docstring changes to WalshCode and walsh_matrix136137Functions138---------139140"""141############################################################################142## Copyright David Joyner, 2007. [email protected].143## This is released under the GPL, version 2 or later (www.fsf.org).144#############################################################################145146147from sage.matrix.matrix_space import MatrixSpace148from sage.matrix.constructor import matrix149from sage.rings.finite_rings.constructor import FiniteField as GF150from sage.groups.perm_gps.permgroup_named import SymmetricGroup151from sage.misc.misc import prod152from linear_code import LinearCodeFromVectorSpace, LinearCode153from sage.modules.free_module import span154from sage.schemes.projective.projective_space import ProjectiveSpace155from sage.structure.sequence import Sequence156from sage.rings.arith import GCD,LCM,divisors,quadratic_residues157from sage.rings.finite_rings.integer_mod_ring import IntegerModRing158from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing159from sage.rings.integer import Integer160from sage.sets.set import Set161from sage.rings.finite_rings.integer_mod import Mod162163############### utility functions ################164165166def cyclotomic_cosets(q, n, t = None):167r"""168INPUT: q,n,t positive integers (or t=None) Some type-checking of169inputs is performed.170171OUTPUT: q-cyclotomic cosets mod n (or, if t is not None, the q-cyclotomic172coset mod n containing t)173174Let q, n be relatively print positive integers and let175`A = q^{ZZ}`. The group A acts on ZZ/nZZ by multiplication.176The orbits of this action are "cyclotomic cosets", or more177precisely "q-cyclotomic cosets mod n". Sometimes the smallest178element of the coset is called the "coset leader". The algorithm179will always return the cosets as sorted lists of lists, so the180coset leader will always be the first element in the list.181182These cosets arise in the theory of duadic codes and minimal183polynomials of finite fields. Fix a primitive element `z`184of `GF(q^k)`. The minimal polynomial of `z^s` over185`GF(q)` is given by186187.. math::188189M_s(x) = \prod_{i \in C_s} (x-z^i),190191192where `C_s` is the q-cyclotomic coset mod n containing s,193`n = q^k - 1`.194195EXAMPLES::196197sage: cyclotomic_cosets(2,11)198[[0], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]199sage: cyclotomic_cosets(2,15)200[[0], [1, 2, 4, 8], [3, 6, 9, 12], [5, 10], [7, 11, 13, 14]]201sage: cyclotomic_cosets(2,15,5)202[5, 10]203sage: cyclotomic_cosets(3,16)204[[0], [1, 3, 9, 11], [2, 6], [4, 12], [5, 7, 13, 15], [8], [10, 14]]205sage: F.<z> = GF(2^4, "z")206sage: P.<x> = PolynomialRing(F,"x")207sage: a = z^5208sage: a.minimal_polynomial()209x^2 + x + 1210sage: prod([x-z^i for i in [5, 10]])211x^2 + x + 1212sage: cyclotomic_cosets(3,2,0)213[0]214sage: cyclotomic_cosets(3,2,1)215[1]216sage: cyclotomic_cosets(3,2,2)217[0]218219This last output looks strange but is correct, since the elements of220the cosets are in ZZ/nZZ and 2 = 0 in ZZ/2ZZ.221"""222from sage.misc.misc import srange223if t is not None and not isinstance(t, Integer):224raise TypeError, "Optional input %s must None or an integer."%t225if q<2 or n<2:226raise TypeError, "Inputs %s and %s must be > 1."%(q,n)227if GCD(q,n) != 1:228raise TypeError, "Inputs %s and %s must be relative prime."%(q,n)229if t is not None and isinstance(t, Integer):230S = Set([t*q**i%n for i in srange(n)])231L = list(S)232L.sort()233return L234ccs = Set([])235ccs_list = [[0]]236for s in range(1,n):237if not(s in ccs):238S = Set([s*q**i%n for i in srange(n)])239L = list(S)240L.sort()241ccs = ccs.union(S)242ccs_list.append(L)243return ccs_list244245def is_a_splitting(S1,S2,n):246"""247INPUT: S1, S2 are disjoint sublists partitioning [1, 2, ..., n-1]248n1 is an integer249250OUTPUT: a, b where a is True or False, depending on whether S1, S2251form a "splitting" of n (ie, if there is a b1 such that b\*S1=S2252(point-wise multiplication mod n), and b is a splitting (if a =253True) or 0 (if a = False)254255Splittings are useful for computing idempotents in the quotient256ring `Q = GF(q)[x]/(x^n-1)`. For257258EXAMPLES::259260sage: from sage.coding.code_constructions import is_a_splitting261sage: n = 11; q = 3262sage: C = cyclotomic_cosets(q,n); C263[[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]]264sage: S1 = C[1]265sage: S2 = C[2]266sage: is_a_splitting(S1,S2,11)267(True, 2)268sage: F = GF(q)269sage: P.<x> = PolynomialRing(F,"x")270sage: I = Ideal(P,[x^n-1])271sage: Q.<x> = QuotientRing(P,I)272sage: i1 = -sum([x^i for i in S1]); i12732*x^9 + 2*x^5 + 2*x^4 + 2*x^3 + 2*x274sage: i2 = -sum([x^i for i in S2]); i22752*x^10 + 2*x^8 + 2*x^7 + 2*x^6 + 2*x^2276sage: i1^2 == i1277True278sage: i2^2 == i2279True280sage: (1-i1)^2 == 1-i1281True282sage: (1-i2)^2 == 1-i2283True284285We return to dealing with polynomials (rather than elements of286quotient rings), so we can construct cyclic codes::287288sage: P.<x> = PolynomialRing(F,"x")289sage: i1 = -sum([x^i for i in S1])290sage: i2 = -sum([x^i for i in S2])291sage: i1_sqrd = (i1^2).quo_rem(x^n-1)[1]292sage: i1_sqrd == i1293True294sage: i2_sqrd = (i2^2).quo_rem(x^n-1)[1]295sage: i2_sqrd == i2296True297sage: C1 = codes.CyclicCodeFromGeneratingPolynomial(n,i1)298sage: C2 = codes.CyclicCodeFromGeneratingPolynomial(n,1-i2)299sage: C1.dual_code() == C2300True301302This is a special case of Theorem 6.4.3 in [HP]_.303"""304if Set(S1).union(Set(S2)) != Set(range(1,n)):305raise TypeError, "Lists must partition [1,2,...,n-1]."306if n<3:307raise TypeError, "Input %s must be > 2."%n308for b in range(2,n):309SS1 = Set([b*x%n for x in S1])310SS2 = Set([b*x%n for x in S2])311if SS1 == Set(S2) and SS2 == Set(S1):312return True, b313return False, 0314315316def lift2smallest_field(a):317"""318INPUT: a is an element of a finite field GF(q)319320OUTPUT: the element b of the smallest subfield F of GF(q) for321which F(b)=a.322323EXAMPLES::324325sage: from sage.coding.code_constructions import lift2smallest_field326sage: FF.<z> = GF(3^4,"z")327sage: a = z^10328sage: lift2smallest_field(a)329(2*z + 1, Finite Field in z of size 3^2)330sage: a = z^40331sage: lift2smallest_field(a)332(2, Finite Field of size 3)333334AUTHORS:335336- John Cremona337"""338FF = a.parent()339k = FF.degree()340if k == 1:341return a, FF342pol = a.minimal_polynomial()343d = pol.degree()344if d == k:345return a, FF346p = FF.characteristic()347F = GF(p**d,"z")348b = pol.roots(F,multiplicities=False)[0]349return b, F350351def lift2smallest_field2(a):352"""353INPUT: a is an element of a finite field GF(q) OUTPUT: the element354b of the smallest subfield F of GF(q) for which F(b)=a.355356EXAMPLES::357358sage: from sage.coding.code_constructions import lift2smallest_field2359sage: FF.<z> = GF(3^4,"z")360sage: a = z^40361sage: lift2smallest_field2(a)362(2, Finite Field of size 3)363sage: FF.<z> = GF(2^4,"z")364sage: a = z^15365sage: lift2smallest_field2(a)366(1, Finite Field of size 2)367368.. warning::369370Since coercion (the FF(b) step) has a bug in it, this371*only works* in the case when you *know* F is a prime field.372373AUTHORS:374375- David Joyner376"""377FF = a.parent()378q = FF.order()379if q.is_prime():380return a,FF381p = q.factor()[0][0]382k = q.factor()[0][1]383for d in divisors(k):384F = GF(p**d,"zz")385for b in F:386if FF(b) == a:387return b, F388389390def permutation_action(g,v):391"""392Returns permutation of rows g\*v. Works on lists, matrices,393sequences and vectors (by permuting coordinates). The code requires394switching from i to i+1 (and back again) since the SymmetricGroup395is, by convention, the symmetric group on the "letters" 1, 2, ...,396n (not 0, 1, ..., n-1).397398EXAMPLES::399400sage: V = VectorSpace(GF(3),5)401sage: v = V([0,1,2,0,1])402sage: G = SymmetricGroup(5)403sage: g = G([(1,2,3)])404sage: permutation_action(g,v)405(1, 2, 0, 0, 1)406sage: g = G([()])407sage: permutation_action(g,v)408(0, 1, 2, 0, 1)409sage: g = G([(1,2,3,4,5)])410sage: permutation_action(g,v)411(1, 2, 0, 1, 0)412sage: L = Sequence([1,2,3,4,5])413sage: permutation_action(g,L)414[2, 3, 4, 5, 1]415sage: MS = MatrixSpace(GF(3),3,7)416sage: A = MS([[1,0,0,0,1,1,0],[0,1,0,1,0,1,0],[0,0,0,0,0,0,1]])417sage: S5 = SymmetricGroup(5)418sage: g = S5([(1,2,3)])419sage: A420[1 0 0 0 1 1 0]421[0 1 0 1 0 1 0]422[0 0 0 0 0 0 1]423sage: permutation_action(g,A)424[0 1 0 1 0 1 0]425[0 0 0 0 0 0 1]426[1 0 0 0 1 1 0]427428It also works on lists and is a "left action"::429430sage: v = [0,1,2,0,1]431sage: G = SymmetricGroup(5)432sage: g = G([(1,2,3)])433sage: gv = permutation_action(g,v); gv434[1, 2, 0, 0, 1]435sage: permutation_action(g,v) == g(v)436True437sage: h = G([(3,4)])438sage: gv = permutation_action(g,v)439sage: hgv = permutation_action(h,gv)440sage: hgv == permutation_action(h*g,v)441True442443AUTHORS:444445- David Joyner, licensed under the GPL v2 or greater.446"""447v_type_list = False448if type(v) == list:449v_type_list = True450v = Sequence(v)451V = v.parent()452n = len(list(v))453gv = []454for i in range(n):455gv.append(v[g(i+1)-1])456if v_type_list:457return gv458return V(gv)459460def walsh_matrix(m0):461"""462This is the generator matrix of a Walsh code. The matrix of463codewords correspond to a Hadamard matrix.464465EXAMPLES::466467sage: walsh_matrix(2)468[0 0 1 1]469[0 1 0 1]470sage: walsh_matrix(3)471[0 0 0 0 1 1 1 1]472[0 0 1 1 0 0 1 1]473[0 1 0 1 0 1 0 1]474sage: C = LinearCode(walsh_matrix(4)); C475Linear code of length 16, dimension 4 over Finite Field of size 2476sage: C.spectrum()477[1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0]478479This last code has minimum distance 8.480481REFERENCES:482483- http://en.wikipedia.org/wiki/Hadamard_matrix484"""485m = int(m0)486if m == 1:487return matrix(GF(2), 1, 2, [ 0, 1])488if m > 1:489row2 = [x.list() for x in walsh_matrix(m-1).augment(walsh_matrix(m-1)).rows()]490return matrix(GF(2), m, 2**m, [[0]*2**(m-1) + [1]*2**(m-1)] + row2)491raise ValueError, "%s must be an integer > 0."%m0492493494##################### main constructions #####################495496497498def BCHCode(n,delta,F,b=0):499r"""500A 'Bose-Chaudhuri-Hockenghem code' (or BCH code for short) is the501largest possible cyclic code of length n over field F=GF(q), whose502generator polynomial has zeros (which contain the set)503`Z = \{a^{b},a^{b+1}, ..., a^{b+delta-2}\}`, where a is a504primitive `n^{th}` root of unity in the splitting field505`GF(q^m)`, b is an integer `0\leq b\leq n-delta+1`506and m is the multiplicative order of q modulo n. (The integers507`b,...,b+delta-2` typically lie in the range508`1,...,n-1`.) The integer `delta \geq 1` is called509the "designed distance". The length n of the code and the size q of510the base field must be relatively prime. The generator polynomial511is equal to the least common multiple of the minimal polynomials of512the elements of the set `Z` above.513514Special cases are b=1 (resulting codes are called 'narrow-sense'515BCH codes), and `n=q^m-1` (known as 'primitive' BCH516codes).517518It may happen that several values of delta give rise to the same519BCH code. The largest one is called the Bose distance of the code.520The true minimum distance, d, of the code is greater than or equal521to the Bose distance, so `d\geq delta`.522523EXAMPLES::524525sage: FF.<a> = GF(3^2,"a")526sage: x = PolynomialRing(FF,"x").gen()527sage: L = [b.minpoly() for b in [a,a^2,a^3]]; g = LCM(L)528sage: f = x^(8)-1529sage: g.divides(f)530True531sage: C = codes.CyclicCode(8,g); C532Linear code of length 8, dimension 4 over Finite Field of size 3533sage: C.minimum_distance()5344535sage: C = codes.BCHCode(8,3,GF(3),1); C536Linear code of length 8, dimension 4 over Finite Field of size 3537sage: C.minimum_distance()5384539sage: C = codes.BCHCode(8,3,GF(3)); C540Linear code of length 8, dimension 5 over Finite Field of size 3541sage: C.minimum_distance()5423543sage: C = codes.BCHCode(26, 5, GF(5), b=1); C544Linear code of length 26, dimension 10 over Finite Field of size 5545546"""547from sage.misc.misc import srange548q = F.order()549R = IntegerModRing(n)550m = R(q).multiplicative_order()551FF = GF(q**m,"z")552z = FF.gen()553e = z.multiplicative_order()/n554a = z**e # order n555P = PolynomialRing(F,"x")556x = P.gen()557cosets = Set([])558for i in srange(b,b+delta-1):559cosets = cosets.union(Set(cyclotomic_cosets(q, n, i)))560L0 = [a**j for j in cosets]561L1 = [P(ai.minpoly()) for ai in L0]562g = P(LCM(L1))563#print cosets, "\n", g, "\n", (x**n-1).factor(), "\n", L1, "\n", g.divides(x**n-1)564if not(g.divides(x**n-1)):565raise ValueError, "BCH codes does not exist with the given input."566return CyclicCodeFromGeneratingPolynomial(n,g)567568569def BinaryGolayCode():570r"""571BinaryGolayCode() returns a binary Golay code. This is a perfect572[23,12,7] code. It is also (equivalent to) a cyclic code, with573generator polynomial574`g(x)=1+x^2+x^4+x^5+x^6+x^{10}+x^{11}`. Extending it yields575the extended Golay code (see ExtendedBinaryGolayCode).576577EXAMPLE::578579sage: C = codes.BinaryGolayCode()580sage: C581Linear code of length 23, dimension 12 over Finite Field of size 2582sage: C.minimum_distance()5837584sage: C.minimum_distance(algorithm='gap') # long time, check d=75857586587AUTHORS:588589- David Joyner (2007-05)590"""591F = GF(2)592B = [[1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\593[0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\594[0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],\595[0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],\596[0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],\597[0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0],\598[0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],\599[0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0],\600[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0],\601[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0],\602[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0],\603[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1]]604# MS = MatrixSpace(F,12,23)605# V = VectorSpace(F,23)606V = span(B, F)607return LinearCodeFromVectorSpace(V, d=7)608609610def CyclicCodeFromGeneratingPolynomial(n,g,ignore=True):611r"""612If g is a polynomial over GF(q) which divides `x^n-1` then613this constructs the code "generated by g" (ie, the code associated614with the principle ideal `gR` in the ring615`R = GF(q)[x]/(x^n-1)` in the usual way).616617The option "ignore" says to ignore the condition that (a) the618characteristic of the base field does not divide the length (the619usual assumption in the theory of cyclic codes), and (b) `g`620must divide `x^n-1`. If ignore=True, instead of returning621an error, a code generated by `gcd(x^n-1,g)` is created.622623EXAMPLES::624625sage: P.<x> = PolynomialRing(GF(3),"x")626sage: g = x-1627sage: C = codes.CyclicCodeFromGeneratingPolynomial(4,g); C628Linear code of length 4, dimension 3 over Finite Field of size 3629sage: P.<x> = PolynomialRing(GF(4,"a"),"x")630sage: g = x^3+1631sage: C = codes.CyclicCodeFromGeneratingPolynomial(9,g); C632Linear code of length 9, dimension 6 over Finite Field in a of size 2^2633sage: P.<x> = PolynomialRing(GF(2),"x")634sage: g = x^3+x+1635sage: C = codes.CyclicCodeFromGeneratingPolynomial(7,g); C636Linear code of length 7, dimension 4 over Finite Field of size 2637sage: C.gen_mat()638[1 1 0 1 0 0 0]639[0 1 1 0 1 0 0]640[0 0 1 1 0 1 0]641[0 0 0 1 1 0 1]642sage: g = x+1643sage: C = codes.CyclicCodeFromGeneratingPolynomial(4,g); C644Linear code of length 4, dimension 3 over Finite Field of size 2645sage: C.gen_mat()646[1 1 0 0]647[0 1 1 0]648[0 0 1 1]649650On the other hand, CyclicCodeFromPolynomial(4,x) will produce a651ValueError including a traceback error message: "`x` must652divide `x^4 - 1`". You will also get a ValueError if you653type654655::656657sage: P.<x> = PolynomialRing(GF(4,"a"),"x")658sage: g = x^2+1659660followed by CyclicCodeFromGeneratingPolynomial(6,g). You will also661get a ValueError if you type662663::664665sage: P.<x> = PolynomialRing(GF(3),"x")666sage: g = x^2-1667sage: C = codes.CyclicCodeFromGeneratingPolynomial(5,g); C668Linear code of length 5, dimension 4 over Finite Field of size 3669670followed by C = CyclicCodeFromGeneratingPolynomial(5,g,False), with671a traceback message including "`x^2 + 2` must divide672`x^5 - 1`".673"""674P = g.parent()675x = P.gen()676F = g.base_ring()677p = F.characteristic()678if not(ignore) and p.divides(n):679raise ValueError, 'The characteristic %s must not divide %s'%(p,n)680if not(ignore) and not(g.divides(x**n-1)):681raise ValueError, '%s must divide x^%s - 1'%(g,n)682gn = GCD([g,x**n-1])683d = gn.degree()684coeffs = Sequence(gn.list())685r1 = Sequence(coeffs+[0]*(n - d - 1))686Sn = SymmetricGroup(n)687s = Sn.gens()[0] # assumes 1st gen of S_n is (1,2,...,n)688rows = [permutation_action(s**(-i),r1) for i in range(n-d)]689MS = MatrixSpace(F,n-d,n)690return LinearCode(MS(rows))691692CyclicCode = CyclicCodeFromGeneratingPolynomial693694def CyclicCodeFromCheckPolynomial(n,h,ignore=True):695r"""696If h is a polynomial over GF(q) which divides `x^n-1` then697this constructs the code "generated by `g = (x^n-1)/h`"698(ie, the code associated with the principle ideal `gR` in699the ring `R = GF(q)[x]/(x^n-1)` in the usual way). The700option "ignore" says to ignore the condition that the701characteristic of the base field does not divide the length (the702usual assumption in the theory of cyclic codes).703704EXAMPLES::705706sage: P.<x> = PolynomialRing(GF(3),"x")707sage: C = codes.CyclicCodeFromCheckPolynomial(4,x + 1); C708Linear code of length 4, dimension 1 over Finite Field of size 3709sage: C = codes.CyclicCodeFromCheckPolynomial(4,x^3 + x^2 + x + 1); C710Linear code of length 4, dimension 3 over Finite Field of size 3711sage: C.gen_mat()712[2 1 0 0]713[0 2 1 0]714[0 0 2 1]715"""716P = h.parent()717x = P.gen()718d = h.degree()719F = h.base_ring()720p = F.characteristic()721if not(ignore) and p.divides(n):722raise ValueError, 'The characteristic %s must not divide %s'%(p,n)723if not(h.divides(x**n-1)):724raise ValueError, '%s must divide x^%s - 1'%(h,n)725g = P((x**n-1)/h)726return CyclicCodeFromGeneratingPolynomial(n,g)727728def DuadicCodeEvenPair(F,S1,S2):729r"""730Constructs the "even pair" of duadic codes associated to the731"splitting" (see the docstring for ``is_a_splitting``732for the definition) S1, S2 of n.733734.. warning::735736Maybe the splitting should be associated to a sum of737q-cyclotomic cosets mod n, where q is a *prime*.738739EXAMPLES::740741sage: from sage.coding.code_constructions import is_a_splitting742sage: n = 11; q = 3743sage: C = cyclotomic_cosets(q,n); C744[[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]]745sage: S1 = C[1]746sage: S2 = C[2]747sage: is_a_splitting(S1,S2,11)748(True, 2)749sage: codes.DuadicCodeEvenPair(GF(q),S1,S2)750(Linear code of length 11, dimension 5 over Finite Field of size 3,751Linear code of length 11, dimension 5 over Finite Field of size 3)752"""753n = max(S1+S2)+1754if not(is_a_splitting(S1,S2,n)):755raise TypeError, "%s, %s must be a splitting of %s."%(S1,S2,n)756q = F.order()757k = Mod(q,n).multiplicative_order()758FF = GF(q**k,"z")759z = FF.gen()760zeta = z**((q**k-1)/n)761P1 = PolynomialRing(FF,"x")762x = P1.gen()763g1 = prod([x-zeta**i for i in S1+[0]])764g2 = prod([x-zeta**i for i in S2+[0]])765P2 = PolynomialRing(F,"x")766x = P2.gen()767gg1 = P2([lift2smallest_field(c)[0] for c in g1.coeffs()])768gg2 = P2([lift2smallest_field(c)[0] for c in g2.coeffs()])769C1 = CyclicCodeFromGeneratingPolynomial(n,gg1)770C2 = CyclicCodeFromGeneratingPolynomial(n,gg2)771return C1,C2772773def DuadicCodeOddPair(F,S1,S2):774"""775Constructs the "odd pair" of duadic codes associated to the776"splitting" S1, S2 of n.777778.. warning::779780Maybe the splitting should be associated to a sum of781q-cyclotomic cosets mod n, where q is a *prime*.782783EXAMPLES::784785sage: from sage.coding.code_constructions import is_a_splitting786sage: n = 11; q = 3787sage: C = cyclotomic_cosets(q,n); C788[[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]]789sage: S1 = C[1]790sage: S2 = C[2]791sage: is_a_splitting(S1,S2,11)792(True, 2)793sage: codes.DuadicCodeOddPair(GF(q),S1,S2)794(Linear code of length 11, dimension 6 over Finite Field of size 3,795Linear code of length 11, dimension 6 over Finite Field of size 3)796797This is consistent with Theorem 6.1.3 in [HP]_.798"""799n = max(S1+S2)+1800if not(is_a_splitting(S1,S2,n)):801raise TypeError, "%s, %s must be a splitting of %s."%(S1,S2,n)802q = F.order()803k = Mod(q,n).multiplicative_order()804FF = GF(q**k,"z")805z = FF.gen()806zeta = z**((q**k-1)/n)807P1 = PolynomialRing(FF,"x")808x = P1.gen()809g1 = prod([x-zeta**i for i in S1+[0]])810g2 = prod([x-zeta**i for i in S2+[0]])811j = sum([x**i/n for i in range(n)])812P2 = PolynomialRing(F,"x")813x = P2.gen()814coeffs1 = [lift2smallest_field(c)[0] for c in (g1+j).coeffs()]815coeffs2 = [lift2smallest_field(c)[0] for c in (g2+j).coeffs()]816gg1 = P2(coeffs1)817gg2 = P2(coeffs2)818C1 = CyclicCodeFromGeneratingPolynomial(n,gg1)819C2 = CyclicCodeFromGeneratingPolynomial(n,gg2)820return C1,C2821822823def ExtendedBinaryGolayCode():824"""825ExtendedBinaryGolayCode() returns the extended binary Golay code.826This is a perfect [24,12,8] code. This code is self-dual.827828EXAMPLES::829830sage: C = codes.ExtendedBinaryGolayCode()831sage: C832Linear code of length 24, dimension 12 over Finite Field of size 2833sage: C.minimum_distance()8348835sage: C.minimum_distance(algorithm='gap') # long time, check d=88368837838AUTHORS:839840- David Joyner (2007-05)841"""842B = [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1],\843[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0],\844[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1],\845[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0],\846[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1],\847[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1],\848[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1],\849[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0],\850[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0],\851[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0],\852[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1],\853[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1]]854V = span(B, GF(2))855return LinearCodeFromVectorSpace(V, d=8)856# C = BinaryGolayCode()857# return C.extended_code()858859860def ExtendedQuadraticResidueCode(n,F):861r"""862The extended quadratic residue code (or XQR code) is obtained from863a QR code by adding a check bit to the last coordinate. (These864codes have very remarkable properties such as large automorphism865groups and duality properties - see [HP]_, Section 6.6.3-6.6.4.)866867INPUT:868869870- ``n`` - an odd prime871872- ``F`` - a finite prime field F whose order must be a873quadratic residue modulo n.874875876OUTPUT: Returns an extended quadratic residue code.877878EXAMPLES::879880sage: C1 = codes.QuadraticResidueCode(7,GF(2))881sage: C2 = C1.extended_code()882sage: C3 = codes.ExtendedQuadraticResidueCode(7,GF(2)); C3883Linear code of length 8, dimension 4 over Finite Field of size 2884sage: C2 == C3885True886sage: C = codes.ExtendedQuadraticResidueCode(17,GF(2))887sage: C888Linear code of length 18, dimension 9 over Finite Field of size 2889sage: C3 = codes.QuadraticResidueCodeOddPair(7,GF(2))[0]890sage: C3x = C3.extended_code()891sage: C4 = codes.ExtendedQuadraticResidueCode(7,GF(2))892sage: C3x == C4893True894895AUTHORS:896897- David Joyner (07-2006)898"""899C = QuadraticResidueCodeOddPair(n,F)[0]900return C.extended_code()901902def ExtendedTernaryGolayCode():903"""904ExtendedTernaryGolayCode returns a ternary Golay code. This is a905self-dual perfect [12,6,6] code.906907EXAMPLES::908909sage: C = codes.ExtendedTernaryGolayCode()910sage: C911Linear code of length 12, dimension 6 over Finite Field of size 3912sage: C.minimum_distance()9136914sage: C.minimum_distance(algorithm='gap') # long time, check d=69156916917AUTHORS:918919- David Joyner (11-2005)920"""921B = [[1, 0, 0, 0, 0, 0, 2, 0, 1, 2, 1, 2],\922[0, 1, 0, 0, 0, 0, 1, 2, 2, 2, 1, 0],\923[0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1],\924[0, 0, 0, 1, 0, 0, 1, 1, 0, 2, 2, 2],\925[0, 0, 0, 0, 1, 0, 2, 1, 2, 2, 0, 1],\926[0, 0, 0, 0, 0, 1, 0, 2, 1, 2, 2, 1]]927V = span(B, GF(3))928return LinearCodeFromVectorSpace(V, d=6)929# C = TernaryGolayCode()930# return C.extended_code()931932def HammingCode(r,F):933r"""934Implements the Hamming codes.935936The `r^{th}` Hamming code over `F=GF(q)` is an937`[n,k,d]` code with length `n=(q^r-1)/(q-1)`,938dimension `k=(q^r-1)/(q-1) - r` and minimum distance939`d=3`. The parity check matrix of a Hamming code has rows940consisting of all nonzero vectors of length r in its columns,941modulo a scalar factor so no parallel columns arise. A Hamming code942is a single error-correcting code.943944INPUT:945946947- ``r`` - an integer 2948949- ``F`` - a finite field.950951952OUTPUT: Returns the r-th q-ary Hamming code.953954EXAMPLES::955956sage: codes.HammingCode(3,GF(2))957Linear code of length 7, dimension 4 over Finite Field of size 2958sage: C = codes.HammingCode(3,GF(3)); C959Linear code of length 13, dimension 10 over Finite Field of size 3960sage: C.minimum_distance()9613962sage: C.minimum_distance(algorithm='gap') # long time, check d=39633964sage: C = codes.HammingCode(3,GF(4,'a')); C965Linear code of length 21, dimension 18 over Finite Field in a of size 2^2966967While the ``codes`` object now gathers all code constructors,968``HammingCode`` is still available in the global namespace::969970sage: HammingCode(3,GF(2))971doctest:1: DeprecationWarning: This method soon will not be available in that way anymore. To use it, you can now call it by typing codes.HammingCode972See http://trac.sagemath.org/15445 for details.973Linear code of length 7, dimension 4 over Finite Field of size 2974975"""976q = F.order()977n = (q**r-1)/(q-1)978k = n-r979MS = MatrixSpace(F,n,r)980X = ProjectiveSpace(r-1,F)981PFn = [list(p) for p in X.point_set(F).points(F)]982H = MS(PFn).transpose()983Cd = LinearCode(H)984# Hamming code always has distance 3, so we provide the distance.985return LinearCode(Cd.dual_code().gen_mat(), d=3)986987988def LinearCodeFromCheckMatrix(H):989r"""990A linear [n,k]-code C is uniquely determined by its generator991matrix G and check matrix H. We have the following short exact992sequence993994.. math::9959960 \rightarrow997{\mathbf{F}}^k \stackrel{G}{\rightarrow}998{\mathbf{F}}^n \stackrel{H}{\rightarrow}999{\mathbf{F}}^{n-k} \rightarrow10000.10011002("Short exact" means (a) the arrow `G` is injective, i.e.,1003`G` is a full-rank `k\times n` matrix, (b) the1004arrow `H` is surjective, and (c)1005`{\rm image}(G)={\rm kernel}(H)`.)10061007EXAMPLES::10081009sage: C = codes.HammingCode(3,GF(2))1010sage: H = C.check_mat(); H1011[1 0 1 0 1 0 1]1012[0 1 1 0 0 1 1]1013[0 0 0 1 1 1 1]1014sage: codes.LinearCodeFromCheckMatrix(H) == C1015True1016sage: C = codes.HammingCode(2,GF(3))1017sage: H = C.check_mat(); H1018[1 0 1 1]1019[0 1 1 2]1020sage: codes.LinearCodeFromCheckMatrix(H) == C1021True1022sage: C = codes.RandomLinearCode(10,5,GF(4,"a"))1023sage: H = C.check_mat()1024sage: codes.LinearCodeFromCheckMatrix(H) == C1025True1026"""1027Cd = LinearCode(H)1028return Cd.dual_code()10291030def QuadraticResidueCode(n,F):1031r"""1032A quadratic residue code (or QR code) is a cyclic code whose1033generator polynomial is the product of the polynomials1034`x-\alpha^i` (`\alpha` is a primitive1035`n^{th}` root of unity; `i` ranges over the set of1036quadratic residues modulo `n`).10371038See QuadraticResidueCodeEvenPair and QuadraticResidueCodeOddPair1039for a more general construction.10401041INPUT:104210431044- ``n`` - an odd prime10451046- ``F`` - a finite prime field F whose order must be a1047quadratic residue modulo n.104810491050OUTPUT: Returns a quadratic residue code.10511052EXAMPLES::10531054sage: C = codes.QuadraticResidueCode(7,GF(2))1055sage: C1056Linear code of length 7, dimension 4 over Finite Field of size 21057sage: C = codes.QuadraticResidueCode(17,GF(2))1058sage: C1059Linear code of length 17, dimension 9 over Finite Field of size 21060sage: C1 = codes.QuadraticResidueCodeOddPair(7,GF(2))[0]1061sage: C2 = codes.QuadraticResidueCode(7,GF(2))1062sage: C1 == C21063True1064sage: C1 = codes.QuadraticResidueCodeOddPair(17,GF(2))[0]1065sage: C2 = codes.QuadraticResidueCode(17,GF(2))1066sage: C1 == C21067True10681069AUTHORS:10701071- David Joyner (11-2005)1072"""1073return QuadraticResidueCodeOddPair(n,F)[0]10741075def QuadraticResidueCodeEvenPair(n,F):1076"""1077Quadratic residue codes of a given odd prime length and base ring1078either don't exist at all or occur as 4-tuples - a pair of1079"odd-like" codes and a pair of "even-like" codes. If n 2 is prime1080then (Theorem 6.6.2 in [HP]_) a QR code exists over GF(q) iff q is a1081quadratic residue mod n.10821083They are constructed as "even-like" duadic codes associated the1084splitting (Q,N) mod n, where Q is the set of non-zero quadratic1085residues and N is the non-residues.10861087EXAMPLES::10881089sage: codes.QuadraticResidueCodeEvenPair(17,GF(13))1090(Linear code of length 17, dimension 8 over Finite Field of size 13,1091Linear code of length 17, dimension 8 over Finite Field of size 13)1092sage: codes.QuadraticResidueCodeEvenPair(17,GF(2))1093(Linear code of length 17, dimension 8 over Finite Field of size 2,1094Linear code of length 17, dimension 8 over Finite Field of size 2)1095sage: codes.QuadraticResidueCodeEvenPair(13,GF(9,"z"))1096(Linear code of length 13, dimension 6 over Finite Field in z of size 3^2,1097Linear code of length 13, dimension 6 over Finite Field in z of size 3^2)1098sage: C1 = codes.QuadraticResidueCodeEvenPair(7,GF(2))[0]1099sage: C1.is_self_orthogonal()1100True1101sage: C2 = codes.QuadraticResidueCodeEvenPair(7,GF(2))[1]1102sage: C2.is_self_orthogonal()1103True1104sage: C3 = codes.QuadraticResidueCodeOddPair(17,GF(2))[0]1105sage: C4 = codes.QuadraticResidueCodeEvenPair(17,GF(2))[1]1106sage: C3 == C4.dual_code()1107True11081109This is consistent with Theorem 6.6.9 and Exercise 365 in [HP]_.1110"""1111q = F.order()1112Q = quadratic_residues(n); Q.remove(0) # non-zero quad residues1113N = range(1,n); tmp = [N.remove(x) for x in Q] # non-zero quad non-residues1114if (n.is_prime() and n>2 and not(q in Q)):1115raise ValueError, "No quadratic residue code exists for these parameters."1116if not(is_a_splitting(Q,N,n)):1117raise TypeError, "No quadratic residue code exists for these parameters."1118return DuadicCodeEvenPair(F,Q,N)111911201121def QuadraticResidueCodeOddPair(n,F):1122"""1123Quadratic residue codes of a given odd prime length and base ring1124either don't exist at all or occur as 4-tuples - a pair of1125"odd-like" codes and a pair of "even-like" codes. If n 2 is prime1126then (Theorem 6.6.2 in [HP]_) a QR code exists over GF(q) iff q is a1127quadratic residue mod n.11281129They are constructed as "odd-like" duadic codes associated the1130splitting (Q,N) mod n, where Q is the set of non-zero quadratic1131residues and N is the non-residues.11321133EXAMPLES::11341135sage: codes.QuadraticResidueCodeOddPair(17,GF(13))1136(Linear code of length 17, dimension 9 over Finite Field of size 13,1137Linear code of length 17, dimension 9 over Finite Field of size 13)1138sage: codes.QuadraticResidueCodeOddPair(17,GF(2))1139(Linear code of length 17, dimension 9 over Finite Field of size 2,1140Linear code of length 17, dimension 9 over Finite Field of size 2)1141sage: codes.QuadraticResidueCodeOddPair(13,GF(9,"z"))1142(Linear code of length 13, dimension 7 over Finite Field in z of size 3^2,1143Linear code of length 13, dimension 7 over Finite Field in z of size 3^2)1144sage: C1 = codes.QuadraticResidueCodeOddPair(17,GF(2))[1]1145sage: C1x = C1.extended_code()1146sage: C2 = codes.QuadraticResidueCodeOddPair(17,GF(2))[0]1147sage: C2x = C2.extended_code()1148sage: C2x.spectrum(); C1x.spectrum()1149[1, 0, 0, 0, 0, 0, 102, 0, 153, 0, 153, 0, 102, 0, 0, 0, 0, 0, 1]1150[1, 0, 0, 0, 0, 0, 102, 0, 153, 0, 153, 0, 102, 0, 0, 0, 0, 0, 1]1151sage: C2x == C1x.dual_code()1152True1153sage: C3 = codes.QuadraticResidueCodeOddPair(7,GF(2))[0]1154sage: C3x = C3.extended_code()1155sage: C3x.spectrum()1156[1, 0, 0, 0, 14, 0, 0, 0, 1]1157sage: C3x.is_self_dual()1158True11591160This is consistent with Theorem 6.6.14 in [HP]_.1161"""1162from sage.coding.code_constructions import is_a_splitting1163q = F.order()1164Q = quadratic_residues(n); Q.remove(0) # non-zero quad residues1165N = range(1,n); tmp = [N.remove(x) for x in Q] # non-zero quad non-residues1166if (n.is_prime() and n>2 and not(q in Q)):1167raise ValueError, "No quadratic residue code exists for these parameters."1168if not(is_a_splitting(Q,N,n)):1169raise TypeError, "No quadratic residue code exists for these parameters."1170return DuadicCodeOddPair(F,Q,N)117111721173def RandomLinearCode(n,k,F):1174r"""1175The method used is to first construct a `k \times n`1176matrix using Sage's random_element method for the MatrixSpace1177class. The construction is probabilistic but should only fail1178extremely rarely.11791180INPUT: Integers n,k, with `n>k`, and a finite field F11811182OUTPUT: Returns a "random" linear code with length n, dimension k1183over field F.11841185EXAMPLES::11861187sage: C = codes.RandomLinearCode(30,15,GF(2))1188sage: C1189Linear code of length 30, dimension 15 over Finite Field of size 21190sage: C = codes.RandomLinearCode(10,5,GF(4,'a'))1191sage: C1192Linear code of length 10, dimension 5 over Finite Field in a of size 2^211931194AUTHORS:11951196- David Joyner (2007-05)1197"""1198MS = MatrixSpace(F,k,n)1199for i in range(50):1200G = MS.random_element()1201if G.rank() == k:1202V = span(G.rows(), F)1203return LinearCodeFromVectorSpace(V) # may not be in standard form1204MS1 = MatrixSpace(F,k,k)1205MS2 = MatrixSpace(F,k,n-k)1206Ik = MS1.identity_matrix()1207A = MS2.random_element()1208G = Ik.augment(A)1209return LinearCode(G) # in standard form121012111212def ReedSolomonCode(n,k,F,pts = None):1213r"""1214Given a finite field `F` of order `q`, let1215`n` and `k` be chosen such that1216`1 \leq k \leq n \leq q`. Pick `n` distinct1217elements of `F`, denoted1218`\{ x_1, x_2, ... , x_n \}`. Then, the codewords are1219obtained by evaluating every polynomial in `F[x]` of degree1220less than `k` at each `x_i`:12211222.. math::12231224C = \left\{ \left( f(x_1), f(x_2), ..., f(x_n) \right), f \in F[x],1225{\rm deg}(f)<k \right\}.122612271228`C` is a `[n, k, n-k+1]` code. (In particular, `C` is MDS.)12291230INPUT: n : the length k : the dimension F : the base ring pts :1231(optional) list of n points in F (if None then Sage picks n of them1232in the order given to the elements of F)12331234EXAMPLES::12351236sage: C = codes.ReedSolomonCode(6,4,GF(7)); C1237Linear code of length 6, dimension 4 over Finite Field of size 71238sage: C.minimum_distance()123931240sage: C = codes.ReedSolomonCode(6,4,GF(8,"a")); C1241Linear code of length 6, dimension 4 over Finite Field in a of size 2^31242sage: C.minimum_distance()124331244sage: C.minimum_distance(algorithm='gap') # long time, check d=n-k+1124531246sage: F.<a> = GF(3^2,"a")1247sage: pts = [0,1,a,a^2,2*a,2*a+1]1248sage: len(Set(pts)) == 6 # to make sure there are no duplicates1249True1250sage: C = codes.ReedSolomonCode(6,4,F,pts); C1251Linear code of length 6, dimension 4 over Finite Field in a of size 3^21252sage: C.minimum_distance()1253312541255While the ``codes`` object now gathers all code constructors,1256``ReedSolomonCode`` is still available in the global namespace::12571258sage: ReedSolomonCode(6,4,GF(7))1259doctest:1: DeprecationWarning: This method soon will not be available in that way anymore. To use it, you can now call it by typing codes.ReedSolomonCode1260See http://trac.sagemath.org/15445 for details.1261Linear code of length 6, dimension 4 over Finite Field of size 712621263REFERENCES:12641265- [W] http://en.wikipedia.org/wiki/Reed-Solomon1266"""1267q = F.order()1268power = lambda x,n,F: (x==0 and n==0) and F(1) or F(x**n) # since 0^0 is undefined1269if n>q or k>n or k>q:1270raise ValueError, "RS codes does not exist with the given input."1271if not(pts == None) and not(len(pts)==n):1272raise ValueError, "You must provide exactly %s distinct points of %s"%(n,F)1273if (pts == None):1274pts = []1275i = 01276for x in F:1277if i<n:1278pts.append(x)1279i = i+11280MS = MatrixSpace(F, k, n)1281rowsG = []1282rowsG = [[power(x,j,F) for x in pts] for j in range(k)]1283G = MS(rowsG)1284return LinearCode(G, d=n-k+1)128512861287def TernaryGolayCode():1288r"""1289TernaryGolayCode returns a ternary Golay code. This is a perfect1290[11,6,5] code. It is also equivalent to a cyclic code, with1291generator polynomial `g(x)=2+x^2+2x^3+x^4+x^5`.12921293EXAMPLES::12941295sage: C = codes.TernaryGolayCode()1296sage: C1297Linear code of length 11, dimension 6 over Finite Field of size 31298sage: C.minimum_distance()129951300sage: C.minimum_distance(algorithm='gap') # long time, check d=51301513021303AUTHORS:13041305- David Joyner (2007-5)1306"""1307F = GF(3)1308B = [[2, 0, 1, 2, 1, 1, 0, 0, 0, 0, 0],\1309[0, 2, 0, 1, 2, 1, 1, 0, 0, 0, 0],\1310[0, 0, 2, 0, 1, 2, 1, 1, 0, 0, 0],\1311[0, 0, 0, 2, 0, 1, 2, 1, 1, 0, 0],\1312[0, 0, 0, 0, 2, 0, 1, 2, 1, 1, 0],\1313[0, 0, 0, 0, 0, 2, 0, 1, 2, 1, 1]]1314V = span(B, F)1315return LinearCodeFromVectorSpace(V, d=5)13161317def ToricCode(P,F):1318r"""1319Let `P` denote a list of lattice points in1320`\ZZ^d` and let `T` denote the set of all1321points in `(F^x)^d` (ordered in some fixed way). Put1322`n=|T|` and let `k` denote the dimension of the1323vector space of functions `V = \mathrm{Span}\{x^e \ |\ e \in P\}`.1324The associated toric code `C` is the evaluation code which1325is the image of the evaluation map13261327.. math::13281329\mathrm{eval_T} : V \rightarrow F^n,133013311332where `x^e` is the multi-index notation1333(`x=(x_1,...,x_d)`, `e=(e_1,...,e_d)`, and1334`x^e = x_1^{e_1}...x_d^{e_d}`), where1335`eval_T (f(x)) = (f(t_1),...,f(t_n))`, and where1336`T=\{t_1,...,t_n\}`. This function returns the toric1337codes discussed in [J]_.13381339INPUT:134013411342- ``P`` - all the integer lattice points in a polytope1343defining the toric variety.13441345- ``F`` - a finite field.134613471348OUTPUT: Returns toric code with length n = , dimension k over field1349F.13501351EXAMPLES::13521353sage: C = codes.ToricCode([[0,0],[1,0],[2,0],[0,1],[1,1]],GF(7))1354sage: C1355Linear code of length 36, dimension 5 over Finite Field of size 71356sage: C.minimum_distance()1357241358sage: C = codes.ToricCode([[-2,-2],[-1,-2],[-1,-1],[-1,0],[0,-1],[0,0],[0,1],[1,-1],[1,0]],GF(5))1359sage: C1360Linear code of length 16, dimension 9 over Finite Field of size 51361sage: C.minimum_distance()136261363sage: C = codes.ToricCode([ [0,0],[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[3,1],[3,2],[4,1]],GF(8,"a"))1364sage: C1365Linear code of length 49, dimension 11 over Finite Field in a of size 2^313661367This is in fact a [49,11,28] code over GF(8). If you type next1368``C.minimum_distance()`` and wait overnight (!), you1369should get 28.13701371AUTHOR:13721373- David Joyner (07-2006)13741375REFERENCES:13761377.. [J] D. Joyner, Toric codes over finite fields, Applicable1378Algebra in Engineering, Communication and Computing, 15, (2004), p. 63-79.1379"""1380from sage.combinat.all import Tuples1381mset = [x for x in F if x!=0]1382d = len(P[0])1383pts = Tuples(mset,d).list()1384n = len(pts) # (q-1)^d1385k = len(P)1386e = P[0]1387B = []1388for e in P:1389tmpvar = [prod([t[i]**e[i] for i in range(d)]) for t in pts]1390B.append(tmpvar)1391# now B0 *should* be a full rank matrix1392MS = MatrixSpace(F,k,n)1393return LinearCode(MS(B))139413951396def TrivialCode(F,n):1397MS = MatrixSpace(F,1,n)1398return LinearCode(MS(0))139914001401def WalshCode(m):1402r"""1403Returns the binary Walsh code of length `2^m`. The matrix1404of codewords correspond to a Hadamard matrix. This is a (constant1405rate) binary linear `[2^m,m,2^{m-1}]` code.14061407EXAMPLES::14081409sage: C = codes.WalshCode(4); C1410Linear code of length 16, dimension 4 over Finite Field of size 21411sage: C = codes.WalshCode(3); C1412Linear code of length 8, dimension 3 over Finite Field of size 21413sage: C.spectrum()1414[1, 0, 0, 0, 7, 0, 0, 0, 0]1415sage: C.minimum_distance()141641417sage: C.minimum_distance(algorithm='gap') # check d=2^(m-1)1418414191420REFERENCES:14211422- http://en.wikipedia.org/wiki/Hadamard_matrix14231424- http://en.wikipedia.org/wiki/Walsh_code1425"""1426return LinearCode(walsh_matrix(m), d=2**(m-1))142714281429